我正在构建与this非常相似的东西。我喜欢的是使每个节点的大小与json文件中定义的大小相同,或者,如果它没有大小属性,而json中的子属性,它是所有子节点大小的总和。怎么会这样做呢?我已经尝试了各种方法,但没有添加东西并用JSON硬编码,这有点蹩脚,我还没有发现任何真正有用的东西;(任何建议,蜂巢头脑?
答案 0 :(得分:6)
如果您的数据是树结构,则可以使用Partition Layout初始化节点的位置和大小。父节点分区返回的d.value
默认为所有子节点的值的总和,假设您已正确设置value accessor function以返回要用于叶子大小的数据变量节点。
虽然partition examples中的标准显示是使用空格填充矩形或弧而不是节点和链接,但它仍然具有其他层次结构布局的所有基本功能。因此,一旦在根上运行布局以生成节点数组,就可以运行links function来计算链接。
如果您仍然需要基于强制的布局而不是静态树,则只需传入节点并链接到力布局并启动它。
总之:
var root = /*root object read from JSON data*/;
var w,h; /*set appropriately */
var partition = d3.layout.partition()
.size([w,h])
.value(function(d){return d.size;})
.children(function(d){return d.children;})
//optional: this is the default, change as needed
.sort(null);
//optional: turns off sorting,
//the default is to sort children by descending size
var nodes = partition(root);
var links = partition.links(nodes);
initialize();
var force = d3.layout.force()
.nodes(nodes)
.links(links)
.size([w,h])
/*and any other customization*/
.start();
svg.on("tick", update);
有一点需要注意。分区布局创建的x
值设计为矩形的角,而不是圆的中心。因此,如果您根据原始x
值定位节点,那么父母最终会离开他们孩子的最左边。如果您之后通过基于强制的布局运行所有内容,它最终将自行排序,但您可以通过在初始化期间在所有节点上设置d.x = d.x + d.dx/2
和d.y = d.y + d.dy/2
从一开始就将它们置于中心位置(例如,使用.each()
链中的enter()
来电。当然,使用d.value
来初始化节点大小(使用适当的比例)。