初始化图形后,d3-force更新forceCollide的半径

Pep*_*G-a 4 d3.js force-layout d3-force-directed

这个问题是对前一个题为"初始化图形后D3强制更新参数"(初始化图形后的 D3- 强制更新参数)和@altocumulus回答的后续问题的后续跟进.

我试图在修改一些节点的半径后更新模拟力.但是,当我打电话forceCollide来考虑更改时,它不起作用.

图形首先正确启动,使用forceCollide和函数使力与半径对应:

var forceCollide = d3.forceCollide()
.radius(function(d){return d.radius;})
.iterations(2)
.strength(0.95);

var simulation = d3.forceSimulation()
.velocityDecay(velocityDecay)
.force("collide", forceCollide);
Run Code Online (Sandbox Code Playgroud)

然后我修改d.radius对象并想要forceCollide反映更改.但是,当我forceCollide再次打电话时,它不起作用:

forceCollide.radius(function(d){
d.radius;})
Run Code Online (Sandbox Code Playgroud)

有关为什么会发生这种情况的任何想法?

alt*_*lus 5

这实际上不会更新半径.您只是重新设置用于确定半径的回调,与之前相比,它甚至没有变化.即使它确实发生了变化,也不会触发更新,因为不会根据更新的数据重新评估半径.

更新链接力的距离回调时,力本身将被初始化.查看源代码会显示对以下内容的调用initializeDistance():

force.distance = function(_) {
  return arguments.length ? (distance = typeof _ === "function" ? _ : constant(+_), initializeDistance(), force) : distance;
};
Run Code Online (Sandbox Code Playgroud)

其他力量参数的许多其他更新也是如此.

但是,查看碰撞力的来源,可以注意到没有调用初始化:

force.radius = function(_) {
  return arguments.length ? (radius = typeof _ === "function" ? _ : constant(+_), force) : radius;
};
Run Code Online (Sandbox Code Playgroud)

由于你的回调没有改变,你不需要forceCollide.radius()再次打电话.相反,你需要打电话

forceCollide.initialize(simulation.nodes());
Run Code Online (Sandbox Code Playgroud)

这将根据您更新的数据重新评估半径.