admin管理员组

文章数量:1303450

Chart.js 2+ does not return percentages for legend items in pie charts anymore.

I am storing the legend in the separate item in my html named #legend. Then I set it's innerHTML to myPieChart.generateLegend(). It returns both the color and name but I'd like to be able to override this HTML template to also return percentages, so the output goes from looking like:

  • A
  • B
  • C

to:

  • A (13%)
  • B (50%)
  • C (37%)

I used to do it with the legendTemplate argument but it does not seem to work anymore:

legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%> (<%=segments[i].value%>%)<%}%></li><%}%></ul>"

Chart.js 2+ does not return percentages for legend items in pie charts anymore.

I am storing the legend in the separate item in my html named #legend. Then I set it's innerHTML to myPieChart.generateLegend(). It returns both the color and name but I'd like to be able to override this HTML template to also return percentages, so the output goes from looking like:

  • A
  • B
  • C

to:

  • A (13%)
  • B (50%)
  • C (37%)

I used to do it with the legendTemplate argument but it does not seem to work anymore:

legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%> (<%=segments[i].value%>%)<%}%></li><%}%></ul>"
Share Improve this question edited Oct 17, 2016 at 20:20 globetrotter asked Oct 16, 2016 at 3:36 globetrotterglobetrotter 1,0471 gold badge18 silver badges43 bronze badges 2
  • Please provide context and code to your question, so others can benefit from it as well; how are you currently generating your legend text? What have you tried so far? – trashr0x Commented Oct 17, 2016 at 18:50
  • hi, thank you for your response, see my update – globetrotter Commented Oct 17, 2016 at 20:21
Add a ment  | 

1 Answer 1

Reset to default 9

Chart.js v2 has a pletely 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 pleteness, 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.

本文标签: javascriptreturn percentage in chartjs (v2) legendStack Overflow