LoginSignup
1
0

More than 1 year has passed since last update.

cytoscape.js を用いたインタラクティブなグラフ描画の実装

Last updated at Posted at 2022-11-12

はじめに

ちょっとしたネットワークグラフを書きたいとき、graphvizplantUMLblockdiag等は便利ですが、細かい調整をしようとすると泥沼にハマります。😅しかし、drawi.io などで1からネットワークグラフを書くのはしんどい。そこで「良きに計らえ」でいい感じでだいたいノードをレイアウトしてもらって、その後手動でノードを動かして最終形にするのが一番効率がよいと思われます。

このようなインタラクティブなグラフ作成をしたいとき、cytoscapeのような本格的なデスクトップアプリもありますが、ウェブサービスで実現したいときは cytoscape.js を使うとよいと思われます。
本記事では cytoscape.js を用いて上記を実現する方法を紹介したいと思います。

描画するグラフデータについて

描画するネットワークの元データとしては、DBpediaを利用しています。ここには概念(単語)とそれらの間の関係(名)が2項関係で大量にストックされて検索可能になっています。詳細はDBpedia 関連を参照ください。これを利用して、あるキーワードを投げて得られたそのキーワードに関係する概念とその関係を図示することにします。
DBpedia が提供する情報だけだと寂しいので、wikipedia の「関連語」情報も併用しています。

Look & Feel

まずは大体どんな感じのものなのか、下記動画で紹介します。
これは、「デンプン」という単語に関連するオントロジー情報を wikidata から検索して表示しています。検索された情報(ネットワーク図)をきれいに配置するため、ここではfcose というアルゴリズムで「デンプン」を中心としたサークル形状としてノードを配置しています。fcose アルゴリズムのspacing Factorパラメータを調整することで、ノードの大きさや密集度を変更しています。
個々のノードの位置はマウスで調整可能です。オブジェクトを選択してコンテキストメニューで選択することにより削除することもできます。

ソースコード

下記から取得できます。

html 単一ファイルです。ダウンロードしてブラウザで開けば使えます。

codePen

上記ファイルを codePen にも上げています。1 こちらはサイト上で直接動作しますが、エディタ画面が邪魔ですね:)また少し動作が遅くなります。

機能

  • ノード追加、ノード検索
    単語を入力してノード追加のボタンを押します。wikiData にその概念があれば、ノードとして追加されます。
    単語を入力してノード検索のボタンを押すと、その単語のノードがselect された状態になります。ノード数が多くなってくると必要になる機能です。
    image.png

  • ZOOMとPan

    • グラフ全体をZOOM IN/OUT します。マウスホイールでもZOOM IN/OUT できますがスライダーを使ったほうが細かく調節できます。
    • `矢印をクリックするとグラフ全体がその方向に平行移動します。グラフエリアのノードとエッジ以外の部分をクリックしてドラッグしてもよいです。
    • squareをクリックすると、グラフ全体がキャンバスにちょうど収まるようzoom in/out してくれます。
      image.png
  • ノードの移動(1つ、複数)
    上記動画で示したように、ノードをクリック&ドラッグでノードを移動できます。複数のノードを動かすときは、コントロールキーを押しながらノードを1つずつクリックすることで複数のノードを選択できるので、最後のノードの選択(クリック)後、クリックしたままドラッグします。
    あるいはシフトキーを押しながらマウスをドラッグすると矩形領域選択モードになり、矩形領域内のすべてのノードが選択された状態になります。この後、選択されたノードのどれか1つをドラッグすることで複数のノード全体が平行移動します。

  • ノードやエッジの削除 (1つ、複数)
    ノードをクリックしてマウスの右ボタンをクリックします。コンテキストメニューからremoveを選択することでそのノード(とそのノードにつながっているエッジ)が削除されます。複数ノードの削除は、上述した方法で複数ノードを選択後に同様の操作を行います。

  • DBpedia による関連概念の追加
    ノードを右クリックしてコンテキストメニューから onto expandを選ぶことにより、その概念に関連した概念(ノード)と関係(エッジ)をグラフに追加します。上記 youtube 動画にあるとおりです。

  • wikipedia による関連語の追加

ノードを右クリックしてコンテキストメニューから wiki expandを選びます。その概念(単語)がタイトルのwikipedia のページがあれば、そのページ内部の関連語をグラフに追加します。

  • 2概念間の関係の発見
    グラフ上の2つの概念をつなぐエッジ(関係名)やノード(概念)をDBpedia から検索してグラフに追加します。実装中です😅

  • ノードレイアウトの保存と読み込み
    保存ボタンを押すと、現在のグラフレイアウトをJSON形式で詳細エリアに出力します。これをコピペしてテキストファイルとして保存します。また保存したJSONデータを詳細エリアにペーストして読み込みボタンを押すと、グラフが復元されます。

  • 選択したノード(複数)のレイアウト変更

選択したノードを指定されたレイアウトアルゴリズムで再配置します。ノードが選択されていない場合は全ノードが再配置されます。レイアウトとしてはbreadthfirst,fcose,grid,random,circle,concentric,cose といったアルゴリズムが選択できます。各アルゴリズムのパラメータの一部はspacing factor スライダーバーで指定することができます。
詳細はここを参照下さい。

  • SVG出力
    実装中です😅

実装

  • DBpedia や wikipedia の検索には axios ライブラリを利用しています。
  • コンテキストメニューにはcytoscape-context-menus.jsを利用しています。
  • パンとズームはcytoscape-panzoom.jsを利用しています。
  • fcoseレイアウトアルゴリズムにはcytoscape-fcose.jsを利用しています。

各ライブラリが依存するモジュールについては、ソースコードを参照下さい。

おわりに

cytoscape.js を利用したインタラクティブな描画実装例として 「Cytoscape.jsを試してみた」があります。大変参考になりました。本記事はこれにノードの動的追加/削減やコンテキストメニューの扱い等を追加したものになります。
実装してみて、豊富な拡張プラグインのお陰で大変書きやすいと感じました。イベントハンドラも書きやすかったです。
問題点としては cytoscape のキャンバスをウェブページ内に組み込むときに絶対位置となるため、ページ上部のボタンやスライダーエリアをresizable にできないという点です。いろいろトライしてみましたがいい解決方法が見つかりませんでした。諸賢の方に(コメント欄で)ご教示いただければ幸いです。

本記事がなにかの参考になれば幸いです。

link

cytoscape.js 関連(日本語の紹介記事)

Cytoscape.jsを試してみた - Qiita https://qiita.com/madilloar/items/bb9e9dddd37639998637

jQuery: Cytoscape.js お試せた17 (layout 混合は使い物になるだろうか + nodes.shift()) | site-hhs https://hhsprings.pinoko.jp/site-hhs/2018/01/jquery-cytoscape-js-%E3%81%8A%E8%A9%A6%E3%81%9B%E3%81%9F17-layout-%E6%B7%B7%E5%90%88%E3%81%AF%E4%BD%BF%E3%81%84%E7%89%A9%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%A0%E3%82%8D%E3%81%86%E3%81%8B-cy-shift/

Cytoscape.jsを用いてデータを可視化する - Qiita https://qiita.com/Wangxinyin/items/6965abdd369736e4073f

ネットワークグラフ描画ライブラリ7個まとめ - Qiita https://qiita.com/SuyamaDaichi/items/c47dc74cfefd92516e28

(2017.6.9) Neo4jの可視化ライブラリまとめ https://www.slideshare.net/mkiuchi4/201769-neo4j

Cytoscape.js でインタラクティブなグラフ構造描画 - WordNet の可視化例 - NO_WAIT_FOREVER https://shinaisan.hatenablog.com/entry/2017/04/30/230908

DBpedia 関連

DBpedia Japanese https://ja.dbpedia.org/

DBペディア - Wikipedia https://ja.wikipedia.org/wiki/DB%E3%83%9A%E3%83%87%E3%82%A3%E3%82%A2

DBpedia Japaneseとは? https://www.slideshare.net/takeda/what-isdpbedia

DBpediaでWikipediaからデータを取得する方法 - Masamuneブログ https://masamune-blog.hatenablog.com/entry/2021/12/17/154837

  1. 同一オリジン制約回避のため、CORS-PROXY を使っています。セキュアでないので github のコードの方を参照して下さい。

1
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
1
0