Information Technology
Information Technology

Reputation: 2333

How do I control the bounce entry of a Force Directed Graph in D3?

I've been able to build a Force Directed Graph using a Force Layout. Most features work great but the one big issue I'm having is that, on starting the layout, it bounces all over the page (in and out of the canvas boundary) before settling to its location on the canvas.

I've tried using alpha to control it but it doesn't seem to work:

    // Create a force layout and bind Nodes and Links
    var force = d3.layout.force()
        .charge(-1000)
        .nodes(nodeSet)
        .links(linkSet)
        .size([width/8, height/10])
        .linkDistance( function(d) { if (width < height) { return width*1/3; } else { return height*1/3 } } ) // Controls edge length
        .on("tick", tick)
        .alpha(-5) // <---------------- HERE
        .start();

Does anyone know how to properly control the entry of a Force Layout into its SVG canvas?

I wouldn't mind the graph floating in and settling slowly but the insane bounce of the entire graph isn't appealing, at all.

BTW, the Force Directed Graph example can be found at: http://bl.ocks.org/Guerino1/2879486enter link description here

Thanks for any help you can offer!

Upvotes: 7

Views: 3471

Answers (2)

Biovisualize
Biovisualize

Reputation: 2475

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: http://bl.ocks.org/mbostock/1129492
  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 http://bl.ocks.org/mbostock/1667139
  4. You can initialize the nodes position https://github.com/mbostock/d3/wiki/Force-Layout#wiki-nodes (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; });

Upvotes: 5

starflyer
starflyer

Reputation: 485

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.

Upvotes: 2

Related Questions