摘要:數據可視化圖表圖表作為數據可視化最常見的表現形式之一,往往被以偏概全的認為圖表就是數據可視化。嚴格來說,數據可視化應該是連接數據與視覺的一個映射關系,將數據映射成人更容易感知其規律的可視化結果。
前端生態中的幾座大山題目中的“新一代”是個相對的概念,事實上本文即將介紹的方法已經有了生產環境可用的實現方案(這也側面佐證了其可行性),但考慮到此方法與現在大部分前端項目中所使用的數據可視化方案相比仍有一些優勢,因此仍以“新一代”進行描述。
在進入主題之前,我們應該先明確需要解決的問題是什么。
當我們進行技術選型的時候,經常會提到一個關鍵詞——周邊生態,其中包含了社區活躍程度、項目穩定性、代碼質量、維護者身份等多個因素。這是因為更好的生態圈意味著有更多的“最佳實踐”,這些實踐一方面指導我們如何更好地開發,另一方面也提供了很多現成可用的方案加速開發。
當技術發生整體性的躍進時(例如vanilla javascript到jQuery,jQuery到新一代前端框架等)往往伴隨著舊生態的廢棄與新生態的建立,在這個漫長而煎熬的過程中我們發現有幾座大山總是新生態中最難被填補的短板:表單系統、數據可視化、復雜交互(如拖拽、手勢等),當然也會有“舊大山”被移走(如兼容性問題)以及“新大山”的出現(如數據流管理),但這些暫時不在本文討論范圍之內。
在生態遷移的過程中也會出現一些連接新舊生態圈的過渡方案,但這些方案往往不能完美契合新技術,因此注定無法成為“最佳實踐”。本文則將逐步講解在數據可視化領域內我們如何去舊迎新,發揮新一代前端框架的最大威力。
數據可視化 VS 圖表圖表作為數據可視化最常見的表現形式之一,往往被以偏概全的認為圖表就是數據可視化。事實上數據可視化的概念極其寬泛,圖表只是它眾多表現形式的一個子集。嚴格來說,數據可視化應該是連接數據與視覺的一個映射關系,將數據映射成人更容易感知其規律的可視化結果。
圖片摘自D3.js Gallery
我們也可以根據數據可視化與圖表的不同對過去的可視化方案進行分類(僅列舉一些常見庫):
數據可視化 | 圖表 |
---|---|
D3.js | Highchart.js |
- | Echart.js |
- | Chart.js |
即使你對以上表格中的JS庫完全沒概念也不用擔心,因為接下來的內容與它們關系并不大。
我們對這些JS庫的使用方式及實現方法分類后會發現:圖表庫大多是通過“配置”的方式工作,用戶無法修改配置中沒有列出的部分,并且大部分的主流圖表庫基于Canvas實現;而作為數據可視化類庫的佼佼者——D3.js則采用“數據驅動”的工作方式,用戶自定義程度很高的同時伴隨著相對較多的代碼量,其大部分的實現則圍繞SVG展開。
SVG VS Canvas在上文中我們引出了前端可視化的兩種主流實現方式——SVG與Canvas,我們的“新一代方案”同樣需要從中做出選擇,因此我們要對兩者進行一定的對比:
SVG | Canvas |
---|---|
基于形狀 | 基于像素 |
每個基礎圖形對應一個DOM元素 | 所有圖形最終只對應同一個HTML標簽 |
可通過JS和CSS控制 | 只能通過JS控制 |
抽象的事件模型 | 顆粒化的事件模型 |
大區域、少對象時性能較好 | 小區域、多對象時性能較好 |
通過以上的對比我們可以看到兩者在實現數據可視化時都沒有什么硬傷,性能差異在絕大部分數據可視化場景中并不產生明顯的影響。
但由于Canvas的事件模型是顆粒化的(例如我們無法直接監聽某個圖形的點擊事件,而是需要判斷鼠標點擊的坐標是否“落在”該圖形內來判斷),因此基于Canvas的實現方式往往伴隨著大量的底層代碼用于封裝一些常用方法,這也使得最終用戶層面上靈活性不足,只能通過繁多的配置來彌補。
服務于現代前端框架之前的鋪墊都是為了最終的目的——服務于現代前端框架。我們暫時放下SVG與Canvas,先來看看這些前端框架的幾個共同優點,我們在現在熱度較高的幾個框架——React、Angular、Vue的文檔中都可以找到這三個關鍵詞:
Declarative(聲明式)
Reactive(響應式)
Component(組件化)
這三者都是這些框架能夠脫穎而出的立身之本,因此能夠充分發揮這幾大優點的方案必然會很好的服務于這些框架。
橫向對比之下,組件化對于數據可視化領域來說不是什么新鮮的概念,所以我們著重在聲明式與響應式上做文章。
過渡方案注意:從此處起我們將引用一些代碼作為示例,涉及框架時使用React作為代表,但對其它框架有一定理解的讀者可以很容易地進行類比。
在文章的開頭我們說過在生態遷移的過程中會產生一些過渡方案,以下寫法就是一種常見的數據可視化過渡方案:
this.chart = new Highcharts[this.props.type || "Chart"]( this.chartContainer, options, ); // Just a wrapper of API!
在需要引入可視化圖形的組件的某個生命周期中初始化一個圖表,傳入對應的DOM節點(通過ref之類的方式獲取),再將一些配置項對應傳入,生成最終的結果。
這類過渡方案如注釋所寫,只是對API的一次再封裝,與聲明式、響應式的設計思想難以結合,但因為遷移/學習成本低這一優勢也能幫助用戶快速完成需求。
嘗試數據驅動當配置式的寫法不太靈時我們不妨看看數據驅動的方式。以下是一段D3.js繪制柱狀圖的代碼:
const svg = d3.select("svg"); svg.selectAll(".bar") .data(data) .enter() .append("rect") .attr("class", "bar") .attr("x", d => d.x) .attr("y", d => d.y) .attr("width", d => d.width) .attr("height", d => d.height); /*
拋開較為特殊的data方法和enter方法不談(它們的作用可以簡單理解為將數據遍歷),這是一段典型的“命令式”編程代碼:依次選擇DOM節點、附加元素(各種SVG圖形,示例中為rect即矩形)、為元素附上各種屬性。
盡管還是與我們想要的代碼有很大的區別,但與過渡方案相比卻有兩個明顯的亮點:
和數據結合的更緊密,將數據解析成單個元素所需屬性的做法和現代框架很相似
最終生成的是一個多DOM節點結構,而現代框架一個共通點就是通過各種方法更好的處理DOM
基于框架改寫代碼基于數據驅動的寫法進行改寫,我們可以寫出這樣的代碼:
{data.map(item => )}
為了充分顯示前端框架的特點,還以組件的形式添加了X軸、提示條等功能,還在Chart組件上展示了怎樣將屬性添加到元素上,最后通過ES6提供的解構語法將數據中的屬性動態的加在了對應的
通過這樣的改寫,我們就將聲明式和響應式的特點充分發揮,這也就意味著以下好處:
使用JavaScript的全部能力
更高的靈活性
更可讀、易懂的代碼
更好的性能(實時動態數據可視化展示等場景)
如何應對更復雜的場景當然不是所有的情況都和最基本的柱狀圖一樣簡單,我們經常需要繪制更復雜的可視化圖形,好在我們并不需要萬丈高樓平地起,而是站在巨人的肩膀上更進一步。
復雜的場景之所以復雜,是因為我們無法將SVG圖形簡單的實現成目標圖形,例如一個的折線圖我們就需要用
將數據的屬性根據對應的比例轉化成坐標點的屬性
編寫一些方法用于動態的生成
如果這樣基本的需求都要重新構思,那么工作量無疑是巨大的,好在我們可以站在“巨人”——D3.js的肩膀上,學習它是如何實現這些方法的,甚至可以直接使用。
import { lineTo, moveTo, closePath } from "path"; import { linearScale } from "scale"; const d = [moveTo(0, height)]; const xScale = linearScale([0, width], [minX, maxX]); const yScale = linearScale([0, height], [minY, maxY]);lineTo(xScale(item.x), yScale(item.y))) .concat([ lineTo(item[item.length -1].x, height), moveTo(0, height), closePath() ]) ).join(",")} />
以上代碼只是一個示例,用于說明我們如何結合已有的工具更加輕松的解決問題。
生態繼承文中講解的這套解決方案之所以可行,也是因為它可以很好的實現對過去生態圈中已有成果的繼承,最大程度地復用各種輪子取長補短。
我們將這套方案歸納為以下幾個步驟:
是否理解并掌握將要使用的框架的基本概念?如果沒做到,先去掌握框架本身。
對于SVG各種圖形元素的作用及屬性是否了解?如果不了解,可以通過文檔進行基本的認知。
對你需要處理的數據有可視化的思路嗎?如果沒思路,可以從龐大的社區中尋找靈感(例如D3.js的Gallery)。
實現過程中需要用到一些工具方法嗎?如果需要并且自己實現有困難,可以參考D3.js的API及對應的實現方式。
需要復用或拓展?如需要,請充分發揮框架帶來的組件化開發方式,并且細心的設計屬性接口。
完成對應組件的開發。
本文內容整理自XSKY前端組組內技術分享,轉載需著名出處。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/81054.html
摘要:一個專注于瀏覽器端和兼容的包管理器。一個整合和的最佳思想,使開發者能快速方便地組織和編寫前端代碼的下一代包管理器。完全插件化的工具,能在中識別和記錄模式。健壯的優雅且功能豐富的模板引擎。完整的經過充分測試和記錄數據結構的庫。 【導讀】:GitHub 上有一個 Awesome – XXX 系列的資源整理。awesome-javascript 是 sorrycc 發起維護的 JS 資源列表...
摘要:轉載來源包管理器管理著庫,并提供讀取和打包它們的工具。能構建更好應用的客戶端包管理器。一個整合和的最佳思想,使開發者能快速方便地組織和編寫前端代碼的下一代包管理器。很棒的組件集合。隱秘地使用和用戶數據。 轉載來源:https://github.com/jobbole/aw... 包管理器管理著 javascript 庫,并提供讀取和打包它們的工具。?npm – npm 是 javasc...
摘要:轉載來源包管理器管理著庫,并提供讀取和打包它們的工具。能構建更好應用的客戶端包管理器。一個整合和的最佳思想,使開發者能快速方便地組織和編寫前端代碼的下一代包管理器。很棒的組件集合。隱秘地使用和用戶數據。 轉載來源:https://github.com/jobbole/aw... 包管理器管理著 javascript 庫,并提供讀取和打包它們的工具。?npm – npm 是 javasc...
摘要:官網全新的靜態包管理器。官網一個整合和官網的最佳思想,使開發者能快速方便地組織和編寫前端代碼的下一代包管理器。官網小巧的兼容的所見即所得的富文本編輯器。官網富文本編輯器。官網由制作,適用于每天寫作的富文本編輯器。 1. 包管理器 管理著 javascript 庫,并提供讀取和打包它們的工具。 npm:npm 是 javascript 的包管理器。官網 cnpm:cnpm 是 由于國...
摘要:也是一款優秀的響應式框架站點所使用的一套框架為微信服務量身設計的一套框架一組很小的,響應式的組件,你可以在網頁的項目上到處使用一個可定制的文件,使瀏覽器呈現的所有元素,更一致和符合現代標準。 GitHub 值得收藏的前端項目 整理與收集的一些比較優秀github項目,方便自己閱讀,順便分享出來,大家一起學習,本篇文章會持續更新,版權歸原作者所有。歡迎github star與fork 預...
閱讀 1980·2021-11-25 09:43
閱讀 664·2021-10-11 10:58
閱讀 1736·2019-08-30 15:55
閱讀 1735·2019-08-30 13:13
閱讀 746·2019-08-29 17:01
閱讀 1848·2019-08-29 15:30
閱讀 804·2019-08-29 13:49
閱讀 2181·2019-08-29 12:13