コールグラフの可視化(毛玉を避ける Focus+Context と描画ライブラリ)

一言まとめ

コールグラフの全体表示は規模を問わず毛玉(hairball)になる。選択ノードと N ホップ近傍だけ展開して残りを畳む Focus+Context が実用解で、数百ノードなら Cytoscape.js + ELKjs の layered レイアウト、配信はローカルサーバ + ブラウザが最小構成。

作成 · 更新 · #call-graph#visualization#cytoscape#elk
目次 10 sections
  1. 01 全体表示は毛玉になる
  2. 02 既存ツールの UX
  3. 03 描画ライブラリ(2026)
  4. 04 レイアウト
  5. 05 分かりやすさの UX パターン
  6. 06 配信形態
  7. 07 使われない図になる失敗パターン
  8. 08 最小構成の推奨
  9. 09 関連
  10. 10 更新履歴

調査時点: 2026-06。TypeScript のコールグラフ抽出ツールの出力をどう見せるかを調べたもの。Mermaid や素の Graphviz は密になると線が絡み、zoom・focus・検索がないため不向き、という前提から始めている。

コールグラフは、関数を頂点、ある関数から別の関数への呼び出しを矢印として表した図。処理の流れや変更の影響範囲を調べるために使う。

全体表示は毛玉になる#

関数単位のコールグラフは、中規模のコードベースで数百ノードになる。force-directed で全体を一度に描くと線が絡んだ塊(hairball)になり、規模を問わず読めない。実用解は 1 つで、選択したノードと N ホップの近傍だけを展開し、残りを畳む Focus+Context。

既存ツールの UX#

ツール方式学べる点 / 弱点
Sourcetrail(OSS、2021-12 アーカイブ、コミュニティフォークが継続)三画面連動検索でシンボルを選ぶ → グラフが即座に再センタリング → エッジをクリックすると該当コード行へジャンプ。クラスは折りたたみスーパーノードで、隠れた要素数を数字バッジで示す。start と target と深さスライダーで Custom Trail を切り出す。bundled edges
go-callvis(Go)ポインタ解析 → dot → SVG を localhost で配信パッケージ単位のフォーカス、-nostd / -noext で標準ライブラリと外部を除外。SVG が大きすぎてブラウザが固まるという批判がある
IDE の Call Hierarchy(VSCode CallHierarchyProvider / IntelliJ)ツリー展開コード連動が完全で学習コストがない。グラフ構造が見えず横断的な把握には向かない
CodeSee / CodeChartaモジュール依存マップ / 3D 都市メトリクス関数レベルの呼び出し関係は出さない

描画ライブラリ(2026)#

ライブラリ描画規模の目安備考
Cytoscape.jsCanvas3〜5k ノードで FPS 低下(二次情報)解析向け。ELK / dagre アダプタが公式、compound node 対応
Sigma.js + graphologyWebGL10k 超大規模に強いが階層レイアウトが薄い
vis-networkCanvasCytoscape と同程度学習コストが低い
React Flow(xyflow)DOM / SVG1000 ノード超は公式が非推奨ダイアグラムエディタ向け
G6(AntV)Canvas / WebGL3 万プリミティブ程度高機能だがドキュメント品質にばらつき

数十〜数百関数のコールグラフなら Cytoscape.js で足りる。数千を超えたら Sigma.js を検討する。

レイアウト#

有向グラフなので階層型レイアウトを使う。

  • ELKjs layered: 活発に開発され、アルゴリズムが多い。cytoscape-elk で Cytoscape.js と組める
  • dagre: 事実上メンテナンスが止まっており、ダウンロード数も桁違いに少ない
  • d3-dag: TypeScript ファーストの現代的な代替

再帰呼び出しがあると厳密な DAG(循環を持たない有向グラフ) にならない。ELK の循環処理(仮想ノードの挿入か)は一次情報で未確認。

分かりやすさの UX パターン#

  1. Focus+Context: 選択ノード + N ホップ近傍だけ展開。残りは数字バッジ付きの折りたたみ。深さスライダーと Trail 履歴を付ける
  2. 段階的開示: クラス / モジュールをスーパーノードにしてクリックで開く(expand-on-click)。ズームレベルでクラスタ表示と個別関数表示を切り替える(semantic zoom)
  3. クラスタリング: ファイル / ディレクトリを compound node でグルーピングする
  4. エッジ管理: bundled edges、方向の色分け(通常は灰、再帰は赤)。Hierarchical Edge Bundling は数百規模には過剰
  5. 毛玉防止: 全体を最初に見せない(entrypoint 起点)、標準ライブラリと node_modules を初期状態でフィルタ、検索 → ハイライト → フォーカスの導線、重要度(betweenness など)をノードサイズに反映

配信形態#

形態利点欠点
ローカルサーバ + ブラウザ(npx <tool> serve)実装が最小、依存フリー、分割ロードできるコマンド起動が要る
静的 HTML 単一ファイル渡せば動く。CI の artifact にできる数千ノードで MB 超。複雑な UI が難しい
VS Code WebView 拡張コードジャンプが完全marketplace 依存、VS Code 専用。Call Graph Navi など既存拡張が多い

OSS として配るなら CLI + ローカルサーバ型を主軸にすると、既存の VS Code 拡張群と役割が分かれる。

使われない図になる失敗パターン#

  1. 全体を一度に見せる設計
  2. インタラクションのない静的 PNG / SVG(go-callvis への「SVG が大きすぎて固まる」批判)
  3. 標準ライブラリ / node_modules を展開してしまう(フィルタの実装忘れ)
  4. force-directed の非決定レイアウト(前回見た位置に戻れない)
  5. 最初の 5 分で有用さが伝わらない

最小構成の推奨#

CLI が静的解析でコールグラフを JSON に出し、serve でローカル HTTP を立て、ブラウザで Cytoscape.js + cytoscape-elk(layered)が描く。UX の最低ラインは 4 点。

  1. 選択ノード + 2 ホップ近傍のみ表示
  2. 標準ライブラリ / node_modules を初期フィルタ
  3. クリックで呼び元 / 呼び先を展開
  4. 検索バーでハイライト

Sourcetrail の「コードへジャンプ」は VS Code 拡張版で後付けし、スタンドアロン版は URL に行番号を渡す程度で代替する。

関連#

更新履歴#

  • 2026-06-19: 初版(ローカル調査ノート)
  • 2026-10-17: Wiki へ移植、概念ページとして再構成。冒頭に定義を追加

出典

  1. https://github.com/CoatiSoftware/Sourcetrail/blob/master/DOCUMENTATION.md
  2. https://ondrajz.github.io/go-callvis/
  3. https://js.cytoscape.org/
  4. https://github.com/cytoscape/cytoscape.js-elk
  5. https://github.com/xyflow/xyflow/discussions/3003
  6. https://erikbrinkman.github.io/d3-dag/
  7. https://cambridge-intelligence.com/blog/hairball-effect-in-graph-visualization/
  8. https://fse.studenttheses.ub.rug.nl/9153/1/hoogendorp10.pdf

同じトピック — ソフトウェア設計