Force directed graph: growing and shrinking nodes
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.