在前端开发过程中,柱状图举例应用突出:例如点击柱形区域时,完成相关操作或跳转至指定界面。尽管Echarts提供了丰富的事件监听机制,但在实现过程中,不同场景对点击调用的需求不完全相同。
本文将详细介绍如何实现柱状图点击事件,并提供实现整条柱形区域点击的方法。
一、需求
领导:这个图表上的点击事件不好操作,特别是在柱状图上点击时,我无法点中!
我:改!像这样在空白处有图例显示时就能点中可以吧?
领导:棒!你小子,前途无量!就这么改
具体实现请移步至【实现二】
实现一、简单点击事件
如果只需要实现点击柱状图中有数据的部分,可以通过 myChart.on
监听事件:
myChart.on('click', function (params) {
console.log(params);
});
这个方法将返回所点击柱状区域对应的数据,例如点击一条柱形,params
属性中将包含其对应的值(value
)和名称(name
)。
如果需要将柱形值上添加更多属性,可以在 series
的数据实例中使用对象进行定义:
seriesData: [
{ value: 1, id: 'ID_1' },
{ value: 2, id: 'ID_2' },
// ...
]
将以上数据添加到Echarts柱状图后,在点击事件中,params
属性中同样可获取到自定义的数据,如下手动打印ID:
myChart.on('click', function (params) {
console.log(params.data.id); // 输出点击柱状区域对应的ID
});
然而,该方法存在一个问题:点击仅限于有值的柱状部分,而对于柱状空白区域,点击无效。
实现二、实现整条柱形区域点击
前置讲解
1. ZRender
在 ECharts 中,点击空白区域(即未绑定数据的区域)默认并不会触发 click 事件,但是 ECharts 使用 ZRender
作为其渲染引擎,提供了对整个画布进行事件监听的能力。你可以通过监听底层的渲染引擎(ZRender
)的 click
事件来捕获整个画布上的点击事件,包括空白区域。
也就是说,可以通过 myChart.getZr()
返回 ZRender
实例,然后监听它上面的 click
事件,通过这种方式,就可以捕获到整个图表区域内的所有点击事件,无论是否在数据或图形上点击。
myChart.getZr().on('click', params => {
console.log(params)
}
myChart.getZr()
打印一下里面的参数:
这里面有用的参数就是 offsetX
和 offsetY
,这两个是当前鼠标位置相对整个Echart 边框的水平和垂直方向上的偏移量。
根据这两个参数,我们就可以确定了鼠标当前的位置,然后在鼠标所有位置的垂直线上,肯定相交了一条数据,这条数据的 x 轴就可以拿到了,然后通过这个 x 轴的关系找到折线上的真实数据
2. containPixel
这里用到一个 api:containPixel
在官方文档上有说明:判断给定的点是否在指定的坐标系或者系列上。
containPixel 是 ECharts 提供的一个方法,用于判断一个像素点是否在某个组件(如图表网格、坐标系等)内。这对于实现图表的交互功能非常重要,尤其是在需要判断鼠标点击、拖动等行为是否发生在特定区域时。
3. convertFromPixel
这里还有一个关键的api:convertFromPixel
在官方文档上有说明:转换像素坐标值到逻辑坐标系上的点。
也就是说,虽然当前点击位置没有折线经过,但我们也可以通过前面点击获取的偏移值 offsetX
和 offsetY
计算出当前点在坐标轴上的真实x、y值,这个x值就是我们要的,通过这个x值我可以遍历y轴对应的 series
中的值,找到y值value。
功能实现
如果需要实现整条柱状区域的点击,不限于柱状中有值的部分,可以使用 getZr()
注册全屏点击事件:
myChart.getZr().on('click', params => {
const pointInPixel = [params.offsetX, params.offsetY];
const pointInGrid = myChart.containPixel('grid', [params.offsetX, params.offsetY]);
// 判断点击位置是否在柱状图内
if (pointInGrid) {
// 转换点击的像素点为数据索引
const coord = myChart.convertFromPixel({ seriesIndex: 0 }, [params.offsetX, params.offsetY]);
if (coord && coord[1] !== undefined) {
// 获取 Y 轴的索引
const dataIndex = Math.round(coord[1]);
console.log(dataIndex);
// 拿到了dataIndex ,就可以直接从数据中获取需要的内容了
// 下面只是简单举个例子【👇 添加ID支持】,至此,就需要根据自己的业务逻辑来开发啦
}
});
示例:添加ID支持
如需要通过点击位置获取柱状数据对应的ID,可以通过 series
数据配置,配合按照对应索引获取:
seriesData: [
{ value: 1, id: 'ID_1' },
{ value: 2, id: 'ID_2' },
// ...
]
myChart.getZr().on('click', params => {
let pointInPixel = [params.offsetX, params.offsetY];
const pointInGrid = myChart.containPixel('grid', [params.offsetX, params.offsetY]);
if (pointInGrid) {
const coord = myChart.convertFromPixel({ seriesIndex: 0 }, [params.offsetX, params.offsetY]);
if (coord && coord[1] !== undefined) {
const dataIndex = Math.round(coord[1]);
const id = seriesData[dataIndex ]?.id;
console.log(id); // 输出点击的柱状对应ID
}
});
进阶扩展
如需要扩展功能,如操作与柱状区域相关的其他元素,可配合使用屏幕坐标和图位转换,实现更维度操作:
myChart.getZr().on('click', params => {
const pointInPixel = [params.offsetX, params.offsetY];
const pointInGrid = myChart.containPixel('grid', [params.offsetX, params.offsetY]);
if (pointInGrid) {
let [xIndex, yIndex] = myChart.convertFromPixel({ seriesIndex: 0 }, [params.offsetX, params.offsetY]);
console.log(`xIndex: ${xIndex}, yIndex: ${yIndex}`);
// 基于事件调用实现进阶操作
}
});
总结
通过Echarts提供的事件监听机制,我们可以实现点击柱状图中指定值的事件,也可以通过全屏监听实现整条柱状区域的监听,同时尽可能扩展事件功能,并为下步功能实现打下基础。