如何在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(); }); };
代码说明
- 光标样式切换:通过监听Canvas的
mousemove和mouseleave事件,检测到鼠标悬停在标签上时,将Canvas的cursor设置为pointer,离开时恢复为default。 - 标签颜色变化:用
hoveredLabelIndex变量记录当前悬停的标签索引,在Y轴的ticks.color配置中,根据该索引动态返回不同颜色,状态变化时调用chart.update()重新渲染图表。 - 标签检测逻辑:使用
getElementsAtEventForMode方法,传入鼠标坐标和index模式,获取对应的标签元素,判断是否处于标签悬停区域。
内容的提问来源于stack exchange,提问作者Software Dev
相关产品推荐
相关产品推荐

