Graph

Библиотека для визуализации больших графов с динамическим уровнем детализации

@gravity-ui/graph · npm package Release storybook

Библиотека для визуализации графов, объединяющая преимущества двух подходов:

  • Canvas для быстрой отрисовки всего графа
  • HTML/React для удобного взаимодействия при приближении

Больше не нужно выбирать между производительностью и интерактивностью. Идеально подходит для больших графов, блок-схем и редакторов на основе узлов.

Мотивация

Современные веб-приложения часто требуют сложной визуализации и интерактивности, но существующие решения обычно используют только одну технологию отрисовки:

  • Canvas обеспечивает высокую производительность для сложной графики, но ограничен в работе с текстом и взаимодействием с пользователем.
  • HTML DOM удобен для интерфейсов, но теряет производительность при сложной графике или большом количестве элементов.

@gravity-ui/graph решает эту проблему, автоматически переключаясь между Canvas и HTML в зависимости от масштаба:

  • При отдалении: Использует Canvas для быстрой отрисовки всего графа
  • Среднее приближение: Показывает упрощенное представление с базовым взаимодействием
  • При приближении: Переключается на HTML/React компоненты для полноценного взаимодействия

Как это работает

Библиотека использует умную систему отрисовки, которая автоматически управляет переключением между Canvas и React компонентами:

  1. На низких уровнях масштаба всё отрисовывается на Canvas для производительности
  2. При приближении к детальному виду, компонент BlocksList:
    • Следит за изменениями области просмотра и масштаба
    • Определяет видимые блоки в текущей области (с запасом для плавного скролла)
    • Создает React компоненты только для видимых блоков
    • Обновляет список при скролле или изменении масштаба
    • Удаляет React компоненты при отдалении
// Пример использования React компонентов
const MyGraph = () => {
  return (
    <GraphCanvas
      graph={graph}
      renderBlock={(graph, block) => (
        <MyCustomBlockComponent 
          graph={graph} 
          block={block}
        />
      )}
    />
  );
};

Storybook

Установка

npm install @gravity-ui/graph

Примеры

Пример на React

Подробная документация по React компонентам

import { GraphCanvas, GraphState, GraphBlock, useGraph } from "@gravity-ui/graph";
import React from "react";

const config = {};

export function GraphEditor() {
  const { graph, setEntities, start } = useGraph(config);

  useEffect(() => {
    setEntities({
      blocks: [
        {
          is: "block-action",
          id: "action_1",
          x: -100,
          y: -450,
          width: 126,
          height: 126,
          selected: true,
          name: "Блок #1",
          anchors: [],
        },
        {
          id: "action_2",
          is: "block-action",
          x: 253,
          y: 176,
          width: 126,
          height: 126,
          selected: false,
          name: "Блок #2",
          anchors: [],
        }
      ],
      connections: [
        {
          sourceBlockId: "action_1",
          targetBlockId: "action_2",
        }
      ]
    });
  }, [setEntities]);

  const renderBlockFn = (graph, block) => {
    return <GraphBlock graph={graph} block={block}>{block.id}</GraphBlock>;
  };

  return (
    <GraphCanvas
      graph={graph}
      renderBlock={renderBlockFn}
      onStateChanged={({ state }) => {
        if (state === GraphState.ATTACHED) {
          start();
          graph.zoomTo("center", { padding: 300 });
        }
      }}
    />
  );
}

Пример на JavaScript

import { Graph } from "@gravity-ui/graph";

// Создаем контейнер
const container = document.createElement('div');
container.style.width = '100vw';
container.style.height = '100vh';
container.style.overflow = 'hidden';
document.body.appendChild(container);

// Инициализируем граф с конфигурацией
const graph = new Graph({
    configurationName: "example",
    blocks: [],
    connections: [],
    settings: {
        canDragCamera: true,
        canZoomCamera: true,
        useBezierConnections: true,
        showConnectionArrows: true
    }
}, container);

// Добавляем блоки и связи
graph.setEntities({
    blocks: [
        {
            is: "block-action",
            id: "block1",
            x: 100,
            y: 100,
            width: 120,
            height: 120,
            name: "Блок #1"
        },
        {
            is: "block-action",
            id: "block2",
            x: 300,
            y: 300,
            width: 120,
            height: 120,
            name: "Блок #2"
        }
    ],
    connections: [
        {
            sourceBlockId: "block1",
            targetBlockId: "block2"
        }
    ]
});

// Запускаем отрисовку
graph.start();

// Центрируем вид
graph.zoomTo("center", { padding: 100 });

Демо

Документация

Основные концепции

РазделОписаниеДокументация
Жизненный цикл компонентовИнициализация, обновление, отрисовка и удаление компонентовПодробнее
Механизм отрисовкиПроцесс отрисовки и оптимизацииПодробнее
Система событийОбработка и распространение событийПодробнее

Основные компоненты

КомпонентОписаниеДокументация
Canvas GraphОснова для визуальных элементов с системой обнаруженияПодробнее
Block ComponentБазовые блоки для узлов графаПодробнее
ConnectionsСоздание и стилизация связейПодробнее

Дополнительные возможности

ВозможностьОписаниеДокументация
Система слоевУправление z-index и отрисовка по слоямПодробнее
Группы блоковАвтоматическая и ручная группировкаПодробнее
ПланировщикУправление кадрами и приоритетами обновленийПодробнее

Конфигурация

ТемаОписаниеДокументация
Настройки графаПараметры конфигурацииПодробнее
APIМетоды для управления графомПодробнее
О библиотеке
Звёзды
27
Версия
0.4.3
Последнее обновление
14.05.2025
Репозиторий
github.com/gravity-ui/graph
Лицензия
MIT License
Maintainers
Участники