成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

聲明式與響應(yīng)式——前端新一代數(shù)據(jù)可視化方案

xuhong / 3204人閱讀

摘要:數(shù)據(jù)可視化圖表圖表作為數(shù)據(jù)可視化最常見(jiàn)的表現(xiàn)形式之一,往往被以偏概全的認(rèn)為圖表就是數(shù)據(jù)可視化。嚴(yán)格來(lái)說(shuō),數(shù)據(jù)可視化應(yīng)該是連接數(shù)據(jù)與視覺(jué)的一個(gè)映射關(guān)系,將數(shù)據(jù)映射成人更容易感知其規(guī)律的可視化結(jié)果。

題目中的“新一代”是個(gè)相對(duì)的概念,事實(shí)上本文即將介紹的方法已經(jīng)有了生產(chǎn)環(huán)境可用的實(shí)現(xiàn)方案(這也側(cè)面佐證了其可行性),但考慮到此方法與現(xiàn)在大部分前端項(xiàng)目中所使用的數(shù)據(jù)可視化方案相比仍有一些優(yōu)勢(shì),因此仍以“新一代”進(jìn)行描述。

前端生態(tài)中的幾座大山

在進(jìn)入主題之前,我們應(yīng)該先明確需要解決的問(wèn)題是什么。

當(dāng)我們進(jìn)行技術(shù)選型的時(shí)候,經(jīng)常會(huì)提到一個(gè)關(guān)鍵詞——周邊生態(tài),其中包含了社區(qū)活躍程度、項(xiàng)目穩(wěn)定性、代碼質(zhì)量、維護(hù)者身份等多個(gè)因素。這是因?yàn)楦玫纳鷳B(tài)圈意味著有更多的“最佳實(shí)踐”,這些實(shí)踐一方面指導(dǎo)我們?nèi)绾胃玫亻_(kāi)發(fā),另一方面也提供了很多現(xiàn)成可用的方案加速開(kāi)發(fā)。

當(dāng)技術(shù)發(fā)生整體性的躍進(jìn)時(shí)(例如vanilla javascript到j(luò)Query,jQuery到新一代前端框架等)往往伴隨著舊生態(tài)的廢棄與新生態(tài)的建立,在這個(gè)漫長(zhǎng)而煎熬的過(guò)程中我們發(fā)現(xiàn)有幾座大山總是新生態(tài)中最難被填補(bǔ)的短板:表單系統(tǒng)、數(shù)據(jù)可視化、復(fù)雜交互(如拖拽、手勢(shì)等),當(dāng)然也會(huì)有“舊大山”被移走(如兼容性問(wèn)題)以及“新大山”的出現(xiàn)(如數(shù)據(jù)流管理),但這些暫時(shí)不在本文討論范圍之內(nèi)。

在生態(tài)遷移的過(guò)程中也會(huì)出現(xiàn)一些連接新舊生態(tài)圈的過(guò)渡方案,但這些方案往往不能完美契合新技術(shù),因此注定無(wú)法成為“最佳實(shí)踐”。本文則將逐步講解在數(shù)據(jù)可視化領(lǐng)域內(nèi)我們?nèi)绾稳ヅf迎新,發(fā)揮新一代前端框架的最大威力。

數(shù)據(jù)可視化 VS 圖表

圖表作為數(shù)據(jù)可視化最常見(jiàn)的表現(xiàn)形式之一,往往被以偏概全的認(rèn)為圖表就是數(shù)據(jù)可視化。事實(shí)上數(shù)據(jù)可視化的概念極其寬泛,圖表只是它眾多表現(xiàn)形式的一個(gè)子集。嚴(yán)格來(lái)說(shuō),數(shù)據(jù)可視化應(yīng)該是連接數(shù)據(jù)與視覺(jué)的一個(gè)映射關(guān)系,將數(shù)據(jù)映射成人更容易感知其規(guī)律的可視化結(jié)果。

圖片摘自D3.js Gallery

我們也可以根據(jù)數(shù)據(jù)可視化與圖表的不同對(duì)過(guò)去的可視化方案進(jìn)行分類(僅列舉一些常見(jiàn)庫(kù)):

數(shù)據(jù)可視化 圖表
D3.js Highchart.js
- Echart.js
- Chart.js

即使你對(duì)以上表格中的JS庫(kù)完全沒(méi)概念也不用擔(dān)心,因?yàn)榻酉聛?lái)的內(nèi)容與它們關(guān)系并不大。

我們對(duì)這些JS庫(kù)的使用方式及實(shí)現(xiàn)方法分類后會(huì)發(fā)現(xiàn):圖表庫(kù)大多是通過(guò)“配置”的方式工作,用戶無(wú)法修改配置中沒(méi)有列出的部分,并且大部分的主流圖表庫(kù)基于Canvas實(shí)現(xiàn);而作為數(shù)據(jù)可視化類庫(kù)的佼佼者——D3.js則采用“數(shù)據(jù)驅(qū)動(dòng)”的工作方式,用戶自定義程度很高的同時(shí)伴隨著相對(duì)較多的代碼量,其大部分的實(shí)現(xiàn)則圍繞SVG展開(kāi)。

SVG VS Canvas

在上文中我們引出了前端可視化的兩種主流實(shí)現(xiàn)方式——SVG與Canvas,我們的“新一代方案”同樣需要從中做出選擇,因此我們要對(duì)兩者進(jìn)行一定的對(duì)比:

SVG Canvas
基于形狀 基于像素
每個(gè)基礎(chǔ)圖形對(duì)應(yīng)一個(gè)DOM元素 所有圖形最終只對(duì)應(yīng)同一個(gè)HTML標(biāo)簽
可通過(guò)JS和CSS控制 只能通過(guò)JS控制
抽象的事件模型 顆粒化的事件模型
大區(qū)域、少對(duì)象時(shí)性能較好 小區(qū)域、多對(duì)象時(shí)性能較好

通過(guò)以上的對(duì)比我們可以看到兩者在實(shí)現(xiàn)數(shù)據(jù)可視化時(shí)都沒(méi)有什么硬傷,性能差異在絕大部分?jǐn)?shù)據(jù)可視化場(chǎng)景中并不產(chǎn)生明顯的影響。

但由于Canvas的事件模型是顆粒化的(例如我們無(wú)法直接監(jiān)聽(tīng)某個(gè)圖形的點(diǎn)擊事件,而是需要判斷鼠標(biāo)點(diǎn)擊的坐標(biāo)是否“落在”該圖形內(nèi)來(lái)判斷),因此基于Canvas的實(shí)現(xiàn)方式往往伴隨著大量的底層代碼用于封裝一些常用方法,這也使得最終用戶層面上靈活性不足,只能通過(guò)繁多的配置來(lái)彌補(bǔ)。

服務(wù)于現(xiàn)代前端框架

之前的鋪墊都是為了最終的目的——服務(wù)于現(xiàn)代前端框架。我們暫時(shí)放下SVG與Canvas,先來(lái)看看這些前端框架的幾個(gè)共同優(yōu)點(diǎn),我們?cè)诂F(xiàn)在熱度較高的幾個(gè)框架——React、Angular、Vue的文檔中都可以找到這三個(gè)關(guān)鍵詞:

Declarative(聲明式)

Reactive(響應(yīng)式)

Component(組件化)

這三者都是這些框架能夠脫穎而出的立身之本,因此能夠充分發(fā)揮這幾大優(yōu)點(diǎn)的方案必然會(huì)很好的服務(wù)于這些框架。

橫向?qū)Ρ戎?,組件化對(duì)于數(shù)據(jù)可視化領(lǐng)域來(lái)說(shuō)不是什么新鮮的概念,所以我們著重在聲明式響應(yīng)式上做文章。

過(guò)渡方案

注意:從此處起我們將引用一些代碼作為示例,涉及框架時(shí)使用React作為代表,但對(duì)其它框架有一定理解的讀者可以很容易地進(jìn)行類比。

在文章的開(kāi)頭我們說(shuō)過(guò)在生態(tài)遷移的過(guò)程中會(huì)產(chǎn)生一些過(guò)渡方案,以下寫法就是一種常見(jiàn)的數(shù)據(jù)可視化過(guò)渡方案:

this.chart = new Highcharts[this.props.type || "Chart"](
  this.chartContainer,
  options,
);
// Just a wrapper of API!

在需要引入可視化圖形的組件的某個(gè)生命周期中初始化一個(gè)圖表,傳入對(duì)應(yīng)的DOM節(jié)點(diǎn)(通過(guò)ref之類的方式獲?。賹⒁恍┡渲庙?xiàng)對(duì)應(yīng)傳入,生成最終的結(jié)果。

這類過(guò)渡方案如注釋所寫,只是對(duì)API的一次再封裝,與聲明式、響應(yīng)式的設(shè)計(jì)思想難以結(jié)合,但因?yàn)檫w移/學(xué)習(xí)成本低這一優(yōu)勢(shì)也能幫助用戶快速完成需求。

嘗試數(shù)據(jù)驅(qū)動(dòng)

當(dāng)配置式的寫法不太靈時(shí)我們不妨看看數(shù)據(jù)驅(qū)動(dòng)的方式。以下是一段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);
/*

  
  
  

*/

拋開(kāi)較為特殊的data方法和enter方法不談(它們的作用可以簡(jiǎn)單理解為將數(shù)據(jù)遍歷),這是一段典型的“命令式”編程代碼:依次選擇DOM節(jié)點(diǎn)、附加元素(各種SVG圖形,示例中為rect即矩形)、為元素附上各種屬性。

盡管還是與我們想要的代碼有很大的區(qū)別,但與過(guò)渡方案相比卻有兩個(gè)明顯的亮點(diǎn):

和數(shù)據(jù)結(jié)合的更緊密,將數(shù)據(jù)解析成單個(gè)元素所需屬性的做法和現(xiàn)代框架很相似

最終生成的是一個(gè)多DOM節(jié)點(diǎn)結(jié)構(gòu),而現(xiàn)代框架一個(gè)共通點(diǎn)就是通過(guò)各種方法更好的處理DOM

基于框架改寫代碼

基于數(shù)據(jù)驅(qū)動(dòng)的寫法進(jìn)行改寫,我們可以寫出這樣的代碼:


  
  
  {data.map(item => )}

為了充分顯示前端框架的特點(diǎn),還以組件的形式添加了X軸、提示條等功能,還在Chart組件上展示了怎樣將屬性添加到元素上,最后通過(guò)ES6提供的解構(gòu)語(yǔ)法將數(shù)據(jù)中的屬性動(dòng)態(tài)的加在了對(duì)應(yīng)的元素上(其效果與x={item.x} y={item.y} width={item.width} height={item.height}一致)。

通過(guò)這樣的改寫,我們就將聲明式和響應(yīng)式的特點(diǎn)充分發(fā)揮,這也就意味著以下好處:

使用JavaScript的全部能力

更高的靈活性

更可讀、易懂的代碼

更好的性能(實(shí)時(shí)動(dòng)態(tài)數(shù)據(jù)可視化展示等場(chǎng)景)

如何應(yīng)對(duì)更復(fù)雜的場(chǎng)景

當(dāng)然不是所有的情況都和最基本的柱狀圖一樣簡(jiǎn)單,我們經(jīng)常需要繪制更復(fù)雜的可視化圖形,好在我們并不需要萬(wàn)丈高樓平地起,而是站在巨人的肩膀上更進(jìn)一步。

復(fù)雜的場(chǎng)景之所以復(fù)雜,是因?yàn)槲覀儫o(wú)法將SVG圖形簡(jiǎn)單的實(shí)現(xiàn)成目標(biāo)圖形,例如一個(gè)的折線圖我們就需要用元素“依次通過(guò)”各個(gè)坐標(biāo)點(diǎn)完成繪制。在這個(gè)場(chǎng)景里,有兩個(gè)比較明顯的需求:

將數(shù)據(jù)的屬性根據(jù)對(duì)應(yīng)的比例轉(zhuǎn)化成坐標(biāo)點(diǎn)的屬性

編寫一些方法用于動(dòng)態(tài)的生成元素所需的路徑屬性d

如果這樣基本的需求都要重新構(gòu)思,那么工作量無(wú)疑是巨大的,好在我們可以站在“巨人”——D3.js的肩膀上,學(xué)習(xí)它是如何實(shí)現(xiàn)這些方法的,甚至可以直接使用。

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(",")}
  />

以上代碼只是一個(gè)示例,用于說(shuō)明我們?nèi)绾谓Y(jié)合已有的工具更加輕松的解決問(wèn)題。

生態(tài)繼承

文中講解的這套解決方案之所以可行,也是因?yàn)樗梢院芎玫膶?shí)現(xiàn)對(duì)過(guò)去生態(tài)圈中已有成果的繼承,最大程度地復(fù)用各種輪子取長(zhǎng)補(bǔ)短。

我們將這套方案歸納為以下幾個(gè)步驟:

是否理解并掌握將要使用的框架的基本概念?如果沒(méi)做到,先去掌握框架本身。

對(duì)于SVG各種圖形元素的作用及屬性是否了解?如果不了解,可以通過(guò)文檔進(jìn)行基本的認(rèn)知。

對(duì)你需要處理的數(shù)據(jù)有可視化的思路嗎?如果沒(méi)思路,可以從龐大的社區(qū)中尋找靈感(例如D3.js的Gallery)。

實(shí)現(xiàn)過(guò)程中需要用到一些工具方法嗎?如果需要并且自己實(shí)現(xiàn)有困難,可以參考D3.js的API及對(duì)應(yīng)的實(shí)現(xiàn)方式。

需要復(fù)用或拓展?如需要,請(qǐng)充分發(fā)揮框架帶來(lái)的組件化開(kāi)發(fā)方式,并且細(xì)心的設(shè)計(jì)屬性接口。

完成對(duì)應(yīng)組件的開(kāi)發(fā)。

本文內(nèi)容整理自XSKY前端組組內(nèi)技術(shù)分享,轉(zhuǎn)載需著名出處。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/81054.html

相關(guān)文章

  • javascript功能插件大集合,寫前端的親們記得收藏

    摘要:一個(gè)專注于瀏覽器端和兼容的包管理器。一個(gè)整合和的最佳思想,使開(kāi)發(fā)者能快速方便地組織和編寫前端代碼的下一代包管理器。完全插件化的工具,能在中識(shí)別和記錄模式。健壯的優(yōu)雅且功能豐富的模板引擎。完整的經(jīng)過(guò)充分測(cè)試和記錄數(shù)據(jù)結(jié)構(gòu)的庫(kù)。 【導(dǎo)讀】:GitHub 上有一個(gè) Awesome – XXX 系列的資源整理。awesome-javascript 是 sorrycc 發(fā)起維護(hù)的 JS 資源列表...

    cfanr 評(píng)論0 收藏0
  • javascript功能插件大集合 前端常用插件 js常用插件

    摘要:轉(zhuǎn)載來(lái)源包管理器管理著庫(kù),并提供讀取和打包它們的工具。能構(gòu)建更好應(yīng)用的客戶端包管理器。一個(gè)整合和的最佳思想,使開(kāi)發(fā)者能快速方便地組織和編寫前端代碼的下一代包管理器。很棒的組件集合。隱秘地使用和用戶數(shù)據(jù)。 轉(zhuǎn)載來(lái)源:https://github.com/jobbole/aw... 包管理器管理著 javascript 庫(kù),并提供讀取和打包它們的工具。?npm – npm 是 javasc...

    Hydrogen 評(píng)論0 收藏0
  • javascript功能插件大集合 前端常用插件 js常用插件

    摘要:轉(zhuǎn)載來(lái)源包管理器管理著庫(kù),并提供讀取和打包它們的工具。能構(gòu)建更好應(yīng)用的客戶端包管理器。一個(gè)整合和的最佳思想,使開(kāi)發(fā)者能快速方便地組織和編寫前端代碼的下一代包管理器。很棒的組件集合。隱秘地使用和用戶數(shù)據(jù)。 轉(zhuǎn)載來(lái)源:https://github.com/jobbole/aw... 包管理器管理著 javascript 庫(kù),并提供讀取和打包它們的工具。?npm – npm 是 javasc...

    netmou 評(píng)論0 收藏0
  • JavaScript 資源大全中文版

    摘要:官網(wǎng)全新的靜態(tài)包管理器。官網(wǎng)一個(gè)整合和官網(wǎng)的最佳思想,使開(kāi)發(fā)者能快速方便地組織和編寫前端代碼的下一代包管理器。官網(wǎng)小巧的兼容的所見(jiàn)即所得的富文本編輯器。官網(wǎng)富文本編輯器。官網(wǎng)由制作,適用于每天寫作的富文本編輯器。 1. 包管理器 管理著 javascript 庫(kù),并提供讀取和打包它們的工具。 npm:npm 是 javascript 的包管理器。官網(wǎng) cnpm:cnpm 是 由于國(guó)...

    jzman 評(píng)論0 收藏0
  • GitHub 值得收藏的前端項(xiàng)目[每月更新...]

    摘要:也是一款優(yōu)秀的響應(yīng)式框架站點(diǎn)所使用的一套框架為微信服務(wù)量身設(shè)計(jì)的一套框架一組很小的,響應(yīng)式的組件,你可以在網(wǎng)頁(yè)的項(xiàng)目上到處使用一個(gè)可定制的文件,使瀏覽器呈現(xiàn)的所有元素,更一致和符合現(xiàn)代標(biāo)準(zhǔn)。 GitHub 值得收藏的前端項(xiàng)目 整理與收集的一些比較優(yōu)秀github項(xiàng)目,方便自己閱讀,順便分享出來(lái),大家一起學(xué)習(xí),本篇文章會(huì)持續(xù)更新,版權(quán)歸原作者所有。歡迎github star與fork 預(yù)...

    maxmin 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<