custom legend hide() does not remove data labels

357 Views Asked by At

I am building a project using React with a doughnut and bar chart. Working with Chart.js 3.xx.

I am trying to make my custom legend functional. I want to make data fractions disappear when the user clicks my legend items - like in the native legend, and optimally also remove the data and make the chart present it's updated data after removal.

I also use data labels to present percentage of the data on the fractions.

import ChartDataLabels from 'chartjs-plugin-datalabels';

I came across this topic: ChartJS - Show/hide data individually instead of entire dataset on bar/line charts and used this suggested code there:

function chartOnClick(evt) {
    let chart = evt.chart
    const points = chart.getElementsAtEventForMode(evt, 'nearest', {}, true);
    
    if (points.length) {
        const firstPoint = points[0];
        //var label = myChart.data.labels[firstPoint.index];
        //var value = myChart.data.datasets[firstPoint.datasetIndex].data[firstPoint.index];
        let datasetIndex = firstPoint.datasetIndex, index = firstPoint.index;
        
        if (firstPoint.element.hidden != true) {
            chart.hide(datasetIndex, index);
        } else {
            chart.show(datasetIndex, index);
        }
    }
}

options: { // chart options
    onClick: chartOnClick
}

It almost works, but the hide() method doesn't remove the fraction's percentage data label when activated, whereas when clicking the native legend it does remove it entirely.

chart

I tried looking in the plugin's docs but didn't manage to find how to remove a single label.

How can I achieve what I am looking for?

EDIT: Options Object:

export const doughnutOptsObj = {
  onClick: chartOnClick,
  responsive: true,
  maintainAspectRatio: false,
  layout: { padding: { top: 16, bottom: 16 } },
  hoverOffset: 32,
  plugins: {
    legend: {
      display: true,
      position: 'bottom',
    },
    datalabels: {
      formatter: (value, dnct1) => {
        let sum = 0;
        let dataArr = dnct1.chart.data.datasets[0].data;
        dataArr.map((data) => {
          sum += Number(data);
        });

        let percentage = ((value * 100) / sum).toFixed() + '%';
        return percentage;
      },
      color: ['#fbfcfd'],
      font: { weight: 'bold' },
      // display: false, <-- this works and makes all of the data labels disappear
    },
  },
};
1

There are 1 best solutions below

2
user2057925 On BEST ANSWER

It seems that the onClick function is working properly.

I have tried the attached code, leveraging on toggleDataVisibility API, and it's working as requested (codepen: https://codepen.io/stockinail/pen/abKNJqJ):

function chartOnClick(evt) {
    let chart = evt.chart
    const points = chart.getElementsAtEventForMode(evt, 'nearest', {}, true);
    
    if (points.length) {
       const firstPoint = points[0];
        chart.toggleDataVisibility(firstPoint.index);
        chart.update();
    }
}