D3.js donut chart with legend
by Kashif Imran
HTML
<script src="http://d3js.org/d3.v3.min.js"></script>
<div id="chart"></div>
CSS
.mid-text-small {
font-family: Helvetica, Arial, sans-serif;
font-size: 22px;
fill: #999999;
text-anchor: middle;
}
.mid-text-big {
font-family: Helvetica, Arial, sans-serif;
font-size: 50px;
fill: #777777;
text-anchor: middle;
}
.legend-amount {
fill: #555555;
font-family: Helvetica, Arial, sans-serif;
font-size: 18px;
}
.legend-name {
fill: #999999;
font-family: Helvetica, Arial, sans-serif;
font-size: 12px;
}
JavaScript
var sort = function (items, prop, dsc) {
if (dsc) {
items.sort(function (a, b) {
if (a[prop] > b[prop]) return -1;
if (a[prop] < b[prop]) return 1;
return 0;
});
} else {
items.sort(function (a, b) {
if (a[prop] > b[prop]) return 1;
if (a[prop] < b[prop]) return -1;
return 0;
});
}
}
var rectSize = 20;
var rectSizeWithGap = 50;
var ringSize = 60;
var extraWidth = 300;
var data = [{
name: 'Salaries',
amount: 19697
}, {
name: 'IT',
amount: 25000
}, {
name: 'Legal',
amount: 8000
}, {
name: 'Operations',
amount: 12000
}, {
name: 'Marketing',
amount: 6000
}, {
name: 'R&D',
amount: 16007
}];
sort(data, 'amount');
var total = 0;
for (var i = 0, len = data.length; i < len; i++) {
var item = data[i];
total += item.amount;
}
var size = 500;
var width = size + 70;
var radius = size / 2;
var barAreaHeight = data.length * rectSizeWithGap;
var height = Math.max(barAreaHeight, size);
var vCenter = height / 2;
var percent = function (index) {
var amount = data[index].amount;
return (amount/total * 100).toFixed(1) + '%';
}
var color = (function () {
var i = d3.interpolate('#FEDED3', '#EE4039');
return function (index) {
var ratio = (index + 1) / data.length;
return i(ratio);
}
})();
var pie = d3.layout.pie()
.sort(null)
.value(function (d) {
return d.amount;
});
var arc = d3.svg.arc()
.innerRadius(radius)
.outerRadius(radius - ringSize);
var svg = d3.select("#chart").append("svg")
.attr("width", width + extraWidth)
.attr("height", height);
var midTextGroup = svg.append("g")
.attr("transform", "translate(" + radius + "," + vCenter + ")");
midTextGroup.append('text').attr("x", 0)
.attr("y", -30)
.text("WHAT WE'RE RAISING")
.attr("class", "mid-text-small");
midTextGroup.append('text').attr("x", 0)
.attr("y", 30)
...