3π
β
First, this issue not related to versions (2.7 VS 2.9 and so on).
In general, please add a demo.
I guess you want this data [5,5] to display as 50%
50%
and [3,3,3] ad 33% / 33% / 33%.
Your issue related to something with the calculations.
The sum
looks βbuggyβ (console.log the value).
The callback runs more than one time (One time for each label) β and you put inside loop
throw array and declare this array again and again.
let dataArr: number[] = ctx.chart.data.datasets[0].data as number[];
dataArr.map((data) => {
sum += data;
});
This example works fine (Without nested loop):
var pieChart = new Chart(ctx, {
type: 'pie',
data: {
labels: ['January', 'February'],
datasets: [{
label: 'My First dataset',
data: [5, 10],
backgroundColor: ["red", "blue"]
}]
},
options: {
legend: {
position: 'bottom',
display: true,
},
plugins: {
datalabels: {
color: '#fff',
display: true,
formatter: function (value, ctx) {
return ((value * 100) / total(ctx)).toFixed(2) + '%';
},
},
},
},
})
function total(chart){
let data = chart.chart.data.datasets[0].data;
const reducer = (accumulator, currentValue) => accumulator + currentValue;
var total = data.reduce(reducer);
return total;
}
<div id="wrapper">
<canvas id="ctx" width="500" height="450"></canvas>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.8.0"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@0.7.0/dist/chartjs-plugin-datalabels.min.js"></script>
DRY
The code above is also a little repeatable β if you declare the data outside of chart.js object you could calculate the data total
only one time.
var data = [4, 9, 5, 2];
/* get total */
const reducer = (accumulator, currentValue) => accumulator + currentValue;
var total = data.reduce(reducer);
var pieChart = new Chart(ctx, {
type: 'pie',
data: {
labels: ['January', 'February', 'March', 'April'],
datasets: [{
label: 'My First dataset',
data: data,
backgroundColor: ["red", "blue", "green", "violet"]
}]
},
options: {
legend: {
position: 'bottom',
display: true,
},
plugins: {
datalabels: {
color: '#fff',
display: true,
formatter: function (value, ctx) {
return ((value * 100) / total).toFixed(2) + '%';
},
},
},
},
})
<div id="wrapper">
<canvas id="ctx" width="500" height="450"></canvas>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.8.0"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@0.7.0/dist/chartjs-plugin-datalabels.min.js"></script>
More dry/modular? (For changeable data) Put total data inside function and so on.
Source:stackexchange.com