Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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
You can’t perform that action at this time.