使用Echarts值得記錄的小案例(一)

從自己的另一論壇移植過來,以后主要在簡書記錄了

需求說明


在開發(fā)項目的時候遇到一個需求,就是如何保證Echarts圖表里至少顯示一個圖例的數(shù)據(jù)(也就是最后一個圖例不能變成unselected的狀態(tài))下圖為最初的實現(xiàn)效果。而我們不想出現(xiàn)圖2的情況。雖然使用起來沒有什么障礙,想要修改只是因為丑。

圖1 最初加載完畢的效果圖
圖2 所有圖例被取消選中狀態(tài)

參考依據(jù)


在發(fā)帖前查閱了一些思路:

  • 有用單選模式曲線救國的,但是就沒有辦法看到多條圖例的數(shù)據(jù)在同一個圖表里顯示
  • 有圖例為最后一個的時候,禁用所有圖例的點擊事件

都不是能夠很好的解決,找到一個可以參考的代碼:

var option = {
    title: {
        text: '折線圖堆疊'
    },
    tooltip: {
        trigger: 'axis'
    },
    legend: {
        data:['郵件營銷','聯(lián)盟廣告','視頻廣告','直接訪問','搜索引擎']
    },
    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:'聯(lián)盟廣告',
            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,
                                                                   //即為高亮狀態(tài),其他的都取消顯示,通俗的講就成了單選模式
        });
    } else {
        select_key.map(res => {
            option.legend[0].selected[res] = false;//先讓所有圖例下的數(shù)據(jù)顯示狀態(tài)為false
        });
        option.legend[0].selected[params.name] = true;//再讓你選中的那個圖例的顯示狀態(tài)變?yōu)閠rue
    }
    this.setOption(option)
});

分析依據(jù)


關鍵代碼就是myChart.on('legendselectchanged', function (params){...}部分,這里涉及到了echarts里如何獲取legend的點擊事件,但是查看文檔后沒有示例不會寫怎么辦?沒關系,用上面的示例代碼,我們把代碼里不明白的變量都打印出來分析一下例如console.log('params',params)console.log('option',option),打印出來后,對照著官方文檔一看就清晰明了很多,這段截圖后面我會補上。

下面說一下上面這段參考代碼的意思,select_keylegend圖例選中狀態(tài)的對應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里的表現(xiàn)效果恰恰相反。

所以,這段代碼的實現(xiàn)效果就是,當圖例均為高亮時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},圖例狀態(tài)均為不顯示的狀態(tài),此時代碼進入if代碼塊,所有的圖例狀態(tài)變成相反值,于是四個圖例全部被選中,圖表顯示四條折線
  2. 點擊其他圖例,比如c,同理進入else代碼塊后,所有狀態(tài)為不顯示,再給選中的c圖例重新賦值使其顯示

解決方案


OK,到這里我們就明白了上面那段代碼到底是什么意思了,所以究竟該如何實現(xiàn)我們需要的功能呢,有意思的是Object.values(params.selected)會返回一個圖例選中態(tài)的布爾值數(shù)組,相當于重組了我們之前聲明的select_key里各項的value值,我們只需在這個布爾值數(shù)組里只有一個false的時候,手動將其顯示狀態(tài)重新賦值為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里的選中態(tài)會變?yōu)閒alse,
            //既有四個false,當有4個false的時候?qū)⒆詈筮x中的圖例的實際顯示值改為true
            option.legend[0].selected[params.name] = true;
     }
     this.setOption(option)
});

排版和說明方式還是瑕疵很多,筆者會逐漸改進,歡迎小伙伴們交流指正~

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容