score:1

Change the setIntervel function , intervel timing

Try this code:

Fiddle:

 setInterval(function(){
  nodes.push({id: ~~(Math.random() * foci.length)});
  force.start();
  node = node.data(nodes);
  node.enter().append("circle")
      .attr("class", "node")
      .attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; })
      .attr("r", 8)
      .style("fill", function(d) { return fill(d.id); })
      .style("stroke", function(d) { return d3.rgb(fill(d.id)).darker(2); })
      .call(force.drag);
}, 50); //change the intervel time

score:3

Don't set a timer to call the tick function, this is done automatically by the force layout.

There are however a number of parameters you can set to modify the behaviour of the force layout. The ones most relevant to what you're trying to do are the following.

  1. .friction() corresponds to how quickly the velocity decays and therefore directly controls how fast nodes move. The default is 0.9, to make everything slower, set it to a lower value.
  2. .charge() controls how strong the attraction/repulsion between nodes is. This doesn't control the velocity directly, but affects it.

Of these parameters, only the latter can be set on a node-by-node basis. This makes achieving what you want a bit tricky, as you would have to carefully balance the forces. As a start, setting the charge of the nodes that you want to move slower closer to 0 should help.

There are a few other parameters of the force layout that I think would not be useful in your particular case (I'm thinking of .linkStrength() and .linkDistance()), but you may want to have a look nevertheless.

score:3

I came to a possible solution. I can just manually call tick function for each node, say 100 times, and record the path. Then I use a timer function to redraw the node according to the path. In this way, I can control the time of drawing for each node. Does this make sense?


Related Query