1.问题描述
我在工作中遇到了这样一个需求:我们都知道点击echarts折线图的图例,是可以控制折线的显隐的。我现在希望点击某一个图例可以改变多条折线的显隐。
例如在下面这张图中,我将“xxx水位”和“yyy水位”分为一组;将“xxx流量”和“yyy流量”分为一组。我希望当点击组内的任意一个图例时,可以改变整组折线的显隐。
2.问题分析
想要实现理想的效果,主要有两个要点:1.获取到图例点击事件;2.找到自定义折线显隐的方法。
(1)图例点击事件
echarts有完整的事件系统,在我们点击图例时legendselectchanged
事件会被触发。
(2)控制折线的显隐
echarts还有一些控制图表的方法,称之为action图表行为。其中的legendToggleSelect
方法就可以切换图例的选中状态,从而控制折线的显隐。
3.实现功能
我一开始的写法如下:
const dimensionNames = [
["xxx水位", "yyy水位"],
["xxx流量", "yyy流量"],
];
onMounted(() => {
nextTick(() => {
const instance = chart.value.getInstance();
instance.on("legendselectchanged", e => {
/**
* e = {
* name //切换的图例名称
* selected //所有图例的选中状态表
* }
*/
const name = dimensionNames
.find(g => g.includes(e.name))
.find(n => n !== e.name);
instance.dispatchAction({
type: "legendToggleSelect",
name,
});
});
});
但是这样写有一个问题:由于legendToggleSelect
行为的会触发legendselectchanged
事件,因此就会出现死循环。
为了解决这个问题就需要在代码中加入一个甄别机制,只在鼠标点击图例所触发的事件中使用legendToggleSelect
行为。
const dimensionNames = [
["xxx水位", "yyy水位"],
["xxx流量", "yyy流量"],
];
onMounted(() => {
nextTick(() => {
const instance = chart.value.getInstance();
instance.on("legendselectchanged", e => {
/**
* e = {
* name //切换的图例名称
* selected //所有图例的选中状态表
* }
*/
const group = dimensionNames.find(g => g.includes(e.name));
// 甄别是否是鼠标点击所触发的事件
if (group.every(i => e.selected[i] == e.selected[e.name])) return;
const name = group.find(n => n !== e.name);
instance.dispatchAction({
type: "legendToggleSelect",
name,
});
});
});
最终效果如下: