I have been thinking about this problem too and this is the solution I came up with. I used nodejs to run the force layout tick offline and save the resulting nodes data to a json file. I used that as the new json file for the layout. I'm not really sure it works better to be honest. I would like hear about any solutions you find.


The nodes are initialized with a random position. From the documentation: "If you do not initialize the positions manually, the force layout will initialize them randomly, resulting in somewhat unpredictable behavior." You can see it in the source code:

// initialize node position based on first neighbor
function position(dimension, size) {
    return Math.random() * size;

They will be inside the canvas boundary, but they can be pushed outside by the force. You have many solutions:

  1. The nodes can be constrained inside the canvas:
  2. Try more charge strength and shorter links, or more friction, so the nodes will tend to bounce less
  3. You can run the simulation without animating the nodes, only showing the end result
  4. You can initialize the nodes position (but if you place them all on the center, the repulsion will be huge and the graph will explode still more):


var n = nodes.length; nodes.forEach(function(d, i) {
    d.x = d.y = width / n * i; });

Related Query

More Query from same tag