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

如何在Chart.js中实现类别标签悬停时的光标与颜色变化?

问题描述

我用最新版本的Chart.js制作了一个条形图,希望在鼠标悬停于类别标签(如示例中的Item A、Item B、Item C)时实现以下一项或两项视觉效果:

  • 悬停标签时将光标设置为指针样式;
  • 悬停时改变标签的颜色。

示例代码如下:

<script src="https://cdn.jsdelivr.net/npm/chart.js@4.2.0"></script>

<div class="chart-container">
  <canvas id="myChart"></canvas>
</div>
.chart-container {
  position: relative;
  height: 90vh;
}
window.onload = function() {
  var ctx = document.getElementById('myChart').getContext('2d');
  window.myBar = new Chart(ctx, {
    type: 'bar',
    data: {
      labels: ['Item A', 'Item B', 'Item C'],
      datasets: [{
        data: [1, 2, 3],
        backgroundColor: 'lightblue'
      }]
    },
    options: {
      responsive: true,
      indexAxis: 'y',
      plugins: {
        legend: {
          display: false
        },
        tooltip: {
          enabled: false
        },
      }
    }
  });
};

实现方案

Chart.js没有直接提供轴标签的悬停事件API,我们可以通过监听Canvas的鼠标事件,结合Chart.js的getElementsAtEventForMode方法检测鼠标是否悬停在标签上,进而实现需求效果。

完整实现代码

<script src="https://cdn.jsdelivr.net/npm/chart.js@4.2.0"></script>

<div class="chart-container">
  <canvas id="myChart"></canvas>
</div>
.chart-container {
  position: relative;
  height: 90vh;
}
window.onload = function() {
  const ctx = document.getElementById('myChart').getContext('2d');
  let hoveredLabelIndex = -1; // 记录当前悬停的标签索引

  window.myBar = new Chart(ctx, {
    type: 'bar',
    data: {
      labels: ['Item A', 'Item B', 'Item C'],
      datasets: [{
        data: [1, 2, 3],
        backgroundColor: 'lightblue'
      }]
    },
    options: {
      responsive: true,
      indexAxis: 'y',
      plugins: {
        legend: {
          display: false
        },
        tooltip: {
          enabled: false
        },
      },
      scales: {
        y: {
          ticks: {
            // 根据悬停状态动态设置标签颜色
            color: function(context) {
              return context.dataIndex === hoveredLabelIndex ? '#ff0000' : '#333';
            }
          }
        }
      }
    }
  });

  // 监听鼠标移动事件
  ctx.canvas.addEventListener('mousemove', function(e) {
    const rect = ctx.canvas.getBoundingClientRect();
    const mouseX = e.clientX - rect.left;
    const mouseY = e.clientY - rect.top;

    // 获取鼠标位置对应的轴元素
    const elements = window.myBar.getElementsAtEventForMode(mouseX, mouseY, 'index', { intersect: false });
    
    if (elements.length > 0) {
      const labelIndex = elements[0].index;
      if (hoveredLabelIndex !== labelIndex) {
        hoveredLabelIndex = labelIndex;
        ctx.canvas.style.cursor = 'pointer';
        window.myBar.update(); // 更新图表以改变标签颜色
      }
    } else {
      if (hoveredLabelIndex !== -1) {
        hoveredLabelIndex = -1;
        ctx.canvas.style.cursor = 'default';
        window.myBar.update();
      }
    }
  });

  // 监听鼠标离开事件,恢复默认状态
  ctx.canvas.addEventListener('mouseleave', function() {
    hoveredLabelIndex = -1;
    ctx.canvas.style.cursor = 'default';
    window.myBar.update();
  });
};

代码说明

  1. 光标样式切换:通过监听Canvas的mousemove和mouseleave事件,检测到鼠标悬停在标签上时,将Canvas的cursor设置为pointer,离开时恢复为default。
  2. 标签颜色变化:用hoveredLabelIndex变量记录当前悬停的标签索引,在Y轴的ticks.color配置中,根据该索引动态返回不同颜色,状态变化时调用chart.update()重新渲染图表。
  3. 标签检测逻辑:使用getElementsAtEventForMode方法,传入鼠标坐标和index模式,获取对应的标签元素,判断是否处于标签悬停区域。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 22:00:58