[Chartjs]-Return percentage in chart.js (v2+) legend

9👍

Chart.js v2 has a completely different API than earlier versions. You should read the new documentation carefully before upgrading (and then having to wonder what wen’t wrong).

The fundamental changes (related to your question) are:

  • legendTemplate and segments are not available anymore. You should instead use legendCallback (in options) to override the default legend implementation. Here’s what the documentation says about this callback:

Function to generate a legend. Receives the chart object to generate a legend from. Default implementation returns an HTML string.

  • The data you used from segments are available in the chart parameter (i.e. your actual chart object) of your legendCallback function here: chart.data.datasets[0].data.
  • Now that we know where to get our required data from, we can loop through chart.data.datasets[0].data to collect the values and append them to the legend HTML string.
  • Then we can simply call myPieChart.generateLegend(), which will invoke our legendCallback.

Complete example:

var myPieChart = new Chart(ctx, {
    type: 'pie',
    data: d,
    options: {
        responsive: true,
        maintainAspectRatio: false,
        tooltips: {
            callbacks: {
                label: function (tooltipItem, data) {
                    return data.labels[tooltipItem.index] + ' (' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index] + '%)';
                }
            }
        },
        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: {
            // since you're providing your own legend
            display: false,
        },                
    }
});

var legend = myPieChart.generateLegend();
document.getElementById("legend").innerHTML = legend;

For purposes of completeness, I’ve also added the same TEXT (PERCENTAGE%) template on the tooltips labels (which similarly to legends, provide their own callbacks for overriding default implementations).

I would also suggest browsing through the actual Chart.js source code, in particular having a look at legendCallBack, generateLegend(), etc, to gain a better understanding of how things work under the hood.

Leave a comment