Reputation: 947
Trying to show the percentages right on the donut charts in dimple.plot.pie
Here is some code that kind of works but places the labels right onto the slices.
Having trouble making the labels show up outside the pie.
rings = chart.addSeries("series", dimple.plot.pie);
rings.afterDraw = function(shape, data) {
var bbox, ctm;
ctm = shape.getCTM();
bbox = shape.getBBox();
return this.chart.svg.append("text")
.attr("x", ctm.e + bbox.x + bbox.width/2)
.attr("y", ctm.f + bbox.y + bbox.height/2)
.text(Math.round(1000*data.piePct)/10 + "%");;
};
Here's the best I can do..
Upvotes: 3
Views: 1660
Reputation: 2839
2 years later and still no solution that works out-of-the-box?
The solution below is a working compilation of all I could find on the topic. Updates are welcome :-)
var pies = chart.addSeries("series", dimple.plot.pie);
pies.radius = 60;
pies.innerRadius = "50%";
pies.afterDraw = function (shape, data) {
var arc = d3.arc()
.outerRadius(radius)
.innerRadius(radius/2);
var ctm = shape.getCTM();
chart.svg.append("text")
// Position text in the centre of the shape
.attr("x", arc.centroid(data)[0])
.attr("y", arc.centroid(data)[1])
.attr("transform", function () {
return "translate("+ctm.e+","+ctm.f+")";
})
// Centre align and nicer display
.style("text-anchor", "middle")
.style("font-size", "10px")
.style("font-family", "sans-serif")
.style("opacity", 0.8)
// Prevent text cursor on hover and allow tooltips
.style("pointer-events", "none")
// Display text
.text((data.piePct*100).toFixed(2) + "%)");
}
Upvotes: 1
Reputation: 4904
I'd like to build this into the dimple library, but for the time being, here is the method I use in one of my own projects:
function getCentroid(data, plot) {
var centerX = plot.x + plot.width / 2,
centerY = plot.y + plot.height / 2,
angle = (data.startAngle + (data.endAngle - data.startAngle) / 2),
hyp = (data.innerRadius + (data.outerRadius - data.innerRadius) / 2),
opp = Math.sin(angle) * hyp,
adj = Math.cos(angle) * hyp;
return [centerX + opp, centerY - adj];
}
series.afterDraw = function (shape, data) {
var ctd = getCentroid(data, plotSize),
s = d3.select(shape),
degrees = ((data.startAngle + (data.endAngle - data.startAngle) / 2) * 180) / Math.PI;
if (degrees < 180) {
degrees -= 90;
} else {
degrees += 90;
}
if (Math.abs(data.startAngle - data.endAngle) > 0.1) {
chart._group.append("text")
.attr("transform", "rotate(" + degrees + ", " + ctd[0] + ", " + ctd[1] + 4 + ")")
.attr("dy", "0.35em")
.attr("x", ctd[0])
.attr("y", ctd[1])
.style("text-anchor", "middle")
.style("pointer-events", "none")
.text(format(data.pValue));
}
};
I took this direct from my own code so it relies on a few variables in scope but hopefully they are fairly self-explanatory.
Upvotes: 3