2

React Chartjs-2 : How can I implement the functionality where when a legend is clicked, instead of hiding the clicked legend, all other legends/datasets get hidden?

Hardik Aswal
  • 227
  • 3
  • 15

1 Answers1

1

By modifying the legend onClick function:

Options:

options: {
    plugins: {
        legend: {
            onClick: newLegendClickHandler
        }
    }
}

OnClick:

var newLegendClickHandler = function (e, legendItem, legend) {    
    let datasetIndex = legendItem.datasetIndex;
    let ci = legend.chart, metaSets = [];
    
    for (let i = 0; i < legend.chart.data.datasets.length; i++) {
        metaSets.push(ci.getDatasetMeta(i));
    }
    
    metaSets.forEach(function(meta) {
        meta.hidden = meta.index === datasetIndex ? false : true;
    });
    ci.update();
    
};

For more on this topic: Legend

A fiddle to see this in effect: JSFiddle

Edit:

Chartjs 2 does it almost the same way.

Options:

options: {
    legend: {
        onClick: newLegendClickHandler
    }
}

OnClick:

var newLegendClickHandler = function (e, legendItem) {    
    let datasetIndex = legendItem.datasetIndex;
    let ci = this.chart, metaSets = [];
    
    for (let i = 0; i < ci.data.datasets.length; i++) {
        metaSets.push(ci.getDatasetMeta(i));
    }
    
    metaSets.forEach(function(meta) {
        meta.hidden = meta.index === datasetIndex ? false : true;
    });
    ci.update();
};

Another Fiddle: 2.9.4 Fiddle

Edit 2:

If you are using chartjs 2.6.0 you need to change meta.index to meta.controller.index

Jesper
  • 1,007
  • 7
  • 24
  • I tried this but for some reason legend is undefined in my case. Could this be due to the chart js version?? – Hardik Aswal Aug 09 '21 at 09:21
  • 1
    @HardikAswal Ah, my bad. Chartjs 2.6.0 seems to support custom legend functions aswell: [2.6.0 Documentation](https://www.chartjs.org/docs/2.6.0/configuration/legend.html#custom-on-click-actions) – Jesper Aug 09 '21 at 09:24
  • @HardikAswal i've made edits for chartjs 2 – Jesper Aug 09 '21 at 09:46
  • This does not work for pie/doughnut charts, migt want to add that, can check this sample on how to differentiate and do it correctly for pie/doughnut charts: https://www.chartjs.org/docs/master/samples/legend/html.html – LeeLenalee Aug 09 '21 at 09:47
  • @Jesper I just can't get this working for some reason. Tried both the examples. The one in which you have used this.chart, typescript throws an error: Property 'chart' does not exist on type '{ display: boolean; position: string; labels: { boxWidth: number; padding: number; fontColor: string; }; onClick: (e: any, legendItem: any) => void; }' & when I used legend in the parameter, it is undefined. – Hardik Aswal Aug 09 '21 at 10:15
  • @LeeLenalee Thanks for your answer but my use case is only line & bar charts for now. – Hardik Aswal Aug 09 '21 at 10:16
  • @HardikAswal are you using my edited answer? because i dropped the legend parameter for chartjs 2 because it is undefined – Jesper Aug 09 '21 at 10:42
  • @Jesper Yes I am using the updated answer. I have found the problem though. Your answer would work fine if the chart is created as an object for. eg. var ch = new Chart(ctx, ......) but since I have imported barchart from react-chartjs-2 there is some problem – Hardik Aswal Aug 09 '21 at 10:46
  • 1
    @HardikAswal i made another edit. I didn't think 2.9.4 and 2.6.0 would be different enough that this wouldn't work. I was wrong – Jesper Aug 09 '21 at 10:52
  • @Jesper Finally got it working. Thanks for all the responses. One more thing though, the current implementation does switch off the other datasets on click of a legend but doesn't switch them back on when clicking the same legend. So if any legend is clicked even once, there would always be some legend that is in switched off mode. – Hardik Aswal Aug 09 '21 at 11:01
  • @HardikAswal as for your this.chart problem, would i work if you created the chart like this: `window.myChart = new Chart(ctx, {` and then instead of `this.chart` you would use `window.myChart` – Jesper Aug 09 '21 at 11:01
  • @HardikAswal thats great! in the chartjs example i provided it toggles them on and off. When i modified the example, i removed that feature, because it toggled the wrong ones on and off, also i didn't know if you even needed it. Should be a simple fix though. – Jesper Aug 09 '21 at 11:05