4

这个问题是对前一个题为“初始化图形后的 D3-Force 更新参数”(初始化图形后的 D3-Force 更新参数)的后续问题,@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);

然后我修改d.radius对象并希望forceCollide反映更改。但是,当我forceCollide再次调用它时它不起作用:

forceCollide.radius(function(d){
d.radius;})

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

4

1 回答 1

5

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

当更新链接力的距离回调时,力本身将被初始化。查看源代码显示调用initializeDistance()

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

对于其他力参数的许多其他更新也是如此。

然而,查看碰撞力的来源,我们注意到没有调用初始化:

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

由于您的回调没有改变,您无需forceCollide.radius()再次致电。相反,您需要致电

forceCollide.initialize(simulation.nodes());

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

于 2016-08-19T16:06:34.723 回答