树布局
最后更新于:2022-04-01 11:12:06
> [Wiki](Home) ▸ [[API--中文手册]] ▸ [[布局]] ▸ **树布局**
* guluT20141102
* 如发现翻译不当或有其他问题可以通过以下方式联系译者:
* 邮箱:zhang_tianxu@sina.com
* QQ群:[D3数据可视化](http://jq.qq.com/?_wv=1027&k=ZGcqYF)205076374,[大数据可视化](http://jq.qq.com/?_wv=1027&k=S8wGMe)436442115
树布局能够用莱因戈尔德-蒂尔福德算法产生一个整洁的树状结点-链接图。例如,树布局可以用来组织软件的包中类的层级结构。
像其他大多数布局一样,d3.layout.tree返回的是一个对象也是一个函数。也就是说:你可以像调用其他函数一样调用布局,并且这个布局函数有可以改变它的行为的附加方法。像D3里的其他类一样,布局遵循函数的链式模式,其中setter返回布局本身,允许在简单的语句中调用多个setter方法。
# d3.layout.tree()
用默认设置创建一个树布局:默认的排序是null;默认的孩子访问器假定每个输入数据是一个带有孩子数组的对象;默认的操作函数为兄弟节点指定一个结点的宽度,没有兄弟姐妹的节点指定两个结点的宽度;默认的尺寸是1X1。
# tree(root)
# tree.nodes(root)
运行树布局,返回一个与特殊的根结点root 有关系的结点数组。树布局是D3的层次布局家族中的一部分。这些布局遵循相似的基本结构:布局的输入参数是层次结构的根节点,输出返回值是一个经过计算的全部结点的位置的数组。
在每个结点中包含下面几个属性:
•双亲-双亲结点,根节点无双亲。
•孩子-孩子结点的数组,叶子无孩子结点。
•深度-结点的深度,根节点深度为0。
•x-计算结点位置的x坐标。
•y-计算结点位置的y坐标。
尽管布局在x和y方向上有大小,这表示了一个任意的坐标系统;例如,你可以将x看做半径,将y看做角度去产生一个径向而不是笛卡尔布局。
# tree.links(nodes)
给定一个特殊的结点数组nodes,比如通过nodes返回的,返回一个表示从双亲结点到每个孩子结点的对象数组。叶子结点将不再有任何链接,每个链接是一个有两个属性的对象:
•源结点-双亲结点(如上文描述)
•目标结点-孩子结点
这种方法是有用的,用于检索一组适合于显示的链接描述,经常与对角线形状发生器一起使用。例如:
svg.selectAll("path")
.data(tree.links(nodes))
.enter().append("path")
.attr("d", d3.svg.diagonal());
# tree.children([children])
如果指定了子节点children ,设置指定的子节点访问器函数。如果未指定子节点,返回当前子节点访问器函数,默认情况下假定输入数据是一个带有子节点数组的对象:
function children(d) {
return d.children;
}
通常,使用d3.json很方便加载节点的层次结构,并用嵌套JSON对象代表输入层次结构。例如:
{
"name": "flare",
"children": [
{
"name": "analytics",
"children": [
{
"name": "cluster",
"children": [
{"name": "AgglomerativeCluster", "size": 3938},
{"name": "CommunityStructure", "size": 3812},
{"name": "MergeEdge", "size": 743}
]
},
{
"name": "graph",
"children": [
{"name": "BetweennessCentrality", "size": 3534},
{"name": "LinkDistance", "size": 5731}
]
}
]
}
]
}
子节点的访问器首先在层次结构的根节点调用。如果访问器返回null,则该节点在布局遍历终止被认为是叶节点。否则,访问器应返回表示子节点数据元素的数组。
# tree.separation([separation])
如果指定分割separation ,使用指定的函数计算两个相邻节点之间的分割。如果,没有指定分割,返回当前的分割函数,默认为:
function separation(a, b) {
return a.parent == b.parent ? 1 : 2;
}
变量更适合径向布局按比例减少半径之间的分割间隙:
function separation(a, b) {
return (a.parent == b.parent ? 1 : 2) / a.depth;
}
分割函数传入两个相邻节点a和b,必须返回节点之间期望的分割。如果布局决定放置这些相邻节点,节点通常是兄弟节点,即使节点可能是表兄弟(甚至更遥远的关系)。
# tree.size([size])
如果指定尺寸size ,设置可用的布局尺寸为给指定的代表x和y两个元素的数组。如果没有指定的,返回当前的尺寸,默认是1x1。布局尺寸可能指定为x和y,但是并不限定屏幕坐标系和其他任意的坐标系统。例如,产生一个径向布局,其中breadth (x)以度为单位,depth (y)以像素为单位的半径r,例如[360,r]。
树的尺寸是tree.nodeSize特有的属性;设定tree.size设置tree.nodeSize为null。
# tree.nodeSize([nodeSize])
如果指定了nodeSize,则为每个节点设置一个固定大小为代表x和y的两元素数组。如果没有指定的,则返回当前结点的尺寸,其中缺省为null表示该布局是使用整体tree.size属性,而不是使用固定的节点大小。布局尺寸用x和y指定,但是并不受限于屏幕坐标系和其他坐标系统。
nodeSize的属性是tree.size特有的;设定tree.size设置tree.nodeSize为null。
# tree.sort([comparator])
如果指定比较器comparator,用指定的比较器来为布局的同级节点设置排序。如果比较器没有被指定,则返回当前组的排序,默认为空即不排序。比较函数被节点对直接调用,传入输入数据的每一个结点。默认的比较器是空,没有排序和者用树的遍历命令。例如,通过传递数据的数值来进行降序排列:
function comparator(a, b) {
return b.value - a.value;
}
通过结点名或者关键字进行排序也是很普遍的。这可以用d3.ascending和d3.descending可以很容易实现。
# tree.value([value])
如果值是指定的,则使用指定的函数来设置值访问器。如果值没有指定,则返回默认为空的当前值访问器,意思是这个值的属性不能被计算。如果指定,值访问器被每一个输入的数据元素调用,一定能返回一个表示结点值的数字。这个值对于布局来说是没有意义的,但是是层次布局提供的通用函数。
* 阿呆不呆20141128
* gulu校对2014-12-7 10:20:53