美文网首页
使用Echarts值得记录的小案例(一)

使用Echarts值得记录的小案例(一)

作者: 有一条大鱼 | 来源:发表于2018-12-21 18:07 被阅读10次

    从自己的另一论坛移植过来,以后主要在简书记录了

    需求说明


    在开发项目的时候遇到一个需求,就是如何保证Echarts图表里至少显示一个图例的数据(也就是最后一个图例不能变成unselected的状态)下图为最初的实现效果。而我们不想出现图2的情况。虽然使用起来没有什么障碍,想要修改只是因为丑。

    图1 最初加载完毕的效果图 图2 所有图例被取消选中状态

    参考依据


    在发帖前查阅了一些思路:

    • 有用单选模式曲线救国的,但是就没有办法看到多条图例的数据在同一个图表里显示
    • 有图例为最后一个的时候,禁用所有图例的点击事件

    都不是能够很好的解决,找到一个可以参考的代码:

    var option = {
        title: {
            text: '折线图堆叠'
        },
        tooltip: {
            trigger: 'axis'
        },
        legend: {
            data:['邮件营销','联盟广告','视频广告','直接访问','搜索引擎']
        },
        grid: {
            left: '3%',
            right: '4%',
            bottom: '3%',
            containLabel: true
        },
        toolbox: {
            feature: {
                saveAsImage: {}
            }
        },
        xAxis: {
            type: 'category',
            boundaryGap: false,
            data: ['周一','周二','周三','周四','周五','周六','周日']
        },
        yAxis: {
            type: 'value'
        },
        series: [
            {
                name:'邮件营销',
                type:'line',
                stack: '总量',
                data:[120, 132, 101, 134, 90, 230, 210]
            },
            {
                name:'联盟广告',
                type:'line',
                stack: '总量',
                data:[220, 182, 191, 234, 290, 330, 310]
            },
            {
                name:'视频广告',
                type:'line',
                stack: '总量',
                data:[150, 232, 201, 154, 190, 330, 410]
            },
            {
                name:'直接访问',
                type:'line',
                stack: '总量',
                data:[320, 332, 301, 334, 390, 330, 320]
            },
            {
                name:'搜索引擎',
                type:'line',
                stack: '总量',
                data:[820, 932, 901, 934, 1290, 1330, 1320]
            }
        ]
    };
    myChart.setOption(option);
    myChart.on('legendselectchanged', function (params) {
        let option = this.getOption();
        let select_key = Object.keys(params.selected);
        if (!params.selected[params.name]) {
            select_key.map(res => {
                option.legend[0].selected[res] = !params.selected[res];//只点击了一个图例,所以select_key里只有被选中的为false,
                                                                       //对应的option.legend[0].selected[res]值就为true,
                                                                       //即为高亮状态,其他的都取消显示,通俗的讲就成了单选模式
            });
        } else {
            select_key.map(res => {
                option.legend[0].selected[res] = false;//先让所有图例下的数据显示状态为false
            });
            option.legend[0].selected[params.name] = true;//再让你选中的那个图例的显示状态变为true
        }
        this.setOption(option)
    });
    

    分析依据


    关键代码就是myChart.on('legendselectchanged', function (params){...}部分,这里涉及到了echarts里如何获取legend的点击事件,但是查看文档后没有示例不会写怎么办?没关系,用上面的示例代码,我们把代码里不明白的变量都打印出来分析一下例如console.log('params',params)console.log('option',option),打印出来后,对照着官方文档一看就清晰明了很多,这段截图后面我会补上。

    下面说一下上面这段参考代码的意思,select_keylegend图例选中状态的对应key-valueJson,高亮的为false,取消的是true(这里和咱们理解的高亮为true是相反的),进入if语句后用mapselect_key中的每一个元素遍历使得option.legend[0].selected[res]值为select_keyboolean值的相反值。

    说到这里可能会有点绕,option.legend[0]里的selected也是一个key-valueJson,高亮为true,取消为false,和select_key里的表现效果恰恰相反。

    所以,这段代码的实现效果就是,当图例均为高亮时select_key = {'a':false,'b':false,'c':false,'d':false},点击b图例,此时select_key['b']=true,于是进入了else代码块,如上面代码注释所写,图例由多变一,此时select_key = {'a':true,'b':false,'c':true,'d':true},这时候有两种操作:

    1. 再次点击b图例select_key = {'a':true,'b':true,'c':true,'d':true},图例状态均为不显示的状态,此时代码进入if代码块,所有的图例状态变成相反值,于是四个图例全部被选中,图表显示四条折线
    2. 点击其他图例,比如c,同理进入else代码块后,所有状态为不显示,再给选中的c图例重新赋值使其显示

    解决方案


    OK,到这里我们就明白了上面那段代码到底是什么意思了,所以究竟该如何实现我们需要的功能呢,有意思的是Object.values(params.selected)会返回一个图例选中态的布尔值数组,相当于重组了我们之前声明的select_key里各项的value值,我们只需在这个布尔值数组里只有一个false的时候,手动将其显示状态重新赋值为true即可option.legend[0].selected[params.name] = true;

    话不多说上代码

    myChart.on('legendselectchanged', function (params) {
         let option = this.getOption();
         let select_key = Object.keys(params.selected);
         let select_value = Object.values(params.selected);
         console.log('select_value',select_value,'length',select_value.length)
         var n = 0;
         select_value.map(res => {
              if(!res){                
                   n++;
              }
         });
         console.log('n',n)
         if( n ==select_value.length){   
                //如果最后一个图例点击后select_key里的选中态会变为false,
                //既有四个false,当有4个false的时候将最后选中的图例的实际显示值改为true
                option.legend[0].selected[params.name] = true;
         }
         this.setOption(option)
    });
    

    排版和说明方式还是瑕疵很多,笔者会逐渐改进,欢迎小伙伴们交流指正~

    相关文章

      网友评论

          本文标题:使用Echarts值得记录的小案例(一)

          本文链接:https://www.haomeiwen.com/subject/wcjvkqtx.html