資料視覺化,個人經驗總結(Echarts相關)

地鐵上的小前端發表於2018-03-06

資料視覺化

個人能力分析
資料視覺化旨在藉助於圖形化手段,清晰有效地傳達與溝通訊息(來源於bd).在我們生活中最常見的,就有各種統計資料做成圖表、股票k線圖、能力雷達圖這些(上面那張個人能力分析圖,圖片資料純屬虛構);而對於前端開發者來說,就是用一些大神開發好的視覺化圖表元件將後端傳過來的資料用一種直觀,清晰的方式呈現在瀏覽器中,常用的視覺化圖表相簿包括(排名不分先後),後面文章中都是圍繞Echarts庫的運用:

  • D3
  • Echarts
  • three.js
  • HighCharts
  • Charts
  • G2

色彩的應用

色彩的應用作為資料視覺化重要的部分,同樣的資料,同樣的圖表型別,如果不同的人或者不同的公司做出來,有可能呈現的效果會截然不同,這其中的重要區別可能就是色彩的應用。Echarts不同的圖表,都提供了一套預設的主題色,所以儘管我們不設定顏色,其呈現的效果也還是不錯的。Echarts圖表中可進行顏色設定的地方很多,包括但不僅限於下圖(官方demo)所示的內容:

clipboard.png

clipboard.png

關於上面圖提到的每個部分在option怎麼設定,Echarts的配置手冊都有詳細描述,這裡主要說一些工作中不常用到但又很關鍵的部分。從實現層面上來講,顏色的設定分兩種,option屬性設定和css樣式設定,至於為什麼,可以從上圖的dom結構得到答案,每個Echarts例項大體都包含兩個元素:canvas 和 div(方框標註部分),div負責圖表tooltip的展示(黃色框圈起部分),而canvas負責除黃色框以外的所有部分。如果是簡單的顏色設定,如上面的展示的那張標註圖,option屬性設定color就足夠了,但如果要做出下圖所示的強調色,option屬性設定color就顯得捉襟見肘了,在標題和tooltip的資料顯示上,應用了混合色用以加強資料的表現:

clipboard.png

對於tooltip中的強調色,由於其根本是dom元素的操作,所以要做出上圖所示的效果很簡單,控制div元素及其子元素的樣式就可以了,like:

      option = {
        tooltip: {
          trigger: 'axis',
          backgroundColor: 'rgba(0,0,0,.8)',
          textStyle: {
            color: '#b4d1e6'
          },
          /*formatter屬性的應用,直接行內css樣式操作*/
          formatter: function (val) {
            return val[0].name + ':<span style="color:#ffbf00;font-weight: bold;font-size:14px;padding: 0 5px;" >' + addSeparator(val[0].data) + '個</span>'
          }
        }
        ...其他設定
     }
複製程式碼

而對於標題或則圖表其他部分要進行混合色的設定,就不是那麼簡單了,因為其不接受tooltip那種dom元素的直接樣式操作,但Echart還是留了足夠多的入口來解決這樣的需求:富文字標籤(rich),官方講解,比如上面那一段混合色的標題,可以這樣來實現,程式碼拷貝到官方demo,即可檢視效果,更多用法可檢視官方示例

title:{
          show:true,
          left:'center',
          top:15,
          text:'{a|2017年全省應聘人員總數統計:}{b|165,338}{c|人}',
          textStyle :{
            rich: {
              a: {
                color: '#8bb8e8',
                fontSize: 14,
                fontWeight: 'bold'
              },
              b: {
                color: '#ffcf2a',
                fontSize: 16,
                fontWeight: 'bold'
              },
              c: {
                color: '#8bb8e8',
                fontSize: 14,
                fontWeight: 'bold'
              }
            }

         }
}
複製程式碼

自動輪播(AutoToolTip)的應用

Echarts中的normal與emphasis,以及tooltip的加入,通過hover與unhover狀態的切換,讓圖表多了一些互動。特別是上面提到的tooltip的自定義樣式,讓展示效果提升了一個檔次。但作為前端視覺化,很多時候顯示在一個大螢幕上,用於參觀展示用,所以參觀展示的人是不大可能用滑鼠一個一個hover來檢視具體的資料,這就要求我們需要用自動輪播來代替hover觸發tooltip。為此,官方提供了dispatchAction方法官方demo,也可參考網上一篇文章提供的思路和原始碼,封裝一個圖表通用的自動輪播工具,我自己也封裝了一個,歡迎參閱,下面是map使用輪播時的效果圖。

clipboard.png
使用思路(Vue框架下使用),首先將autoShowTip物件新增為Echarts的一個方法;然後在Echarts例項例項化之後,呼叫this.$echarts.AutoShowTip方法,並傳入例項物件,option物件,輪播時間等引數:

clipboard.png
這裡需要提醒兩點:

  • Echarts的dispatchAction方法對常用圖表中的Radar圖還不支援,個人知道支援的圖表型別有:pie,bar,line,map,scatter系列;為解決Radar圖的單軸hover與自動輪播,自己寫了個方法,並將其也封裝到autoShowTip物件中,具體的實現可參考個人部落格的文章:從0開始擼一個支援單軸輪播的雷達圖之末篇

  • toolTip使用時,其顯示的位置也是大有學問,比如下圖左邊所示,會弄巧成拙,所以控制tooltip的位置也很重要,Echarts也為此提供了相應的方法,比如加入下面這段程式碼,就可以達到右圖所示的效果:

           position: function (pos, params, dom, rect, size) {
             var obj = {top: '10%'}; //y軸方向,其位置固定
            // obj[['left', 'right'][+(pos[0] < size.viewSize[0] - 20)]] = 5;
             if (pos[0] > (size.viewSize[0] - 100)) {
               obj['right'] = 0;
             } else {
               obj['left'] = pos[0];
             }
             return obj;
           }
    複製程式碼

clipboard.png

  • 另外,自動輪播還可以更好的展示資料,當我們資料過長,而展示空間有限時,我們可以把資料切為兩端甚至多段,通過自動輪播切換,這樣就可以在有限的空間裡,展現最好的效果,下面是我做的一個Demo,原始碼及效果圖:

     myChart = this.$echarts.init(target);
     let step =0;
     option.xAxis.data = labelData.slice(0,length);
     option.series[0].data = realData.slice(0,length);
     option.series[1].data = symbolData.slice(0,length);
     myChart.setOption(option);
     this.$echarts.AutoShowTip(myChart, option, 3000,{
       refreshOption: function () {
         step = ((step + length)>labelData.length)?0:(step+length);
         let endStep = ((step + length)>labelData.length)?8:(step+length);
         option.xAxis.data = labelData.slice(step,endStep);
         option.series[0].data = realData.slice(step,endStep);
         option.series[1].data = symbolData.slice(step,endStep);
       },
       isRefresh: labelData.length>length });
    複製程式碼

clipboard.png

座標系的優化

在做bar或則line,或則基於這兩者的擴充套件系列時,除了上面提到的,其實設定或數值(value)軸的刻度,也是一件需要注意的事情。比如下面兩張圖片這樣,如果單看,感覺沒啥,但如果在一個大屏裡有多個這種柱狀或曲線圖,有些間隔線三四根,有些八九根,還有些沒有均分,這種視覺化展示,就會給人一種七零八落的感覺,根據個人經驗,將間隔線控制在6根以下,體驗較好。

clipboard.png
除了上面提到的這一種,還有就是座標軸範圍過大,數值過大,造成不美觀及可讀性差。比如下面這種,簡直就是失敗的炫富,除去y軸數字重疊的問題,還有就是根本無法一眼知道他總收入究竟在那個段位,只知道很多,需要專心的數,才能知道,哦,,,嗦嘎,572.67億元,搶了他,立刻,馬上,現在就去:

clipboard.png

上面分享了兩種表達不友好的資料展示圖表,那怎麼才能更好的優化呢。下面我提供一下自己在做公司一個專案時的思路,關於具體實現可以自己摸索,但如果你們家的後端都為你計算好了單位,處理了前兩步,那你就只需要做最後一步了。關於為什麼不直接設定yaxis的min,max,spiktLine來控制間隔線及間隔,Echarts官方文件有這樣的回答:座標軸的分割段數,需要注意的是這個分割段數只是個預估值,最後實際顯示的段數會在這個基礎上根據分割後坐標軸刻度顯示的易讀程度作調整,關於操作interval來控制間隔,也有這樣一句提示:因為 splitNumber 是預估的值,實際根據策略計算出來的刻度可能無法達到想要的效果,這時候可以使用 interval 配合 min、max 強制設定刻度劃分,一般不建議使用

clipboard.png

地圖的應用

Echarts地圖,其可以設定為geo地圖引擎或百度地圖引擎,好像其他地圖也支援,只要你知道座標系的轉換關係。geo地圖由於部分資料不符合國家《測繪法》規定,目前暫時已經停止下載服務,不過你想找,還是能找到,比如Echarts github賬號下。地圖表面上在充當一個圖表的背景,實際上其更多的作用是作為一個座標系-經緯度座標系。關於Echarts geo地圖的使用,個人有幾點經驗分享一下:

  • 不同版本的js或則json地圖資料,呈現出來的效果差別很大,大到測試給你提bug的地步,比如下面兩幅圖所示,左邊圖的甘孜州名稱已經把自己的爪牙完全伸到雅安去了,而綿陽則像已經吞併了德陽,自己對比了一下資料,左圖的地圖json資料是壓縮過的,右圖是未壓縮的,但講道理的話,應該是這兩個json不是同一個版本:

clipboard.png

  • geo的設定的必要性,前面說過,geo其實存在的重要的作用是作為圖表座標系。所以當你的series存在多個系列需要在同一個座標系能設定資料,那設定geo是非常有必要的。但值得注意的是,一旦系列中設定了全域性geo為參考座標系,即指定了geoIndex,那麼series-map.map 屬性,以及 series-map.itemStyle 等樣式配置不再起作用,而是採用 geo 中的相應屬性;另外要強調的就是謹慎使用roam:true,最好設定一個縮放區間;
  • 如果涉及到政府專案,對邊界區域很敏感,則最好的選擇就是使用Bmap作為地圖座標系;

自定義系列

當時學了Echarts不久,看到Gallery上面一些炫酷的例項,自己也是想動手做了一個,可一看Echarts原始碼,一臉懵逼,後面又看了一下zRender及羨轍老師的水球圖,感覺入了點門,但離做出炫酷效果還是有些差距。直到最近發現4.0版本介紹了自定義系列,搗鼓半天,自己做了個偽3d填充,2d座標系的柱狀圖效果(載入動畫化花了點時間),感興趣的可以自己去研究一下:

clipboard.png

打個總結

感覺這個經驗分享帖,寫的越來越像Echarts宣傳貼了。掐指一算,自己做資料視覺化已經快一年了,但感覺就像入了個門,作為前端的一個分支,水一樣深。如果你對視覺化還沒有概念,推薦看一下螞蟻金服去年推出的G2,其作者也是前Echarts的作者,裡面講了更多視覺化圖表理論性的東西,G2視覺化基礎文件。為了有一個直觀的表現,自己用Vue搭了一個視覺化Demo,感興趣的可以留下你的郵箱。
順便打個賣身廣告:本人現在處於離職,如果哪位大神的公司需要找個搬磚的,請收下我的膝蓋,線上簡歷,座標成都。
本文首發於:http://closertb.site ,轉載請註明

相關文章