Protovisで入れ子のForceレイアウト

2011/03/08 2:06 PM

 

Protovisで、バネのようなリンクと、反発力を持つノードを表現したpv.Layout.Forceというレイアウトがある(サンプル)。
このレイアウトの各ノード内に、さらにForceを置いて小宇宙のような表現をしたい。
いろいろ試した結果、とりあえず、入れ子の表現をすることは可能だった。

やり方として、
全体のForceのnodesにクラスタのノード、linksにクラスタ間リンク情報をセット、
nodeにpv.Panelを入れ、さらにパネルにForceを入れる。
そして、この内部Forceのノードに、各クラスタ内のノードとリンクを設定する。
と考えた。
・・・同じものがクラスタ数分できてしまったりしたのだが、
解決した時は、JavaScriptの関数の自在さを痛感せざるをえなかった。

Protovisを使うコーディングは、そのほとんどがプロトタイプの定義と考えてよい。
例えば、innerForceに、各クラスタ内のノードとリンクの情報をセットするが、これをループで書くと、先に書いたような同じものがクラスタ数分できることになる。
だから、これは間違い。

for (var i= 0, max = allClusters.clusters.length; i < max; i++) {   innerForce.nodes(allClusters.clusters[i].nodes);   innerForce.links(allClusters.clusters[i].links); }

nodes()には、nodes()が実行されるタイミングでのスコープでの処理を書いてやる必要がある。
こちらが正解。

innerForce
  .nodes(function(d) allClusters.clusters[d.clusterId].nodes)
  .links(function(d) allClusters.clusters[d.clusterId].links);

Protovisが厄介なのは、pvクラスの各プロパティ内のプロパティメソッドに何が渡されるのか、戻り値が何なのかがぱっとわかりにくいものがある、ということだ。

これで、単純にForceを入れ子することはできたが、実はクラスタ内でノードを振り回しているとクラスタを出て飛んでいってしまうという問題がある。Forceに制約をつける必要があるだろう。
また、クラスタをドラッグが非常にぎこちないのが気になる。

サンプルソースのワンピースのキャラの相関図は、ワンピース本編とは全く関係ないので悪しからず。



コメントはまだありません

まだコメントはありません。

RSS feed for comments on this post. TrackBack URI

コメントを書く

WordPress Themes