I was trying to pack circles of different sizes into a rectangular container, not packing in circular container that d3.js
bundled with, under
If your primary concern finding a tight packing of different-sized circles within a rectangle, then unfortunately you'll have to implement a new d3 layout. I don't know of a plugin that's already written that will do this.
However, if what you're looking for is any old packing into a rectangle, then you can use the the existing circle packing algorithm that d3 provides in d3.layout.pack
. When you specify the bounds for this layout, you're specifying the dimensions of a rectangle. d3 then determines a circle that the bounding rectangle will circumscribe, and uses that circle to visualize the root of the hierarchical data. So what you can do is provide a "dummy" root node which you don't actually render, and have the real data that you want to visualize be the children of that node.
Code example below, and I also put it up on bl.ocks.org so you can see it in action.
var w = 640,
h = 480;
var data = {
name : "root",
children : [
{ name: '1', size: 100 }, { name: '2', size: 85 },
{ name: '3', size: 70 } , { name: '4', size: 55 },
{ name: '5', size: 40 } , { name: '6', size: 25 },
{ name: '7', size: 10 } ,
]
}
var canvas = d3.select("#canvas")
.append("svg:svg")
.attr('width', w)
.attr('height', h);
var nodes = d3.layout.pack()
.value(function(d) { return d.size; })
.size([w, h])
.nodes(data);
// Get rid of root node
nodes.shift();
canvas.selectAll('circles')
.data(nodes)
.enter().append('svg:circle')
.attr('cx', function(d) { return d.x; })
.attr('cy', function(d) { return d.y; })
.attr('r', function(d) { return d.r; })
.attr('fill', 'white')
.attr('stroke', 'grey');