| <!DOCTYPE html> | |
| <html> | |
| <style> | |
| body { | |
| margin: 0; | |
| } | |
| </style> | |
| <body> | |
| <script src="http://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> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment