Skip to content

Instantly share code, notes, and snippets.

@git-ashish
Forked from sim0nf/README.md
Last active August 29, 2015 14:22
Show Gist options
  • Select an option

  • Save git-ashish/570d649c1a69b0ae96e3 to your computer and use it in GitHub Desktop.

Select an option

Save git-ashish/570d649c1a69b0ae96e3 to your computer and use it in GitHub Desktop.

This is an example of building a tree layout using the Reingold-Tilford "tidy" algorithm, as described in "Tidier Drawings of Trees". As each new element is added to the graph, it animates in, starting at the previous position of the parent node. Thus, the existing nodes and the new node transition smoothly to their new positions. The animation stops when 500 nodes have been added to the tree.

Built with D3.js.

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>Node-Link Tree</title>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.layout.js"></script>
<style type="text/css">
.node {
stroke: #fff;
stroke-width: 2px;
}
.link {
fill: none;
stroke: #000;
}
</style>
</head>
<body>
<script type="text/javascript">
var sfid = 1000;
var w = 960,
h = 500,
root = {},
data = [root],
tree = d3.layout.tree().size([w - 20, h - 20]),
diagonal = d3.svg.diagonal(),
duration = 250,
timer = setInterval(update, duration);
var vis = d3.select("body").append("svg:svg")
.attr("width", w)
.attr("height", h)
.append("svg:g")
.attr("transform", "translate(10, 10)");
vis.selectAll("circle")
.data(tree(root))
.enter().append("svg:circle")
.attr("class", "node")
.attr("r", 3.5)
.attr("cx", x)
.attr("cy", y);
function update() {
if (data.length >= 100) {
data.splice(50, 1);
}
// Add a new datum to a random parent.
var d = {id: "ohai"+(++sfid)}, parent = data[~~(Math.random() * data.length)];
if (parent.children) parent.children.push(d); else parent.children = [d];
data.push(d);
// Compute the new tree layout. We'll stash the old layout in the data.
var nodes = tree(root);
// Update the nodes…
var node = vis.selectAll("circle.node")
.data(nodes, nodeId);
// Enter any new nodes at the parent's previous position.
node.enter().append("svg:circle")
.attr("class", "node")
.attr("r", 3.5)
.attr("cx", function(d) { return d.parent.data.x0; })
.attr("cy", function(d) { return d.parent.data.y0; })
.transition()
.duration(duration)
.attr("cx", x)
.attr("cy", y);
node.exit().remove();
// Transition nodes to their new position.
node.transition()
.duration(duration)
.attr("cx", x)
.attr("cy", y);
// Update the links…
var link = vis.selectAll("path.link")
.data(tree.links(nodes), linkId);
// Enter any new links at the parent's previous position.
link.enter().insert("svg:path", "circle")
.attr("class", "link")
.attr("d", function(d) {
var o = {x: d.source.data.x0, y: d.source.data.y0};
return diagonal({source: o, target: o});
})
.transition()
.duration(duration)
.attr("d", diagonal);
// Transition links to their new position.
link.transition()
.duration(duration)
.attr("d", diagonal);
}
function linkId(d) {
return d.source.data.id + "-" + d.target.data.id;
}
function nodeId(d) {
return d.data.id;
}
function x(d) {
return d.data.x0 = d.x;
}
function y(d) {
return d.data.y0 = d.y;
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment