1. 前言
ECharts 柱状图的点击事件默认仅响应柱子本身的点击,本文旨在实现整个背景区域均可触发点击事件
2. 实现思路
- 核心:全局监听 + 坐标判断 + 数据转换
- 通过 getZr() 监听整个画布点击,结合像素坐标判断是否在图表区域内
- 通过 containPixel() 判断点击位置是否在坐标系内
- 通过 convertFromPixel() 方法将点击的像素坐标转换为对应的数据索引,从而关联到对应柱子
3. 源码
// 初始化图表
const myChart = echarts.init(document.getElementById('chart'));
myChart.setOption({
xAxis: { type: 'category', data: ['A', 'B', 'C'] },
yAxis: { type: 'value' },
series: [{ type: 'bar', data: [10, 20, 30] }]
});
// 监听全局画布点击事件
myChart.getZr().on('click', (params) => {
const point = [params.offsetX, params.offsetY]; // 获取点击坐标
// 判断点击位置是否在坐标系内
if (myChart.containPixel('grid', point)) {
// 将像素坐标转换为数据索引
const xIndex = myChart.convertFromPixel({ seriesIndex: 0 }, point);
// 触发自定义逻辑(模拟柱子点击)
handleBarClick(xIndex);
}
});
// 自定义点击处理函数
function handleBarClick(index) {
console.log('点击背景对应的柱子索引:', index);
// 模拟高亮柱子(可选)
myChart.dispatchAction({
type: 'highlight',
seriesIndex: 0,
dataIndex: index
});
}
4. 优化
- 悬停鼠标改为手形,提示用户可点击
- 事件回调可加上防抖
myChart.getZr().on("mousemove", () => {
myChart.getZr().setCursorStyle("pointer"); // 鼠标悬停时显示手型
});
- 添加边界处理,避免无效点击
if (xIndex >= 0 && xIndex < myChart.getOption().series.data.length) {
handleBarClick(xIndex);
}
5. 多说一句
- 官方文档并未提及getZr 这个 API?
getZr() 属于底层 ZRender 引擎的集成方法,需结合 ZRender 文档理解
getZr() 返回的是 ECharts 底层使用的 ZRender 实例(一个轻量级 Canvas 库),属于内部实现细节。官方通常不推荐直接操作 ZRender,因为这可能破坏 ECharts 的封装性。