Javascript 使用分离元件的力布局物理

Javascript 使用分离元件的力布局物理,javascript,d3.js,nodes,force-layout,Javascript,D3.js,Nodes,Force Layout,我在D3.jsv4中使用了force布局。现在,我想单击一个节点,并仅对该节点使用力物理,如collide 整个SVG上每个节点的模拟如下: var simulation = d3.forceSimulation() .force("link", d3.forceLink().id(function(d) { return d.index })) .force("collide", d3.forceCollide(function(d) {

我在D3.jsv4中使用了force布局。现在,我想单击一个节点,并仅对该节点使用力物理,如
collide

整个SVG上每个节点的模拟如下:

var simulation = d3.forceSimulation()
    .force("link", d3.forceLink().id(function(d) {
        return d.index
    }))
    .force("collide", d3.forceCollide(function(d) {
        return d.r + 8
    }).iterations(16))
    .force("charge", d3.forceManyBody())
    .force("center", d3.forceCenter(chartWidth / 2, chartWidth / 2))
现在,我想更改我单击的一个节点的碰撞行为,以将其他节点推离或吸引它们

有人知道解决办法吗?我尝试了一些过滤功能并停止/重新启动布局,但没有成功。

您说:“我想更改我单击的一个节点的碰撞行为,以将其他节点推开或吸引它们”

如果您想使用d3.forceCollide吸引其他节点,那么您在任务中使用了错误的工具

根据报告:

碰撞力将节点视为具有给定半径的圆,而不是点,并防止节点重叠

因此,
collide
基本上会将其他节点推开,以避免重叠

这就是说,此解决方案只处理问题的第一部分:“我想将我单击的一个节点的碰撞行为更改为将其他节点推开”

有不同的方法可以做到这一点。在我的解决方案中,单击节点时,它会更改绑定数据中的
r
属性:

d3.select(this).datum().r = 20;
无需重新绘制实际的SVG圆。这会将其他节点推开,使单击的节点保持相同的大小

以下是演示(单击节点):

var svg=d3.选择(“svg”);
var color=d3.scaleOrdinal(d3.schemeCategory 10);
var数据=d3.range(30.map)(d=>({
r:6
}));
var模拟=d3.力模拟(数据)
.力(“x”,d3.力x(150).强度(0.05))
力量(“y”,d3。力量(75)。力量(0.05))
.力(“碰撞”,d3.力碰撞(功能(d){
返回d.r+1;
}));
var node=svg.selectAll(“.circles”)
.数据(数据)
.输入()
.附加(“圆圈”)
.attr(“r”,d=>d.r)
.attr(“填充”(d,i)=>颜色(i));
节点上(“单击”,功能(d){
d3.选择all(“circle”).data().forEach(d=>d.r=6);
d3.选择(此).datum().r=20;
模拟。节点(数据);
simulation.alpha(0.8).restart();
})
模拟.节点(数据)
.on(“勾选”,d=>{
node.attr(“cx”,d=>d.x).attr(“cy”,d=>d.y);
});


我这样做只是为了更快地在一个数组中创建20个对象。旧的数组是
[0,1,2,3…,20]
,由
d3.range(20)
@Derick制作。我必须跟你说实话:当我们花一些时间为答案编写代码,OP只是简单地说“谢谢”时,这有点烦人。我通常在心理上将这些人列入黑名单,而忽略他们未来的问题。别这样。。。你不必接受答案,但提高投票率是一种简单而廉价的表示感谢的方式。@Gerado:糟糕,我花了很多时间试图理解每一行代码(仍然有很多问题),然后我就忘了提高投票率。此外,有时我会发布一些东西,然后离开电脑几天,所以我并不总是更新答案。平心而论:如果你看看我以前的帖子,如果可能的话,我总是投赞成票,接受别人的帮助。别担心,德里克。我从前面的问题中认识你,我知道你通常不会这样做,这就是为什么我很乐意写我在上面的评论中写的东西。关于这一行:它选择所有的圆元素并获取绑定到它们的数据(当您在没有任何参数的情况下编写
data()
时,它是一个getter,而不是setter)。然后,它将所有数据的
r
属性覆盖为6,这使得所有圆元素在其数据中的
r
属性为6(但这不会改变实际的DOM元素)。哎呀,糟糕,最后一个不应该在那里。我刚刚编辑了这个片段。