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

Chart.js使用chartjs-plugin-annotation时hover数据点tooltip不显示问题

问题描述

当用户悬浮在图表数据点上时,仅显示蓝色竖线,未正常弹出tooltip提示。

依赖版本

  • chart.js: ^2.9.3
  • chartjs-plugin-annotation: ^0.5.7

效果说明

  • 实际效果:仅显示蓝色悬浮竖线,无tooltip提示
  • 预期效果:悬浮时同时显示蓝色竖线和对应数据点的tooltip提示

相关代码

图表配置代码

export chart = () => {
  data:{ ... },
  options: {
    tooltips: {
      displayColors: false,
      mode: 'index',
      intersect: true,
      callbacks: {
        label: function (tooltipItem, data) {
          return `${data.datasets[tooltipItem.datasetIndex].label}(${Math.round(tooltipItem.xLabel * 100) / 100},${Math.round(tooltipItem.yLabel * 100) / 100})`;
        },
      },
    },
    legend: {
      display: false,
    },
    annotation: {
      drawTime: "afterDatasetsDraw",
      events: ["mouseover"],
      annotations: [],
    },
  }
}

convertToHoverLine函数代码

export const convertToHoverLine = (value, scaleID) => {
  return {
    key: "hoverLine",
    type: "line",
    mode: "vertical",
    scaleID,
    value,
    borderColor: "blue",
    onMouseout: null,
    onMouseover: null,
  }
}

handleHoverChart函数代码(悬浮触发逻辑)

export const handleHoverChart = (myChart, x, scaleID) => {
  const indexLine = myChart.options.annotation.annotations.findIndex(i => i.key === "hoverLine")
  if (indexLine === -1) {
    myChart.options.annotation.annotations.push(convertToHoverLine(x,scaleID))
  } else {
    myChart.options.annotation.annotations[indexLine] = convertToHoverLine(x,scaleID);
  }
  myChart.update()
}

修复方案

问题由两个配置冲突导致:

  1. 注解插件的events: ["mouseover"]配置会拦截所有mouseover事件,不会向下传递给tooltip组件,导致tooltip收不到触发信号
  2. tooltip的intersect: true要求鼠标必须精确落在数据点像素上才会触发,和index模式搭配时触发成功率极低

按如下方式修改配置即可解决:

  1. 删除annotation配置中的events: ["mouseover"],避免事件被拦截
  2. 将tooltip的intersect属性改为false,只要鼠标落在对应x轴索引的垂直范围内就触发tooltip,不需要完全命中数据点

修改后的核心配置示例:

// annotation配置
annotation: {
  drawTime: "afterDatasetsDraw",
  annotations: [],
}

// tooltip配置
tooltips: {
  displayColors: false,
  mode: 'index',
  intersect: false,
  callbacks: {
    label: function (tooltipItem, data) {
      return `${data.datasets[tooltipItem.datasetIndex].label}(${Math.round(tooltipItem.xLabel * 100) / 100},${Math.round(tooltipItem.yLabel * 100) / 100})`;
    },
  },
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 21:15:07