Chartjs-Hide legend for "empty" labels in Chartjs

0👍

You could leverage on onClick option on legend, hiding the datasets of the same stack and change a bit the filter callback returning if the datasets with empty labels are visibile.

const legendClickHandler = Chart.defaults.plugins.legend.onClick;
const ctx = document.getElementById("myChart");
const myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        labels: ['January', 'Fabruary', 'March', 'April', 'May', 'June', 'July'],
        datasets: [{
            label: 'user 1 online',
            data: [50, 35, 45, 47, 0, 3, 27],
            backgroundColor: [
                'rgba(40, 139, 170, 1)'
            ],
            borderColor: [
                'rgb(40, 139, 170)'
            ],
            stack: 'Stack 0',
            borderWidth: 1
        },
        {
            label: '',
            data: [30, 20, 20, 67, 10, 25, 3],
            backgroundColor: [
                'rgb(196, 201, 201)'
            ],
            borderColor: [
                'rgb(196, 201, 201)'
            ],
            stack: 'Stack 0',
            borderWidth: 1
        },
        {
            label: 'user 2 online',
            data: [50, 35, 45, 47, 0, 3, 27],
            backgroundColor: [
                'rgba(107, 112, 176, 1)'
            ],
            borderColor: [
                'rgb(107, 112, 176)'
            ],
            stack: 'Stack 1',
            borderWidth: 1
        },
        {
            label: '',
            data: [30, 20, 20, 67, 10, 25, 3],
            backgroundColor: [
                'rgb(196, 201, 201)'
            ],
            borderColor: [
                'rgb(196, 201, 201)'
            ],
            stack: 'Stack 1',
            borderWidth: 1
        },
        {
            label: 'user 3 online',
            data: [50, 35, 45, 47, 0, 3, 27],
            backgroundColor: [
                'rgba(208, 98, 155, 1)'
            ],
            borderColor: [
                'rgb(208, 98, 155)'
            ],
            stack: 'Stack 2',
            borderWidth: 1
        },
        {
            label: '',
            data: [30, 20, 20, 67, 10, 25, 3],
            backgroundColor: [
                'rgb(196, 201, 201)'
            ],
            borderColor: [
                'rgb(196, 201, 201)'
            ],
            stack: 'Stack 2',
            borderWidth: 1
        },
        {
            label: 'user 4 online',
            data: [50, 35, 45, 47, 0, 3, 27],
            backgroundColor: [
                'rgba(144, 71, 158, 1)'
            ],
            borderColor: [
                'rgb(144, 71, 158)'
            ],
            stack: 'Stack 3',
            borderWidth: 1
        },
        {
            label: '',
            data: [30, 20, 20, 67, 10, 25, 3],
            backgroundColor: [
                'rgb(196, 201, 201)'
            ],
            borderColor: [
                'rgb(196, 201, 201)'
            ],
            stack: 'Stack 3',
            borderWidth: 1
        },
        {
            label: 'user 5 online',
            data: [0, 35, 45, 47, 0, 3, 27],
            backgroundColor: [
                'rgba(40, 139, 170, 1)'
            ],
            borderColor: [
                'rgb(40, 139, 170)'
            ],
            stack: 'Stack 4',
            borderWidth: 1
        },
        {
            label: '',
            data: [30, 20, 20, 67, 10, 25, 3],
            backgroundColor: [
                'rgb(196, 201, 201)'
            ],
            borderColor: [
                'rgb(196, 201, 201)'
            ],
            stack: 'Stack 4',
            borderWidth: 1
        }]
    },
    options: {
        plugins: {
            drawTime: 'afterDraw',
            title: {
                display: true,
                text: 'Stacked, agregated, multi column'
            },
            legend: {
                labels: {
                  filter(item, data, chart){
                    const lbl = data.datasets[item.datasetIndex].label;
                    if (lbl === '') {
                       const chart = this._context.chart;
                       return chart.isDatasetVisible(item.datasetIndex);
                    }
                    return true;
                  }
                },
                onClick(e, item, legend) {
                   if (item.text !== '') {
                      const ci = legend.chart;
                      const stack = ci.data.datasets[item.datasetIndex].stack;
                      const dsStack = ci.data.datasets.filter((el) => el.stack === stack);
                      if (dsStack.length) {
                        dsStack.forEach(function(dsitem) {
                          const index = ci.data.datasets.indexOf(dsitem);
                          ci.setDatasetVisibility(index, !ci.isDatasetVisible(index)); 
                        });
                        ci.update();
                        return;
                      }
                      legendClickHandler(e, item, legend);
                   }
               }
            }
        },
        responsive: true,
        scales: {
            x: {
                stacked: true
            },
            y: {
                stacked: true
            }
        },
        
    }
});
.myChartDiv {
  max-width: 600px;
  max-height: 400px;
}
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.9.1/dist/chart.min.js"></script>
<html>
  <body>
    <div class="myChartDiv">
      <canvas id="myChart" width="600" height="400"/>
    </div>
  </body>
</html>

Leave a comment