最近在作公司的數據大盤,要用到圖表顯示,echarts研二的時候有用過,我就決定用它了。echarts
這裏用到一個能夠同時顯示多條曲線的line-charts,基本樣子以下:框架
看到這個畫紅色圈圈的地方了嗎??? 正常來說,有色調的就是激活狀態,沒色調的就是未激活狀態,ok,我以爲很不錯,徹底知足需求。但是需求方之前用過別人寫的數據大盤,用的圖表框架不同,他們的操做有點「另類」:ide
(1)一開始初始化,所有都是選中的(和咱們的echarts)一毛同樣!假如說有3個按鈕,btn1,btn2和btn3.初始化的時候,全是激活狀態。函數
(2)隨便點擊哪一個,假如說點了btn1, 其餘的都變成非選中,即btn2,btn3都變灰(尼瑪。。。。),this
(3)再點擊btn1,又全選!!! 點擊別的,好比說,點擊btn2,則btn1和btn3都變灰。 spa
ok!!,那怎麼多選呢???,請按 command+點擊,實現多選,鬆開command,單純的點擊又像步驟(2)同樣。設計
這個需求拿到,我就尷尬了,不過我不能留下沒技術的眼淚,決定想想,實現這樣的功能須要哪些知識!!!code
(1)組合鍵操做對象
(2)監聽選擇改變事件(echarts已經自帶了!!問題是回調函數的參數不是event,而是包裝了一層的數據!!)blog
(3)event去哪裏拿?爲何要event?由於我要監聽組合鍵啊!!!我要metaKey啊,別急!!!window上是掛着的。
好了,有了以上知識,咱們就能夠設計如何將echarts的選擇事件改爲咱們要的了。
這事情其實也不是很簡單!!!可是理清楚流程就ok了!!!
(1)先從最簡單的開始,一開始初始化的時候,是全選的,而後點擊任意一個,除了這個被點擊的btn,其餘的都變灰。記住,這時候咱們尚未按command。 怎麼寫????
ok,原本btn1,btn2,btn3都是選中狀態,你點擊btn1,btn1確定變成灰色了,即btn1未激活,btn2,btn3都是激活的,可是你的目標是反過來!!!echats有個「legendToggleSelect」事件,那你把全部的如今的狀態,都反轉一遍就是你要的了!!!!
(2)當你再次點擊的時候,記住你已經不是第一次點擊了!!若是仍是點擊btn1,又變成全選,怎麼寫???
仔細想一想,原本就一個btn1是激活的,你再點一下,就全是未激活的了,可是你的目標是全激活???好!!!就判斷是否是所有未激活的!是的話繼續反轉!!!而後就變成了(1)的狀態了!!
(3)若是(2)中 當你再次點擊的不是btn1,而是點擊btn2,又變成btn2激活,btn1和btn3未激活,怎麼寫???
思考一會,你會發現,這種狀況相比前一個狀態,永遠只會改變一個地方!!什麼意思??原本你btn1激活,btn2,btn3未激活,下載你點擊btn2,那是否是,btn1和btn2都激活了,就btn3未激活!!
也就是改變了btn2而已!!!發現這個規律,咱們就把前一次狀態和當前狀態比較,相同的所有變灰!!!不相同的取反。因此你須要一個變量preSelect來存儲上一個狀態。
-------------------------------------------以上都是沒有加command---------------------
-------------------------------------------如下開始加command---------------------
(1)若是你加了command,能夠實現多選,那其實就是利用echarts自己的方法,那你其實什麼都不用作,使用默認行爲就行!!!
(2)假如你利用command多選了btn1和btn2,如今你鬆開command,要點擊btn3,你但願,btn3激活,btn1和btn2都是未激活,怎麼辦???
其實這裏也是用了上面(3)中的preSelect狀態,去比較,由於這樣的狀況和上一個狀態比,只會改變一個狀態,但你不能把代碼和上面的(1)、(2)、(3)合併,這樣會亂了以前的狀態。你須要額外一個變量
1 const savePreSelected = (selected) => { 2 if (!this.isFirst) { 3 this.isFirst = true; 4 } 5 for (name in selected) { 6 if (!selected.hasOwnProperty(name)) { 7 continue; 8 } 9 10 this.preSelect[name] = selected[name]; 11 } 12 }; 13 14 const isFirstUnSelect = (selected) => { 15 if (!this.isFirst) { 16 this.isFirst = true; 17 18 this.preSelect = cloneObj(selected); 19 20 for (name in selected) { 21 if (!selected.hasOwnProperty(name)) { 22 continue; 23 } 24 25 this.preSelect[name] = !selected[name]; 26 } 27 return true; 28 } else if (!this.metaKey) { 29 let totalTrue = 0; 30 const newObj = {}; 31 for (name in selected) { 32 if (!selected.hasOwnProperty(name)) { 33 continue; 34 } 35 36 if (selected[name] === true) { 37 totalTrue++; 38 } 39 } 40 41 if (totalTrue === 2) { 42 for (name in selected) { 43 if (!selected.hasOwnProperty(name)) { 44 continue; 45 } 46 if (this.preSelect[name] === true) { 47 newObj[name] = true; 48 this.preSelect[name] = false; 49 } else if (this.preSelect[name] !== selected[name]) { 50 this.preSelect[name] = selected[name]; 51 } 52 } 53 this.selected = newObj; 54 } else if (totalTrue === 0) { 55 for (name in selected) { 56 if (!selected.hasOwnProperty(name)) { 57 continue; 58 } 59 60 selected[name] = false; 61 this.preSelect[name] = !selected[name]; 62 } 63 64 this.isFirst = false; 65 } 66 return true; 67 } else if (this.metaKey) { 68 const newObj = {}; 69 for (name in selected) { 70 if (!selected.hasOwnProperty(name)) { 71 continue; 72 } 73 74 if (this.preSelect[name] === selected[name]) { 75 if (this.preSelect[name] === true) { 76 newObj[name] = true; 77 } 78 this.preSelect[name] = false; 79 } else if (this.preSelect[name] !== selected[name] && selected[name] === false) { 80 newObj[name] = true; 81 this.preSelect[name] = true; 82 } else if (this.preSelect[name] !== selected[name] && selected[name] === true) { 83 this.preSelect[name] = true; 84 } 85 } 86 this.selected = newObj; 87 88 89 this.metaKey = false; 90 return true; 91 } 92 }; 93 94 95 if (!this.myChart) { 96 this.myChart = echarts.init(document.getElementById(id)); 97 this 98 .myChart 99 .on('legendselectchanged', (obj) => { 100 this.selected = obj.selected; 101 // 使用 legendToggleSelect Action 會從新觸發 legendselectchanged Event,致使本函數重複運行 使得 無 102 // selected 對象 103 if (this.selected !== undefined) { 104 if (!window.event.metaKey && isFirstUnSelect(this.selected)) { 105 triggerAction('legendToggleSelect', this.selected); 106 } else { 107 if (!this.preSelect) { 108 this.preSelect = {}; 109 } 110 this.metaKey = true; 111 savePreSelected(this.selected); 112 } 113 } 114 }); 115 }