Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the equivalent to force.start() in d3 v5?

I am converting d3 from v3.5.5 into v5. It has a block of code to force movement in a set of circles.

var force = d3.layout.force()
    .nodes(nodes)
    .size([width, height])
    .gravity(0)
    .charge(0)
    .friction(.9)
    .on("tick", tick)
    .start();

And it also has a function to pause the action with a pause/resume code using force.resume();.

I'm trying to move this into the current version of d3. This is my version of the force variable.

var force = d3.forceSimulation(nodes)
.velocityDecay(.9)
.force("center", d3.forceCenter(width / 2,height / 2))
.force("charge", d3.forceManyBody().strength())
.on("tick", tick)
.start()

I run into two errors. I get a type error that start() is not a valid function and I also get an error for the tick function. The code to define the tick is here, but that may be out of scope for this question.

TypeError: Cannot read property 'alpha' of undefined at Object.tick

function tick(e) {

  var k = 0.03 * e.alpha;

  // Push nodes toward their designated focus.
  nodes.forEach(function(o, i) {
    var curr_act = o.act;

    // Speed of movement change based on user speed.
    if (USER_SPEED == "slow") var damper = .85;
    else var damper = 1;


    o.x += (x(+o.decade) - o.x) * k * damper;

    // If starting at the beginning.
    if (curr_index < 0) {
        o.y += (y('met') - o.y) * k * damper;
        o.color = color('met');
    }

    // Already started.
    else {
        o.y += (y(curr_act) - o.y) * k * damper;
        o.color = color(curr_act);
    }

  });

  circle
      .each(collide(.5))
      .style("fill", function(d) { return d.color; })
      .attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; });
}

Is there a new way to start the force movement in v5?

like image 875
tadon11Aaa Avatar asked Feb 02 '26 13:02

tadon11Aaa


1 Answers

According to the D3.js v5 changelog for d3.force,

The force layout’s internal timer now starts automatically on creation, removing force.start.

In d3.js v3.x, you will need to use d3.layout.force().start(), but in v5, there is no such need anymore. You can remove .start() from your force variable which contains that function. This is because d3.forceSimulation() starts automatically, as explained over here.

If for any reason you need to restart the simulation, calling .restart() will allow you to reset the simulation's internal timer.

You read more about it on that changelog. It has a pretty detailed migration guide to migrate to v4/5.x.

like image 171
wentjun Avatar answered Feb 04 '26 01:02

wentjun



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!