This example demonstrates how to add and remove nodes and links from a force layout. The graph initially appears with three nodes A, B and C connected in a loop. Three seconds later, node B is removed, along with the links B-A and B-C. At six seconds, node B is reintroduced, restoring the original links B-A and B-C. This example uses the general update pattern for data joins.
| <!DOCTYPE html> | |
| <meta charset="utf-8"> | |
| <style> | |
| .link { | |
| stroke: #000; | |
| stroke-width: 1.5px; | |
| } | |
| .node { | |
| fill: #000; | |
| stroke: #fff; | |
| stroke-width: 1.5px; | |
| } | |
| .node.a { fill: #1f77b4; } | |
| .node.b { fill: #ff7f0e; } | |
| .node.c { fill: #2ca02c; } | |
| </style> | |
| <body> | |
| <script src="http://d3js.org/d3.v3.min.js"></script> | |
| <script> | |
| var width = 960, | |
| height = 500; | |
| var color = d3.scale.category10(); | |
| var nodes = [], | |
| links = []; | |
| var force = d3.layout.force() | |
| .nodes(nodes) | |
| .links(links) | |
| .charge(-400) | |
| .linkDistance(120) | |
| .size([width, height]) | |
| .on("tick", tick); | |
| var svg = d3.select("body").append("svg") | |
| .attr("width", width) | |
| .attr("height", height); | |
| var node = svg.selectAll(".node"), | |
| link = svg.selectAll(".link"); | |
| // 1. Add three nodes and three links. | |
| setTimeout(function() { | |
| var a = {id: "a"}, b = {id: "b"}, c = {id: "c"}; | |
| force.stop(); | |
| nodes.push(a, b, c); | |
| links.push({source: 0, target: 1}, {source: 0, target: 2}, {source: 1, target: 2}); | |
| start(); | |
| }, 0); | |
| // 2. Remove node B and associated links. | |
| setTimeout(function() { | |
| nodes.splice(1, 1); // remove b | |
| links.shift(); // remove a-b | |
| links.pop(); // remove b-c | |
| start(); | |
| }, 3000); | |
| // Add node B back. | |
| setTimeout(function() { | |
| var a = nodes[0], b = {id: "b"}, c = nodes[1]; | |
| nodes.push(b); | |
| links.push({source: a, target: b}, {source: b, target: c}); | |
| start(); | |
| }, 6000); | |
| function start() { | |
| force.start(); | |
| link = link.data(force.links(), function(d) { return d.source.id + "-" + d.target.id; }); | |
| link.enter().insert("line", ".node").attr("class", "link"); | |
| link.exit().remove(); | |
| node = node.data(force.nodes(), function(d) { return d.id;}); | |
| node.enter().append("circle").attr("class", function(d) { return "node " + d.id; }).attr("r", 8); | |
| node.exit().remove(); | |
| } | |
| function tick() { | |
| node.attr("cx", function(d) { return d.x; }) | |
| .attr("cy", function(d) { return 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; }); | |
| } | |
| </script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment