Cytoscape.jsを試してみた
Cytoscape.jsとは
もともとはクライアントアプリとして欧米の研究機関によって開発されているオープンソースのネットワーク可視化ソフトウェアプラットフォームであるCytoscapeが10年ほど前に作られ現在も継続して開発が行われています。Cytoscapeはデータの読み込み、分析、可視化といった一連の処理を行うことができますが、分析は別のソフト例えばRなどを使い、それから分析結果をエクスポートしてCytoscapeで可視化と言った使われ方もあるようです。クライアントアプリでは分析結果の共有に不便であるためカナダのトロント大学Cytoscape.jsのを開発を始めたようです。
以下のデモを見るのが一番わかりやすいと思います。
js.cytoscape.org
Cytoscapeでの処理フローについて
下記URLのCytoscapeの開発者の記事によりますと以下のような処理フローになるようです。
http://qiita.com/keiono/items/0db6495c4d8bc215de67
ネットワークデータを読み込む アトリビュート(データテーブル)を読み込む ソーシャルネットワークの例で言えば 人の名前、年齢、職業、性別などがノードアトリビュート 婚姻関係、友人関係、メールの交換された数などといった関係性に関する情報がエッジアトリビュート 統合されたデータを使って、統計的な解析やフィルタリングなどを行い分析する 自動レイアウト機能を使って、ノードを見やすく配置する ノード、エッジに付随する各種データに基づきマッピングを設定し、描画を行う PDFやJavaScriptウィジェットに出力する
Cytoscape.jsを試してみる
では実際にCytoscape.jsを試しに動かしてみたいと思います。
ここのチュートリアルを試してます。
1.ソース取得
ソースををgithubからダウンロードしておきます。
https://github.com/cytoscape/cytoscape.js
2.html作成
以下のhtmlを記述します。srcのパスはダウンロードしたCytoscape.jsのdist/cytoscape.min.jsを参照するように修正しておいてください。
<!doctype html> <html> <head> <title>Tutorial 1: Getting Started</title> <script src="cytoscape.js"></script> </head> <style> #cy { width: 100%; height: 100%; position: absolute; top: 0px; left: 0px; } </style> <body> <div id="cy"></div> </body> </html>
divタグに対してcanvasを埋め込んでグラフの描画を行いまして、cssで表示領域を設定しています。
3.グラフインスタンスの作成
var cy = cytoscape({ container: document.getElementById('cy'), elements: [ { data: { id: 'a' } }, { data: { id: 'b' } }, { data: { id: 'ab', source: 'a', target: 'b' } }] });
上記スクリプトで描画するノードとエッジを指定しています。data: { id: ‘a’ } 、data: { id: ‘b’ } とありますので2つのノードが描画されます。それから、data: {id: ‘ab’,source: ‘a’,target: ‘b’}とありますので2つのノードを結んだエッジも表示されます。
先ほど作成したhtmlにスクリプトを記述して開いてみるとグラフが表示されたことが確認できます。cytoscape.jsには自動レイアウト機能がありますのでウィンドウのサイズを変更して開き直すとノードが縦に並んだり、横に並んだりして自動でレイアウトして描画されることが確認できます。
4.グラフの描画設定 3で描画したスクリプトのelementsに続けて以下のstyleを追記してください。
style: [ { selector: 'node', style: { shape: 'hexagon', 'background-color': 'red', label: 'data(id)' } }]
それから開き直すとノードが赤色六角形のID付きで表示されることが確認できたかと思います。
styleについて他にどんな設定があるかは以下を見たら良いと思います。
https://github.com/cytoscape/cytoscape.js/blob/master/documentation/md/style.md
5.ノードの配置設定
ノードをどのように配置するかはlayoutで指定できるようになっています。例えばノードを円状に並べて描画したい場合は、以下を追記したら行えます。
cy.layout({ name: 'circle' });
円状に並べたのをわかりやすくするためhtmlを編集しノードを増やしてみます。
<!doctype html> <html> <head> <title>Tutorial 1: Getting Started</title> <script src="../cytoscape.js/dist/cytoscape.min.js"></script> </head> <style> #cy { width: 100%; height: 100%; position: absolute; top: 0px; left: 0px; } </style> <body> <div id="cy"></div> <script> var cy = cytoscape({ container: document.getElementById('cy'), elements: [ { data: { id: 'a' } }, { data: { id: 'b' } }, { data: { id: 'ab', source: 'a', target: 'b' } }], style: [ { selector: 'node', style: { shape: 'hexagon', 'background-color': 'red', label: 'data(id)' } }] }); for (var i = 0; i < 10; i++) { cy.add({ data: { id: 'node' + i } } ); var source = 'node' + i; cy.add({ data: { id: 'edge' + i, source: source, target: (i % 2 == 0 ? 'a' : 'b') } }); } cy.layout({ name: 'circle' }); </script> </body> </html>
これで開きなおしてみると以下のように円状に並んで表示されることが確認できます。
レイアウトの描画設定は自分で行うこともできここにまとめられているのですがcircleに配置するのであれば、以下の設定でも同様となっております。
var options = { name: 'circle', fit: true, // whether to fit the viewport to the graph padding: 30, // the padding on fit boundingBox: undefined, // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h } avoidOverlap: true, // prevents node overlap, may overflow boundingBox and radius if not enough space radius: undefined, // the radius of the circle startAngle: 3 / 2 * Math.PI, // where nodes start in radians sweep: undefined, // how many radians should be between the first and last node (defaults to full circle) clockwise: true, // whether the layout should go clockwise (true) or counterclockwise/anticlockwise (false) sort: undefined, // a sorting function to order the nodes; e.g. function(a, b){ return a.data('weight') - b.data('weight') } animate: false, // whether to transition the node positions animationDuration: 500, // duration of animation in ms if enabled animationEasing: undefined, // easing of animation if enabled ready: undefined, // callback on layoutready stop: undefined // callback on layoutstop }; cy.layout( options );
6.ノードごとでスタイルを変えてみる
ノードごとでスタイルを変更したい場合があると思うのですが、その場合はノードに付与したIDを指定してstyle属性に設定を追加してあげれば行えます。
例えばID=node1に対してスタイルを設定したい場合は以下のようになります。
{ selector: '#node1', style: { 'background-image': 'https://farm8.staticflickr.com/7272/7633179468_3e19e45a0c_b.jpg', 'height': 80, 'width': 80, 'background-fit': 'cover', 'border-color': '#000', 'border-width': 3, 'border-opacity': 0.5 }
結果、このようになりスタイルが適用されているのが確認できます。
触ってみた感想として表示するデータに合わせて柔軟にレイアウトを調整するというよりかは、事前に表示するデータを想定した上でそれに合わせてレイアウトをどう調整するのかが重要そうな気がしました。他の分析ソフトからエッジとノードあとアトリビュートをエクスポートできたら分析結果の共有に便利そうです。