【发布时间】:2016-11-18 06:57:53
【问题描述】:
我想要d3.forceCollide() 的两个实例。一方面,每个节点都被推开以防止重叠。在第二种情况下,只有一部分节点被推开,半径更大。
为了完成第二个力量,我调整了初始化方法来过滤传入的节点,如下所示:
function selective(force,filter){
var init = force.initialize;
force.initialize = function(_){return init(_.filter(filter));};
return force;
}
var dpi = 90; // approximate pixels per inch in SVG
var size = dpi * (1/4); // quarter-inch unit size
var universally_applied =
d3.forceCollide()
.radius(size)
.strength(1);
var selectively_applied =
selective(
d3.forceCollide(),
function(d){return d.id === color;}
)
.radius(size*5)
.strength(1);
}
现在,这几乎可以工作了。我创建了一个小提琴来查看它的实际效果:https://jsfiddle.net/jarrowwx/0dax43ue/38/ - 每个彩色圆圈都应该从远处排斥所有其他相同颜色的圆圈。其他所有颜色,它都会碰到并推开它。
如果我不更改定义事物的顺序,则选择性施加的力仅应用于第一种颜色(红色)。如果我在施加力之前对data 数组进行洗牌,则很难准确定义会发生什么,但力会施加到某些圆圈而不是大多数其他圆圈,即使在相同颜色中也是如此。
有什么想法,或者如何解决它?
【问题讨论】:
-
嗯,这很有趣。该问题甚至不是由两个实例同时运行引起的,如果您注释掉
universally_appliedforce 也会出现问题。但是,如果您另外将颜色数组限制为仅red,那么它就像预期的那样works smoothly。必须是部分施加力的问题。我已经重新检查了我的answer 到"Partial forces on nodes in D3.js",你采用了它,但在这种情况下它工作得很好。还在琢磨…… -
我认为有一些关于洗牌的数据。如果我删除该步骤,它似乎每次运行都可以正常工作。
-
@Rothrock:是的,直到我把红色移到列表的末尾。
-
如果有 20 个圆圈,其中 5 个是红色的,那么数组前 5 个元素中出现的所有红色圆圈都会正确地获得施加到它们的部分力。 6岁或以后的人没有。我认为它隐藏在如何使用 QuadTree 优化力的某个地方。它可能对输入数据的性质有一些(非显而易见的)编码假设。
-
我看到它与前 5 个红色以上的作品一起工作,刚刚尝试了 10 个。
标签: javascript d3.js force-layout d3-force-directed