Chart.js 3.8.0如何实现悬停图例项时显示对应数据提示框
Chart.js 3.8.0 图例悬停触发数据Tooltip实现方案
3.8.0版本重构了图例、Tooltip的内部事件体系,旧版本直接操作图例DOM、调用废弃Tooltip实例方法的方案无法运行,可通过图例事件回调+手动控制Tooltip显隐的方式实现效果,具体如下:
- 核心逻辑
- 借助图例配置项自带的
onHover、onLeave钩子捕获鼠标在图例上的进出事件,拿到当前悬停图例对应的数据集索引 - 调用Chart实例内置的Tooltip API,传入对应数据集的目标点位信息,主动触发Tooltip渲染
- 鼠标移出图例范围时主动清空Tooltip激活状态,避免提示框残留
- 借助图例配置项自带的
- 完整可运行代码示例
// 初始化图表实例 const myChart = new Chart(document.getElementById('chartCtx'), { type: 'line', // 兼容bar、pie、radar等所有内置图表类型 data: { labels: ['Q1', 'Q2', 'Q3', 'Q4'], datasets: [ { label: '线上营收', data: [120, 190, 300, 250], borderColor: 'rgb(75, 192, 192)' }, { label: '线下营收', data: [80, 120, 150, 170], borderColor: 'rgb(255, 99, 132)' } ] }, options: { plugins: { legend: { position: 'top', onHover: (event, legendItem, legend) => { const chartIns = legend.chart; const datasetIdx = legendItem.datasetIndex; // 匹配当前数据集下第一个可见的数据点作为Tooltip触发锚点 const datasetMeta = chartIns.getDatasetMeta(datasetIdx); const firstVisiblePointIdx = datasetMeta.data.findIndex((point, idx) => chartIns.getDataVisibility(idx)); const targetPoint = datasetMeta.data[firstVisiblePointIdx === -1 ? 0 : firstVisiblePointIdx]; // 手动激活Tooltip chartIns.tooltip.setActiveElements( [{ datasetIndex: datasetIdx, index: targetPoint.index }], { x: event.x, y: event.y } ); chartIns.update('none'); // 用none模式更新避免全图表重绘卡顿 }, onLeave: (event, legendItem, legend) => { const chartIns = legend.chart; // 清空激活状态隐藏Tooltip chartIns.tooltip.setActiveElements([], { x: 0, y: 0 }); chartIns.update('none'); } }, tooltip: { // 按需配置Tooltip内容,确保展示标签与对应Y轴数值 callbacks: { label: (context) => `${context.label}: ${context.parsed.y}` } } } } });
- 适配说明
- 如果业务中存在隐藏数据点、分段数据集的场景,可自行调整目标触发点的查找逻辑,只要给
setActiveElements传入合法的数据集索引、数据点索引即可正常触发 - 禁止直接给图例DOM绑定原生mouseover事件,3.x版本图例在图表更新、窗口resize时会重绘,原生事件绑定会直接丢失
- 调用Tooltip API后必须执行图表更新才会生效,使用
update('none')可跳过不必要的动画和重绘逻辑,交互更流畅
- 如果业务中存在隐藏数据点、分段数据集的场景,可自行调整目标触发点的查找逻辑,只要给
内容的提问来源于stack exchange,提问作者VioletSkies
相关产品推荐
相关产品推荐

