Skip to content

Instantly share code, notes, and snippets.

@recursionbane
Forked from mbostock/.block
Last active February 27, 2017 16:39
Show Gist options
  • Select an option

  • Save recursionbane/be5b87e918907bab8a521b9c43898efb to your computer and use it in GitHub Desktop.

Select an option

Save recursionbane/be5b87e918907bab8a521b9c43898efb to your computer and use it in GitHub Desktop.
Cluster Dendrogram
license: gpl-3.0
height: 2000
border: no

A dendrogram is a node-link diagram that places leaf nodes of the tree at the same depth. In this example, the classes (leaf nodes) are aligned on the right edge, with the packages (internal nodes) to the left. Data shows the Flare class hierarchy, courtesy Jeff Heer.

Compare to this radial layout.

id value
my__prc
my__prc.blockA
my__prc.blockA.ipo1234_run1
my__prc.blockA.ipo1234_run1.setup 1
my__prc.blockA.ipo1234_run1.prep 2
my__prc.blockA.ipo1234_run1.plan 3
my__prc.blockA.ipo1234_run1.place 4
my__prc.blockA.ipo1234_run1.cts 5
my__prc.blockA.ipo1234_run1.postcts 6
my__prc.blockA.ipo1234_run1.route 7
my__prc.blockA.ipo1234_run1.postroute 8
my__prc.blockA.ipo1234_run1.fill 9
my__prc.blockA.ipo1234_run2
my__prc.blockA.ipo1234_run2.setup 1
my__prc.blockA.ipo1234_run2.prep 2
my__prc.blockA.ipo1234_run2.plan 3
my__prc.blockA.ipo1234_run2.place 4
my__prc.blockA.ipo1234_run2.cts 5
my__prc.blockA.ipo1234_run2.route 6
my__prc.blockA.ipo1234_run2.postroute 7
my__prc.blockA.ipo1234_run2.fill 8
my__prc.blockB
my__prc.blockB.ipo1234_run1
my__prc.blockB.ipo1234_run1.setup 1
my__prc.blockB.ipo1234_run1.prep 2
my__prc.blockB.ipo1234_run1.plan 3
my__prc.blockB.ipo1234_run1.place 4
my__prc.blockB.ipo1234_run1.cts 5
my__prc.blockB.ipo1234_run1.postcts 6
my__prc.blockB.ipo1234_run1.route 7
my__prc.blockB.ipo1234_run1.postroute 8
my__prc.blockB.ipo1234_run1.fill 9
my__prc.blockB.ipo1234_run2
my__prc.blockB.ipo1234_run2.setup 1
my__prc.blockB.ipo1234_run2.prep 2
my__prc.blockB.ipo1234_run2.plan 3
my__prc.blockB.ipo1234_run2.place 4
my__prc.blockB.ipo1234_run2.cts 5
my__prc.blockB.ipo1234_run2.route 6
my__prc.blockB.ipo1234_run2.postroute 7
my__prc.blockB.ipo1234_run2.fill 8
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.node circle {
fill: #999;
}
.node text {
font: 10px sans-serif;
}
.node--internal circle {
fill: #555;
}
.node--internal text {
text-shadow: 0 1px 0 #fff, 0 -1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff;
}
.link {
fill: none;
stroke: #555;
stroke-opacity: 0.4;
stroke-width: 1.5px;
}
</style>
<svg width="960" height="2000"></svg>
<script src="//d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height"),
g = svg.append("g").attr("transform", "translate(40,0)");
var tree = d3.cluster()
.size([height, width - 160]);
var stratify = d3.stratify()
.parentId(function(d) { return d.id.substring(0, d.id.lastIndexOf(".")); });
d3.csv("flare.csv", function(error, data) {
if (error) throw error;
var root = stratify(data)
.sort(function(a, b) { return (a.height - b.height) || a.id.localeCompare(b.id); });
tree(root);
var link = g.selectAll(".link")
.data(root.descendants().slice(1))
.enter().append("path")
.attr("class", "link")
.attr("d", function(d) {
return "M" + d.y + "," + d.x
+ "C" + (d.parent.y + 100) + "," + d.x
+ " " + (d.parent.y + 100) + "," + d.parent.x
+ " " + d.parent.y + "," + d.parent.x;
});
var node = g.selectAll(".node")
.data(root.descendants())
.enter().append("g")
.attr("class", function(d) { return "node" + (d.children ? " node--internal" : " node--leaf"); })
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
node.append("circle")
.attr("r", 2.5);
node.append("text")
.attr("dy", 3)
.attr("x", function(d) { return d.children ? -8 : 8; })
.style("text-anchor", function(d) { return d.children ? "end" : "start"; })
.text(function(d) { return d.id.substring(d.id.lastIndexOf(".") + 1); });
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment