(2)Echarts图表绑定特殊事件-图表元素绑定选中事件

在上篇文章中,介绍了Echarts关于元素绑定特殊事件需要做的处理和操作。而本文手把手教大家如何在源码中添加自己定义的事件。

需求介绍 :假设有个需求,一个图表有多根y轴,当用户点击某根轴的范围时,需要显示一个矩形框,表示用户选中了这根轴。如图1所示。第二根y轴区域被选中。又或者如图2所示,图中曲线被选中。
这里写图片描述

图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
谢谢。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值