在歷經兩年多的迭代後,Odeon大數據平臺在底層能力建設上已經至關豐滿。最近大半年來在數據可視化方面也投入了很大的精力,目前自助 BI 產品也已經成功上線並穩定運行了一段時間,今天小劇就來分享下咱們在數據可視化中的一些經驗。git
今天的分享主要圍繞 可視化佈局模塊 的一些工做,佈局模塊是承載可視化圖表的一塊畫布,是用戶用來組織業務邏輯的重要手段之一。先來體驗下 在線demo 或者看下面的效果圖:github
圖一:可視化佈局模塊效果圖dom
其實不論是在數據可視化,仍是在一些自助發佈的運營平臺,自助佈局一直是一個難以跳過的問題。在項目開始之初這個問題也一樣在困擾着咱們,是咱們開發幾套預置模版讓用戶挑選,仍是開發一套讓用戶可拖拽配置的佈局模塊?佈局
前者實現上很是簡單,也很容易設計的很是精美,可是缺乏了不少靈活性,很容易千篇一概。後者用戶在使用上自由度很是高,能夠拖拽出更符合本身預期的界面,可是開發成本相對較高,而且想要達到穩定、易用、高輔助性卻比較難。性能
綜合考慮上面的這些問題,咱們對制定的幾套方案均不滿意,最終仍是決定本身動手實現一個能夠輔助用戶進行拖拽佈局的組件。大數據
通過設計,咱們對交互模型作了梳理,設計了卡片、圖表兩層結構。在此基礎上對數據模型作了總體設計,結合上面效果圖和 在線 demo 能夠更加容易理解下面的劃分。設計
首先是局部範圍內單例的 Map 類,用來描述整個 dashboard 佈局,以及其餘數據存儲。3d
其次是 Widget 類,用來定義卡片信息,包含卡片的尺寸、位置信息,以及更詳細的卡片標題、卡片類型、腳註、圖表ID 等信息。code
最後是 Chart 類,用來定義圖表信息。爲了佈局與圖表模型分離,這裏的圖表信息放置較少,僅僅存儲了必要的 id 等字段,圖表自己實現由外部 slot 插槽來完成。cdn
圖二:數據模型
數據模型構建好了,接下來就是着手設計拖拽交互了。
出於響應式考慮,同時爲了減小用戶操做的隨意性,在佈局設計上咱們放棄了像素單位,而是針對節點尺寸設計了虛擬的 12 柵格切分,在初始化、縮放、移動時都嚴格參照此柵格佈局。
爲了保障用戶拖拽體驗的順暢,使佈局保持整齊,咱們在遵循卡片自動調整邏輯的基礎上,設計了卡片的重繪流程,這一點在後面會有詳細的介紹。
爲了提供更好的拖拽體驗,咱們額外設計了虛擬卡片用來輔助用戶進行佈局,用戶隨時能夠預覽鬆開鼠標後卡片處在的位置及大小,效果以下圖陰影處所示。
圖三:拖拽預覽效果圖
有上面的數據模型設計,其實一大半的困難已經被解決了。難點主要體如今輔助佈局過程當中易用性上的一些處理,總結下來有如下幾點。
其實單純的碰撞檢測是很容易解決的,畢竟全部卡片只是二維矩形而已,這一點並非難事,困難的是碰撞後被接觸的卡片須要騰出位置進行讓位,咱們須要找到全部被碰撞到的卡片,以及受此卡片影響的全部後續卡片,這是一個較爲困難的點。
圖四:碰撞檢測佈局重繪過程
在設計佈局的過程當中,用戶可能會把卡片拖得七零八落,並且在上面提到的碰撞檢測的處理過程當中,也會致使相鄰卡片受影響。初期的交互在體驗後發現,拖拽過程當中用戶須要花很長時間來從新整理佈局,所以爲了保證佈局排列緊密,必需要有一個方法,可以將全部處於懸空狀態的卡片依序吸頂處理。
圖五:自動吸頂佈局重繪過程
上面提到的這兩個困難點,在移動、縮放這兩個拖拽交互中都存在,而且邏輯上是一致的,所以在拖拽佈局過程當中咱們抽象出了一套重繪邏輯,按順序整理以下:
由於拖拽須要實時預覽效果,上面這四步重繪邏輯會被頻繁觸發。爲了不在佈局過程當中反覆污染真實的位置數據,咱們爲卡片位置咱們引入了 previewOffset
字段,用來存放預覽效果時的垂直偏移量。
可能會有同窗會產生一個疑問:這裏是業務上的重繪邏輯,如此高密度的修改數據會不會在性能上表現比較差 ?
其實這個問題的解決得益於 Widget 類 的數據模型設計,在從碰撞檢測到自動吸頂等一系列處理過程當中,被頻繁計算、修改的僅僅爲相對單位的 position
對象,而界面佈局使用的是絕對單位的 screenPosition
對象。數據與表現是分離的,僅當一個重繪流程結束以後纔去觸發 screenPosition
的更新,如此設計使得界面更新節奏更可控,界面更穩定,避免了視覺上卡片位置的閃爍的問題。
按照此重繪邏輯,既避免了 dom 層冗餘的重繪開銷,提升了總體性能,又在界面佈局的易用性上獲得大大提高,操做體驗上也更加穩定、流暢。
本文主要從可視化佈局模塊的交互邏輯的設計上展開,並未涉及到具體代碼實現,做爲 Odeon 大數據平臺在可視化佈局模塊的一些思路,相信經過本文您已經有了初步的瞭解。
若是您對文中提到的碰撞檢測、讓位處理、吸頂效果以及輔助佈局中等具體實現細節感興趣,歡迎私下進行探討,可能的話我會另開一篇文章詳細展開來聊。