Reputation: 506
I am working to get the percents between my data point categories to display in my custom legend. I know I am close (as I have gotten them to work for the tooltips) but I haven't been able to quite crack it.
Right now I have 1 item in each category, and my tooltips are displaying 25% for each (correct) but my legend is showing 1% for each lol obviously wrong.
Here is my config:
var chart = new Chart(ctx, {
type: 'doughnut',
data: {
datasets: [{
data: getValues,
backgroundColor: getColorValues,
}],
labels: getLabels
},
options: {
responsive: true,
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var dataset = data.datasets[tooltipItem.datasetIndex];
var total = dataset.data.reduce(function(previousValue, currentValue, currentIndex, array) {
return previousValue + currentValue;
});
var currentValue = dataset.data[tooltipItem.index];
var precentage = Math.floor(((currentValue / total) * 100) + 0.5);
return precentage + "%";
}
}
},
legendCallback: function(chart) {
var text = [];
text.push('<ul class="' + chart.id + '-legend">');
var data = chart.data;
var datasets = data.datasets;
var labels = data.labels;
if (datasets.length) {
for (var i = 0; i < datasets[0].data.length; ++i) {
text.push('<li><span style="background-color:' + datasets[0].backgroundColor[i] + '"></span>');
if (labels[i]) {
text.push(labels[i] + ' (' + datasets[0].data[i] + '%)');
}
text.push('</li>');
}
}
text.push('</ul>');
return text.join('');
},
legend: {
display: false,
},
elements: {
arc: {
borderWidth: 0
}
},
cutoutPercentage: 70,
title: {
display: true
},
animation: {
animateScale: true,
animateRotate: true
}
}
});
document.getElementById('js-legend').innerHTML = chart.generateLegend();
I would really appreciate any help!
Upvotes: 0
Views: 4665
Reputation: 32859
Replace your legendCallback
function with the following :
legendCallback: function(chart) {
var text = [];
text.push('<ul class="' + chart.id + '-legend">');
var data = chart.data;
var datasets = data.datasets;
var labels = data.labels;
if (datasets.length) {
for (var i = 0; i < datasets[0].data.length; ++i) {
text.push('<li><span style="background-color:' + datasets[0].backgroundColor[i] + '"></span>');
if (labels[i]) {
// calculate percentage
var total = datasets[0].data.reduce(function(previousValue, currentValue, currentIndex, array) {
return previousValue + currentValue;
});
var currentValue = datasets[0].data[i];
var percentage = Math.floor(((currentValue / total) * 100) + 0.5);
text.push(labels[i] + ' (' + percentage + '%)');
}
text.push('</li>');
}
}
text.push('</ul>');
return text.join('');
}
Basically, you would also need to calculate the percentage for legend's labels, as you are doing for tooltips.
ᴡᴏʀᴋɪɴɢ ᴇxᴀᴍᴘʟᴇ ⧩
var getValues = [1, 2, 3],
getLabels = ['Jan', 'Feb', 'Mar'],
getColorValues = ['red', 'green', 'blue']
var chart = new Chart(ctx, {
type: 'doughnut',
data: {
datasets: [{
data: getValues,
backgroundColor: getColorValues,
}],
labels: getLabels
},
options: {
responsive: true,
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var dataset = data.datasets[tooltipItem.datasetIndex];
var total = dataset.data.reduce(function(previousValue, currentValue, currentIndex, array) {
return previousValue + currentValue;
});
var currentValue = dataset.data[tooltipItem.index];
var precentage = Math.floor(((currentValue / total) * 100) + 0.5);
return precentage + "%";
}
}
},
legendCallback: function(chart) {
var text = [];
text.push('<ul class="' + chart.id + '-legend">');
var data = chart.data;
var datasets = data.datasets;
var labels = data.labels;
if (datasets.length) {
for (var i = 0; i < datasets[0].data.length; ++i) {
text.push('<li><span style="background-color:' + datasets[0].backgroundColor[i] + '"></span>');
if (labels[i]) {
// calculate percentage
var total = datasets[0].data.reduce(function(previousValue, currentValue, currentIndex, array) {
return previousValue + currentValue;
});
var currentValue = datasets[0].data[i];
var precentage = Math.floor(((currentValue / total) * 100) + 0.5);
text.push(labels[i] + ' (' + precentage + '%)');
}
text.push('</li>');
}
}
text.push('</ul>');
return text.join('');
},
legend: {
display: false,
},
elements: {
arc: {
borderWidth: 0
}
},
cutoutPercentage: 70,
title: {
display: true
},
animation: {
animateScale: true,
animateRotate: true
}
}
});
document.getElementById('js-legend').innerHTML = chart.generateLegend();
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="ctx"></canvas>
<div id="js-legend"></div>
Upvotes: 3