本記事は個人で行った検証をまとめたものです。性能に関する記述は、手元のWindows 11・Chrome環境で確認した参考値です。
はじめに
Obsidianのグラフビューという有名な画面があります。ノート同士のつながりを力学シミュレーションで自動配置して見せてくれるものです。私も何回か使ってみたことがあるのですが、正直なところ、よく使い方がわかりませんでした。ただ、言及している人は多く、何かに使えるのではないかと注目はしていて、自分でも実装してみたいと思っていました。
調べた範囲では、使い方の一つとして、どこからもリンクされていない孤立ノードを見つけるのに役立ちそうです。また、私はLLMを使ったWiki作り(LLM Wiki)を続けています。LLM Wikiの基本設計はObsidianを使う前提なので、Obsidian上ならグラフビューは何もしなくても見られるのですが、私はMkDocsでWebページとして構築しているため、同じようなグラフビューをWebページ上に独自に表示する必要があります。リンクの管理は現状Wiki Linkで問題なくできているものの、グラフとして見えるようになれば、もっと効率的な管理ができるのではないかという期待もあります。その模索も兼ねて、自分で実装してみることにしました。
まずVis Networkで実装した
最初に選んだライブラリはVis Network(vis-network)です。グラフ表示用のデータ(ノードとエッジのJSON)は、このために自分で用意しました。
実装したのは次のような機能です。
- ノードをクリックすると詳細パネルを表示
- ダブルクリックで該当ページへジャンプ
- 接続数に応じてノードのサイズを変更
- カテゴリごとの色分け
- 力学シミュレーションによる自動配置
数百ノード規模で、機能・使用感とも問題なく、やりたいことは全部実現できました。
そのうえで、他のライブラリを選んでいたらどう違ったのかを確認するため、同じデータ・同じ機能で主要ライブラリを一通り実装して比較してみました。この記事はその記録です。
同じものを5つのライブラリで作る
対象は次の5つです。いずれも実装に使ったバージョンを固定しています(2026年7月時点の安定版)。
| ライブラリ | 公式ページ | 使用バージョン |
|---|---|---|
| Vis Network(vis-network) | https://visjs.github.io/vis-network/ | 10.1.0 |
| force-graph | https://github.com/vasturiano/force-graph | 1.51.4 |
| Cytoscape.js | https://js.cytoscape.org/ | 3.34.0 |
| Sigma.js | https://www.sigmajs.org/ | 3.0.3 |
| D3(D3.js) | https://d3js.org/ | 7.9.0 |
候補としてはApache EChartsも調査しましたが、グラフ特化のライブラリではないため、今回の実装比較からは外しています。
実装する機能は先ほどの箇条書きと同じ(表示、クリックで詳細、ダブルクリックでリンクを開く、接続数に応じたノードサイズ)に揃えました。
データは公開できるものにするため、この5ライブラリと関連パッケージ(3D版、React版、Cytoscape.jsの拡張、Graphology一式など)のnpm依存関係を使いました。package-lock.jsonからパッケージ名単位で生成した簡易グラフで、同名の別バージョンは1ノードに統合しています。全部で172ノード、312エッジです。
デモとソースコードはGitHubに置きました。ブラウザでそのまま触れます。
5つのプレビューは、それぞれ次のような表示になります。
作ってみて気付いたのは、基本表示までなら、どのライブラリも50〜60行程度のJavaScriptで実装できたことです。少なくともこの最小機能の範囲では、導入の難度に大きな差は感じませんでした。
行数の計測ルール
スケール切替機能を追加する前の初期実装について、HTML内のグラフ生成・操作にあたるJavaScriptを、空行・コメント抜きで数えたものです(CSSやHTMLは含みません)。Vis Network 52行、Sigma.js 53行、Cytoscape.js 59行、force-graph 64行、D3 65行でした。なおSigma版はSigma.js本体に加えてGraphologyとgraphology-libraryを読み込んでいます。行数は改行スタイルや共通処理の切り出し方に左右されるため、あくまで参考値です。
人気と保守状況を数字で見る
定番の数字を整理しておきます。2026年7月19日時点の値です。
| ライブラリ | GitHub Star | npm週間DL数 | 最新安定版 | 最終リリース |
|---|---|---|---|---|
| D3 | 113k | 14,745,591 | v7.9.0 | 2024年3月。以降新リリースなし(リポジトリの更新は継続) |
| Sigma.js | 12k | 280,907 | v3.0.3(v4.0.0-alpha.7あり) | 2026年4月(モノレポ内の最新リリース) |
| Cytoscape.js | 11k | 10,492,865 | v3.34.0 | 2026年6月 |
| Vis Network | 3.6k | 628,624 | v10.1.0 | 2026年5月。2025年にv10メジャー更新 |
| force-graph | 2.1k | 655,576 | v1.51.4 | 2026年4月(GitHub Releasesではなくタグで運用) |
この表の読み方には注意が必要です。
npm週間DL数は、npmのダウンロード数APIで開始日・終了日を明示して、全パッケージ同一期間(2026-07-11〜17)で取得した値です。日付を指定しない取得では、パッケージによって集計週の揃わない値が返ることがありました。また、DL数にはCIや自動ビルド、依存パッケージとしてのインストールも含まれるため、実利用者数を直接示す数字ではありません。
「最終コミットが新しい=開発が活発」でもありません。近年はRenovateなどのbotによる依存更新コミットが多いため、活動状況はリリースの中身と頻度で判断する必要があります。
なお、「vis.jsはもう終わった」という情報を見かけることがありますが、これは旧vis.jsリポジトリが2019年に開発終了・アーカイブされた件を指しています。その後継として分割されたVis Networkはvisjsコミュニティで保守が継続しており、上の表の通り2025年以降もリリースが続いています。
データを10倍・100倍にして動作を確認する
172ノード程度ではどのライブラリも問題なく動くため、規模を上げたときの挙動を確認しました。データを複製して、×10(1,720ノード・3,210エッジ)と×100(17,200ノード・32,190エッジ)を用意し、各デモのスケール切替(ライブデモの各ページ上部にあります)で試せるようにしています。
この比較の前提条件です。
- ×10・×100のデータは、元グラフを複製してコピー間を疎なエッジでつないだ負荷試験用データです。コピー分のノードはラベルや詳細属性を省略しているため、ラベル描画の負荷は実際より軽めに出ます
- ブラウザが即座に停止しないよう、反復回数やレイアウト方式をライブラリごとに個別調整しています(例えば×100のCytoscape.jsはランダム配置のみ)。同一条件の厳密なベンチマークではなく、「各実装を実用的な設定で動かしたときの動作比較」です
- 各ライブラリの標準的な構成で比較しています。Cytoscape.jsには3.31以降、実験的なWebGL描画モードがありますが、今回は未使用です。表のCytoscape.jsの結果は通常レンダラーのものです
- ×100のD3(SVG実装)はブラウザがクラッシュ同然になることがあります。試す場合は未保存の作業がないブラウザで実行してください
手元のWindows 11・Chrome環境での結果です。
| ライブラリ | ×10(1,720ノード) | ×100(17,200ノード) |
|---|---|---|
| Vis Network | 問題なし | 操作できないレベル。Chromeから「応答なし」の通知 |
| force-graph | 問題なし | 遅いが、なんとか操作できる |
| Cytoscape.js | レイアウト計算が非常に長い | 描画が長すぎて実用外 |
| Sigma.js | 快適 | 計算も速く、操作できる |
| D3(SVG実装) | 描画は速いが、その後の操作がカクつく | ブラウザがクラッシュ同然で操作不能 |
なお、この表の結果は当初Sigma.js v2.4.0・Vis Network 9.1.9で確認したものですが、その後それぞれv3.0.3・10.1.0へ更新して再確認したところ、操作感は変わりませんでした。
今回の確認では、WebGLで描画するSigma.jsが最も余裕がありました。反対に、SVGで素朴に実装したD3版が最も危険な結果になりました。SVGはノードもエッジもDOM要素になるため、×100ではノード17,200個に加えてエッジ32,190本、グラフ部分だけで約4万9千個のSVG要素の座標を、シミュレーションが動いている間ずっと更新し続けることになります。なおD3自体はCanvasでも描画できるので、これはD3というライブラリの限界というより、SVGという実装方式の限界です。
もう1つ、Sigma.jsで確認できたことがあります。レンダラーの初期化は短時間で終わる一方、レイアウト計算(ForceAtlas2)には規模に応じた時間がかかります。「WebGLだから大規模でも安心」と言えるのは描画の部分だけで、レイアウト計算は別のコストとして残ります。逆に言えば、座標を事前計算してデータに焼き込んでおけば、この計算を省略できるので初期表示を大幅に短縮できます。
データ総数と同時表示数を分けて考える
規模の話には重要な前提があります。「データベース全体のノード数」と「一度に画面へ表示するノード数」は別物だということです。
データ全体が数万件でも、検索や選択で基点ノードを決めて、そこから1〜2ホップ先までを取得し、同時表示数を数百件に抑える設計は可能です。Obsidianにも、現在のノート周辺だけを表示するローカルグラフという機能があります。この設計を取るなら、表示部分はどのライブラリでも成立する規模に収まります。
ただし、どのデータを表示するかの選定、上限件数での足切り、ズームに応じた段階表示といった制御は、ライブラリ任せにはできません。ライブラリが担当するのは基本的に描画で、表示対象の設計はアプリケーション側の仕事になります。
また、数万ノードの全体表示は、Sigma.jsのように技術的には描画できても、ノードが小さすぎて識別できない、エッジが密集して読めないなど、可読性の問題は別に残ります。描画性能と情報設計は分けて考える必要があります。
ライブラリ固有機能への依存と移行コスト
もう1つ、比較していて重要だと感じたのが、ライブラリ固有の組み込み機能にどれだけ依存するかという観点です。
機能は3種類に分けられます。1つめは、ノード・エッジの表示、色やサイズ、ズーム・パン、クリックイベントといった、どのライブラリでも実装できる基本機能。2つめは、特定ライブラリだけが組み込みで持つ機能。例えばVis Networkのクラスタリングと編集UI、Cytoscape.jsのグラフ分析API、force-graphの3D系エコシステムです。3つめは、検索や永続化など、どのみちアプリケーション側で作る機能です。
このうち基本機能だけに絞った実装なら、移行は比較的容易です。実際、Vis Network版の基本表示をSigma.js版へ移植したところ、コードは52行が53行になった程度で、データ変換も機械的でした。一方、2つめの固有機能に依存した部分は、移行先に同等機能がなければ作り直しになります。
Vis Networkのクラスタリング機能について補足しておきます。これは複数のノードを1つにまとめて、展開・折り畳みできる機能です。任意の条件(グループ名の一致など)だけでなく、接続関係やハブ、末端ノードを基準にまとめることもでき、クラスターノードのラベルや属性も設定できます。ただし、コミュニティ検出や意味に基づく自動分類を行う機能とは目的が異なります。私が自作しているカテゴリ分類(粒度の変更、命名、アルゴリズムの変更などができるもの)の代替にはなりませんが、グラフの簡略表示や既存カテゴリの折り畳みには活用できます。

Vis Network標準機能だけで作ったクラスタリング+編集UIのデモ(ライブデモで試せます)
ここから導ける設計上のアドバイスは次の通りです。将来、データの増加などでライブラリを移行する可能性があるなら、共通のデータ形式を正本にして、ライブラリごとの描画処理をアダプターとして分離し、固有の組み込み機能への依存は最小限にしておく。移行コストはコードの行数ではなく、固有機能への依存の数で決まります。
結論:小規模で完結するならVis Network、大規模表示が見えているなら最初からWebGL系
用途別の整理です。
| 想定 | 候補 |
|---|---|
| 同時表示数が数百で収まり、手早く関係グラフを出したい | Vis Network |
| 動きのある表現や3D展開を重視する | force-graph |
| 最短経路や中心性など、グラフ分析までやりたい | Cytoscape.js |
| 数千〜数万ノードの同時表示が要件にある | Sigma.js |
| 既存の枠にない独自表現を作り込みたい | D3 |
そのうえで、選定の進め方について私の考えを書いておきます。
プロトタイプなら、すぐ作って比べるのが一番です。基本表示は50〜60行で動くので、迷っている時間で全部試せます。
しかし本採用の選定は別です。将来の最大同時表示数、必要になる分析・編集機能、固有機能への依存度をまず整理して、移行の可能性があるならそのコストまで織り込んで選ぶべきです。ライブラリはプロジェクトの根幹に組み込むほど、あとからの差し替えコストが大きくなります。将来数万ノードの表示が必要だとわかっているのに、目先の手軽さでライブラリを選び、あとから大きなコストをかけて移行するのは合理的ではありません。その場合は最初からWebGL系を中心に検討すべきです。
私自身はどうするかというと、冒頭の「まずVis Networkで実装した」グラフビューは、扱うデータが数万件を超えてくる可能性があります。その規模になっても現状と同じように高速に扱えるよう、WebGL系、具体的にはSigma.jsへ移行しようと考えています。
デモは触ってみるのが一番早いので、よければどうぞ。





