2👍
✅
The following solution is using the same calculation as lamelemon’s but using Chart.js plugins, which brings additional benefits :
-
There is no longer this blink effect caused by the
animation.onComplete
since it occurs immediatly without waiting for antything. -
The tooltip is above the text, which is more natural.
Follows the plugin that does it :
Chart.pluginService.register({
afterDatasetsDraw: function(chartInstance) {
// We get the canvas context
var ctx = chartInstance.chart.ctx;
// And set the properties we need
ctx.font = Chart.helpers.fontString(14, 'bold', Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
ctx.fillStyle = '#666';
// For ervery dataset ...
chartInstance.config.data.datasets.forEach(function(dataset) {
// For every data in the dataset ...
for (var i = 0; i < dataset.data.length; i++) {
// We get all the properties & values we need
var model = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._model,
total = dataset._meta[Object.keys(dataset._meta)[0]].total,
mid_radius = model.innerRadius + (model.outerRadius - model.innerRadius) / 2,
start_angle = model.startAngle,
end_angle = model.endAngle,
mid_angle = start_angle + (end_angle - start_angle) / 2;
// We calculate the right positions for our text
var x = mid_radius * 1.5 * Math.cos(mid_angle);
var y = mid_radius * 1.5 * Math.sin(mid_angle);
// We calculate the percentage
var percent = String(Math.round(dataset.data[i] / total * 100)) + "%";
// And display it
ctx.fillText(percent, model.x + x, model.y + y);
}
});
}
});
You can check this plugin working on this jsFiddle, and here is the result :
1👍
Alright looks like you have some simple syntax errors in your updated code that probably happened with copying over. Ignoring those, you can manage this by creating a function in your animation options. Here is the fiddle. Thanks to Hung Tran’s work here.
animation: {
duration: 0,
easing: "easeOutQuart",
onComplete: function () {
var ctx = this.chart.ctx;
ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontFamily, 'normal', Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
this.data.datasets.forEach(function (dataset) {
for (var i = 0; i < dataset.data.length; i++) {
var model = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._model,
total = dataset._meta[Object.keys(dataset._meta)[0]].total,
mid_radius = model.innerRadius + (model.outerRadius - model.innerRadius)/2,
start_angle = model.startAngle,
end_angle = model.endAngle,
mid_angle = start_angle + (end_angle - start_angle)/2;
var x = mid_radius * Math.cos(mid_angle);
var y = mid_radius * Math.sin(mid_angle);
ctx.fillStyle = '#fff';
if (i == 3){ // Darker text color for lighter background
ctx.fillStyle = '#444';
}
var percent = String(Math.round(dataset.data[i]/total*100)) + "%";
// this prints the data number
ctx.fillText(dataset.data[i], model.x + x, model.y + y);
// this prints the percentage
ctx.fillText(percent, model.x + x, model.y + y + 15);
}
});
}
}
Source:stackexchange.com