D3.js Template
CSS
* {
margin: 0;
padding: 0;
border: 0;
}
body {
background: #ffd;
}
JavaScript
var width = 600;
var height = 400;
var svg = d3.select('svg').attr("width", width).attr("height",height);
var data = [{
"name": "Twitter",
"items": [{
"value": 2000
}, {
"value": 3000
}]
}, {
"name": "Facebook",
"items": [{
"value": 200
}, {
"value": 300
}]
}, {
"name": "Ebay",
"items": [{
"value": 2000
}, {
"value": 1000
}]
}, {
"name": "Foursquare",
"items": [{
"value": 2000
}, {
"value": 3000
},
{
"value": 4000
}]
}];
// organise the data.
// Insert indices and sort items in each series
// keep a running total of max circle size in each series
// for later positioning
var x = 0;
var totalWidth = d3.sum (
data.map (function (series) {
series.items.forEach (function (item, i) {
item.index = i;
});
series.items.sort (function (a, b) {
return b.value - a.value;
});
var maxr = Math.sqrt(series.items[0].value);
x += maxr;
series.xcentre = x;
x += maxr;
return maxr * 2;
})
);
// make scales for position and colour
var scale = d3.scale.linear().domain([0,totalWidth]).range([0, width]);
var colScale = d3.scale.category10();
// add a group per series, position the group according to the values and position scale we calculated above
var groups = svg.selectAll("g").data(data);
groups.enter().append("g");
groups.attr("transform", function(d) {
return ("translate("+d.xcentre+",0)");
});
// then add circles per series, biggest first as items are sorted
// colour according to index (the property we inserted previously so we can
// keep track of their original position in the series)
var circles = groups.selectAll("circle").data(function(d) { return d.items;}, function(d) { return d.index; });
circles.enter().append("circle").attr("cy", height/2).attr("cx",0);
circles
.attr("r", function(d) { return Math.sqrt...