從0到1開發(fā)可視化數(shù)據(jù)大屏(上)

?前言:大數(shù)據(jù)時代,以大屏為載體的數(shù)據(jù)可視化需求日漸增多,數(shù)據(jù)大屏成為越來越多企業(yè)績效展示,報表展示,業(yè)務監(jiān)控等等的一種形式,大屏的上線帶來的是便捷,無需編碼,用戶可以直接將所要呈現(xiàn)的組件拖拽到畫布上,然后進行隨意配置和布局,所見及所得。前段時間我們上線了內(nèi)部的自己的可視化數(shù)據(jù)大屏 beta 版本
?
1 前期調(diào)研
?各云服務商也都推出自己的數(shù)據(jù)大屏整體解決方案,比如阿里云的 datav、騰訊云的騰訊云圖、網(wǎng)易的網(wǎng)易有數(shù)、百度的 Sugar,都在給自家產(chǎn)品賦能后推出自己的可視化方案,你可以會有疑惑 ??,別人有成熟的方案,為啥我們還要自己造輪子?無非一方面考慮的是業(yè)務場景的不同,雖然目前服務商已經(jīng)提供了很多業(yè)務場景的大屏模版供用戶選擇,其次是私有化部署成本高等等
?
1.1 調(diào)研對象
上一篇關于推薦幾個數(shù)據(jù)大屏可視化開發(fā)工具[1]提到目前國內(nèi)現(xiàn)有優(yōu)秀的數(shù)據(jù)大屏解決方案提供商
阿里云(DataV)??[2] 騰訊云(騰訊云圖(DataV)??[3] 網(wǎng)易有數(shù)(EasyScreen)??[4] 百度智能云(Sugar)??[5]
如果你對目前的報價好奇,下面是百度 Sugar 的報價

1.2 功能解析
調(diào)研并體驗了前面提到的解決方案,我對數(shù)據(jù)大屏功能進行了拆解,大概梳理了一個簡單的數(shù)據(jù)大屏可視化編輯所需要的功能包括如下

1.3 開源社區(qū)現(xiàn)有可視化編輯方案
?數(shù)據(jù)大屏 dashboard 本質(zhì)上跟 H5、Web 等在線頁面可視化編輯的邏輯是相同的,本質(zhì)上還是拖拽、控件管理、畫布、組件屬性管理、預覽等等,只是數(shù)據(jù)大屏強調(diào)的更多是數(shù)據(jù)的可視化,重點在圖表通過數(shù)據(jù)的渲染,下面分享幾個開源社區(qū)的可視化編輯解決方案,有需求的童鞋可以參考借鑒
?
luban(魯班 H5) ??[6]
h5-Dooring ??[7]
2.開發(fā)
上一節(jié)我們拆解了數(shù)據(jù)大屏的功能模塊,主要分為控件區(qū)域、畫布區(qū)域、控件屬性配置區(qū)域、圖層區(qū)管理等等幾個模塊,因為涉及內(nèi)部的隱私,我這里以網(wǎng)易有數(shù)為參照來做展示,大概模塊如下

2.1 控件區(qū)域
控件區(qū)域包括大屏控件的展示、控件組件的注冊與初始化,控件支持拖拽到畫布等功能,以下是控件區(qū)域的交互演示圖 ??
動態(tài)圖太大,只能改為靜態(tài)
2.1.1 圖表庫的選擇
在調(diào)研中,我們參考了魯班 h5 的可視化搭建,發(fā)現(xiàn)魯班使用了echart作為圖表控件的渲染圖表庫,可以看鏈接[8]
而我們在圖表庫的選型是使用螞蟻金服的 antv 的G2Plot??[9],而且 antv 也推出基于 G2Plot 的 AntV 在線圖表制作工具chartCube??[10],可以在線演示和預覽不同圖表數(shù)據(jù)渲染效果

其他諸如文本框、圖片、時間器等等控件都是自定義,如果想看源碼的童鞋可以參考 魯班 h5 的plugins??[11]
2.1.2 組件的注冊和初始化
舉個例子注冊一個文本控件,你可能說我可以這樣挨個配置啊,如下所示 ??
但是這種方式如果隨著后期維護的控件多了,導致在畫布中根據(jù)類型判斷渲染組件的時候,會有很多冗余代碼,這個時候我們可以用通過 vue 的is屬性動態(tài)渲染組件操作,如下所示

2.1.3 關于拖拽到畫布
關于控件的拖拽,使用的是vuedraggable 鏈接 ??[12],它是基于Sortable.js實現(xiàn)的 vue 拖拽插件, 實現(xiàn)如下
?? 拓展閱讀
2.2 畫布模塊
畫布是用來放置控件,作為控件拖拽拉伸的區(qū)域限制。畫布模塊設置背景圖片或背景色設置、控件的編排、畫布比例的設置、響應式畫布、全屏展示等等等。
2.2.1 響應式畫布
?? 編輯模式
當我們拉伸調(diào)整瀏覽器窗口視圖大小的時候,我們通過監(jiān)聽onresize事件,onresize 事件會在窗口或框架被調(diào)整大小時發(fā)生,一般畫布的比例設置大多以16:9或者4:3兩種比例居多, 我們看看下面這個效果


ps: 我們通過判斷是否在全屏展示模式下,如果不是,則給畫布視圖保留一部分空白區(qū)域
?? 預覽模式
編輯模式我們是允許可以有滾動條的出現(xiàn), 但預覽模式下的 dashboard 是用于展示,通常是不允許滾動條出現(xiàn)的。那這種場景我們?nèi)绾螌崿F(xiàn),我理想效果是無論窗口怎么變,我們的內(nèi)容都保持原來的比例,并盡量占滿窗口
我參考了這個方案: 大屏上的全屏頁面的自適應適配方案[13]
2.2.2 全屏展示
數(shù)據(jù)大屏最終的展現(xiàn)形式是全屏展示,本質(zhì)上就是只顯示畫布區(qū)域,隱藏所有編輯區(qū)域和配置區(qū)域,我們通過 isEdit來控制除畫布之外的其他區(qū)域的是否展示
如何對全屏事件監(jiān)聽
通過監(jiān)聽fullscreenchange事件,退出全屏則重新計算畫布視圖大小

ps: 出于安全考慮全屏只能從用戶操作的事件觸發(fā),而不能用代碼直接觸發(fā),會報錯
2.2.3 大屏快照
我們想給大屏生成一張圖片,而快照的生成,使用的是domtoimage??[14],可以將 code 轉(zhuǎn)化為圖片,同類工具還有html2canvas,對比中 domtoimage 無論在圖片質(zhì)量還是拓展方面都更勝一籌,下面是具體的使用

2.2.4 控件大小拖拽
?上一節(jié)我們提過,畫布其實是由控件區(qū)域拖拽構(gòu)成的,畫布中有我們自定義的控件,而這些控件應該是可以是自定義進行大小拖拽,我們 fork 了
?vue-draggable-resizable??[15],然后在它的基礎上做一些調(diào)整,當然你也可以自己造輪子。

使用如下 ??,包括其中一些 api 的使用
draggable: 用來識別是否為編輯模式,編輯模式控件不可移動dragstop: 監(jiān)聽控件拖拽結(jié)束,這個時候我們畫布中控件位置信息都改變了,這個時候需要跟右側(cè)工具欄數(shù)據(jù)同步,用來做更新工具攔表單數(shù)據(jù)resizstop: 縮放結(jié)束后再進行接口請求更新數(shù)據(jù)delete: 我們在 vue-draggable-resizable 原有基礎上添加的keyEvent事件用來判斷鍵盤的 delete 事件activated: 監(jiān)聽點擊控件,進行選中處理
2.2.5 畫布縮放
?控件支持縮放,畫布應該也是支持縮放的,我們定義 scale,可以進行操作改變其縮放數(shù)值,然后通過計算一個 zoomstyle 來改變畫布的屬性
?

3.1 控件配置區(qū)域
?控制配置區(qū)域分為兩個模塊,一個模塊是用來管理畫布中控件的屬性,其中包括高度、寬度、大小、字體大小、字體類型等等這些基礎屬性,像其他控件,文本有對齊方式、圖片有圖片上傳模塊、填充模式,時鐘有時間格式選擇等等,這里不一一羅列。本質(zhì)上是動態(tài)表單的一種配置,感興趣的童鞋可以看看之前的《前端那些事》從 0 到 1 開發(fā)動態(tài)表單[16],其次是數(shù)據(jù)管理
?
3.1.1 數(shù)據(jù)管理
?通常我們數(shù)據(jù)管理是用來配置控件諸如圖表的數(shù)據(jù),一般支持 json 靜態(tài)數(shù)據(jù)、csv 表格數(shù)據(jù)導入、api 接口動態(tài)配置。
?
下期跟大家聊聊關于數(shù)據(jù)管理如何實現(xiàn)、圖層是如何進行管理、以及使用中的一些心得體會.
