はじめに
JavaScriptのネットワークグラフ描画ライブラリであるSigma.jsについて学んだことをまとめました。
ネットワークグラフとは、ある「ノード(頂点)」(node)から別のノードに「エッジ(辺)」(edge)が伸びているものの集合体を指します。
また、今回はReact内で使用することを想定しているためReact Sigmaを使用します。
使い方
Sigma.jsをReact上で使用する手順
-
ReactアプリをViteなどを用いて作成(ここでは詳細は省略)
-
Reactアプリ作成後に以下コマンドをターミナルで実行
npm install sigma @react-sigma/core graphology graphology-types lodash @types/lodash
-
簡単な例として以下のように記述
import Graph from "graphology"; import { SigmaContainer } from "@react-sigma/core"; import "@react-sigma/core/lib/style.css"; export const DisplayGraph = () => { // グラフ生成 const graph = new Graph(); // ノード追加 graph.addNode("first", { x: 0, y: 0, size: 10, label: "My first node", color: "red", }); graph.addNode("second", { x: 1, y: 1, size: 15, label: "My second node", color: "blue", }); // エッジ追加 graph.addEdge("first", "second", { label: "edge", size: 5, color: "black" }); return ( <SigmaContainer graph={graph} style={{ height: "500px", width: "500px" }} ></SigmaContainer> ); };
または、
import Graph from "graphology"; import { SigmaContainer, useLoadGraph } from "@react-sigma/core"; import "@react-sigma/core/lib/style.css"; export const LoadGraph = () => { // グラフ生成 const graph = new Graph(); const loadGraph = useLoadGraph(); // ノード追加 graph.addNode("first", { x: 0, y: 0, size: 10, label: "My first node", color: "red", }); graph.addNode("second", { x: 1, y: 1, size: 15, label: "My second node", color: "blue", }); // エッジ追加 graph.addEdge("first", "second", { label: "edge", size: 5, color: "black" }); // グラフ読み込み loadGraph(graph); return null; }; export const DisplayGraph = () => { return ( <SigmaContainer style={{ height: "500px", width: "500px" }}> <LoadGraph /> </SigmaContainer> ); };
注意点
- SigmaContainerを描画するには、以下importが必要
import "@react-sigma/core/lib/style.css";
- SigmaContainerにはheightやwidthなどのstyleが必要
style={{ height: "500px", width: "500px" }}
ノードとエッジのプロパティ
ノードとエッジにはグラフを見やすくするためのプロパティが用意されている。このプロパティには必須や任意のものがある。また、ノードもエッジも共に任意のプロパティを設定することができます。
ノードやエッジに対するメソッドは以下を参考。
ノード
プロパティ | 必須 | 説明 |
---|---|---|
id | ⚪︎ | edgeで結ぶためのkeyとなる |
label | ノード名 | |
x | ⚪︎ | ノードのx座標 |
y | ⚪︎ | ノードのy座標 |
size | ノードの大きさ | |
color | ノードの色 | |
image | ノードに画像を付与する |
エッジ
プロパティ | 必須 | 説明 |
---|---|---|
id | ⚪︎ | addEdgeWithKeyメソッド使用時に必須 |
source | ⚪︎ | エッジの始点 |
target | ⚪︎ | エッジの終点 |
label | エッジ名 | |
type | エッジの形状(line, arrowなど) | |
size | エッジの太さ | |
color | エッジの色 |
自動配置アルゴリズム
ノードはx, y座標を指定することで任意の位置に配置することができます。しかし、全体のノード同士の繋がりを把握できれば良い場合、位置は重要ではないことがあるかと思います。その場合、自動で視覚的に分かりやすい配置になってくれると全体の把握がしやすくなります。
そこで利用できるのが自動配置アルゴリズム「ForceAtlas2」です。
上記サイトで説明されています。以下の規則に従ってノード同士がもっとも安定する位置に配置されます。
エッジで繋がっていないノード
エッジで繋がっているノード
自動配置アルゴリズムの導入
以下のコマンドを実行
npm install @react-sigma/layout-forceatlas2
ForceAtlas2の効果を確認するため以下のように書き換えます。
import Graph from "graphology";
import { SigmaContainer } from "@react-sigma/core";
import "@react-sigma/core/lib/style.css";
import { useWorkerLayoutForceAtlas2 } from "@react-sigma/layout-forceatlas2";
import { useEffect } from "react";
export const Fa2 = () => {
const { start, kill } = useWorkerLayoutForceAtlas2({
settings: { slowDown: 10 },
});
useEffect(() => {
// start FA2
start();
// kill FA2 on unmount
return () => {
kill();
};
}, [start, kill]);
return null;
};
export const DisplayGraph = () => {
// グラフ生成
const graph = new Graph();
// ノード追加
graph.addNode("1", {
x: 0,
y: 0,
size: 10,
label: "1",
});
graph.addNode("2", {
x: 1,
y: 1,
size: 10,
label: "2",
});
graph.addNode("3", {
x: 0.8,
y: 0.4,
size: 10,
label: "3",
});
graph.addNode("4", {
x: 0.2,
y: 0.6,
size: 10,
label: "4",
});
graph.addNode("5", {
x: 0.5,
y: 0.9,
size: 10,
label: "5",
});
graph.addNode("6", {
x: 0.3,
y: 0.8,
size: 10,
label: "6",
});
graph.addNode("7", {
x: 0.2,
y: 0.3,
size: 10,
label: "7",
});
// エッジ追加
graph.addEdge("1", "2", { color: "red" });
graph.addEdge("1", "3", { color: "red" });
graph.addEdge("1", "4", { color: "red" });
graph.addEdge("1", "5", { color: "red" });
graph.addEdge("1", "6", { color: "red" });
graph.addEdge("1", "7", { color: "red" });
graph.addEdge("2", "3", { color: "red" });
graph.addEdge("2", "4", { color: "red" });
graph.addEdge("2", "5", { color: "red" });
graph.addEdge("2", "6", { color: "red" });
graph.addEdge("2", "7", { color: "red" });
return (
<SigmaContainer graph={graph} style={{ height: "500px", width: "500px" }}>
<Fa2 />
</SigmaContainer>
);
};
ここで重要なのがFa2コンポーネント内のuseWorkerLayoutForceAtlas2です。このように記述することで、SigmaContainer内のグラフにForceAtlas2が適用されます。
Fa2コンポーネントの有無による表示の違いを見てみましょう。(ここではノードのx, y座標を特定の値で指定していますが、ランダムな値でも問題ありません。)
Fa2コンポーネントなし | Fa2コンポーネントあり |
---|---|
![]() |
![]() |
Fa2コンポーネントがある場合、ForceAtlas2の効果が適用されて各ノードがもっともバランスの取れた位置に配置されていることが確認できます。
ForceAtlas2を利用することでノードの関係性が視覚的にわかりやすくなります。
さらに使いこなす
Sigma.jsを使うことによってネットワークグラフに対して以下の操作ができるようになります。
- ノードを任意の位置へ移動させる
- ノードのクリックイベント(ノードの非表示、詳細情報をハイライトさせるなど)
参考