Skip to content

Instantly share code, notes, and snippets.

@emeeks
Last active March 17, 2016 02:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save emeeks/8e73290130d9e25c6d9c to your computer and use it in GitHub Desktop.
Save emeeks/8e73290130d9e25c6d9c to your computer and use it in GitHub Desktop.
Orbital Layout 2

This is an early draft of a hierarchical orbital layout. Like other hierarchical layouts (pack, tree, treemap, etc) It takes nested data annotates it with xy values for display, in this case arranging the data into orbits, with child nodes orbiting parents and the root node at the center.

You can set the layout size as an array but for now only circular orbits are supported (no ellipses) and as such only the first value in the array is honored.

This version displays orbital rings by calling orbit.orbitalRings(), which returns an array of data corresponding to each ring. You can also see an animated version here.

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Orbits 2</title>
<meta charset="utf-8" />
</head>
<style>
#viz, svg {
width: 500px;
height: 500px;
}
</style>
<script>
function makeViz() {
nodes = [];
///All of this is just to fake some nested data
randomCountry = d3.scale.quantize().domain([0,1]).range(["USA", "FRA", "MEX", "GBR", "CAN"])
randomStatus = d3.scale.quantize().domain([0,1]).range(["amazing","okay", "cool", "boss", "dope", "lame"])
randomRole = d3.scale.quantize().domain([0,1]).range(["capital","metropole", "port"])
trafficCategories = ["high","medium","low","fargo"];
quantizeTraffic = d3.scale.quantize().domain([0,500]).range(trafficCategories);
//200 random things with random categorical attributes
nodes = d3.range(200).map(function(d,i) {return {i: i} })
nodes.forEach(function (node) {
node.country = randomCountry(Math.random());
node.status = randomStatus(Math.random());
node.traffic = parseInt(Math.random() * 500);
node.trafficRank = quantizeTraffic(node.traffic);
node.role = randomRole(Math.random())
})
var nest = d3.nest()
.key(function(d) {return d.country})
.key(function(d) {return d.trafficRank})
.key(function(d) {return d.status})
.key(function(d) {return d.role})
var awesomeFakeNestedData = nest.entries(nodes);
//If you already have some nested data, just send it to drawOrbit
drawOrbit(awesomeFakeNestedData)
}
function drawOrbit(_data) {
//down with category20a()!!
colors = d3.scale.category20b();
orbit = d3.layout.orbit().size([500,500]).nodes(_data);
d3.select("svg").selectAll("circle").data(orbit.nodes())
.enter()
.append("circle")
.attr("r", function(d) {return Math.max(1, 5 - d.depth)})
.attr("cx", function(d) {return d.x})
.attr("cy", function(d) {return d.y})
.style("fill", function(d) {return colors(d.depth)})
d3.select("svg").selectAll("circle.orbits")
.data(orbit.orbitalRings())
.enter()
.insert("circle", "circle")
.attr("r", function(d) {return d.r})
.attr("cx", function(d) {return d.x})
.attr("cy", function(d) {return d.y})
.style("fill", "none")
.style("stroke", "black")
.style("stroke-width", "1px")
.style("stroke-opacity", .15)
}
</script>
<body onload="makeViz()">
<div id="viz"><svg></svg></div>
<footer>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="http://bl.ocks.org/emeeks/raw/531f107a0ff6eff5d543/d3.layout.orbit.js" charset="utf-8" type="text/javascript"></script>
</footer>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment