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

如何使ChartJS堆叠柱状图始终显示分组Tooltip(label/index模式)

How to Keep Grouped Tooltips Permanently Visible on a Stacked Bar Chart in Chart.js

我明白你的需求——你想让堆叠柱状图的分组Tooltip(就是鼠标悬停时显示同组所有堆叠条信息的那种)一直固定在图表上,而不是只在hover时出现,同时避免每个堆叠条单独弹出Tooltip的问题。

你的核心问题出在原来的插件逻辑里:你是逐个遍历每个数据集的每个数据点,单独创建Tooltip实例,所以每个堆叠条都会弹出自己的Tooltip。要实现分组Tooltip永久显示,我们需要按X轴的索引来分组,把同一组的所有堆叠条数据点作为一个整体传入Tooltip,这样就能生成包含整组信息的Tooltip了。

修改后的插件代码

Chart.pluginService.register({
    beforeRender: function(chart) {
        // 强制设置tooltip模式为index,确保分组显示逻辑生效
        chart.options.tooltips.mode = 'index';
        const groupCount = chart.data.datasets[0].data.length;
        chart.pluginTooltips = [];

        // 按X轴分组循环,每个分组对应一组堆叠条
        for (let groupIndex = 0; groupIndex < groupCount; groupIndex++) {
            const activeGroupElements = [];
            // 收集当前分组下所有有有效数据的堆叠条元素
            chart.data.datasets.forEach((dataset, datasetIdx) => {
                const dataValue = Number(dataset.data[groupIndex]);
                if (dataValue > 0) {
                    activeGroupElements.push(chart.getDatasetMeta(datasetIdx).data[groupIndex]);
                }
            });

            // 只有当分组有有效数据时,才创建分组Tooltip
            if (activeGroupElements.length > 0) {
                chart.pluginTooltips.push(new Chart.Tooltip({
                    _chart: chart.chart,
                    _chartInstance: chart,
                    _data: chart.data,
                    _options: chart.options.tooltips,
                    _active: activeGroupElements
                }, chart));
            }
        }
    },
    afterDatasetsDraw: function(chart, easing) {
        // 渲染所有分组Tooltip
        Chart.helpers.each(chart.pluginTooltips, function(tooltip) {
            tooltip.initialize();
            tooltip.update();
            tooltip.pivot();
            tooltip.transition(easing).draw();
        });
    }
});

关键改动说明

  1. 循环逻辑调整:不再遍历每个数据集的单个数据点,而是按X轴分组索引循环,确保同一组的所有堆叠条被归为一类。
  2. 收集分组元素:对每个分组,收集所有数据集中对应位置且数值>0的元素,将它们作为_active数组传入Tooltip实例,触发分组信息的渲染。
  3. 强制Tooltip模式:在beforeRender阶段明确设置mode: 'index',保证Tooltip会按组展示所有相关数据,和鼠标悬停时的效果一致。

配套的图表配置示例

const stackedBarChart = new Chart(document.getElementById('yourChartContainer'), {
    type: 'bar',
    data: {
        labels: ['Group A', 'Group B', 'Group C'],
        datasets: [
            { label: 'Series 1', data: [25, 40, 15], backgroundColor: 'rgba(255, 99, 132, 0.6)' },
            { label: 'Series 2', data: [30, 15, 20], backgroundColor: 'rgba(54, 162, 235, 0.6)' },
            { label: 'Series 3', data: [10, 25, 35], backgroundColor: 'rgba(255, 206, 86, 0.6)' }
        ]
    },
    options: {
        responsive: true,
        scales: {
            y: { stacked: true },
            x: { stacked: true }
        },
        tooltips: {
            mode: 'index',
            intersect: false,
            // 可自定义Tooltip样式,比如背景色、字体大小等
            backgroundColor: 'rgba(0, 0, 0, 0.8)',
            titleFontSize: 14,
            bodyFontSize: 12
        }
    }
});

额外注意事项

  • 如果某个分组的所有数据都是0,代码会跳过该分组的Tooltip创建,避免空Tooltip出现。
  • 可以通过tooltips配置里的position、caretSize等属性,调整Tooltip的显示位置和外观,适配你的图表布局。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:14:54