數(shù)據(jù)可視化在滴滴的應(yīng)用

桔妹導讀:現(xiàn)代的數(shù)據(jù)可視化產(chǎn)品相較于之前的儀表盤應(yīng)用,在數(shù)據(jù)方面呈現(xiàn)更加生動、數(shù)據(jù)實時性高、交互更為友好、效果更加震撼等特點,越來越多的人傾向于通過各類可視化產(chǎn)品使靜態(tài)的數(shù)據(jù)“活”起來。基于此背景,我們結(jié)合滴滴的各業(yè)務(wù)線發(fā)展,打造了本文介紹的數(shù)據(jù)可視化大屏產(chǎn)品。
1.
前言

隨著技術(shù)的發(fā)展,更多的人不滿足于使用基礎(chǔ)的圖表來展示數(shù)據(jù),如何讓數(shù)據(jù)更直觀、更炫酷的展示成為了大家的追求。為了能更好的展示滴滴各業(yè)務(wù)線的發(fā)展,本文介紹的數(shù)據(jù)可視化大屏從城市、全國和全球維度展示了業(yè)務(wù)線的實時信息,下面將從基礎(chǔ)地圖的構(gòu)建、軌跡、氣泡、熱力、飛線、散點六個方面來講述一下開發(fā)中遇到的難題及解決方案。

1)地圖的一次性加載,考慮到易用性和維護性,需自研一套地圖框架;
2)大量數(shù)據(jù)涉及到的性能問題,包含數(shù)據(jù)的計算、傳輸和實時渲染;
3)數(shù)據(jù)業(yè)務(wù)方較多,接口穩(wěn)定性和維護性問題;
4)可視化還原度;
1)自研地圖框架map3;
2)將數(shù)據(jù)計算移到后端,對數(shù)據(jù)進行壓縮,同時在大量數(shù)據(jù)的傳輸方面采用ArrayBuffer。盡量減輕GPU和CPU的壓力,提高頁面流暢度。
3)因為數(shù)據(jù)大屏對數(shù)據(jù)的依賴性較強,為了保障展示的穩(wěn)定性,對數(shù)據(jù)采取了緩存兜底方案;
4)通過開發(fā)調(diào)試面板,降低與設(shè)計師溝通的成本,為提高可視化還原度提供了便利。


const map3 = new Map3({container: string | HTMLElement;style: Style;center?: number[];pitch?: number;bearing?: number;zoom?: number;controller?: boolean;hash?: boolean;});

最后說下項目中對geobuf的改進。主要包含以下兩點:
1)因為項目中繪制的區(qū)域相對較小,例如杭州,范圍在東經(jīng)118°21′-120°30′,北緯29°11′-30°33′ °,這樣對于每一條LineString或者polygon的首個點來說,存儲全部的數(shù)值也存在一些浪費,于是我們在計算前加入了一個減法計算,將所有的經(jīng)緯度減去一組數(shù)值,例如上面的例子中,減去[120, 30],這樣數(shù)值將變?yōu)閇[7045, 20248], [1, -22], [-1, -9]...],首個點的數(shù)值更小了,所需要的字節(jié)數(shù)也更少了(這一步雖然減小了一點數(shù)據(jù)量,但失去了靈活性,需要權(quán)衡利弊)。
2)地圖繪制都存在投影計算,我們將投影計算放在了encode的代碼中,瀏覽器接收到數(shù)據(jù)decode后可以直接使用,這步可以減小瀏覽器的計算,節(jié)省cpu和計算時間的開支。

▍4.可視化還原

圖3.4 數(shù)據(jù)大屏設(shè)計稿



這部分主要介紹的是上圖長軌跡的實時繪制,同時這也是影響性能的很重要的一部分。正式展開敘述之前先看下需求是怎樣的。如動圖中所示,需要獲取實時軌跡數(shù)據(jù)在前端進行展示,軌跡需要流動起來,且在地圖視野拉近(近看城市)時運動變慢、軌跡變細,在地圖視野拉遠時(俯視北京全城)運動變快、軌跡變粗。效果要反映真實的訂單情況,所以數(shù)據(jù)需要實時更新。下面從幾個重要的點來展開介紹。






上圖展示了著色器的相關(guān)限制,與紋理相關(guān)的部分限制了片元著色器的紋理單元數(shù)量不超過16個,這就意味著如果我們將每個氣泡單獨繪制在一個canvas上,至多只能繪制16種類型的氣泡,當然這對于我們當前的業(yè)務(wù)場景也是夠用的,但是容量天花板相對較低。假設(shè)我們一個紋理單元繪制兩種氣泡,最多可繪制32種,以此類推。同時需要注意一下單個紋理單元的最大限制是16384,假設(shè)一張圖片的大小是200*200,那么一個紋理單元最多容納6561張圖片。如果我們繪制的范圍超過該限制,即要添加新的紋理單元,所以要注意邊界判斷。


時間范圍
可以展示過去一分鐘、十分鐘、一小時等任意時間間隔內(nèi)的熱力情況。
半徑大小
可以以任意距離為單位,該范圍內(nèi)的訂單數(shù)對應(yīng)的色階上的顏色即為該范圍的熱力圖顏色。 色階
熱力圖的顏色是可調(diào)的。


▍2.映射熱力圖
▍3.調(diào)試工具
在調(diào)試過程中,因為燈光和屏幕的分辨率等因素導致最終在大屏上展示的效果和在臺式機上的效果還是有一些差別的,加之設(shè)計師側(cè)也不方便準確的描述差異,例如紅色淡一些這些想象空間很大的描述,所以溝通之后開放了上圖所示的半徑和四種顏色的調(diào)試接口,方便設(shè)計師現(xiàn)場實時查看熱力圖的改動效果。
為了加快調(diào)參時熱力圖的響應(yīng),同時減少計算量,我們對原本的熱力圖代碼做了一些修改。原來代碼里和重繪有關(guān)的方法是repaint方法,但是調(diào)用該方法觸發(fā)的操作是全部重新繪制,包括灰度圖、線性色譜和熱力圖等。當我們只改變顏色時,是線性色譜發(fā)生改變從而著色時影響最終的熱力圖,灰度圖并沒有改變,所以我們添加了recolor方法,調(diào)試顏色時不會重繪灰度圖。但是,如果改變了半徑范圍,還是需要調(diào)用原本的repaint方法,全部重新繪制。
▍4.參數(shù)解讀


7.
飛線



1)取點


的曲線采用了不同于三維三次貝塞爾曲線的方法,使用的是CatmullRomCurve3,即使用Catmull-Rom算法, 從一系列的點創(chuàng)建一條平滑的三維樣條曲線,不僅限于兩個控制點。我們采取的方案是根據(jù)起點和終點的經(jīng)緯度差值、地球的半徑和曲線最高點對應(yīng)的半徑進行插值計算,得到20個插值點的坐標,將這20個點傳入CatmullRomCurve3中生成曲線,并利用其提供的getPoints方法得到曲線上的100個點用于繪制。2)紋理映射
上一步我們獲取的100個點是描繪一條完整曲線的全部點,但是從圖7.1(b)中可以看出,飛線在飛的過程中展示的是完整的紋理,但是飛線長度只占總長度的1/3。如果按照正常的映射的話應(yīng)該是完整的紋理對應(yīng)完整的曲線,所以在飛的過程中應(yīng)該只展示對應(yīng)的紋理部分。那么如何實現(xiàn)動圖中的效果呢?
第一反應(yīng)就是改變頂點坐標,例如第一次render第0~30個點的范圍,第二次render第10~40個點的范圍,以此類推。效果確實是實現(xiàn)了,但是性能上有問題,由于頻繁的更換頂點導致了頁面的卡頓。
想到的第二種方案就是100個點全部繪制,在render的過程中z不斷變換頂點對應(yīng)的uv坐標。例如開始是第0~30個對應(yīng)的uv坐標從0~1,下一次是第10~40個點對應(yīng)的uv坐標從0~1,以此類推可以滿足1/3長度的飛線展示完整的紋理,且不斷移動。在這里還有個優(yōu)化,一開始是在每次render的時候去遍歷uv數(shù)組更改每個點對應(yīng)的值,但是遍歷數(shù)組也是耗性能的,特別是當數(shù)據(jù)量大的時候,后來是將一個常數(shù)傳進了shader中用于計算每個點此時的uv坐標,每次render都會改變這個數(shù),同時同步到shader中。
8.
散點 
平時我們用靜態(tài)的散點比較多,這種實現(xiàn)很簡單。但當展示的信息量不是很豐滿時就顯得頁面有些空洞,這時候就需要添加動態(tài)呼吸的散點,讓頁面看起來更熱鬧。我們在散點大小變化的過程中對應(yīng)的改變其透明度,產(chǎn)生漸隱漸現(xiàn)的呼吸效果,同時我們可以隨機點出現(xiàn)的位置,讓效果看起來更靈動。
9.
結(jié)語 
以上就是在全業(yè)務(wù)之城開發(fā)過程中的一些總結(jié)和思考,日后在不斷開發(fā)數(shù)據(jù)可視化大屏的同時,我們也會加速沉淀通用組件庫和搭建平臺。 
·················END················· 推薦閱讀
歡迎長按掃碼關(guān)注「數(shù)據(jù)管道」



推薦閱讀
歡迎長按掃碼關(guān)注「數(shù)據(jù)管道」
