Skip to content

Instantly share code, notes, and snippets.

@emmasaunders
Last active October 20, 2016 10:23
Show Gist options
  • Save emmasaunders/5a3ec2a4dd08e12d87b4d3959df7d897 to your computer and use it in GitHub Desktop.
Save emmasaunders/5a3ec2a4dd08e12d87b4d3959df7d897 to your computer and use it in GitHub Desktop.
Tree (v4)

##Explanation D3 commands shown as a dendrogram with perpendicular "elbow" connectors. Transforms JSON data with d3.cluster and d3.hierarchy. Creates appearance of lines (path.link) stopping short of the word by adding text, creating white background rectangles to match length of text, and then adding text again on top. Convoluted, but it works! Click "Open" to see full graphic. See: https://github.com/d3/d3-hierarchy/blob/master/README.md#cluster

{
"name": "d3",
"children": [
{
"name": "svg",
"children": [
{"name":"axis"},
{ "name":"line", "children": [{"name":"radial"}]},
{ "name":"area", "children": [{"name":"radial"}] },
{ "name":"diagonal", "children": [{"name":"radial"}]},
{ "name":"arc" },
{ "name":"symbol" },
{ "name":"chord" },
{"name":"brush"}
]},
{
"name": "layout",
"children": [
{"name":"bundle" },
{"name":"chord" },
{"name":"cluster" },
{"name":"force" },
{"name":"hierarchy" },
{"name":"histogram" },
{"name":"pack" },
{"name":"partition" },
{"name":"pie" },
{"name":"stack" },
{"name":"tree" },
{"name":"treemap" }
]},
{
"name": "geo",
"children": [
{"name":"path" },
{"name":"graticule" },
{"name":"circle" },
{"name":"area" },
{"name":"bounds" },
{"name":"centroid" },
{"name":"distance" },
{"name":"interpolate" },
{"name":"length" },
{"name":"rotation" },
{"name":"projection" },
{"name":"Albers et al." },
{"name":"stream" },
{"name":"transform" },
{"name":"clipExtent" }
]},
{
"name": "geom",
"children": [
{"name":"voronoi" },
{"name":"quadtree" },
{"name":"polygon" },
{"name":"hull" }
]},
{
"name": "behavior",
"children": [
{"name":"drag" },
{"name":"zoom" }
]},
{
"name": "time",
"children": [
{"name":"scale" },
{"name":"interval" },
{"name":"day, week, et al." },
{"name":"format", "children": [{"name":"multi"},{"name":"iso"},{"name":"utc"}] }
]},
{
"name": "scale",
"children": [
{"name":"ordinal" },
{"name":"linear" },
{"name":"log" },
{"name":"quantize" },
{"name":"quantile" },
{"name":"threshold" },
{"name":"identity" },
{"name":"pow" },
{"name":"sqrt" },
{"name":"category10()" },
{"name":"category20()" },
{"name":"category20b()" },
{"name":"category20c()" }
]},
{
"name": "",
"children": [
{"name":"rgb" },
{"name":"hsl" },
{"name":"hcl" },
{"name":"lab" }
]},
{
"name": "",
"children": [
{"name":"xhr" },
{"name":"json" },
{"name":"text" },
{"name":"html" },
{"name":"xml" },
{"name":"csv" },
{"name":"tsv" },
{"name":"dsv" }
]},
{
"name": "",
"children": [
{"name":"select" },
{"name":"selectAll" },
{"name":"selection" }
]},
{
"name": "",
"children": [
{"name":"nest" },
{"name":"map" },
{"name":"set" }
]},
{
"name": "",
"children": [
{"name":"event" },
{"name":"mouse" },
{"name":"touch" },
{"name":"touches" }
]},
{
"name": "",
"children": [
{"name":"transition" },
{"name":"ease" },
{"name":"timer" },
{"name":"dispatch" },
{"name":"interpolate" }
]}
]
}
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.node circle {
fill: #fff;
stroke: steelblue;
stroke-width: 1.5px;
}
.node circle:hover {
fill: steelblue;
cursor: pointer;
}
.node {
font: 11px sans-serif;
fill: gray;
}
.link {
fill: none;
stroke: #ccc;
stroke-width: 1.5px;
}
.rectLabel {
fill: white;
opacity: 1;
}
</style>
<body>
<script type="text/javascript" src="http://d3js.org/d3.v4.min.js"></script>
<script>
var d = document, e = d.documentElement, w = e.clientWidth, h = e.clientHeight ;
var width = w,
height = h*2;
var tree = d3.cluster()
.size([height, width -500]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var svg = d3.select("body").select("svg").append("g")
.attr("transform", "translate(80,0)");
d3.json("d3Functions.json", function(json) {
var root = d3.hierarchy(json);
tree(root);
var link = svg.selectAll("path.link")
.data(root.descendants().slice(1))
.enter().append("path")
.attr("class", "link")
.attr("d", elbow);
var node = svg.selectAll("g.node")
.data(root.descendants())
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
node.append("circle")
.filter(function(d){ return d.data.name.length>0; })
.attr("r", 4);
node.append("text")
.filter(function(d){ return d.data.name.length>0; })
.attr("dx", function(d) { return d.children ? -8 : 8; })
.attr("class","textLabel")
.attr("id",function(d,i){ return "txt"+i; })
.attr("dy", 3)
.attr("text-anchor", function(d) { return d.children ? "end" : "start"; })
.text(function(d) { return d.data.name; });
var objs = document.querySelectorAll("text.textLabel");
var widths = [];
for (var o=0; o<objs.length; o++) {
var obj = document.getElementById(objs[o].id);
var bb = obj.getBoundingClientRect();
widths.push(bb.width);
}
node.append("rect")
.filter(function(d){ return d.data.name.length>0; })
.attr("x", function(d,i){ return d.children ? (-1*widths[i])-12 : 9 ;})
.attr("class","rectLabel")
.attr("id",function(d,i){ return "rect"+i; })
.attr("y", -4)
.attr("height","10")
.attr("width", function(d,i) { return widths[i] + 4; });
node.append("text")
.filter(function(d){ return d.data.name.length>0; })
.attr("dx", function(d) { return d.children ? -8 : 8; })
.attr("class","textLabel")
.attr("id",function(d,i){ return "txt"+i; })
.attr("dy", 3)
.attr("text-anchor", function(d) { return d.children ? "end" : "start"; })
.text(function(d) { return d.data.name; });
});
function elbow(d, i) {
return "M" + d.parent.y + "," + d.parent.x
+ "V" + d.x + "H" + (d.y-0);
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment