d3-force update radius of forceCollide after initializing graph

亡梦爱人 提交于 2019-12-19 08:59:31

问题


This question is a follow-up on a previous one titled "D3-Force updating parameters after initializing graph" (D3-Force updating parameters after initializing graph) and that @altocumulus answered.

I am trying to update the simulation forces after modifying the radius of some nodes. However, when I call on forceCollide to account for the changes it does not work.

The graph first initiates correctly, using forceCollide and a function to have the force correspond with the radius:

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

var simulation = d3.forceSimulation()
.velocityDecay(velocityDecay)
.force("collide", forceCollide);

I then modify the d.radius object and want forceCollide to reflect the changes. However, when I call on the forceCollide again it does not work:

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

Any thoughts on why this is happening?


回答1:


This will not actually update the radius. You are just re-setting the callback used to determine the radius, which doesn't even change compared to what it was before. Even if it did change, this would not trigger your update, because the radii won't be re-evaluated based on your updated data.

When updating the distance callback of the link force, the force itself will get initialized. A look at the source shows a call to initializeDistance():

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

The same holds true for many other updates of other forces' parameters.

Looking at the source of the collide force, however, one notices that there is no initialization invoked:

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

Since your callback doesn't change you won't need to call forceCollide.radius() again. Instead you need to call

forceCollide.initialize(simulation.nodes());

This will re-evaluate the radii based on your updated data.



来源:https://stackoverflow.com/questions/39043121/d3-force-update-radius-of-forcecollide-after-initializing-graph

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!