Skip to content

Instantly share code, notes, and snippets.

@jstcki
Last active December 16, 2015 17:08
Show Gist options
  • Save jstcki/5467720 to your computer and use it in GitHub Desktop.
Save jstcki/5467720 to your computer and use it in GitHub Desktop.
Indented tree layout
Country Continent
Argentina South America
Bangladesh Asia
Botswana Africa
Bulgaria Europe
Canada North America
Chile South America
China Asia
Ethiopia Africa
France Europe
Germany Europe
Ghana Africa
India Asia
Japan Asia
Kenya Africa
Mexico South America
Mozambique Africa
Poland Europe
Senegal Africa
Spain Europe
Sri Lanka Asia
Sweden Europe
Thailand Asia
Turkey Asia
United Kingdom Europe
United States North America
Viet Nam Asia
(function() {
d3.layout.indent = function() {
var hierarchy = d3.layout.hierarchy(),
separation = d3_layout_indentSeparation,
nodeSize = [1, 1];
function position(node, previousNode) {
var children = node.children;
node.y = previousNode ? previousNode.y + nodeSize[1] * separation(node, previousNode) : 0;
node.x = node.depth * nodeSize[0];
if (children && (n = children.length)) {
var i = -1,
n;
while (++i < n) {
node = position(children[i], node);
}
}
return node;
}
function indent(d, i) {
var nodes = hierarchy.call(this, d, i);
position(nodes[0]);
return nodes;
}
indent.nodeSize = function(value) {
if (!arguments.length) return nodeSize;
nodeSize = value;
return indent;
};
indent.separation = function(value) {
if (!arguments.length) return separation;
separation = value;
return indent;
};
return d3_layout_hierarchyRebind(indent, hierarchy);
};
function d3_layout_indentSeparation() {
return 1;
}
// A method assignment helper for hierarchy subclasses.
function d3_layout_hierarchyRebind(object, hierarchy) {
d3.rebind(object, hierarchy, "sort", "children", "value");
// Add an alias for nodes and links, for convenience.
object.nodes = object;
object.links = d3_layout_hierarchyLinks;
return object;
}
// Returns an array source+target objects for the specified nodes.
function d3_layout_hierarchyLinks(nodes) {
return d3.merge(nodes.map(function(parent) {
return (parent.children || []).map(function(child) {
return {source: parent, target: child};
});
}));
}
})();
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font-family: Helvetica;
font-size: 10px;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="d3.layout.indent.js"></script>
<script>
function id(d) { return d.Country ? d.Country : d.key; };
var width = 960,
height = 500;
var layout = d3.layout.indent()
.sort(function(a, b) { return d3.ascending(id(a), id(b)) })
.children(function(d) { return d.values; })
.nodeSize([10, 15])
.separation(function(node, previousNode) { return node.parent === previousNode.parent || node.parent === previousNode ? 1 : 2; });
var nestAlpha = d3.nest()
.key(function(d) { return d.Country.slice(0,1); });
var nestContinent = d3.nest()
.key(function(d) { return d.Continent; });
d3.csv("countries.csv", function(error, countries) {
var svg = d3.select("body").append("svg")
.attr({
width: width,
height: height
})
.append("g")
.attr("transform", "translate(10,10)");
var continents = {
key: "Countries",
values: nestContinent.entries(countries)
};
var alphabet = {
key: "Countries",
values: nestAlpha.entries(countries)
};
var countries = {
key: "Countries",
values: countries
}
function update(tree) {
var nodes = layout(tree);
labels = svg.selectAll(".label")
.data(nodes, function(d) { return d.Country + d.key });
labels.enter()
.append("text")
.attr({
"class": "label",
dy: ".35em",
transform: function(d) { return "translate(" + (d.x - 200) + "," + d.y + ")"; }
})
.style("font-weight", function(d) { return d.Country ? null : "bold" })
.text(function(d) { return id(d); });
labels.transition().delay(250).duration(1000)
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
labels.exit().transition()
.attr("transform", function(d) { return "translate(" + (d.x - 200) + "," + d.y + ")"; })
.remove()
}
function init() {
update(countries);
setTimeout(function() { update(continents) }, 3000);
setTimeout(function() { update(alphabet) }, 6000);
setTimeout(init, 9000);
}
init();
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment