A small multiples visualization of donut charts showing the breakdown of religions for the largest 5 countries.
Note that area is proportional to population, because the area of each pie corresponds to the population of each country (the sum of all religions). This makes the visualization more "honest" than the fixed size Donut Chart Small Multiples.
forked from curran's block: Sized Pie Charts
Thanks to enjalot for the idea to size each donut.
xxxxxxxxxx
<html>
<head>
<meta charset="utf-8">
<title>D3 Example</title>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3-legend/1.1.0/d3-legend.js"></script>
<link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<style>
.axis text {
font-family: 'Open Sans', sans-serif;
font-size: 21pt;
}
.axis path, .axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.color-legend text {
font-family: 'Open Sans', sans-serif;
font-size: 17pt;
}
</style>
</head>
<body>
<script>
var outerWidth = 960;
var outerHeight = 500;
var margin = { left: 95, top: 0, right: 64, bottom: 297 };
var xColumn = "country";
var colorColumn = "religion";
var areaColumn = "population";
var radiusMax = 95;
var innerWidth = outerWidth - margin.left - margin.right;
var innerHeight = outerHeight - margin.top - margin.bottom;
var svg = d3.select("body").append("svg")
.attr("width", outerWidth)
.attr("height", outerHeight);
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var xAxisG = g.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + innerHeight + ")");
var colorLegendG = svg.append("g")
.attr("class", "color-legend")
.attr("transform", "translate(415, 255)");
var xScale = d3.scale.ordinal().rangePoints([0, innerWidth]);
var radiusScale = d3.scale.sqrt().range([0, radiusMax]);
var colorScale = d3.scale.category10();
var xAxis = d3.svg.axis().scale(xScale).orient("bottom")
.outerTickSize(0);
var pie = d3.layout.pie();
var arc = d3.svg.arc();
arc.innerRadius(0);
var colorLegend = d3.legend.color()
.scale(colorScale)
.shapePadding(3)
.shapeWidth(25)
.shapeHeight(25)
.labelOffset(4);
function render(data){
var nested = d3.nest()
.key(function (d){ return d[xColumn]; })
.entries(data);
// Compute sums for the radius field,
// for setting the size of each pie.
nested.forEach(function (xEntry){
xEntry.areaColumnSum = d3.sum(xEntry.values, function (d){
return d[areaColumn];
});
});
xScale.domain(nested.map( function (d){ return d.key; }));
colorScale.domain(nested[0].values.map(function (d){ return d[colorColumn]; }));
pie.value(function(d) { return d[areaColumn]; });
radiusScale.domain([
0,
d3.max(nested, function (xEntry){
return xEntry.areaColumnSum;
})
]);
var pies = g.selectAll(".pie").data(nested);
pies.enter().append("g").attr("class", "pie");
pies.attr("transform", function (d){
var x = xScale(d.key);
return "translate(" + x + "," + innerHeight / 2 + ")";
});
pies.exit().remove();
var slices = pies.selectAll("path").data(function (d){
return pie(d.values);
});
slices.enter().append("path");
slices
.attr("d", function (d, i, j){
var r = radiusScale(nested[j].areaColumnSum);
arc.outerRadius(r);
arc.innerRadius(r / 2);
return arc(d);
})
.attr("fill", function (d){ return colorScale(d.data[colorColumn]); });
slices.exit().remove();
xAxisG.call(xAxis);
colorLegendG.call(colorLegend);
}
function type(d){
d.name = "World";
d.population = +d.population;
return d;
}
d3.csv("religionByCountryTop5.csv", type, render);
</script>
</body>
</html>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js
https://cdnjs.cloudflare.com/ajax/libs/d3-legend/1.1.0/d3-legend.js