block by vicapow 3d24f96c240eeb8d14e3

circle packing with depth dependent padding

Full Screen

index.html

<!DOCTYPE html>
<html>
<style>
body {
  margin: 0;
}
</style>
<body>
  <script src="//d3js.org/d3.v3.js" charset="utf-8"></script>
  <script>

var data = {
  children: [
    {children: [{value: 1}, {value: 1}, {value: 1}]},
    {children: [{value: 1}, {value: 1}, {value: 1}, {value: 1}]},
    {children: [{value: 1}, {value: 1}, {value: 1}]},
    {children: [{value: 1}, {value: 1}, {value: 1}]},
    {children: [{value: 1}, {value: 7}, {value: 4}]},
    {children: [{value: 1}, {value: 1}, {value: 3}]},
    {children: [{value: 1}, {value: 2}]},
    {children: [{value: 1}, {value: 2}]},
    {children: [{value: 1}, {value: 2}]},
    {children: [{value: 1}]},
    {children: [{value: 1}]},
    {children: [{value: 1}]},
    {children: [{value: 1}]},
    {children: [{value: 1}]},
    {children: [{value: 1}]}
  ]
};

(function value(node) {
  if (node.value) return node.value;
  if (!node.children) return node.value = 0;
  return node.value = node.children.reduce(function(total, child) {
    return total + value(child);
  }, 0);
}(data));

var width = window.innerWidth, height = window.innerHeight;
var svg = d3.select('body').append('svg').attr({
  width: width + 'px',
  height: height + 'px'
});

var pack = d3.layout.pack()
  .size([width, height])
  .sort(function(a, b) { return b.value - a.value;})
  .padding(20);

var layout = pack.nodes(data);

var color = d3.scale.category10();

function recusiveOffset(node, pos) {
  node.x -= pos.x;
  node.y -= pos.y;
  if (node.children) node.children.forEach(function(child) {
    recusiveOffset(child, pos);
  });
}


// for all the children of each root child, offset the children by the root 
// childs position.
data.children.forEach(function(rootChild) {
  var pos = {x: rootChild.x, y: rootChild.y};
  rootChild.children.forEach(function (child) {
    recusiveOffset(child, pos);
  });
  rootChild.allChildren = [];
});

layout.forEach(function(node) {
  if (node.parent && node.parent.allChildren) {
    node.parent.allChildren.push(node);
  }
});

// Add the root children.
var rootChildren = svg.selectAll('g').data(data.children).enter().append('g')
  .attr({
    transform: function(d) {
      return 'translate(' + [d.x, d.y] + ') scale(0.6)'
    }
  });

rootChildren.append('circle')
  .attr('r', function(d) { return d.r + 20; })
  .style('fill', function(d) { return 'rgba(0, 0, 0, 0.3)'; })

rootChildren.append('g').selectAll('circle')
  .data(function(d) { return d.allChildren; })
  .enter().append('circle')
    .attr({
      cx: function(d) { return d.x; },
      cy: function(d) { return d.y; },
      r: function(d) { return d.r; }
    }).style({
      fill: function(d) { return color(d.value); }
    })

  </script>
</body>
</html>