echarts文檔爬坑計劃(1)

正文之前的吐槽

作為一個入門不久,臉皮又薄的前端小白。每次遇到坑去提問的時候,我最怕看見的三個字就是「看文檔」,許多文檔對於還不熟練的新人來說真的很不友好,但對於已經掌握熟練的老手而言,就是自然而然的東西。

老手們無法理解為什麼文檔都寫得這麼直白了新手們還是看不懂,就像學會騎單車之後就不太記得學車時候的搖搖晃晃和提心弔膽。人在理解並習慣某項技能後,就會變得無法理解還沒有掌握的初學者。

暑假找了一個央企的前端開發實習,結果進去後發現其實是做數據可視化,前端的東西基本上只有靜態界面和表單,大部分都是Echarts3圖表,主要邏輯三種:載入圖表數據、切換圖表、用戶和圖表的交互。

Echarts3雖然用起來方便,但是像區域刷選、時間軸、圖表事件觸發等功能也不是拿來就能用,特別是當一個圖裡同時要幾種坐標系+N多功能的時候,就必須和官方文檔進行一番鬥智斗勇了。

非同步數據載入和更新

官方示例里的數據都是寫死在代碼里的,非同步教程也很簡略,剛接觸Echarts3的人可能會有點不知所云。下面從我實習項目的具體需求開始,說說Echarts3非同步數據的載入和更新。

項目的數據來自國家統計局,主要是世界四大經濟體和國內的各項宏觀經濟指標,在菜單中選擇指標名稱後,主視圖中刷出圖表,就像這樣:

(項目組沒有UI,界面略丑輕噴)

一共有十九個圖表,有些只有一組數據,有些有多組,還有一個圖表不僅有四組數據,還要四個Y軸。這些圖表並不是獨立的,切換的時候會互相影響,可是開始我並沒有意識到這個問題。

按照官方文檔的非同步教程,我寫了第一版代碼,長這個樣子:

$.ajax({ type: GET, url: http://localhost:8080/BIMPlus/seasonReport.json, data: $("#reportlist").serialize(), dataType: jsonp, jsonp: callback, success: function (json) { for (let i = 0; i < json.ydata.length; i++) { option1.series.push({ name: json.legend[i], type: line, data: [] }); }; myChart1.setOption(option1) for (let i = 0; i < json.ydata.length; i++) { myChart.setOption({ series: [{ name: json.legend[i], data: json.ydata[i] }] }); }

按照官方文檔的思路,先在option里把樣式設置好,然後單獨更新數據,各series以name對應。由於不確定圖表有多少組數據,所以等非同步數據傳過來之後再把series的內容push進去。

看起來好像沒什麼問題,雖然感覺很啰嗦,但功能是實現了。然而多組切換測試,並且轉換成柱形圖後,我感覺有點不對。

這麼寬的位置這兩根棍子卻擠這麼緊,明顯是有看不見的條目佔了位置。我加了一個數據視圖,打開一看,果然

雖然圖表換了,但之前添加的series還在。不要代碼里的第一個循環,直接都寫在第二個循環里更加不行,載入出來會發現只有最後一個柱子。想了想感覺這個問題應該挺常見,Echarts應該有內置方法來清空series,一查文檔果然有個類似的。

???能不能稍微具體一點,因為還有30秒下班了所以只夠寫一句話是嗎?完全還是不知道該怎麼用啊!去項目Issues上搜了一下,有人說這麼用

myChart.clear();myChart.setOption(...);

我試了一下,沒有任何作用,連報錯都沒有,彷彿根本不存在。然後我抱著僥倖心理換了一種用法

option.series=myChart.clear;myChart.setOption(...);

然後圖表就沒了。。。整個都沒了,乾乾淨淨。果然是移除實例中的所有組件和圖表啊,可是我都重新setOption了為啥還是沒有。

看完了github上所有關於清除series問題的Issues,我發現在Echarts的開發者之一,pissang大大的回答里,一直都沒有提到過clear這個方法,而是在強調myChart.setOption(option,true)這種用法,當setOption的第二個參數notMerge設置為true時,不會跟之前的配置項合併,只會載入本次添加的配置項。但是按照我目前這種代碼寫法,即使加上true也起不到作用。因為那些series已經push到option里去了。。。

我想了大概有半天時間,覺得應該是我的代碼寫的有問題。因為一開始先設置option再按需載入數據的慣性思維,我多此一舉地寫了一堆for循環。想明白後,我寫了第二版代碼,直接在 myChart1.setOption()裡面添加series,看起來清爽了不少。

$.ajax({ type:GET, url:http://localhost:8080/BIMPlus/seasonReport.json, data:$("#reportlist").serialize(), dataType:jsonp, jsonp:callback, success:function(json){ myChart1.setOption(option1,true);//每次都重新載入最初的option myChart1.setOption({ xAxis:{ data:json.xdata } });//非同步載入x軸的數據 if(json.legend){ myChart1.setOption({ legend:{ data:json.legend }//非同步載入圖例數據 }); myChart1.setOption({ series:(function(){ var ser=[]; for(let i=0;i<json.ydata.length;i++){ ser.push({ name:json.legend[i], type:line, data:json.ydata[i] }) } return ser; })()//循環添加series });

加上一行myChart1.setOption(option1,true);後,問題果然解決了。

總結

1.myChart.setOption()是載入圖表的關鍵,設置好基本配置後,再使用此方法添加數據,數據以name來和series對應,就實現了圖表數據的動態更新。

2.如果有多個圖表需要相互切換,在同一個實例下添加過的series會保留下來,即使沒有數據也會佔用位置。需要設置setOption()中第二個參數為true來確保每次切換圖表都載入最初的設置。

3.Echarts用法其實很簡單,只是每種圖表組件有其固定的數據結構,如果後台傳回的數據就是按照規定的結構組織的,直接丟到相應組件的data里就好了,否則需要前端對數據進行操作,做成Echarts規定的結構。

4.那個myChart.clear究竟怎麼用我還是沒搞明白。。。

5.封面圖來自網路,侵刪。


推薦閱讀:

前端系列教學(入門篇) - CSS初階(1)
技術分享——ES2017繼發與並發!
TCP/IP網路模型
Daguo的每周清單:第一期
《Oli-Zhao的前端一萬小時》之:離不開的Git和GitHub(1)——版本控制、Git、GitHub初認識

TAG:數據可視化 | 前端入門 | 非同步 |