树状布局Tree-Layout简介
显而易见,树状布局就是我们通常所理解的数据结构中的树,由一个根节点向外展开,与前面力导向图的数据结构模型其实是一致的,只是展示形式略有差别,用树状结构展示看起来更加简洁清晰一点。
API
树结构
d3.layout.tree()
使用默认设置创建一个新的树状布局:
tree.nodes(root)
根据传入数据计算树的布局返回一组节点数组
tree.links(nodes)
根据节点数组返回节点之间的父子连接关系
tree.separation([separation]):
设置或取得两个节点之间的间距
tree.size([size])
指定树布局的尺寸一个
svg形状
因为需要实现一个辐射布局,并且连线是贝塞尔曲线,需要用到坐标投影来实现路径形状生成。
路径形状有很多种选择,比如d3.svg.line()、d3.svg.area()、d3.svg.diagonal()等等。这里选用d3.svg.diagonal(),它能利用projection的API来生成svg中的path形状的路径。
d3.svg.diagonal.radial().projection()
示例代码
根据官网一些人提供的Demo修改来写了一个辐射布局。里面做了一些注释,但仍然有一些疑惑点,比如d.x-90那里的原因还是比较模糊。
下面是完整demo代码
tree layout.node {
cursor: pointer;
}
.node circle {
fill: #fff;
stroke: steelblue;
stroke-width: 1.5px;
}
.node text {
font: 10px sans-serif;
}
.link {
fill: none;
stroke: #ccc;
stroke-width: 1.5px;
}
var width = 800,
height = 800;
var i = 0,
duration = 6000,
root;
var tree = d3.layout.tree()
.size([360, 320]) //360代表展开的最大角度也就是圆,后面的r值代表整个辐射布局的展开最大半径,并不是指某一层级的半径而是整个树,超过这个范围的就不显示了,后面85行d.y的才是某一层级的半径设置。
.separation(function(a, b) {
return (a.parent == b.parent ? 1 : 2) / a.depth; //适应radial布局,可以简单的理解为深度越高,相邻子节点之间的距离越小。
});
var diagonal = d3.svg.diagonal.radial()
.projection(function(d) { return [d.y, d.x / 180 * Math.PI]; }); //d.y代表半径,(d.x/180)*PI就是各个节点的弧度表示。
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
d3.json("flare1.json", f