25๐
First you should know that if you return an array instead of a single string in the callback
of the tooltip, it will display all the strings in your array as if it were different datasets (see this answer for more details).
So I edited a little bit your callback to the following:
callbacks: {
label: function(tooltipItem, data) {
var corporation = data.datasets[tooltipItem.datasetIndex].label;
var valor = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
// Loop through all datasets to get the actual total of the index
var total = 0;
for (var i = 0; i < data.datasets.length; i++)
total += data.datasets[i].data[tooltipItem.index];
// If it is not the last dataset, you display it as you usually do
if (tooltipItem.datasetIndex != data.datasets.length - 1) {
return corporation + " : $" + valor.toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,');
} else { // .. else, you display the dataset and the total, using an array
return [corporation + " : $" + valor.toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,'), "Total : $" + total];
}
}
}
You can see the full code in this jsFiddle, and here is its result :
25๐
i modified tektiv answer to show Total only for active sets and move it to tooltips footer.
tooltips: {
mode: 'label',
callbacks: {
afterTitle: function() {
window.total = 0;
},
label: function(tooltipItem, data) {
var corporation = data.datasets[tooltipItem.datasetIndex].label;
var valor = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
window.total += valor;
return corporation + ": " + valor.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " ");
},
footer: function() {
return "TOTAL: " + window.total.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " ");
}
}
}
12๐
Shorter version of Gasparโs answer:
tooltips: {
callbacks: {
footer: (tooltipItems, data) => {
let total = tooltipItems.reduce((a, e) => a + parseInt(e.yLabel), 0);
return 'Total: ' + total;
}
}
}
Example: https://jsfiddle.net/g3ba60zc/2/
11๐
In the other answers you replace the last dataset, with this you donโt need to
tooltips: {
callbacks: {
title: function(tooltipItems, data) {
return _this.chart.data.labels[tooltipItems[0].index];
},
footer: function(tooltipItems, data) {
let total = 0;
for (let i = 0; i < tooltipItems.length; i++) {
total += parseInt(tooltipItems[i].yLabel, 10);
}
return 'Total: ' + total;
}
}
}
Ps: Itโs typescript lang.
3๐
@Haider this is what you were looking for, I had the same problem.
I have reused your code and built upon it @tektiv
I have made one small change where instead of building into the label I have made use of the afterbody. This removes the key color
afterBody code:
afterBody: function (tooltipItem, data) {
var corporation = data.datasets[tooltipItem[0].datasetIndex].label;
var valor = data.datasets[tooltipItem[0].datasetIndex].data[tooltipItem[0].index];
var total = 0;
for (var i = 0; i < data.datasets.length; i++)
total += data.datasets[i].data[tooltipItem[0].index];
return "Total : $" + total;
}
Full code here at JSFiddle
2๐
Using Chart.js 2.5.0
var valor = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
returns a string value. To calculate the correct sum value you have to add a parseFloat statement:
tooltips: {
mode: 'label',
callbacks: {
afterTitle: function() {
window.total = 0;
},
label: function(tooltipItem, data) {
var corporation = data.datasets[tooltipItem.datasetIndex].label;
var valor = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
//THIS ONE:
valor=parseFloat(valor);
window.total += valor;
return corporation + ": " + valor.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " ");
},
footer: function() {
return "TOTAL: " + window.total.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " ");
}
}
}
0๐
If you are on older ChartJs version you have to handle this in a different way. Iโm using Chart.js Version 2.7.2 and this is how I handled it:
tooltips: {
mode: 'label',
callbacks: {
footer: function (data) {
var total = 0;
for (var i = 0; i < data.length; i++) {
total += data[i].yLabel;
}
return 'Total: ' + total
}
}
}
0๐
Chart.js made their own, very satisfying solution:
options: {
interaction: {
intersect: false,
mode: 'index',
},
plugins: {
tooltip: {
callbacks: {
footer: footer,
}
}
}
}
and somewhere else in your code:
const footer = (tooltipItems) => {
let sum = 0;
tooltipItems.forEach(function(tooltipItem) {
sum += tooltipItem.parsed.y;
});
return 'Sum: ' + sum;
};
Worked just fine for me!