Javascript 使d3.forceCollide()的两个实例能够很好地配合使用

Javascript 使d3.forceCollide()的两个实例能够很好地配合使用,javascript,d3.js,force-layout,d3-force-directed,Javascript,D3.js,Force Layout,D3 Force Directed,我想要两个d3.forceCollide()的实例。在一种情况下,每个节点都被推开以防止重叠。在第二种情况下,只有一部分节点彼此推开,半径要大得多 为了完成第二个力,我调整了initialize方法来过滤传入的节点,如下所示: function selective(force,filter){ var init = force.initialize; force.initialize = function(_){return init(_.filter(filter));};

我想要两个
d3.forceCollide()
的实例。在一种情况下,每个节点都被推开以防止重叠。在第二种情况下,只有一部分节点彼此推开,半径要大得多

为了完成第二个力,我调整了initialize方法来过滤传入的节点,如下所示:

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);
}
现在,这几乎奏效了。我制作了一把小提琴来观察它的作用:-每一个彩色圆圈都应该在一定距离内排斥其他相同颜色的圆圈。每隔一种颜色,它就会撞到它,然后把它推开

如果我不改变事物定义的顺序,那么有选择地施加的力只应用于第一种颜色(红色)。如果在应用力之前洗牌
数据
数组,很难准确定义发生了什么,但力应用于某些圆,而不是大多数其他圆,即使是在相同颜色中


你知道这里发生了什么,或者如何修复它吗?

D3团队认为这是一个bug(),并修复了它。该修复包含在d3 force的1.0.4版中,从4.4.0版开始,该版本作为完整d3构建的一部分提供


使用建议的解决方案解决了问题,代码现在可以按预期工作。

Hm,这很有趣。问题甚至不是由两个实例同时运行引起的,如果注释掉
普遍应用的
强制,也会出现问题。但是,如果您另外将颜色数组限制为仅
红色
,则会按预期进行。这一定是部分施力的问题。我已经重新检查了我的to,这是您采用的,但在这种情况下,它工作得非常好。仍在思考…我认为数据的混乱是有原因的。如果我每次运行时删除该步骤,它似乎都能正常工作。@Rothrock:是的,直到我将红色移动到列表的末尾。如果有20个圆圈,其中5个是红色的,则数组前5个元素中出现的所有红色圆圈都能正确地应用部分力。那些6岁或更高的人不会。我认为它隐藏在如何使用四叉树优化力的某个地方。它可能对输入数据的性质有一些(不明显的)编码假设。我看到它使用的不仅仅是前5个红色,只是用10个红色试过。很高兴看到这个问题终于解决了!不过,我在您的回答中添加了更多细节,以使未来的读者更容易访问该解决方案。我自己的回答虽然给出了一些暗示,但也有其缺陷,对任何一个在这个问题上结结巴巴的人来说都是误导。考虑到问题已经解决,我非常认真地决定删除它。有趣的是,这同时发生了,即当你提出问题时,迈克·博斯托克已经开始着手解决问题。