企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
> [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