D3-Force update options after graph initialization

In D3 v4 with a power module, how do you update the simulation parameters after initializing the graph?

More precisely, I try to change .forceLinkand the .forceManyBodypattern of the force when the user clicks on one of their sites.

 var node = svg
    .append("g")
    .attr("class", "gnodes")
    .selectAll(".node")
    .data(graph.nodes)
    .enter()
    .append("g")
    .attr("class", "node")
    .on('dblclick', connectedNodes); //calls for change in simulation parameters

So far, I could update it by duplicating the simulation in the connectedNodes function:

function connectedNodes() {

//new parameters
linkDistance = 5;
fCharge = -10;

//replicates the initial simulation code
simulation = d3.forceSimulation()
    .force("link", d3.forceLink()
        .id(function(d) {return d.id;})
        .distance(linkDistance)
        )
    .force("collide", d3.forceCollide()
        .radius(function(d){return d.r + 10})
        .strength(1)
        )
    .force("charge", d3.forceManyBody()
        .strength(fCharge)
        )
    .force("center", d3.forceCenter(width / 2, height / 2));

simulation.nodes(graph.nodes).on("tick", ticked);

simulation.force("link").links(graph.links);

Although this works, it is very redundant. Is there a way in which a simulation can be updated with new parameters? I tried the following, but it does not work.

function connectedNodes() { 

//new parameters
linkDistance = 5;
fCharge = -10;

//restart simulation with new parameters
simulation.restart();
}
+3
source share
1 answer

You need a link to the forces that you would like to upgrade. This can be done in one of two ways:

  • Cool Blue comment, , simulation.force(), , . , , , :

    var simulation = d3.forceSimulation()
      .force("link", d3.forceLink()            // "link" is the name to register the force
        .id(function(d) { return d.id; })
        .distance(linkDistance)
      );
    

    :

    var forceLink = simulation.force("link");  // Get the force by its name
    

    , , / .

  • .

    var forceLink = d3.forceLink()      // Keep a reference to the force
      .id(function(d) { return d.id; })
      .distance(linkDistance);
    
    var simulation = d3.forceSimulation()
      .force("link", forceLink )        // Pass the reference when creating the simulation
    

, , , -

linkDistance += 10;
forceLink.distance(linkDistance);

. ,

simulation.alpha(1).restart();

, , SVG. linkDistance .

+5

Source: https://habr.com/ru/post/1651818/


All Articles