Skip to content

Instantly share code, notes, and snippets.

@syntagmatic
Forked from mbostock/.block
Last active February 24, 2021 05:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save syntagmatic/eebcb592d3fdd9ac4a5c92361c1e7066 to your computer and use it in GitHub Desktop.
Save syntagmatic/eebcb592d3fdd9ac4a5c92361c1e7066 to your computer and use it in GitHub Desktop.
d3-hierarchy tree
license: gpl-3.0
border: no
height: 500

A visualization of files in d3-hierarchy, based on Radial Tidy Tree.

Data Collection

Use git to clone a repository, then du to create a tsv with the directory contents.

git clone https://github.com/d3/d3-hierarchy.git
(echo -n 'size\tfile\n'; du -a d3-hierarchy/*) > d3-hierarchy.tsv

Burrow - recursive nesting

An updated version of the burrow function from d3 src tree in plain JavaScript. This function takes an array of keys to generate a hierarchy.

Compared to d3.nest: burrow allows for branches of arbitrary depth.

Compared to d3.stratify: parent nodes do not need to be specified as separate rows in the tabular data. Parents are created automatically as they are encountered.

size file
8 LICENSE
72 README.md
8 d3-hierarchy.sublime-project
88 img/cluster.png
200 img/pack.png
56 img/partition.png
72 img/stratify.png
72 img/tree.png
144 img/treemap.png
632 img
8 index.js
8 package.json
8 src/accessors.js
8 src/cluster.js
8 src/constant.js
8 src/hierarchy/ancestors.js
8 src/hierarchy/descendants.js
8 src/hierarchy/each.js
8 src/hierarchy/eachAfter.js
8 src/hierarchy/eachBefore.js
8 src/hierarchy/index.js
8 src/hierarchy/leaves.js
8 src/hierarchy/path.js
8 src/hierarchy/sort.js
8 src/hierarchy/sum.js
80 src/hierarchy
8 src/pack/enclose.js
8 src/pack/index.js
8 src/pack/shuffle.js
8 src/pack/siblings.js
32 src/pack
8 src/partition.js
8 src/stratify.js
16 src/tree.js
8 src/treemap/binary.js
8 src/treemap/dice.js
8 src/treemap/index.js
8 src/treemap/round.js
8 src/treemap/slice.js
8 src/treemap/sliceDice.js
8 src/treemap/squarify.js
56 src/treemap
224 src
136 test/data/flare-one.json
136 test/data/flare-phi.json
16 test/data/flare.csv
24 test/data/flare.json
8 test/data/simple.json
8 test/data/simple2.json
8 test/data/simple3.json
336 test/data
24 test/stratify-test.js
8 test/treemap/binary-test.js
8 test/treemap/dice-test.js
8 test/treemap/flare-test.js
16 test/treemap/index-test.js
8 test/treemap/round.js
8 test/treemap/slice-test.js
8 test/treemap/sliceDice-test.js
8 test/treemap/squarify-test.js
72 test/treemap
432 test
<!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>
<body>
<script src="//d3js.org/d3.v4.0.0-alpha.29.js"></script>
<script>
var width = 960,
height = 500,
radius = 250;
var burrow = function(table) {
// create nested object
var obj = {};
table.forEach(function(row) {
// start at root
var layer = obj;
// create children as nested objects
row.taxonomy.forEach(function(key) {
layer[key] = key in layer ? layer[key] : {};
layer = layer[key];
});
});
// recursively create children array
var descend = function(obj, depth) {
var arr = [];
var depth = depth || 0;
for (var k in obj) {
var child = {
name: k,
depth: depth,
children: descend(obj[k], depth+1)
};
arr.push(child);
}
return arr;
};
// use descend to create nested children arrys
return {
name: "root",
children: descend(obj, 1),
depth: 0
}
};
var tree = d3.tree()
.size([360, radius - 90])
.separation(function(a, b) { return (a.parent == b.parent ? 1 : 2) / a.depth; });
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + (width / 2) + "," + (height / 2) + ")");
d3.tsv("d3-hierarchy.tsv", function(error, data) {
if (error) throw error;
// splitting keys into an array is required before passing data into burrow
data.forEach(function(row) {
row.taxonomy = row.file.split("/");
});
var root = d3.hierarchy(burrow(data));
tree(root);
var link = svg.selectAll(".link")
.data(root.descendants().slice(1))
.enter().append("path")
.attr("class", "link")
.attr("d", function(d) {
return "M" + project(d.x, d.y)
+ "C" + project(d.x, (d.y + d.parent.y) / 2)
+ " " + project(d.parent.x, (d.y + d.parent.y) / 2)
+ " " + project(d.parent.x, d.parent.y);
});
var node = svg.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(" + project(d.x, d.y) + ")"; });
node.append("circle")
.attr("r", 2.5);
node.append("text")
.attr("dy", ".31em")
.attr("x", function(d) { return d.x < 180 === !d.children ? 6 : -6; })
.style("text-anchor", function(d) { return d.x < 180 === !d.children ? "start" : "end"; })
.attr("transform", function(d) { return "rotate(" + (d.x < 180 ? d.x - 90 : d.x + 90) + ")"; })
.text(function(d) { return d.data.name; });
});
function project(x, y) {
var angle = (x - 90) / 180 * Math.PI, radius = y;
return [radius * Math.cos(angle), radius * Math.sin(angle)];
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment