最近看到了一个需求,想要监听图例元素的鼠标事件(不限于点击),所以光靠监听「legendselectchanged」就不够用了。
为此,打算尝试一下仿制图例
简易版
一开始,先做了个简易版
直接改配置项的、不可复用的简易版
思路很简单,就是用柱图的一个柱子充当图例,监听鼠标点击事件,触发「legendSelect」或者「legendUnSelect」动作:
主要代码如下:
myChart.on('click', {
seriesName: 'myLegend'
}, function(params) {
if (params.color === '#CCC') {
myChart.dispatchAction({
type: 'legendSelect',
// 图例名称
name: params.name
});
option.series[params.seriesIndex].data[params.dataIndex].itemStyle.color = colorList[params.dataIndex];
myChart.setOption(option);
} else {
myChart.dispatchAction({
type: 'legendUnSelect',
// 图例名称
name: params.name
});
option.series[params.seriesIndex].data[params.dataIndex].itemStyle.color = '#CCC';
myChart.setOption(option);
}
});
函数版
简易版做好后,觉得如果下次想用,还得手动一步一步重来一遍,这也太麻烦了吧
所以我打算写个函数,把配置项传进来,返回一个加好图例的新配置项,这样省下的时间就可以起身活动一下,比如去逛一下小超市~(把体力劳动和脑力结合起来,有益身心,胜于吃药)
于是把简易版的思路提炼、完善了下:
效果如下:
比较完善的函数版,传入原配置项,返回加好图例的新配置项
其中定义的函数如下:
// 传入原 option,返回新 option
function addLegend(src) {
let dst = JSON.parse(JSON.stringify(src));
let legendSymbol = 'roundRect';
let legendSymbolSize = [40, 25];
let legendSeries = {
type: 'line',
name: 'legendSeries',
//symbolSize: [40, 25],
tooltip: {
show: false
},
symbolKeepAspect: true,
lineStyle: {
opacity: 0
},
label: {
show: true,
position: 'right',
formatter: '{b}'
},
hoverAnimation: false,
data: []
};
// 设置一个隐藏的默认图例
dst.legend = {
show: false
};
// 如果原 option 没配置 color ,则直接设置为默认颜色
typeof dst.color === 'undefined' ?
dst.color = ['#c23531', '#2f4554', '#61a0a8', '#d48265', '#91c7ae', '#749f83', '#ca8622', '#bda29a', '#6e7074', '#546570', '#c4ccd3'] :
null;
// 根据原 option.grid 的情况,添加自制图例所需的直角坐标
if (typeof dst.grid === 'object') {
typeof dst.grid.length === 'undefined' ?
dst.grid = [dst.grid, {
top: '5%',
bottom: '90%',
left: '60%',
right: '20%'
}] :
dst.grid.push({
top: '5%',
bottom: '90%',
left: '60%',
right: '20%'
});
} else {
dst.grid = [{},
{
top: '5%',
bottom: '90%',
left: '60%',
right: '20%'
}
];
}
// 根据原 option.xAxis 的情况,添加自制图例所需的 x 轴
if (typeof dst.xAxis === 'object') {
typeof dst.xAxis.length === 'undefined' ?
dst.xAxis = [dst.xAxis, {
gridIndex: dst.grid.length - 1,
type: 'category',
show: false
}] :
dst.xAxis.push({
gridIndex: dst.grid.length - 1,
type: 'category',
show: false
});
} else {
dst.xAxis = [{
gridIndex: dst.grid.length - 1,
type: 'category',
show: false
}];
}
// 根据原 option.yAxis 的情况,添加自制图例所需的 y 轴
if (typeof dst.yAxis === 'object') {
typeof dst.yAxis.length === 'undefined' ?
dst.yAxis = [dst.yAxis, {
gridIndex: dst.grid.length - 1,
show: false
}] :
dst.yAxis.push({
gridIndex: dst.grid.length - 1,
show: false
});
} else {
dst.yAxis = [{
gridIndex: dst.grid.length - 1,
show: false
}];
}
legendSeries.xAxisIndex = dst.xAxis.length - 1;
legendSeries.yAxisIndex = dst.yAxis.length - 1;
for (let i = 0; i < dst.series.length; i++) {
if (dst.series[i].type === 'line') {
legendSymbolSize = [40, 40];
typeof dst.series[i].symbol !== 'undefined' ?
legendSymbol = dst.series[i].symbol :
legendSymbol = 'path://M0 29 L30 29 L30 31 L0 31 Z \
M100 29 L70 29 L70 31 L100 31 Z \
M 50 10 A 20 20 0 1 0 50 50 A 20 20 0 1 0 50 10 Z \
M 50 12 A 18 18 0 1 1 50 48 A 18 18 0 1 1 50 12 Z';
// 线图图例线条太细不容易点中,可以考虑将上面 svg path 的最后一行去掉,
// 这样就是实心的了。
} else {
legendSymbolSize = [40, 25];
legendSymbol = 'roundRect';
}
legendSeries.data.push({
name: dst.series[i].name,
itemStyle: {
color: dst.color[i],
},
value: [i, 1],
symbol: legendSymbol,
symbolSize: legendSymbolSize
});
}
if (typeof dst.series === 'object') {
typeof dst.series.length === 'undefined' ?
dst.series = [dst.series, legendSeries] :
dst.series.push(legendSeries);
}
return dst;
}
监听鼠标点击事件,实现对应 series 的显示/隐藏:
// 监听处理自制图例的点击事件
myChart.on('click', {
seriesName: 'legendSeries'
}, function(params) {
if (params.color === '#CCC') {
myChart.dispatchAction({
type: 'legendSelect',
// 图例名称
name: params.name
});
option.series[params.seriesIndex].data[params.dataIndex].itemStyle.color = colorList[params.dataIndex];
myChart.setOption(option);
} else {
myChart.dispatchAction({
type: 'legendUnSelect',
// 图例名称
name: params.name
});
option.series[params.seriesIndex].data[params.dataIndex].itemStyle.color = '#CCC';
myChart.setOption(option);
}
});
监听鼠标 mouseover、mouseout 事件,实现联动高亮:
// 监听处理自制图例的鼠标滑过事件
myChart.on('mouseover', {
seriesName: 'legendSeries'
}, function(params) {
myChart.dispatchAction({
type: 'highlight',
seriesName: params.name
});
});
myChart.on('mouseout', {
seriesName: 'legendSeries'
}, function(params) {
myChart.dispatchAction({
type: 'downplay',
seriesName: params.name
});
});
以上这种图例「仿制」操作,是不是能够给大家打开一些思路,是不是可以更好地满足甲方爸爸乱飞放飞了的想象力了?
比如:
本文分享自 ZXand618的ECharts之旅 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体分享计划 ,欢迎热爱写作的你一起参与!