In D3 force orientation, how can I position the fixed nodes programmatically without dragging and dropping?

In the answer to this question, mbostock notes that "if a node is fixed, it can only be moved by drag and drop, not by simulation."

What if I want to position the nodes programmatically, however, perhaps setting the dx and dy values? My attempts so far have failed. I've tried the obvious setting dx and dy, but those values ​​are ignored for fixed nodes. I also tried to temporarily "remove the fix", redraw and then "reinstall" the nodes, but that also doesn't work - the nodes magically reset to their original position on the next tick.

Here's an example of doing this last approach.

Here's the clickable bit of that code's key:

function explicitlyPosition() {
  node.each(function(d) {
    d.x = 0;
    d.y = 0;
    d.fixed = false;
  });
  tick();
  node.each(function(d) {
    d.fixed = true;
  });
  force.resume();
}

      

Is there a way to do this using the approach I tried, or one similar? Or I could use a completely different graph scheme in D3, but ideally I would like large portions of my graph to be force-mapped.

Thank!

+3


source to share


2 answers


When triggered, the tick

previous positions of the nodes are used to define new positions and are stored in the px

and attributes py

. If you change these attributes, run tick

update attributes x

, and y

these values.

Fiddle.



Essentially, your nodes will magically correct new values ​​when they are changed again, rather than magically resetting their old values.

+5


source


The jsfiddles used in the 2014 answer and comments on this question are deprecated for version D3 4. In version 4, the process of creating fixed nodes is greatly simplified. You can just set the values fx

and fy

for each node you want to fix.

For example, for example:

var graph = {
    "nodes": [
        // unfixed
        {"id":0},
        // fixed
        {"id":1, "fx": 200, "fy": 200},
        {"id":2, "fx": 200, "fy": 300},
        {"id":3, "fx": 300, "fy": 250}
    ],
    "links": [
        {"source": 0, "target": 1},
        {"source": 0, "target": 2},
        {"source": 1, "target": 3},
        {"source": 2, "target": 3}
    ]
};

      

or that:



graph.nodes[3].fx = 500;
graph.nodes[3].fy = 250;

      

or that:



graph.nodes.each(function(d) {
    if(d.id == 2) {
        d.fx = 0;
        d.fy = 0;       
    }
});

      

+1


source







All Articles