d3.js advent calendar 20日目

d3 advent calendar 20日目
d3.layout.tree

d3.layout.tree

d3.layout.treeは「樹形図」を描くことができる.layoutです

f:id:muddydixon:20130330235522j:plain

書きたいですよね?樹形図!

概要

このlayoutは、前回紹介したhierarchyの具体的な表現例の1つになります。

従って、ネスト化されたデータを用意して渡し、nodes、linksの2つのデータを表現していくことになります。

さっさと実例

var data; // {name: 'root', nodes: [{name: 'child1', value: 3}, {name: 'child2', value: 5}]}
var tree = d3.layout.tree().size([300, 300]).children(function(d){ return d.nodes;});
var nodes = tree.nodes(data), links = tree.links(nodes);
var svg = d3.select('svg');
var node = svg.selectAll('circle').data(nodes).enter().append('circle'); // nodeを描きます
var link = svg.selectAll('path').data(links).enter().append('path'); // pathを描きます

linkの描き方(直線)

pathのd属性を設定します。この際に、例えば

var link = svg.selectAll('path.link').data(links).enter().append('path').attr('class', 'link');
link.attr('d', function(d){ return 'M'+d.source.x+','+d.source.y+'L'+d.target.x+','+d.target.y; })

とすることで直線を引くことができます

linkの描き方(曲線)

pathのd属性を設定します。直線を引いても楽しくないので、diagonalを使います

var diagonal = d3.svg.diagonal().projection(function(d){ return [d.x, d.y]; });
var link = svg.selectAll('path.link').data(links).enter().append('path').attr('class', 'link');
link.attr('d', diagnoal);

とすると美しい曲線を引くことができます!

diagnoal

内部的にはsourceとtargetを補間して4点の軌跡に変換してくれます

d3/src/svg/diagnoal.js
  function diagonal(d, i) {
    var p0 = source.call(this, d, i),
        p3 = target.call(this, d, i),
        m = (p0.y + p3.y) / 2,
        p = [p0, {x: p0.x, y: m}, {x: p3.x, y: m}, p3]; // ここで曲線の曲がりを指定してる
    p = p.map(projection);
    return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3];
  }