0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Sigma.js】Reactでネットワークグラフを描画してみる

Posted at

はじめに

JavaScriptのネットワークグラフ描画ライブラリであるSigma.jsについて学んだことをまとめました。
ネットワークグラフとは、ある「ノード(頂点)」(node)から別のノードに「エッジ(辺)」(edge)が伸びているものの集合体を指します。
Vite___React___TS.png

また、今回はReact内で使用することを想定しているためReact Sigmaを使用します。

使い方

Sigma.jsをReact上で使用する手順

  1. ReactアプリをViteなどを用いて作成(ここでは詳細は省略)


  2. Reactアプリ作成後に以下コマンドをターミナルで実行

    npm install sigma @react-sigma/core graphology graphology-types lodash @types/lodash
    

  3. 簡単な例として以下のように記述

    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>
      );
    };
    

  4. グラフ描画結果
    2つのノードと、それをつなぐエッジが表示される
    Vite___React___TS.png

注意点

  • 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」です。

上記サイトで説明されています。以下の規則に従ってノード同士がもっとも安定する位置に配置されます。

エッジで繋がっていないノード

エッジで繋がっていないノード同士は反発する
無題のプレゼンテーション_-_Google_スライド.png

エッジで繋がっているノード

エッジで繋がっているノード同士は引き合う
無題のプレゼンテーション_-_Google_スライド.png

自動配置アルゴリズムの導入

以下のコマンドを実行

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コンポーネントあり
Vite___React___TS.png Vite___React___TS.png

Fa2コンポーネントがある場合、ForceAtlas2の効果が適用されて各ノードがもっともバランスの取れた位置に配置されていることが確認できます。
ForceAtlas2を利用することでノードの関係性が視覚的にわかりやすくなります。

さらに使いこなす

Sigma.jsを使うことによってネットワークグラフに対して以下の操作ができるようになります。

  • ノードを任意の位置へ移動させる
  • ノードのクリックイベント(ノードの非表示、詳細情報をハイライトさせるなど)

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?