はじめに
ちょっとしたネットワークグラフを書きたいとき、graphviz、plantUML、blockdiag等は便利ですが、細かい調整をしようとすると泥沼にハマります。😅しかし、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 された状態になります。ノード数が多くなってくると必要になる機能です。
-
ZOOMとPan
-
ノードの移動(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
-
同一オリジン制約回避のため、CORS-PROXY を使っています。セキュアでないので github のコードの方を参照して下さい。 ↩