Skip to content

Instantly share code, notes, and snippets.

@IPWright83
Last active November 15, 2016 13:26
Show Gist options
  • Save IPWright83/c2d55588d0294a039b87098757bea3ce to your computer and use it in GitHub Desktop.
Save IPWright83/c2d55588d0294a039b87098757bea3ce to your computer and use it in GitHub Desktop.
Circle Packing layouts

This illustrates the different layouts that the d3.pack layout produces when the circles are all of equal size.

var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var margin = 10;
var svg = d3.select("body")
.append("svg")
.attr("height", "100%")
.attr("width", "100%")
.append("g")
.attr("transform", "translate(" + [margin, margin] + ")");
// Grab the height and the width
var width = parseFloat(d3.select("svg").style("width"));
var height = parseFloat(d3.select("svg").style("height"));
var size = Math.min(width / 6, height / 4);
var maxColumn = 7;
for(var row = 0, column = 0; (row * maxColumn) + column <= letters.length; row++, column = 0) {
for(; column < maxColumn && (row * maxColumn) + column <= letters.length; column++) {
// Create a container
var viz = svg.append("g")
.attr("class", "container")
.attr("transform", "translate(" + [ column * (size+margin), row * (size+margin) ] + ")");
// Show the bounding boxes
viz.append("rect").attr("width", size).attr("height", size).style("fill", "none").style("stroke", "red");
viz = viz.append("g")
.attr("transform", "translate(" + [size / 2, size / 2] + ")");
// Create the layout
var pack = d3.layout.pack()
.padding(5)
.size([size, size])
.value(function(d) { return d.name === "B" ? 0.5 : 1; });
// Create the set of nodes
var root = { name: "root", children: [] };
for(var j = 0; j < (row * maxColumn) + column; j++) {
root.children.push({ name: letters[j], children: []});
}
// Create the set of nodes
var nodes = pack.nodes(root);
var node = viz.selectAll("circle,text");
// Create the circles
var groups = viz.selectAll("g")
.data(nodes)
.enter()
.append("g");
var circles = groups.append("circle")
.attr("r", function(d) { return d.r; })
.attr("class", function(d) {
var cssClass = "node";
if(d.name === "A") cssClass += " fixed";
if(d.parent == null) cssClass += " node--root";
if(d.children == null) cssClass += " node--leaf";
return cssClass;
});
// Create the labels
var text = groups.append("text")
.attr("class", "label")
.style("fill-opacity", function(d) { return d.parent === root ? 1 : 0; })
.style("display", function(d) { return d.parent === root ? "inline" : "none"; })
.text(function(d) { return d.name; });
zoomTo([root.x, root.y, root.r * 2 + margin]);
function zoom(d) {
var focus0 = focus; focus = d;
var transition = d3.transition()
.duration(d3.event.altKey ? 7500 : 750)
.tween("zoom", function(d) {
var i = d3.interpolateZoom(view, [focus.x, focus.y, focus.r * 2 + margin]);
return function(t) { zoomTo(i(t)); };
});
transition.selectAll("text")
.filter(function(d) { return d.parent === focus || this.style.display === "inline"; })
.style("fill-opacity", function(d) { return d.parent === focus ? 1 : 0; })
.each("start", function(d) { if (d.parent === focus) this.style.display = "inline"; })
.each("end", function(d) { if (d.parent !== focus) this.style.display = "none"; });
}
function zoomTo(v) {
var k = size / v[2]; view = v;
groups.attr("transform", function(d) { return "translate(" + (d.x - v[0]) * k + "," + (d.y - v[1]) * k + ")"; });
circles.attr("r", function(d) { return d.r * k; });
}
}
}
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head>
<style>
body {
background: #EEE;
}
.container {
border: thin solid red;
}
.node {
fill: white;
stroke: #3d8b40;
stroke-width: 2px;
}
.label {
font: 11px "Helvetica Neue", Helvetica, Arial, sans-serif;
text-anchor: middle;
text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff, 0 -1px 0 #fff;
}
.fixed {
stroke: red !important;
}
.label,
.node--root,
.node--leaf {
pointer-events: none;
}
.node--root {
fill: #4caf50 !important;
}
html { height: 100%; }
body { height: 100%; }
.viz { width: 100%; height: 100%; position: absolute; }
</style>
</head>
<body></body>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script type="text/javascript" src="graph.js"></script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment