前回はtransitionで、ひたすら円を動かし、そして消すをやりました。
今回は、見た目難しそうなアレをやってみます。
force layout
力学モデル
Wikipedia見ましょう。
あんなやつです。
作ってみる
データの用意
nodes用のデータ、links用のデータの2つを用意します。
データの例として、
var data = {
nodes: [
{ name: 'Alice' },
{ name: 'Bob' },
{ name: 'Eve' }
],
links: [
{ source: 0, target: 1 },
{ source: 0, target: 2 },
{ source: 1, target: 2 }
]
};
nodesにはAlice、Bob、Eveの3要素。
linksにはnodesのどの要素が、どの要素と繋がりがあるかを表しています。
例のデータだと、
source: 0, target: 1
で、nodesの0番目(Alice)から1番目(Bob)へと繋がるようなイメージ。
Alice → Bob、Alice → Eve、 Bob → Eveと繋がるので、結果は三角形が出来上がります。
このようなデータだと良さ気です。
データを使って、作る
svg要素を作るところはカット。
force、line、circleを作ります。
var force, line, circle;
force = d3.layout.force()
.nodes(data.nodes)
.links(data.links)
.size([200, 200])
.linkDistance([100])
.charge([-100])
.start();
line = d3.selectAll('line')
.data(data.links)
.enter()
.style({
});
circle = d3.selectAll('circle')
.data(data.nodes)
.enter()
.attr('r', 20)
.call(force.drag);
forceのnodes、linksでデータを指定してやります。
linkDistanceはnodes同士の間隔。
chargeは反発力みたいな。そんな感じです。
正の値を入れると面白い動きをします。
そして、circleの最後のcall(force.drag)
。
これで、マウスドラッグが可能になります。
tick
最後にtickを。
force.on('tick', function () {
line.attr({
'x1': function (d) { return d.source.x; },
'y1': function (d) { return d.source.y; },
'x2': function (d) { return d.target.x; },
'y2': function (d) { return d.target.y; }
});
circle.attr({
'cx': function (d) { return d.x; },
'cy': function (d) { return d.y; }
});
});
これで大体完成となります。
意味なんかはreference読むのが一番かなぁと思っていますが、
きの基本形覚えてしまえば、いろいろ応用が利くはずです。
サンプル
今回もサンプルを作りました。
今回は、TwitterのREST APIから自分のアカウントのフォローしているアカウント一覧を取得。
jsonファイルに落とし込んで、フォローしている人との繋がりを描画しました。
要するに、0が自分で、targetをフォローしているユーザとするだけです。
{ source: 0, target: 1 },
{ suurce: 0, target: 2 }
nodeはcircleではなく、imageを使用し、フォローしている方のアイコンを表示しています。
デモはこちら (URL間違ってたから修正w)
※重いので注意
ソースはこちら
最後に
難しそうなものですが、案外やってみると簡単に作れてしまいます。
どちらかというと、データに何を使うか、繋がりをどう表すのかが重要になりそうです。
今度は何をしよう。。。