Show/Hide chart by click custom legend

Hello!
Thanks for this very cool library!
My question is how it is possible to repeat functionality for show/hide chart for custom legend? Yes, this functionality working for charts by default. But I have to change default legend to custom and lost show/hide function.

I made a default legend hidden and generate my own like this:

var weightChartOptions = {
    responsive: true,
    legendCallback: function(chart) {
        var legendHtml = []; 
        legendHtml.push('<table>');
        legendHtml.push('<tr>');
        for (var i=0; i<chart.data.datasets.length; i++) {
            legendHtml.push('<td><div class="chart-legend" style="background-color:' + chart.data.datasets[i].backgroundColor +'"></div></       td>');  
            if (chart.data.datasets[i].label) {
                legendHtml.push('<td class="chart-legend-label-text">' + chart.data.datasets[i].label + '</td>');
            }
        }
        legendHtml.push('</tr>');
        legendHtml.push('</table>');
        return legendHtml.join("");
    },
    legend: {
        display: false
    }
};

var ctx = document.getElementById("weightChart").getContext("2d");
var weightChart = new Chart(ctx, {
    type: 'line',
    data: weightChartData,
    options: weightChartOptions
});
document.getElementById("weightChartLegend").innerHTML = weightChart.generateLegend();

How I can keep this custom legend and add show/hide function?
Thanks.

Author: Fantashit

2 thoughts on “Show/Hide chart by click custom legend

  1. Git it! Thank you very much!

    var weightChartOptions = {
            responsive: true,
            legendCallback: function(chart) {
                console.log(chart);
                var legendHtml = [];
                legendHtml.push('<table>');
                legendHtml.push('<tr>');
                for (var i=0; i<chart.data.datasets.length; i++) {
                    legendHtml.push('<td><div class="chart-legend" style="background-color:' + chart.data.datasets[i].backgroundColor + '"></div></td>');                    
                    if (chart.data.datasets[i].label) {
                        legendHtml.push('<td class="chart-legend-label-text" onclick="updateDataset(event, ' + '\'' + chart.legend.legendItems[i].datasetIndex + '\'' + ')">' + chart.data.datasets[i].label + '</td>');
                    }                                                                              
                }                                                                                  
                legendHtml.push('</tr>');                                                          
                legendHtml.push('</table>');                                                       
                return legendHtml.join("");                                                        
            },                                                                                     
            legend: {                                                                              
                display: false                                                                     
            }                                                                                      
        };                                                                                         
    
        // Show/hide chart by click legend
        updateDataset = function(e, datasetIndex) {
            var index = datasetIndex;
            var ci = e.view.weightChart;
            var meta = ci.getDatasetMeta(index);
    
            // See controller.isDatasetVisible comment
            meta.hidden = meta.hidden === null? !ci.data.datasets[index].hidden : null;
    
            // We hid a dataset ... rerender the chart
            ci.update();
        };
    
        var ctx = document.getElementById("weightChart").getContext("2d");
        window.weightChart = new Chart(ctx, {
            type: 'line',
            data: weightChartData, 
            options: weightChartOptions
        });
        document.getElementById("weightChartLegend").innerHTML = weightChart.generateLegend();
    };

    The most important parts are:

    onClick function call for each legend label

    if (chart.data.datasets[i].label) {
        legendHtml.push('<td class="chart-legend-label-text" onclick="updateDataset(event, ' + '\'' + chart.legend.legendItems[i].datasetIndex + '\'' + ')">' + chart.data.datasets[i].label + '</td>');
    }

    and function

    updateDataset = function(e, datasetIndex) {
        var index = datasetIndex;
        var ci = e.view.weightChart;
        var meta = ci.getDatasetMeta(index);
    
        // See controller.isDatasetVisible comment
        meta.hidden = meta.hidden === null? !ci.data.datasets[index].hidden : null;
    
        // We hid a dataset ... rerender the chart
        ci.update();
    };

    Also make chart instance of Window adding window. before:

    window.weightChart = new Chart(ctx, {
            type: 'line',
            data: weightChartData, 
            options: weightChartOptions
    });
  2. I’m actually facing a similar issue. I”ve make a custom legend component and I’m able to show/hide using the above codes. However, this only works for bar chart. It raise the following exception when using it with donut chart:

    TypeError: Cannot read property '_meta' of undefined at Chart.getDatasetMeta (core.controller.js:656)

    Have anyone faced a similar issue please?

Comments are closed.