在上篇文章中,介绍了Echarts关于元素绑定特殊事件需要做的处理和操作。而本文手把手教大家如何在源码中添加自己定义的事件。
需求介绍 :假设有个需求,一个图表有多根y轴,当用户点击某根轴的范围时,需要显示一个矩形框,表示用户选中了这根轴。如图1所示。第二根y轴区域被选中。又或者如图2所示,图中曲线被选中。
本文以图2为例,实现曲线的选中事件。
(1)曲线的绘制前处理代码大概在Echarts源码3.6.2版本的27329行左右。我们可以在此处加入选中事件处理代码,然后选中图形跟随曲线的绘制一起进行。
//selectEvent配置项是自定义的,为true表示元素绑定选中事件
var selectEvent = seriesModel.get('selectEvent');
if (selectEvent) {
polyline.silent = false;
//选中事件回调处理
var onElementClick = zrUtil.curry(setSelectEvent, {
that: that,
selectRectPainter: selectRectPainter,
buildSelectElem: buildSelectElem,
points: points,
isAreaChart: isAreaChart,
group: group,
stackedOnPoints: stackedOnPoints,
seriesModel: seriesModel,
graphic: graphic
});
//选中除曲线外的其他地方回调处理
var onOtherElementClick = zrUtil.curry(setOtherEvent, {
that: that,
selectRectPainter: selectRectPainter,
group: group
});
group.off('click');
group.on('click', onElementClick);
group.__zr.on('click', onOtherElementClick);
}
/**
* 选中曲线后的回调处理
* 主要负责构建曲线的选中状态或者显示选中状态
* @param {Object} params: set params
* @parsm {Object.<Event Object>} event
*/
function setSelectEvent (params, event) {
// 已经存在隐藏的选中状态,直接显示
if (params.that.selectGroup) {
params.selectRectPainter.show(params.that.selectGroup);
} else {
//不存在隐藏的选中状态,需要构造选中状态
params.buildSelectElem.call(params.that, params.group, params.points, params.graphic);
params.isAreaChart && params.buildSelectElem.call(params.that, params.group, params.stackedOnPoints, params.graphic);
}
// 加入选中后的事件参数
params.selectRectPainter.setEventData(params.group, {
series: params.seriesModel,
selectMode: true
}, params.that);
event.event.preventDefault();
event.event.stopPropagation();
}
/**
* 选中除曲线外的图表其他地方后的回调处理,
* 主要负责隐藏选中状态
* @param {Object} params: set params
* @parsm {Object.<Event Object>} event
*/
function setOtherEvent (params, event) {
//判断是否是曲线
if ((params.that.selectGroup && !params.selectRectPainter.isChildFromGroup(params.group, event.target, params.that)) || event.outerClick) {
if (!params.that.selectGroup) {
return;
}
params.selectRectPainter.hide(params.that.selectGroup);
// 加入选中后的事件参数
params.selectRectPainter.setEventData(params.group, {
selectMode: false
}, params.that);
}
}
(2)第一步中有一个重要的步骤是构建选中状态,主要有一下代码生成
/**
* param {Object.<Echarts class>} group
* param {Array} points: 组成曲线的点的坐标
*/
function buildSelectElem(group, points) {
var selectGroup = this.selectGroup;
var coordinate = {};
if (!selectGroup) {
this.selectGroup = selectGroup = new graphic.Group();
group.add(selectGroup);
}
for (var i = 0; i < points.length; i++ ) {
coordinate.x = points[i][0];
coordinate.y = points[i][1];
selectRectPainter.painterSelectElems(coordinate, selectGroup);
}
this.selectGroup = selectGroup;
}
/**
@param {Object} group
*/
selectRectPainter.show = function (group) {
group.traverse(function (elem) {
elem.setStyle && elem.setStyle({
opacity: 1
});
elem.z = 3;
});
return this;
};
/**
@param {Object} group
*/
selectRectPainter.hide = function (group) {
if (!group) {
return;
}
group.eachChild(function (elem) {
elem.setStyle({
opacity: 0
});
elem.z = 0;
});
return this;
};
/**
@param {Object} coordinate
@param {Object} group
*/
selectRectPainter.painterSelectElems = function (coordinate, group, flag) {
var rect, circle, x , y;
x = coordinate.x;
y = coordinate.y;
if (flag) {
circle = new graphic.Circle({
shape:{
cx: x ,
cy: y ,
r: 4
},
z:3,
style:{
fill:'rgba(0, 128, 0, 0.5)'
},
silent:false
});
group.add(circle);
return;
}
rect = new graphic.Rect({
shape: {
x: x - 6,
y: y - 6,
height: 12,
width: 12
},
z:3,
style: {
fill: 'rgba(255, 255, 255, 0)',
stroke: '#000',
linewidth: 1
},
silent: false
});
group.add(rect);
for (var i = 0; i < 4; i++) {
circle = new graphic.Circle({
shape:{
cx: x + (i % 2) * 12 - 6,
cy: y + (i >= 2 ? 12 : 0) - 6,
r: 4
},
z:3,
style:{
fill:'rgba(0, 128, 0, 0.5)'
},
silent:false
});
group.add(circle);
}
return this;
};
(3)配置option参数,初始化图表。如下所示:
var chart = echarts.init(document.getElementById("content"));
var colors = ['#5793f3', '#d14a61', '#675bba'];
var option = {
color: colors,
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
}
},
grid: {
right: '20%'
},
toolbox: {
feature: {
dataView: {show: true, readOnly: false},
restore: {show: true},
saveAsImage: {show: true}
}
},
legend: {
data:['蒸发量','降水量','平均温度']
},
xAxis: [
{
type: 'category',
axisTick: {
alignWithLabel: true
},
splitLine: {
show: true
},
silent: false,
triggerEvent: true,
selectEvent:true,
data: ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月']
}
],
yAxis: [
{
type: 'value',
name: '蒸发量',
min: 0,
max: 250,
position: 'right',
axisLine: {
show: true,
lineStyle: {
color: colors[0]
}
},
splitLine: {
show: true
},
silent: false,
triggerEvent: true,
selectEvent: true,
axisLabel: {
formatter: '{value} ml'
}
},
{
type: 'value',
name: '降水量',
min: 0,
max: 250,
position: 'right',
offset: 80,
splitLine: {
show:true
},
silent: false,
triggerEvent: true,
selectEvent:true,
axisLine: {
show: true,
lineStyle: {
color: colors[1]
}
},
axisLabel: {
formatter: '{value} ml'
}
},
{
type: 'value',
name: '温度',
min: 0,
max: 25,
splitLine: {
show: true
},
silent: false,
triggerEvent: true,
selectEvent: true,
position: 'left',
axisLine: {
show: true,
lineStyle: {
color: colors[2]
}
},
axisLabel: {
formatter: '{value} °C'
}
}
],
series: [
{
name:'蒸发量',
type:'bar',
selectEvent: true,
data:[2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3]
},
{
name:'降水量',
type:'bar',
selectEvent: true,
yAxisIndex: 1,
data:[2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3]
},
{
name:'平均温度',
type:'line',
selectEvent: true,
yAxisIndex: 2,
data:[2.0, 2.2, 3.3, 4.5, 6.3, 10.2, 20.3, 23.4, 23.0, 16.5, 12.0, 6.2]
}
]
};
chart.setOption(option);
chart.on('contextmenu',function (params) {
console.log(params);
});
以上,差不多就是选中事件的处理代码,由于在代码中还调用了其他接口,故难免有些地方让人看不懂,详细的源码,我会上传到csdn,有兴趣的可以下载下来。源码地址如下:http://download.csdn.net/download/mulumeng981/9975060
谢谢。