让d3.forceCollide()的两个实例一起玩得很好

时间:2016-11-18 06:57:54

标签: 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));};
    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);
}

现在,这个ALMOST正常工作。我创造了一个小提琴,看它在行动:https://jsfiddle.net/jarrowwx/0dax43ue/38/ - 每个彩色圆圈都应该从远处击退相同颜色的每个其他圆圈。每隔一种颜色,它就会撞到并推开它。

如果我不改变定义事物的顺序,则选择性施加的力仅应用于第一种颜色(红色)。如果我在施加力之前对data阵列进行洗牌,则难以准确定义发生的情况,但是力会应用于某些圆圈而不是大多数其他圆圈,即使是相同的颜色。

这里有什么想法,或者如何修复它?

1 个答案:

答案 0 :(得分:1)

D3团队认为此行为是一个错误(Isolating forces to a subset of nodes? #72),并修复了它。该修复程序包含在d3-force的1.0.4版本中,该版本在4.4.0版本的完整D3版本中可用。

使用"Partial forces on nodes in D3.js"建议的解决方案解决了问题,代码现在按预期工作。