国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

xuhong / 3163人閱讀

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

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

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

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

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

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

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

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

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

圖片摘自D3.js Gallery

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

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

即使你對以上表格中的JS庫完全沒概念也不用擔(dān)心,因為接下來的內(nèi)容與它們關(guān)系并不大。

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

SVG VS Canvas

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

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

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

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

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

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

Declarative(聲明式)

Reactive(響應(yīng)式)

Component(組件化)

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

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

過渡方案

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

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

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

在需要引入可視化圖形的組件的某個生命周期中初始化一個圖表,傳入對應(yīng)的DOM節(jié)點(通過ref之類的方式獲取),再將一些配置項對應(yīng)傳入,生成最終的結(jié)果。

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

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

當(dāng)配置式的寫法不太靈時我們不妨看看數(shù)據(jù)驅(qū)動的方式。以下是一段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方法不談(它們的作用可以簡單理解為將數(shù)據(jù)遍歷),這是一段典型的“命令式”編程代碼:依次選擇DOM節(jié)點、附加元素(各種SVG圖形,示例中為rect即矩形)、為元素附上各種屬性。

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

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

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

基于框架改寫代碼

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


  
  
  {data.map(item => )}

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

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

使用JavaScript的全部能力

更高的靈活性

更可讀、易懂的代碼

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

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

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

復(fù)雜的場景之所以復(fù)雜,是因為我們無法將SVG圖形簡單的實現(xiàn)成目標(biāo)圖形,例如一個的折線圖我們就需要用元素“依次通過”各個坐標(biāo)點完成繪制。在這個場景里,有兩個比較明顯的需求:

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

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

如果這樣基本的需求都要重新構(gòu)思,那么工作量無疑是巨大的,好在我們可以站在“巨人”——D3.js的肩膀上,學(xué)習(xí)它是如何實現(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(",")}
  />

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

生態(tài)繼承

文中講解的這套解決方案之所以可行,也是因為它可以很好的實現(xiàn)對過去生態(tài)圈中已有成果的繼承,最大程度地復(fù)用各種輪子取長補(bǔ)短。

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

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

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

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

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

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

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

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

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

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/81054.html

相關(guān)文章

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

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

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

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

    netmou 評論0 收藏0
  • javascript功能插件大集合 前端常用插件 js常用插件

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

    Hydrogen 評論0 收藏0
  • JavaScript 資源大全中文版

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

    jzman 評論0 收藏0
  • GitHub 值得收藏的前端項目[每月更新...]

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

    maxmin 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<