Donut with labels
by Rob Carroll
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.16/d3.js"></script>
JavaScript
var data = [
{name: "abolitionist-all", val: 98},
{name: "abolitionist-ordinary", val: 7},
{name: "abolitionist-practice", val: 35},
{name: "retentionist", val: 58}
];
var w = 400,
h = 400,
r = Math.min(w, h) / 2,
labelr = r + 1000, // radius for label anchor
donut = d3.layout.pie(),
arc = d3.svg.arc().innerRadius(r*.5).outerRadius(r);
var color = d3.scale.ordinal()
.domain(["abolitionist-all","abolitionist-ordinary","abolitionist-practice","retentionist"])
.range(["#FFFF00", "#515151", "#808080", "#000000"]);
var vis = d3.select("body")
.append("svg:svg")
.data([data])
.attr("width", w +150)
.attr("height", h);
var arcs = vis.selectAll("g.arc")
.data(donut.value(function(d) { return d.val }))
.enter().append("svg:g")
.attr("class", "arc")
.attr("transform", "translate(" + (r + 30) + "," + r + ")");
arcs.append("svg:path")
.attr("fill", function(d, i) { return color(i); })
.attr("d", arc);
arcs.append("text")
.attr("text-anchor", "end")
.attr("x", function(d) {
var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2;
d.cx = Math.cos(a) * (r - 45);
return d.x = Math.cos(a) * (r+30);
})
.attr("y", function(d) {
var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2;
d.cy = Math.sin(a) * (r - 45);
return d.y = Math.sin(a) * (r+30);
})
.text(function(d) {
return d.value.toFixed(2);
})
.each(function(d) {
var bbox = this.getBBox();
d.sx = d.x - bbox.width/2 - 2;
d.ox = d.x + bbox.width/2 + 2;
d.sy = d.oy = d.y + 5;
});
arcs.append("path")
.attr("class", "pointer")
.style("fill", "none")
.style("stroke", "black")
.attr("d", function(d) {
if(d.cx > d.ox) {
return "M" + d.sx + "," + d.sy + "L" + d.ox + "," + d.oy + " " + d.cx + "," + d.cy;
} else {
return "M" + d.ox + "," + d.oy + "L"...