主题:使用echarts绘制图表并,点击曲线上的点时跳转到指定链接,点击绘图区域空白处时,绘制标线
本文中使用的是按需加载的方式引入 echart,若需要使用标线功能,请至少require(“echarts/lib/component/markLine”);
点击事件
echarts中,有两种方式可以捕捉点击事件,
- 用于捕捉曲线的点击事件:chartInstance.on(‘click’,funtion(param){});
- 用于捕捉画布的点击事件:chartInstance.getZr().on(‘click’,funtion(param){});
第一种点击事件的捕捉方式,仅能捕捉点击到echart图表元素上的事件
,例如点击在曲线
上,点击在坐标轴上(需要设置坐标轴的slient属性为false)
,点击在标线上(需要设置MarkLine的slient属性为false)
; 但无法捕捉点击在空白位置的事件
;
以下是点击事件回调函数的参数,
来自 events.鼠标事件
{
// 当前点击的图形元素所属的组件名称,
// 其值如 'series'、'markLine'、'markPoint'、'timeLine' 等。
componentType: string,
// 系列类型。值可能为:'line'、'bar'、'pie' 等。当 componentType 为 'series' 时有意义。
seriesType: string,
// 系列在传入的 option.series 中的 index。当 componentType 为 'series' 时有意义。
seriesIndex: number,
// 系列名称。当 componentType 为 'series' 时有意义。
seriesName: string,
// 数据名,类目名
name: string,
// 数据在传入的 data 数组中的 index
dataIndex: number,
// 传入的原始数据项
data: Object,
// sankey、graph 等图表同时含有 nodeData 和 edgeData 两种 data,
// dataType 的值会是 'node' 或者 'edge',表示当前点击在 node 还是 edge 上。
// 其他大部分图表中只有一种 data,dataType 无意义。
dataType: string,
// 传入的数据值
value: number|Array,
// 数据图形的颜色。当 componentType 为 'series' 时有意义。
color: string,
// 用户自定义的数据。只在 graphic component 和自定义系列(custom series)
// 中生效,如果节点定义上设置了如:{type: 'circle', info: {some: 123}}。
info: *
}
这个使用比较简单,我们可以在 series.data中携带一些冗余的数据方便我们在点击事件回调函数中获取数据
如,
chartInstance.setOption({
series:{
data: [[x,y, data1,data2,data3...], [x,y, data1,data2,data3...],]
}
});
这样,在回调函数中 可以获取到这些冗余信息,如:
function(param)
{
let nowData = param.data;// [x,y, data1,data2,data3...]
///当然也可以通过索引获取数据
let index = param.dataIndex;
}
第二种点击事件的捕捉方式,能捕捉任意点击在 Canvas
上的点击事件,但是不太方便区分鼠标具体点击在哪个图表元素上
这种方式echarts官方文档中没有明确说明,并且事件的参数也不够明确,这里我依据我的一些经验给出我的一些用法:
chartInstance.getZr().off('click');
chartInstance.getZr().on('click', function (param)
{
let x = param.offsetX; //获取当前点击位置相对于图表左上角的 横向偏移量 (单位是像素, 但是不建议直接使用,因为你可能无法正确映射到图表上的位置)
let y = param.offsetY; // 获取当前点击位置相对于图表左上角的纵向偏移量
let result = chartInstance.convertFromPixel({
seriesIndex:0,
xAxisIndex:0,
},[x,y]); // echarts 4.0新增 功能,将像素坐标转换为图表的逻辑坐标,这里的result就是当前点击位置的图表坐标索引了
let xAxisDataIndex= result[0];
let xData= xAxisData[xAxisDataIndex]; //通过原始x轴数组获取x轴位置,可以类似的获取series的数据
}
上面的代码中,我们可以获取点击位置的像素坐标,并将其转换为点击位置的逻辑坐标(也就数据索引)
,但是有一个问题,我们无法判断点击的位置是图表元素还是空白处
,
下面是点击在曲线上时的事件参数
下面是点击在空白处时的事件参数
下面是点击在非曲线上,但是是图表元素上时的事件参数
我多次实践后,得出以下结论:
- param.target !== ‘undefined’ 时,表示点击在曲线上
- param.target === ‘undefined’ && param.topTarget !== ‘undefined’ 时,表示点击在非曲线的图表元素上
- param.tartget === ‘undefined’ && param.topTarget === ‘undefined’ 时,表示点击在空白区域
因此,我们可以通过上面的条件来判断当前点击的位置是否是曲线,从而完成一些操作;
以下是核心示例代码:
initClickWithMarkLine:function()
{
let xAxisData = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
let option = {
xAxis: {
type: 'category',
data: xAxisData,
},
yAxis: {
type: 'value'
},
series: [{
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: 'line'
}]
};
let dom = document.getElementById('app2');
let chartInstance = echarts.init(dom);
chartInstance.setOption(option);
let self = this;
chartInstance.getZr().off('click');//取消监听点击事件,也可以防止重复绑定
chartInstance.getZr().on('click',function(param)
{
let x = param.offsetX;
let y = param.offsetY;
let result = chartInstance.convertFromPixel({
seriesIndex:0,
xAxisIndex:0,
},[x,y]);
let index = result[0];
let xAxis =xAxisData[index];
self.setMarkLine(xAxis,chartInstance);
});
},
setMarkLine:function(xAxis,chartInstance)
{
let markLine = {
silent:true, //取消标线的点击事件
animation:false, //不播放标线的动画
data: [{
name: xAxis,
xAxis: xAxis, //表示标注 x=xAxis的线, 具体配置项可以参考 https://www.echartsjs.com/zh/option.html#series-line.markLine
label: {
silent: true,
position : 'end',
}
}]
};
chartInstance.setOption({
series:{
markLine:markLine,
},
})
代码同步上传至github,工程见:https://github.com/blowingBreeze/Tick/tree/master/Web/demo
具体代码见: 工程目录下的 /src/components/ChartClick.vue