1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        可視化圖表實現(xiàn)揭秘

        共 13505字,需瀏覽 28分鐘

         ·

        2021-11-29 10:49

        職業(yè)規(guī)劃  高級前端  可視化低代碼

        點擊上方 趣談前端,關(guān)注公眾號

        回復(fù)進群,加入前端交流群

        1. 介紹

        1.1 什么是數(shù)據(jù)可視化?

        可視化是利用計算機圖形學(xué)和圖像處理技術(shù),將數(shù)據(jù)轉(zhuǎn)換成圖形或者圖像在屏幕上顯示出來,再進行交互處理的理論、方法和技術(shù)。

        數(shù)據(jù)可視化并不是簡單的將數(shù)據(jù)變成圖表,而是以數(shù)據(jù)為視角,看待世界。數(shù)據(jù)可視化就是將抽象概念形象化表達,將抽象語言具體化的過程。

        1.2 為什么要用數(shù)據(jù)可視化

        1. 首先我們利用視覺獲取的信息量絕對遠遠的比別的感官要多得多。

        2. 它能幫助分析的人對數(shù)據(jù)有更全面的認識,下面舉個??

        我們看下面幾組數(shù)據(jù):



        對數(shù)據(jù)進行簡單的數(shù)據(jù)分析,每組數(shù)據(jù)都有兩個變量 X 和 Y,然后用常用的統(tǒng)計算法評估其特點。

        • Means(平均值):X = 9Y = 7.5

        • Variance(總體方差):X = 11Y = 4.122

        • Line regression(線性回歸方程):Y = 3.0 + 0.5X

        猛一看,你會覺得數(shù)據(jù)都是同一個特點。但如果通過可視化方式展示出來,就會有不同效果



        1. 人類大腦在記憶能力的限制。實際上我們觀察物體的時候,我們大腦和計算機一樣有長期的記憶(memory 硬盤)和短期記憶(cache 內(nèi)存),只要我們讓短期記憶中的文字、物體等一遍遍的鞏固,它們才可能進入長期記憶。很多研究表明,在進行理解和學(xué)習(xí)的時候,圖文更有效的幫助我們記憶,也更有趣,容易理解。

        1.3 常見的前端開發(fā)中有什么可視化工具

        對于在 Data 部門或者做跟數(shù)據(jù)相關(guān)工作的同學(xué),一定對可視化不陌生,常見的場景有大屏、3D 展示等等。同樣,現(xiàn)階段前端層面涌現(xiàn)出多種可視化方案,這里簡單羅列幾種:

        • Echarts,可以流暢的運行在 PC 和移動設(shè)備,且兼容絕大部分瀏覽器(IE 8/9/10),底層使用 ZRender 作為渲染引擎,提供直觀、交互豐富、可高度個性化定制的數(shù)據(jù)圖表。

        • Antv,是螞蟻金服新一代數(shù)據(jù)可視化解決方案,致力于提供一套簡單方便、專業(yè)可靠、無限可能的數(shù)據(jù)可視化最佳實踐。其包括 G(可視化引擎)、G2(可視化圖表)、G6(圖可視化引擎)、F2(移動可視化方案)、L7(地理空間數(shù)據(jù)可視化)。

        • D3,其實一個可以基于數(shù)據(jù)來操作文檔的 JavaScript 庫,其遵循現(xiàn)有 Web 標準,可以不需要其他任何框架運行在現(xiàn)代瀏覽器中。

        1.4 前端可視化圖表是怎么繪制出來的

        這里我們只簡單介紹 2D 的繪制方案。

        1. Canvas。其基于位圖的圖像。其使用 JavaScript 程序繪圖(動態(tài)生成),提供的功能更原始,適合圖像處理、動態(tài)渲染以及大數(shù)據(jù)量繪制。優(yōu)點如下:

          1. 性能高,可以自己控制繪制過程。
          2. 可控性高(像素級別)。
          3. 內(nèi)存占用恒定(與像素點個數(shù)有關(guān))。
        2. Svg。其基于矢量的圖像。適合用來做動態(tài)生成,且容易編輯。

          1. 不失真,放大縮小都清晰。
          2. 學(xué)習(xí)成本低,其也是一種 DOM 結(jié)構(gòu)。
          3. 使用方便,設(shè)計軟件即可導(dǎo)出(icon 就是這樣實現(xiàn)的)。



        聽了上面的介紹,似乎感覺對可視化有了一定的了解,但它到底是怎么繪制出來的以及交互是怎么做的呢?

        2. 如何實現(xiàn)繪圖(Canvas 版本)

        先不要著急,在介紹如何繪圖之前,我們先來了解幾個專業(yè)名詞:

        • 包圍盒。包圍盒是一種求解離散點集最優(yōu)包圍空間的算法,基本思想是用體積稍大且特性簡單的幾何體(稱為包圍盒)來近似地代替復(fù)雜的幾何對象,常見的包圍盒算法有 AABB 包圍盒、包圍球以及固定方向凸包 FDH。包圍盒算法是進行碰撞干涉初步檢測的重要方法。

        • 貝塞爾曲線,是應(yīng)用于二維圖形應(yīng)用程序的數(shù)學(xué)曲線。其由線段和節(jié)點組成,節(jié)點是可拖動的支點,線段像可伸縮的皮筋,它的計算參數(shù)公式為

        • 插值函數(shù),簡單理解就是在離散數(shù)據(jù)的基礎(chǔ)上補差連續(xù)函數(shù),使得這條連續(xù)曲線通過全部給定的離散數(shù)據(jù)點。

        • B 樣條基函數(shù)。令 U={u0,u1,…,um} 是一個單調(diào)不減的實數(shù)序列,即 ui<=ui+1,i=0,1,…,m-1。其中,ui 稱為節(jié)點,U 稱為節(jié)點矢量,用 Ni,p (u) 表示第 i 個 p 次 B 樣條基函數(shù),其定義為:

        • B 樣條有如下性質(zhì):

          • 遞推性
          • 局部支承性
          • 規(guī)范性
          • 可微性

        看完上面的一連串專業(yè)名稱,先別著急腦袋暈,下面我們看看怎么用 Canvas 繪制一條線

        2.1 繪制一條線

        線是可視化中最常見的圖形元素了,最常見的就是折線圖



        一條線是由多個點來定義,按照點和點之間的連接方式不同,我們可分為 “折線” 和 “曲線”,在可視化渲染時又能分為 “虛線” 和 “實線”。

        換個思路,我們用線來繪制閉合的路徑,從而形成封閉區(qū)域,就能實線面積圖和雷達圖,就像這樣。



        下面我們來看看到底如何繪制一個線圖呢?

        2.1.1 什么是線?

        我們都知道,線是由點組成的,兩個相鄰的點連接起來就成為一個 “段”,多個段拼裝組成一條線,就像這樣。



        轉(zhuǎn)化成程序思維我們可以得知:

        • 點有坐標(x, y)

        • 段有起點、終點且它們都是點,還有長度以及順序

        • 線有若干個段也有若干個點

        2.2 實現(xiàn)折線

        2.2.1 獲取段

        折線拆分為段的實現(xiàn)很簡單,根據(jù)傳入的點數(shù)據(jù),相鄰兩點劃為一段。下面簡單演示一下(大概寫個邏輯):

        getSegment(points, defined) {  segCache ← [];
         totalLength ← 0;
         for p, i
           pnext ← points[i + 1]
           if pnext
             // 兩個點確定一條段 調(diào)用對應(yīng)函數(shù)
             segment = CreateSegment
             // 緩存數(shù)據(jù)
             segCache ← segment
             // 計算段的長度
             segment.length ← distance
             // 計算總長度
             totalLen ·····
             // 判斷是否空段
             if ···
               // 一些邏輯
         // 返回段和總長度      
        }

        實現(xiàn)很簡單,依次遍歷點數(shù)據(jù),初始化段對象,這里有個計算段長度的邏輯,段的長度要用后面會說到,至于長度怎么算,很簡單就不說了。上面有個判斷是否為空段的邏輯,之所以做這個操作是因為在實際應(yīng)用中,有些業(yè)務(wù)場景需要隱藏某些段,可以看看下面的圖:



        2.2.2 使用 Canvas 繪制線段

        Canvas 提供了兩個 API —— moveTo 和 lineTo,具體操作中我們需要調(diào)用 moveTo 將畫筆定位到線段的起點,然后通過 lineTo 繪制到線段的終點即可,如果多個首尾相接的線段可以忽略 moveTo(Canvas 內(nèi)部存儲當(dāng)前上下文),直接 lineTo。

        基于上述方法,我們只需要遍歷一條線中所有段,依次連接就可以了,為了處理空段,我們需要設(shè)置一個 start 的標記變量,如果處于 start 狀態(tài),會先 moveTo 到新的點,而不是 lineTo,大概代碼如下:

        drawLine(ctx) {
         defined ← false
         // 設(shè)置開始標志(先moveTo)
         lineStart
         for i ← 0 to len
           seg ← segCache[i]
           ...
           if i = len
             lineEnd
             strokeLine
           else
               // 判斷是否為空段
               if ...
                 drawSeg //否
               else
                lineStart // 是
        }
        drawSeg(seg, ctx) {
         if lineStart
           moveTo
         ····
         drawLine
        }
        drawLine(x, y, ctx) {
         lineTo
        }

        這塊可能會有個疑惑,感覺把線拆成段繪制好像更麻煩了,多了一個拆段的步驟,為什么不直接連接點呢?這樣劃分相當(dāng)于拆分了不同結(jié)構(gòu),那么每個結(jié)構(gòu)下的元素都有自己的定制化,可視化層面可能展示的樣式等等不同。比如說下面的,通過這樣的靈活拼裝,提升了擴展性,同時在其他方面也有優(yōu)勢,下面會具體介紹。



        2.3 實現(xiàn)曲線

        2.3.1 貝塞爾曲線

        前面我們簡單介紹了貝塞爾曲線,Canvas 也支持貝塞爾二次和三次曲線,通常使用三次貝塞爾曲線畫法。下面我們詳細講解一下。

        Bézier curve(貝塞爾曲線)是應(yīng)用于二維圖形應(yīng)用程序的數(shù)學(xué)曲線。貝塞爾曲線點的數(shù)量決定了曲線的階數(shù),一般 N 個點構(gòu)成的 N-1 階貝塞爾曲線,即 3 個點為二階。一般我們都會要求曲線至少包含 3 個點,因為兩個點的貝塞爾曲線是一條直線。按順序,第一個點為 起點 ,最后一個點為 終點 ,其余點都為 控制點 。

        下面以二次貝塞爾曲線為例。

        2.3.1.1 二次貝塞爾曲線

        給定點 P0,P1,P2,P0 和 P2 為起點和終點,P1 為控制點。從 P0 到 P2 的弧線即為一條二次貝塞爾曲線。



        在這里我們要將整個曲線的繪制量化為從 0~1 的過程,用 t 為當(dāng)前過程的進度,t 的區(qū)間即 0~1。每一條線都需要根據(jù) t 生成一個點,如下圖,一個點從 P0 移動到 P1,這是這條線從 0~1 的過程。




        下面我們還原一下一個二次貝塞爾曲線的生成過程。

        1. 首先我們鏈接 P0P1,P1P2,得到兩條線段。然后我們對進度 t 進行取值,比如 0.3,取一個 Q0 點,使得 P0Q0 的長度為 P0P1 總長度的 0.3 倍。



        1. 同時我們在 P1P2 上取一點 Q1,使得 P0Q0: P0P1 = P1Q1: P1P2。接下來我們再在 Q0Q1 上取一點 B,使得 P0Q0: P0P1 = P1Q1: P1P2 = Q0B:Q0Q1。



        現(xiàn)在我們得到的點 B 就是二次貝塞爾曲線的上的一個點,如果我們使 t=0 開始取值,逐步遞增進行插值,就會得到一系列的點 B,進行連接就會形成一條完整的曲線。



        最終經(jīng)過數(shù)據(jù)推導(dǎo),我們得到了二次貝塞爾曲線公式(具體推導(dǎo)我們不搞了,感興趣可以去百度看看)。



        2.3.1.2 三次貝塞爾曲線

        三次貝塞爾曲線由四個點組成,通過更多的迭代步驟來確定曲線上的點。




        2.3.2 使用 Canvas 繪制貝塞爾曲線

        在 Canvas 中繪制三次貝塞爾曲線使用 bezierCurveTo() 方法,具體參數(shù)定義可以在 MDN 上查閱,這里不羅列了。

        2.3.3 樣條曲線與獲取段

        了解了如何繪制三次貝塞爾曲線,我們回到實際場景,一個線圖會有若干個數(shù)量的點連接生成。但只使用 Canvas 提供的功能,并不能滿足這個需求。前面我們繪制折線是提出了段的概念,如果我們將一條完整的曲線拆分成多個段,每個段都是個三次貝塞爾曲線,問題好像就可以解決。那么問題就轉(zhuǎn)化為如何生成多個貝塞爾曲線且它們能平滑連接。

        上面我們介紹概念時提出了樣條曲線,可能大家也沒看懂,是有些抽象。簡單將就是有一個點的集合,分成多段曲線,各曲線處的連接點處可以平滑連接,轉(zhuǎn)化成數(shù)學(xué)術(shù)語就是說連接點有連續(xù)的一次和二次導(dǎo)數(shù)且一次和二次導(dǎo)數(shù)相同。下面我們看個??



        上面這個圖是由多個三次貝塞爾曲線拼接而成,我們要將其劃分前,需要確定幾個參數(shù):

        • 每條三次貝塞爾曲線的起點和終點

        • 每條三次貝塞爾曲線的兩個控制點

        只有當(dāng)我們選擇合適的起點、終點和控制點,相鄰的兩條曲線才能平滑連接。拆分算法很多,這里不詳細介紹了(其實我也看不懂),我們實現(xiàn)可以直接用 d3-shape 的 Curves 接口。下面用 Basis 算法的實現(xiàn)用例,我們簡單了解一下。

        getSegment(points, defined){
         segCache ← []
         totalLen ← 0
         if points.len < 3
           getSegment
         start, end, controll1, controll2
         for i ← 0 to points.len - 2
           first ← points[i]
           second ← points[i + 1]
           third ← points[i + 2]
           if i = 0
             start ← first
           else
             start ← end
           
           // 計算起點、終點、控制點
           // 計算長度
           // 補算最后點
        }

        這段邏輯也比較簡單,循環(huán)給到的點,從當(dāng)前索引位置開始向后取三個點,根據(jù)這個三個點以及當(dāng)前段的起始點計算結(jié)束點和控制點。每個新段的起點是上個段的終點。但是當(dāng)前循環(huán)邏輯不會計算最后一個點,所以會少一段,最后加個單獨邏輯處理。

        2.3.4 點的計算

        我們用一個簡單的公式來計算各個點的值(公式結(jié)合 B 樣條曲線和三次貝塞爾曲線在端點處的一階和二階導(dǎo)出得到),這里不介紹具體公式推導(dǎo)。

        if (i === 0) {
        start = first
        } else {
         start = end
        }
        end = Point((first.x + 4 * second.x + third.x) / 6, (first.y + 4 * second.y + third.y) / 6)
        controll1 = Point((2 * first.x + second.x) / 3, (2 * first.y + second.y) / 3)
        controll2 = Point((first.x + 2 * second.x) / 3), (first.y + 2 * second.y) / 3 )

        2.3.5 曲線分割與長度計算

        聽起來這不是一個容易的事情。由于貝塞爾曲線是插值函數(shù),所以計算只能先對曲線進行切割,然后計算足夠小的這一小段的曲線近似長度,再累加。這個計算量有點大,不過有大神給了個思路 傳送門。



        1. 找到連接的點。假設(shè)我要在 t=0.25 的位置將當(dāng)前曲線切分成兩條曲線,首先我們要知道點 B 的位置。根據(jù)公式代入即可。

        2. 獲取控制點。拿到點 B 之后,其為第一段的終點,第二段的起點,我們需要計算控制點。根據(jù)數(shù)學(xué)邏輯,我們可以得出:

          • 第一段曲線的第一個控制點的運動軌跡是線段 P0P1,和 t 線性相關(guān)

          • 第一段曲線的第二個控制點的運動軌跡是線段 Q0Q1,和 t 線性相關(guān)

          • 第二段曲線的第一個控制點的運動軌跡是線段 Q1Q2,和 t 線性相關(guān)

          • 第二段曲線的第二個控制點的運動軌跡是線段 P2P3,和 t 線性相關(guān)

        根據(jù)上面結(jié)論,拆分就很簡單了。(這塊代碼有點長,就不寫了)

        1. 長度計算。我們可以在任意位置對三次貝塞爾曲線進行拆分了,結(jié)合二分法,控制迭代次數(shù),結(jié)合近似長度計算函數(shù),我們可以得到想要精度的長度值了。(代碼也不寫了)

        2. 獲取段?,F(xiàn)在我們需要處理最后一個點的特殊邏輯,這里將第二個點和第三個點都用最后一個點表示。

        firstpoints[i - 2]
        secondpoints[i - 1]
        thirdpoints[i -1]
        start ← end
        end ← third

        ···
        ···
        1. 曲線畫法。前面都準備好了,現(xiàn)在只需要調(diào)用 Canvas 的 API 就能畫線了。

        2.4 怎么處理動畫

        前面我們遺留了一個問題,為什么需要計算長度?

        我們已經(jīng)完成了線的繪制,如何做少量的改動實現(xiàn)動畫呢?我們可以了解到不管直線和曲線,我們都分了很多段,而這些段都是和 t 相關(guān)的。

        2.4.1 方案

        動畫的本質(zhì)就是在一定的時間內(nèi)繪制某一部分區(qū)域,我們將整個線條區(qū)域劃分到 [0, 10] 區(qū)間,啟動一個循環(huán),每次繪圖時更新 t 的值,在上面循環(huán)繪制 segment 的代碼中,將整條線圖的 t 轉(zhuǎn)化為每一個段內(nèi)部的 t 值,段內(nèi)部根據(jù) t 值對自身切割,只畫應(yīng)該繪制的那部分即可。

        由于我們已經(jīng)計算了每個段的長度和總長度,所以每個段的占比可以計算,此占比再和整個線圖的 t 值進行換算即可。這個思路其實就是 局部繪制。

        但對于面積圖,其實會分為兩組 segment 繪制,繪制時我們會發(fā)現(xiàn)在同一個 t 時,在 x 方向的位移是不同步的。繪制動畫從左向右推進,比如繪制第一段時,計算第一段應(yīng)該被繪制的區(qū)間,最后填充上下兩段的閉合區(qū)間,但有個問題,如果相同的 t,代入不同組 segment 的函數(shù)中,產(chǎn)生的 x 值不一樣,那么繪制的效果就不對了,切面會是斜的。

        解決這個問題做法是根據(jù) x 或者 y 值反求 t 值,再代入目標函數(shù)中。對于三次貝塞爾曲線來說,這又是一個大難題,由于篇幅所限及代碼實現(xiàn)的比較復(fù)雜,這里不講了(其實我不會,但這有地方會)。



        2.5 交互

        交互無非是點一點,摸一摸。但從上面我們得知,一條線有那么多點,怎么知道鼠標觸發(fā)的是那個點呢?

        2.5.1 Canvas 的拾取方案

        繪制時 Canvas 不會保存繪制圖形的信息,一旦繪制完成用戶在瀏覽器中其實是一個由無數(shù)像素點組成的圖片,用戶點擊時無法從瀏覽器自帶的 API 獲取點擊到的圖形。常見的拾取方案有以下幾種:

        • 使用緩存 Canvas 通過顏色拾取圖形
        • 使用 Canvas 內(nèi)置的 API 拾取圖形
        • 使用幾何圖形包圍盒
        • 混雜上面的幾種方式

        上面的各種拾取方案各有利弊,下面來詳細的介紹各種方案的實現(xiàn)方式和一些問題,最后對比一下性能。

        2.5.1.1 使用緩存 Canvas 方案

        使用緩存的 Canvas 來進行圖形的拾取步驟如下:

        • 在顯示的 Canvas 上繪制圖形
        • 在緩存(隱藏)的 Canvas 上重新繪制一下所有的圖形,使用圖形的索引值作為圖形的顏色來繪制圖形
        • 在顯示的 Canvas 進行點擊,獲取緩存 Canvas 上對應(yīng)位置的像素點,將像素的顏色轉(zhuǎn)換成數(shù)字,這個數(shù)字就是圖形的索引值
        優(yōu)缺點
        • 優(yōu)點

          • 實現(xiàn)簡單,只需要將圖形繪制兩遍即可

          • 拾取性能好,核心的拾取算法復(fù)雜度 O(1)

        • 缺點

          • 渲染開銷加倍

          • 畫布過大時獲取緩存數(shù)據(jù) getImageData() 方法開銷很大,會降低快速拾取的收益

        適合的場景和不適宜的場景
        • 適合的場景

          • 圖形的數(shù)量比較大、重繪不頻繁的場景

          • 支持局部刷新的場景效果更好

        • 不適合的場景

          • 頻繁動畫的場景,兩倍的渲染開銷和獲取緩存數(shù)據(jù)方法的開銷過大,性能反而降低

          • 圖形的數(shù)據(jù)量很小的情況下優(yōu)勢不明顯

        性能檢測
        • 繪制顯示的 10000 個圖形 6ms
        • 在緩存的圖形 14ms ,增加了將數(shù)字轉(zhuǎn)換成顏色的開銷
        • 獲取緩存的圖片數(shù)據(jù) getImageData() 的開銷 14ms
        • 圖形拾取的開銷 0.1ms

        2.5.1.2 使用內(nèi)置 API

        Canvas 標簽提供了一個接口 isPointInPath() 來獲取對應(yīng)的點是否在繪制的圖形內(nèi)部,操作步驟如下:

        • 繪制所有圖形
        • 進行拾取時,調(diào)用 isPointInPath() 方法判斷點是否在圖形中。
        優(yōu)缺點
        • 優(yōu)點

          • 實現(xiàn)簡單,僅使用 Canvas 原生的接口

          • 不會拖慢首次渲染的時間

        • 缺點

          • 性能差,每次檢測都得走一遍圖形的繪制

          • 僅能檢測是否被包圍,不能檢測是否在線上

        適合的場景
        • 圖形的量非常小,小于 100 個時

        • 可以配合包圍盒檢測、四分樹檢測一起使用

        性能檢測
        • 拾取 10000 個圖形的時間 2000ms

        2.5.1.3 幾何包圍盒檢測方案

        最開始我們提到了包圍盒,現(xiàn)在有了使用的地方。

        Canvas 上繪制的圖形都是標準的幾何圖形,點、線、面的檢測在幾何算法中比較成熟,每個圖形在繪制時都會給其生成一個包圍盒并保存,當(dāng)拾取圖形時可以直接使用數(shù)據(jù)運算檢測。

        檢測過程如下:

        • 反序檢測所有的圖形

        • 判斷點是否在圖形的包圍盒內(nèi),如果不在,則返回 false

        • 如果圖形繪制線,則判斷是否在線上

        • 如果圖形被填充,則判斷是否被包圍

        優(yōu)缺點
        • 優(yōu)點

          • 圖形檢測算法比較成熟
          • 思路比較清晰,優(yōu)化潛力大,可以通過各種緩存機制優(yōu)化檢測性能
          • 不會影響圖形的渲染性能
        • 缺點

          • 實現(xiàn)復(fù)雜,特別是一些貝塞爾曲線和非閉合曲線的檢測性能比較差
          • 在存在大量分層的場景下,每個分層上有 transform 的存在,矩陣運算大大降低運算的性能
        適合的場景
        • 使用范圍廣

        性能檢測:
        • 10000 個點的檢測性能 5 - 20ms

        2.5.1.4 混雜拾取

        在實例的應(yīng)用過程中并非使用某一種拾取方案,通常將多種拾取方案混合使用,大致分為以下方案:

        • 包圍盒 + 緩存 Canvas:使用緩存 Canvas 時需要緩存的 Canvas 的大小跟原始 Canvas 的大小保持一致,但是可以僅僅創(chuàng)建 1*1 的緩存 Canvas,先通過計算是否在圖形的包圍盒內(nèi),將所有包含拾取點的圖形在這個一像素的畫布上進行繪制(需要進行 translate 將畫布中心定位到拾取的點上), 然后對這一像素進行顏色的檢測。

          注意:這種混雜模式對于簡單圖形” 圓 “、” 矩形 “ 的拾取并不比單純的幾何算法更快。

        • 包圍盒 + isPointInPath: 簡單的圖形使用幾何算法,復(fù)雜的很多填充的圖形可以使用包圍盒檢測和 Canvas 內(nèi)置的 isPointInPath 來檢測。

        2.5.1.5 總結(jié)

        在 Canvas 上拾取圖形時的方案選擇與用戶的場景密切相關(guān),不同的場景適用的方案也不同:

        • 在圖形數(shù)量少,不需要精確拾取的場景下(移動端)可以直接使用 isPointInPath 方法

        • 在畫布不頻繁刷新、圖形量大的場景下適合使用緩存的 Canvas 的方法

        • 使用幾何算法的拾取方案幾乎適合于所有的場景,但是需要配合各種緩存機制,并注意矩陣乘法帶來的開銷

        • 上面的幾種方法可以混合使用,拾取的優(yōu)化無止境,但是滿足需求即可。

        3. 總結(jié)

        上述全文介紹了什么是可視化,緊接著我們分析了線圖的實現(xiàn)方案以及圖形的交互實現(xiàn)。總結(jié)來說,可視化無時無刻不存在在我們身邊,看起來好像充滿神秘色彩,但我們仔細研究會發(fā)現(xiàn),實現(xiàn)可視化并不是一件難事,上述流程如果有出錯的地方,還請批評指正。

        4. 本文引用

        1. G 渲染引擎文檔

        2. 貝塞爾曲線

        3. ByteCharts 實現(xiàn)文檔

        4. BizCharts

        5. D3


        ?? 看完三件事

        如果你覺得這篇內(nèi)容對你挺有啟發(fā),我想邀請你幫我三個小忙:

        • 點個【在看】,或者分享轉(zhuǎn)發(fā),讓更多的人也能看到這篇內(nèi)容
        • 關(guān)注公眾號【趣談前端】,定期分享 工程化 可視化 / 低代碼 / 優(yōu)秀開源




        從零搭建全??梢暬笃林谱髌脚_V6.Dooring

        從零設(shè)計可視化大屏搭建引擎

        Dooring可視化搭建平臺數(shù)據(jù)源設(shè)計剖析

        可視化搭建的一些思考和實踐

        基于Koa + React + TS從零開發(fā)全棧文檔編輯器(進階實戰(zhàn)



        點個在看你最好看

        瀏覽 44
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            靠逼视频免费看欧美 | 老女人日逼 | 激情拍拍拍 | 爆操爆乳| 久久v | 日韩一区二区三区电影 | 免费看的黄色小说 | 91亚洲成人精品性色 | 国产又大又粗的视频 | 国产一区二区在线电影 |