如何实现Apache ECharts仪表盘彩色轴线的可点击与悬停交互?
解决Apache ECharts仪表盘轴线区段的点击与悬停交互问题
首先明确:ECharts仪表盘(gauge)组件的axisLine.lineStyle并不支持直接给彩色区段绑定onclick或悬停事件,你之前的写法自然不会生效。要实现这个需求,得通过全局事件监听+坐标角度计算来判断用户点击/悬停的是哪个轴线区段。
核心思路
仪表盘的轴线默认是从 -120° 到 120° 的扇形(总跨度240°),对应配置里color数组的比例区间(0到1)。我们可以把点击/悬停的坐标转换成相对于仪表盘中心的角度,再映射到比例区间,从而判断用户操作的是哪个彩色区段。
完整实现代码
option = { tooltip: { formatter: '{a} <br/>{b} : {c}%' }, series: [ { name: 'Pressure', type: 'gauge', axisLine: { lineStyle: { opacity: 0.5, color: [ [0, '#00f'], [0.25, '#0ff'], [0.5, '#0f0'], [0.75, '#ff0'], [1, '#f00'] ] } }, detail: { valueAnimation: true, formatter: '{value}' }, data: [ { value: 50, name: 'SCORE' } ] } ] }; // 获取仪表盘实例 const myChart = echarts.init(document.getElementById('main')); myChart.setOption(option); // 定义轴线区段的比例区间和对应信息 const axisSections = [ { start: 0, end: 0.25, color: '#00f', label: '0-25%' }, { start: 0.25, end: 0.5, color: '#0ff', label: '25-50%' }, { start: 0.5, end: 0.75, color: '#0f0', label: '50-75%' }, { start: 0.75, end: 1, color: '#f00', label: '75-100%' } ]; // 计算点击/悬停点对应的轴线区段 function getSectionByPoint(point) { const { center } = myChart.getModel().getSeries()[0].coordinateSystem; // 计算点击点相对于中心的角度(弧度转角度) const angle = Math.atan2(point.y - center[1], point.x - center[0]) * 180 / Math.PI; // 转换为仪表盘的比例:默认范围是-120°到120°,对应0-1 let ratio = (angle + 120) / 240; // 过滤仪表盘外部的点击 if (ratio < 0 || ratio > 1) return null; // 匹配对应的区段 return axisSections.find(section => ratio >= section.start && ratio < section.end); } // 点击事件处理 myChart.on('click', (event) => { const section = getSectionByPoint(event); if (section) { console.log(`点击了区段:${section.label},颜色:${section.color}`); // 这里可以添加自定义逻辑,比如弹窗、数据交互等 } }); // 悬停事件处理:实现区段高亮 myChart.on('mouseover', (event) => { const section = getSectionByPoint(event); if (section) { // 复制原轴线样式,修改当前区段的透明度实现高亮 const newAxisLineStyle = JSON.parse(JSON.stringify(option.series[0].axisLine.lineStyle)); // 找到对应区段的索引,将颜色转为全透明度 const sectionIndex = axisSections.findIndex(item => item === section); const rgb = section.color.slice(1).match(/.{2}/g).map(val => parseInt(val, 16)); newAxisLineStyle.color[sectionIndex][1] = `rgba(${rgb[0]}, ${rgb[1]}, ${rgb[2]}, 1)`; // 更新配置 myChart.setOption({ series: [{ axisLine: { lineStyle: newAxisLineStyle } }] }); } }); // 鼠标移出时恢复原样式 myChart.on('mouseout', () => { myChart.setOption({ series: [{ axisLine: { lineStyle: option.series[0].axisLine.lineStyle } }] }); });
关键说明
- 角度转比例:通过
Math.atan2计算点击点相对于仪表盘中心的角度,再转换为0-1的比例,对应axisLine.color的区间。 - 区段匹配:提前定义好每个区段的比例范围、颜色和标签,方便快速匹配用户操作的区域。
- 悬停高亮:通过修改对应区段颜色的透明度实现高亮效果,鼠标移出时恢复原配置。
内容的提问来源于stack exchange,提问作者Prakash Khadka
相关产品推荐
相关产品推荐

