(1)Echarts图表绑定特殊事件

前言:Echarts插件是基于canvas画布而构建的一个图表库,每一个图表由一个或者多个canvas画布构成,大多数时候都由一个canvas构成,图表内部不同组件和图形可以分属于不同的层级,类似于html的z-index属性的功能。不同的层级组件在刷新的时候,有性能的差异。而事件的捕捉和监听,与html存在本质的不同,dom事件的那一套处理规则,在Echarts插件内部并没有具体的元素去支撑,这与基于svg技术的d3和highcharts图表存在本质不同,也可以说是canvas图表库的天然缺陷。

Echarts事件处理原理:Echarts事件的监听和响应,是由底层的zrender库来模拟和封装的。封装后,接口的调用和使用,跟dom元素的事件接口的使用方法类似。具体的实现原理:监听事件的发生坐标(如鼠标点击或者悬浮时候的坐标),判断在哪个绘制元素的范围中,如果在某个元素包含的范围中,该元素就可以监听该事件,执行与该事件相关的事件处理逻辑。具体的解释可参考:HTML5 Canvas绘制的图形的事件处理。Echarts内部每一个类都有一个getBoundingRect方法,该方法会返回与这个类相关的矩形信息。该矩形对应这个元素在图表上的包含范围。如图1所示,当点击y轴的时候,Echarts内部会判断,鼠标的点击位置是否在y轴组件的矩形框包含的范围内。
这里写图片描述

Echarts初始化事件的总函数:该函数是echartsProto原型下_initEvents的函数,这个函数处理和逻辑,决定我们在内部编写的自定义事件,能不能正常执行和响应。这个坑是我当初花了很多时间才发现的。如下代码段是它的源码。从源码中,不知大家有木有发现params参数的秘密:params若为空,则无法触发事件。而只有el && el.dataIndex和
el && el.eventData这两种情况下,params才不为空,事件才能正常监听。故要监听某图表元素绑定的事件,一定要满足上面两个条件,或者传递某个参数,然后根据参数在_initEvents函数内部做处理,如代码2所示,通过在el元素添加eventData属性,然后在_initEvents函数中添加代码2所示的代码,即可实现。

代码1:
echartsProto._initEvents = function () {
       each(MOUSE_EVENT_NAMES, function (eveName) {
            this._zr.on(eveName, function (e) {
                var ecModel = this.getModel();
                var el = e.target;
                var params;

                // no e.target when 'globalout'.
                if (eveName === 'globalout') {
                    params = {};
                }
                else if (el && el.dataIndex != null) {
                    var dataModel = el.dataModel || ecModel.getSeriesByIndex(el.seriesIndex);
                    params = dataModel && dataModel.getDataParams(el.dataIndex, el.dataType) || {};
                }
                // If element has custom eventData of components
                else if (el && el.eventData) {
                    params = zrUtil.extend({}, el.eventData);
                }                                               
                if (params) {
                    params.event = e;
                    params.type = eveName;
                    this.trigger(eveName, params);
                }

            }, this);
        }, this);

        each(eventActionMap, function (actionType, eventType) {
            this._messageCenter.on(eventType, function (event) {
                this.trigger(eventType, event);
            }, this);
        }, this);
    };

    代码2if (eveName === 'contextmenu') {                       
            if (el && el.eventData && el.eventData.selectMode) {
                e.event.preventDefault();
                e.event.stopPropagation();
                params = zrUtil.extend(params, el.eventData);
            } else {
                params = null;
            }
        }               

option配置项的配置
此外,我们在源码中绑定的自定义事件,要生效还需要修改两个配置项属性,一个是silent属性:当它为true的时候,会禁止所有的事件响应,为false的时候,响应事件。triggerEvent属性: 为true的 时候,响应事件。这两个配置项,silent属性每一个图表元素都具有;triggerEvent则是组件和图形元素才有。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值