Graph

動的なスケール対応の詳細化を備えた高性能グラフレンダラー。

@gravity-ui/graph · npm package Release storybook

v0.x から v1.x への移行ガイド →

両方の長所を兼ね備えたグラフ描画ライブラリです。

  • 全体像を表示する際の高パフォーマンスのために Canvas を使用
  • ズームイン時のリッチなインタラクションのために HTML/React を使用

パフォーマンスとインタラクティブ性のどちらかを選択する必要はもうありません。大規模な図、フローチャート、ノードベースのエディタに最適です。

preview graph.

モチベーション

現代のウェブアプリケーションでは、複雑な描画とインタラクションが求められることがよくありますが、既存のソリューションは通常、単一のレンダリング技術に焦点を当てています。

  • Canvas は複雑なグラフィックスに対して高いパフォーマンスを提供しますが、テキスト処理やインタラクションには制限があります。
  • HTML DOM はインターフェースには便利ですが、複雑なグラフィックスや多数の要素には効率が悪いです。

@gravity-ui/graph は、ズームレベルに応じて Canvas と HTML を自動的に切り替えることで、この問題を解決します。

  • ズームアウト時: グラフ全体を効率的にレンダリングするために Canvas を使用
  • 中程度のズーム: 基本的なインタラクションを備えた概略図を表示
  • ズームイン時: リッチなインタラクションのために HTML/React コンポーネントに切り替え

仕組み

このライブラリは、Canvas と React コンポーネント間の遷移を自動的に管理するスマートなレンダリングシステムを使用しています。

  1. 低いズームレベルでは、パフォーマンスのためにすべて Canvas 上にレンダリングされます。
  2. 詳細表示にズームインすると、GraphCanvas コンポーネントは以下の処理を行います。
    • カメラのビューポートとスケールの変更を追跡します。
    • 現在のビューポートで表示されているブロックを(スムーズなスクロールのためのパディングを含めて)計算します。
    • 表示されているブロックに対してのみ 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 React, { useEffect } from "react";
import type { Graph, TBlock } from "@gravity-ui/graph";
import { EAnchorType, GraphState } from "@gravity-ui/graph";
import { GraphCanvas, GraphBlock, useGraph } from "@gravity-ui/graph/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: "Block #1",
          anchors: [
            {
              id: "out1",
              blockId: "action_1",
              type: EAnchorType.OUT,
              index: 0,
            },
          ],
        },
        {
          id: "action_2",
          is: "block-action",
          x: 253,
          y: 176,
          width: 126,
          height: 126,
          selected: false,
          name: "Block #2",
          anchors: [
            {
              id: "in1",
              blockId: "action_2",
              type: EAnchorType.IN,
              index: 0,
            },
          ],
        },
      ],
      connections: [
        {
          sourceBlockId: "action_1",
          sourceAnchorId: "out1",
          targetBlockId: "action_2",
          targetAnchorId: "in1",
        },
      ],
    });
  }, [setEntities]);

  const renderBlockFn = (graph: Graph, block: TBlock) => {
    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 });
        }
      }}
    />
  );
}

Vanilla 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",
            anchors: [
                {
                    id: "out1",
                    blockId: "block1",
                    type: EAnchorType.OUT,
                    index: 0
                }
            ]
        },
        {
            is: "block-action",
            id: "block2",
            x: 300,
            y: 300,
            width: 120,
            height: 120,
            name: "ブロック #2",
            anchors: [
                {
                    id: "in1",
                    blockId: "block2",
                    type: EAnchorType.IN,
                    index: 0
                }
            ]
        }
    ],
    connections: [
        {
            sourceBlockId: "block1",
            sourceAnchorId: "out1",
            targetBlockId: "block2",
            targetAnchorId: "in1"
        }
    ]
});

// レンダリングを開始
graph.start();

// ビューを中央に配置
graph.zoomTo("center", { padding: 100 });

ライブデモ

ドキュメント

目次

  1. システム

  2. コンポーネント

  3. レンダリング

  4. ブロックと接続

ライブラリについて
スターでライブラリを応援
バージョン
1.8.6
最終更新日
05.03.2026
リポジトリ
github.com/gravity-ui/graph
ライセンス
MIT License
メンテナー
コントリビューター