You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chart.js中隐藏空标签图例及实现图例堆叠展开功能

解决方案:Chart.js 图例过滤与分组控制

一、隐藏空标签图例

修改图例的过滤函数,只保留标签非空的图例项:
在options.plugins.legend.labels中替换filter函数:

filter: (legendItem, data) => {
  // 过滤掉标签为空的图例
  return data.datasets[legendItem.index].label !== '';
}

二、实现灰色图例分组切换

要实现“点击单个灰色图例控制其他同类型图例显示/隐藏”,需要以下步骤:

  1. 给所有灰色离线数据集添加自定义分组标识,同时设置4个空标签灰色数据集初始隐藏
  2. 自定义图例点击事件,监听目标灰色图例的点击,切换同组其他数据集的显示状态

修改后的完整代码

<div class="canvasHolder">
  <canvas id="stackedChartAgregateMulti" width="400" height="250"></canvas>
</div>
<script>
window.ctx10 = document.getElementById('stackedChartAgregateMulti');
if (window.ctx10Chart) window.ctx10Chart.destroy();
window.ctx10Chart = new Chart(window.ctx10, {
  type: 'bar',
  data: {
    labels: ['January', 'February', '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: 'user 1 offline',
      data: [30, 20, 20, 67, 10, 25, 3],
      backgroundColor: ['rgb(196, 201, 201)'],
      borderColor: ['rgb(196, 201, 201)'],
      stack: 'Stack 0',
      borderWidth: 1,
      // 标记为离线分组的控制图例
      group: 'offline',
      isController: true
    },
    {
      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,
      // 标记为离线分组,初始隐藏
      group: 'offline',
      hidden: true
    },
    {
      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,
      group: 'offline',
      hidden: true
    },
    {
      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,
      group: 'offline',
      hidden: true
    },
    {
      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,
      group: 'offline',
      hidden: true
    }]
  },
  options: {
    plugins: {
      title: {
        display: true,
        text: 'Stacked, aggregated, multi column'
      },
      legend: {
        labels: {
          // 过滤空标签图例
          filter: (legendItem, data) => {
            return data.datasets[legendItem.index].label !== '';
          }
        },
        // 自定义图例点击事件
        onClick: (e, legendItem, legend) => {
          const chart = legend.chart;
          const targetDataset = chart.data.datasets[legendItem.index];
          
          // 判断点击的是离线分组的控制图例
          if (targetDataset.group === 'offline' && targetDataset.isController) {
            // 切换所有离线分组的非控制数据集的显示状态
            chart.data.datasets.forEach(dataset => {
              if (dataset.group === 'offline' && !dataset.isController) {
                dataset.hidden = !dataset.hidden;
              }
            });
            chart.update();
          } else {
            // 其他图例保持默认点击逻辑
            Chart.defaults.plugins.legend.onClick.call(this, e, legendItem, legend);
          }
        }
      }
    },
    responsive: true,
    scales: {
      x: {
        stacked: true
      },
      y: {
        stacked: true
      }
    }
  }
});
</script>

代码说明

  1. 空标签过滤:通过filter函数筛选出标签非空的图例,直接隐藏所有无标签的灰色图例项
  2. 分组标记:给所有灰色离线数据集添加group: 'offline',其中user 1 offline额外标记isController: true作为控制开关,其余4个空标签灰色数据集设置hidden: true初始隐藏
  3. 点击事件控制:点击user 1 offline图例时,遍历所有离线分组数据集,切换非控制数据集的hidden状态,实现批量显示/隐藏;其他图例保持默认的单个切换逻辑

内容的提问来源于stack exchange,提问作者ilya Tan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 18:21:29