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

Chart.js柱状图鼠标移入移出事件如何实现?

当然可行!Chart.js其实提供了直接监听柱子鼠标悬停/离开事件的机制,完全不用依赖tooltip回调这种间接方式——之前的问题在于tooltip回调没法追踪鼠标离开的时机,咱们换个思路就能解决。

核心实现思路

通过监听图表画布的mousemove和mouseleave事件,结合Chart.js自带的元素定位方法,精准判断鼠标是否落在柱子上,同时维护一个变量跟踪当前悬停的柱子,确保mousein和mouseout事件只在状态变化时触发。

具体代码示例

// 获取画布上下文,初始化图表
const ctx = document.getElementById('myBarChart').getContext('2d');
// 用来记录当前悬停的柱子,避免重复触发事件
let currentHoveredBar = null;

const barChart = new Chart(ctx, {
  type: 'bar',
  data: {
    labels: ['Q1', 'Q2', 'Q3', 'Q4'],
    datasets: [{
      label: '季度销售额',
      data: [12000, 19000, 15000, 22000],
      backgroundColor: 'rgba(54, 162, 235, 0.6)',
      borderColor: 'rgba(54, 162, 235, 1)',
      borderWidth: 1
    }]
  },
  options: {
    // 明确开启需要监听的事件(默认已包含,但写出来更清晰)
    events: ['mousemove', 'mouseleave', 'click'],
    scales: {
      y: { beginAtZero: true }
    }
  }
});

// 监听鼠标移动事件
barChart.canvas.addEventListener('mousemove', (e) => {
  // 获取鼠标位置对应的柱子元素
  const activeBars = barChart.getElementsAtEventForMode(
    e, 
    'nearest', 
    { intersect: true }, 
    true
  );

  if (activeBars.length > 0) {
    const targetBar = activeBars[0];
    // 如果当前悬停的柱子和之前的不同,触发mousein和mouseout
    if (currentHoveredBar !== targetBar) {
      // 先处理之前悬停柱子的离开逻辑
      if (currentHoveredBar) {
        console.log(`离开柱子:${currentHoveredBar.index}`);
        // 这里恢复你的布尔值,比如:isBarHovered = false;
      }
      currentHoveredBar = targetBar;
      console.log(`进入柱子:${targetBar.index}`);
      // 执行悬停逻辑,比如:isBarHovered = true;
    }
  } else {
    // 鼠标不在任何柱子上,且之前有悬停记录,触发离开逻辑
    if (currentHoveredBar) {
      console.log(`离开柱子:${currentHoveredBar.index}`);
      // 恢复布尔值
      // isBarHovered = false;
      currentHoveredBar = null;
    }
  }
});

// 监听鼠标离开整个图表的事件,防止遗漏离开逻辑
barChart.canvas.addEventListener('mouseleave', () => {
  if (currentHoveredBar) {
    console.log(`离开柱子(鼠标移出图表):${currentHoveredBar.index}`);
    // 恢复布尔值
    // isBarHovered = false;
    currentHoveredBar = null;
  }
});

关键细节说明

  1. getElementsAtEventForMode方法:这个方法能精准定位鼠标所在的图表元素,nearest模式配合intersect: true确保只选中鼠标实际覆盖的柱子。
  2. 状态跟踪变量:currentHoveredBar用来记录当前悬停的柱子,避免鼠标在同一柱子上移动时重复触发事件。
  3. mouseleave兜底:单独监听画布的mouseleave事件,防止鼠标直接移出整个图表而没触发柱子的离开逻辑,保证布尔值能被正确恢复。

如果是多数据集的柱状图,还可以通过targetBar.datasetIndex区分不同数据集的柱子,灵活调整逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:11:43