Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!

like image 226
Information Technology Avatar asked Jun 23 '13 13:06

Information Technology


2 Answers

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; });
like image 116
Biovisualize Avatar answered Oct 26 '22 15:10

Biovisualize


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.

like image 41
starflyer Avatar answered Oct 26 '22 15:10

starflyer