首先介紹下背景:最近,接到一個任務,将資料可視化展示出來。項目是基于Vue的,開搞呗,安裝echarts庫。。。按照官方的說明文檔,開始實作,效果如下:
看着好像也沒啥問題。
想多了,從上圖中,還不能看出資料大小的明顯差異,但到了測試環境,由于資料的差異過大,有的是個數級别的,有的是百萬級别的,結果就導緻了那些個資料較小的柱子基本看不出來,高度太低(因為echarts是根據資料的大小配置設定高度的)。沒辦法,查了一圈官方文檔也沒啥眉目,就百度了下,看到了 “資料映射”關鍵詞,開始動手實作第一步:先将y軸等分成幾份(這裡是5等分),然後設定最小值(這裡設定成0),由于資料是接口傳回的,這裡最大值不設定,由庫自己定,然後自定義y軸的刻度标簽顯示:
yAxis: { type: 'value', min: 0, splitLine: { show: false }, interval: this.interval, axisLabel: { formatter: (v, ix) => { if (this.max <= this.boundary) { return v } else { let vl switch (ix) { case 0: vl = this.ylabel[0] break case 1: vl = this.ylabel[1] break case 2: vl = this.ylabel[2] break case 3: vl = this.ylabel[3] break case 4: vl = this.ylabel[4] break case 5: vl = this.ylabel[5] break } return vl } } }}
interval是強制設定坐标軸分割間隔,因為我是五等分y軸,是以這裡的interval值是0.2倍最大值(最大值在第二步中會擷取并存在data中),這裡的刻度值我是按照[0,10,0.1max,0.2max,0.5max,max]設定,需要說明的是,這裡的刻度标簽僅僅是展示變了,實際上其代表的值沒變,是以需要資料映射。
第二步:y軸設定好了之後,就開始關鍵的資料映射了,簡單了解就是将原始資料通過計算變成可以分布在處理過的y軸上的資料,
// 資料映射處理if (this.max > this.boundary) { drt = rt.map(el => { return el.map((elv, elix) => { if (elix == 0) { return elv } else if (elv >= this.ylabel[0] && elv <= this.ylabel[1]) { return (elv / this.ylabel[1]) * this.interval } else if (elv > this.ylabel[1] && elv <= this.ylabel[2]) { return (elv / this.ylabel[2]) * this.interval + this.interval } else if (elv > this.ylabel[2] && elv <= this.ylabel[3]) { return (elv / this.ylabel[3]) * this.interval + this.interval * 2 } else if (elv > this.ylabel[3] && elv <= this.ylabel[4]) { return (elv / this.ylabel[4]) * this.interval + this.interval * 3 } else { return (elv / this.ylabel[5]) * this.interval + this.interval * 4 } }) }) return drt}
這裡要注意儲存處理前的資料,即實際資料,到此,圖表即可滿足需求
和之前的對比,可以看出,數值較小時,也能明顯展示,不足的是,滑鼠放在柱子上的提示框會展示處理之後的資料,即非實際資料,是以我們需要将提示框展示的資料處理下。第三步:設定tooltip
tooltip: { formatter: params => { if (this.max <= this.boundary) { return `${params.seriesName}${params.name}:${params.data[params.seriesIndex + 1]}` } else { const va = this.od[params.dataIndex][params.seriesIndex + 1] return `${params.seriesName}${params.name}:${va}` } }}
這裡使用之前儲存的原始資料,這樣就不用因為反計算導緻精度有差異了。
搞定!