I am using D3.js for rendering about 500 nodes and links among them. It usually needs 10 seconds for the layout to settle down (the iteration to converge).
How do I speed up the whole process,say, the nodes are moving 2x faster during animation. then the time will be 50% (The CPU time that used for the iteration should be much less than 10 seconds, but how can I reduce the animation time).
I have tried:
Any suggestions? Thanks.
Injecting a call / calls within ticked event handler can be better, the requestAnimationFrame method would cause a weird bug on MacBook with touch pad environment.
function ticked() {
for (let i = 0; i < 5; i++) {
force.tick();
}
link.attr('x1', (d) => d.source.x)
.attr('y1', (d) => d.source.y)
.attr('x2', (d) => d.target.x)
.attr('y2', (d) => d.target.y);
node.attr('transform', (d) => `translate(${d.x}, ${d.y})`);
}
Check out this thread which has a lot of good info relating to this topic.
One suggestion from that thread that you might try to implement is to call force.tick()
several times within a single requestAnimationFrame
callback, then update the node and link positions, and then loop until force.alpha
reaches 0 (or whatever you want your alpha threshold to be). Try something like this:
var ticksPerRender = 3;
requestAnimationFrame(function render() {
for (var i = 0; i < ticksPerRender; i++) {
force.tick();
}
// UPDATE NODE AND LINK POSITIONS HERE
if (force.alpha() > 0) {
requestAnimationFrame(render);
}
});
That would render once for every 3 ticks, or 3x speed. Adjust the ticksPerRender
value as needed.
HERE is a simple demo. In this case, I've used the force.on('start', callback)
to call the rendering logic described above. This means it will automatically be called again when beginning a drag interaction.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With