back · main · about · writing · notes · reading · d3 · now · contact · uncopyright


Force directed graph: growing and shrinking nodes
17 Mar 2017 · 278 words

This example was written as a demonstration of custom forces with d3’s force directed graph.

The custom forces change the size of the nodes over time. The blue “male” nodes gradually grow larger and the pink “female” nodes gradually grow smaller.

Implementing the custom force is simple. On each tick of the simulation, we loop through every node and check to see if its sex attribute is M or F. If it’s M we increase the radius slightly, and if it’s F we decrease the radius slightly.

//Example of a custom force 
//Slowly increases the size of the male nodes and decreases the size of the female nodes 
function node_increase_force() {   
  for (var i = 0, n = nodes_data.length; i < n; ++i) {
    curr_node = nodes_data[i];
    if(curr_node.sex === "M"){
      d3.selectAll("circle")._groups[0][i].attributes.r.value = +d3.selectAll("circle")._groups[0][i].attributes.r.value + 0.003;
    } else if(curr_node.sex === "F"){
    d3.selectAll("circle")._groups[0][i].attributes.r.value = +d3.selectAll("circle")._groups[0][i].attributes.r.value - 0.003;
    }    
  }
}

//add forces to the simulation                        
simulation
    .force("charge_force", charge_force)
    .force("center_force", center_force)
    .force("links",link_force)
    .force("node_increase_force",node_increase_force);

At the same time the nodes are bounded inside a box through limitations imposed in the tick function.

function tickActions() {
    //constrains the nodes to be within a box
      node
        .attr("cx", function(d) { return d.x = Math.max(radius, Math.min(width - radius, d.x)); })
        .attr("cy", function(d) { return d.y = Math.max(radius, Math.min(height - radius, d.y)); });
        
    link
        .attr("x1", function(d) { return d.source.x; })
        .attr("y1", function(d) { return d.source.y; })
        .attr("x2", function(d) { return d.target.x; })
        .attr("y2", function(d) { return d.target.y; });
}

The end result is a graph where the pink nodes dissolve into nothingness while the blue nodes grow disproportionally large.


Hope you found that useful! Click here to view to the rest of the force directed graph series.


back · main · about · writing · notes · reading · d3 · now · contact · uncopyright