相關(guān)JavaScript在覽器中實(shí)現(xiàn)可視化的四種方式
前言
可視化用一句話來(lái)說(shuō),本質(zhì)上就是將數(shù)據(jù)信息組織起來(lái)后,以圖形的方式呈現(xiàn)出來(lái)。在 Web 上,圖形通常是通過(guò)瀏覽器繪制的?,F(xiàn)代瀏覽器是一 個(gè)復(fù)雜的系統(tǒng),其中負(fù)責(zé)繪制圖形的部分是渲染引擎。渲染引擎繪制圖形的方式,大體上有 4 種。
第 1 種是傳統(tǒng)的 HTML+CSS。這種方式通常用來(lái)呈現(xiàn)普通的 Web 網(wǎng)頁(yè)。
第 2 種是使用 SVG。SVG 和傳統(tǒng)的 HTML+CSS 的繪圖方式差別不大。只不過(guò),HTML 元素在繪制矢量圖形方面的能力有些不足,而 SVG 恰好彌補(bǔ)了這方面的缺陷。
第 3 種是使用 Canvas2D。這是瀏覽器提供的 Canvas API 中的其中一種上下文,使用它可以非常方便地繪制出基礎(chǔ)的幾何圖形。
第 4 種是使用 WebGL。這是瀏覽器提供的 Canvas API 中的另一種上下文,它是 OpenGL ES 規(guī)范在 Web 端的實(shí)現(xiàn)。我們可以通過(guò)它,用 GPU 渲染各種復(fù)雜的 2D 和 3D 圖形。值得一提的是,WebGL 利用了 GPU 并行處理的特性,這讓它在處理大量數(shù)據(jù)展現(xiàn)的時(shí)候,性能大大優(yōu)于前 3 種繪圖方式。因此,在可視化的應(yīng)用中,一些數(shù)據(jù)量大、視覺(jué)效果要求高的特殊場(chǎng)景,使用 WebGL 渲染是一種比較合適的選擇。
方式一:HTML+CSS
與傳統(tǒng)的 Web 應(yīng)用相比,可視化項(xiàng)目,尤其是 PC 端的可視化大屏展現(xiàn),不只是使用 HTML 與 CSS 相對(duì)較少,而且使用方式也不太一樣。于是,有些同學(xué)就會(huì)認(rèn)為,可視化只能使用 SVG、Canvas 這些方式,不能使用 HTML 與 CSS。當(dāng)然了,這個(gè)想法是不對(duì)。具體的原因是什么呢?我一起來(lái)看看。 實(shí)際上,現(xiàn)代瀏覽器的 HTML、CSS 表現(xiàn)能力很強(qiáng)大,完全可以實(shí)現(xiàn)常規(guī)的圖表展現(xiàn),比如,我們常見(jiàn)的柱狀圖、餅圖和折線圖。
- 一些簡(jiǎn)單的可視化圖表,用 CSS 來(lái)實(shí)現(xiàn)很有好處,既能簡(jiǎn)化開(kāi)發(fā),又不需要引入額外的 庫(kù),可以節(jié)省資源,提高網(wǎng)頁(yè)打開(kāi)的速度。
- 理解 CSS 的繪圖思想對(duì)于可視化也是很有幫助的,比如,CSS 的很多理論就和視覺(jué)相關(guān),可視化中都可以拿來(lái)借鑒。
缺點(diǎn):
HTML 和 CSS 作為瀏覽器渲染引擎的一部分,為了完成頁(yè)面渲染的工作,除了繪制圖形外,還要做很多額外的工作。比如說(shuō),瀏覽器的渲染引擎在工作時(shí),要先解析 HTML、SVG、CSS,構(gòu)建 DOM 樹(shù)、RenderObject 樹(shù)和 RenderLayer 樹(shù),然后用 HTML(或 SVG)繪圖。當(dāng)圖形發(fā)生變化時(shí),我們很可能要重新執(zhí)行全部的工作,這樣的性能開(kāi)銷(xiāo)是非常大的。
而且傳統(tǒng)的 Web 開(kāi)發(fā),因?yàn)樯婕?UI 構(gòu)建和內(nèi)容組織,所以這些額外的解析和構(gòu)建工作都 是必須做的。而可視化與傳統(tǒng)網(wǎng)頁(yè)不同,它不太需要復(fù)雜的布局,更多的工作是在繪圖和數(shù) 據(jù)計(jì)算。所以,對(duì)于可視化來(lái)說(shuō),這些額外的工作反而相當(dāng)于白白消耗了性能。
方式二:SVG
現(xiàn)代瀏覽器支持 SVG(Scalable Vector Graphics,可縮放矢量圖),SVG 是一種基于 XML 語(yǔ)法的圖像格式,可以用圖片(img 元素)的 src 屬性加載。而且,瀏覽器更強(qiáng)大的是,它還可以內(nèi)嵌 SVG 標(biāo)簽,并且像操作普通的 HTML 元素一樣,利用 DOM API 操作 SVG 元素。甚至, CSS 也可以作用于內(nèi)嵌的 SVG 元素。
SVG 繪制圖表與 HTML 和 CSS 繪制圖表的方式差別不大,只不過(guò)是將 HTML 標(biāo)簽替換成 SVG 標(biāo)簽,運(yùn)用了一些 SVG 支持的特殊屬性。 HTML 的不足之處在于 HTML 元素的形狀一般是矩形,雖然用 CSS 輔助,也能夠繪制出各種其它形狀的圖形,甚至不規(guī)則圖形,但是總體而言還是非常麻煩的。
而 SVG 則彌補(bǔ)了這方面的不足,讓不規(guī)則圖形的繪制變得更簡(jiǎn)單了。因此,用 SVG 繪圖比用 HTML 和 CSS 要便利得多。
但是,SVG 圖表也有缺點(diǎn)。在渲染引擎中,SVG 元素和 HTML 元素一樣,在輸出圖形前都需要經(jīng)過(guò)引擎的解析、布局計(jì)算和渲染樹(shù)生成。而且,一個(gè) SVG 元素只表示一種基本圖形,如果展示的數(shù)據(jù)很復(fù)雜,生成圖形的 SVG 元素就會(huì)很多。這樣一來(lái),大量的 SVG 元素不僅會(huì)占用很多內(nèi)存空間,還會(huì)增加引擎、布局計(jì)算和渲染樹(shù)生成的開(kāi)銷(xiāo),降低性能,減慢渲染速度。這也就注定了 SVG 只適合應(yīng)用于元素較少的簡(jiǎn)單可視化場(chǎng)景。
方式三:Canvas2D
除了 SVG,使用 Canvas2D 上下文來(lái)繪制可視化圖表也很方便,但是在繪制方式上, Canvas2D 和 HTML/CSS、SVG 又有些不同。
無(wú)論是使用 HTML/CSS 還是 SVG,它們都屬于聲明式繪圖系統(tǒng),也就是我們根據(jù)數(shù)據(jù)創(chuàng)建各種不同的圖形元素(或者 CSS 規(guī)則),然后利用瀏覽器渲染引擎解析它們并渲染出來(lái)。 但是 Canvas2D 不同,它是瀏覽器提供的一種可以直接用代碼在一塊平面的“畫(huà)布”上繪 制圖形的 API,使用它來(lái)繪圖更像是傳統(tǒng)的“編寫(xiě)代碼”,簡(jiǎn)單來(lái)說(shuō)就是調(diào)用繪圖指令,然 后引擎直接在頁(yè)面上繪制圖形。這是一種指令式的繪圖系統(tǒng)。
那 Canvas 到底是怎么繪制可視化圖表的呢?我們一起來(lái)看。 首先,Canvas 元素在瀏覽器上創(chuàng)造一個(gè)空白的畫(huà)布,通過(guò)提供渲染上下文,賦予我們繪制 內(nèi)容的能力。然后,我們只需要調(diào)用渲染上下文,設(shè)置各種屬性,然后調(diào)用繪圖指令完成輸出,就能在畫(huà)布上呈現(xiàn)各種各樣的圖形了。
為了實(shí)現(xiàn)更加復(fù)雜的效果,Canvas 還提供了非常豐富的設(shè)置和繪圖 API,我們可以通過(guò)操作上下文,來(lái)改變填充和描邊顏色,對(duì)畫(huà)布進(jìn)行幾何變換,調(diào)用各種繪圖指令,然后將繪制的圖形輸出到畫(huà)布上。
總結(jié)來(lái)說(shuō),Canvas 能夠直接操作繪圖上下文,不需要經(jīng)過(guò) HTML、CSS 解析、構(gòu)建渲染樹(shù)、布局等一系列操作。因此單純繪圖的話,Canvas 比 HTML/CSS 和 SVG 要快得多。
這里有一點(diǎn)需要你注意,Canvas 和 SVG 的使用也不是非此即彼的,它們可以結(jié)合使用。 因?yàn)?SVG 作為一種圖形格式,也可以作為 image 元素繪制到 Canvas 中。舉個(gè)例子,我們可以先使用 SVG 生成某些圖形,然后用 Canvas 來(lái)渲染。這樣,我們就既可以享受 SVG 的便利性,又可以享受 Canvas 的高性能了。
方式四:WebGL
一般情況下,Canvas2D 繪制圖形的性能已經(jīng)足夠高了,但是在三種情況下我們有必要直接操作更強(qiáng)大的 GPU 來(lái)實(shí)現(xiàn)繪圖。
第一種情況,如果我們要繪制的圖形數(shù)量非常多,比如有多達(dá)數(shù)萬(wàn)個(gè)幾何圖形需要繪制,而 且它們的位置和方向都在不停地變化,那我們即使用 Canvas2D 繪制了,性能還是會(huì)達(dá)到瓶頸。這個(gè)時(shí)候,我們就需要使用 GPU 能力,直接用 WebGL 來(lái)繪制。
第二種情況,如果我們要對(duì)較大圖像的細(xì)節(jié)做像素處理,比如,實(shí)現(xiàn)物體的光影、流體效果 和一些復(fù)雜的像素濾鏡。由于這些效果往往要精準(zhǔn)地改變一個(gè)圖像全局或局部區(qū)域的所有像素點(diǎn),要計(jì)算的像素點(diǎn)數(shù)量非常的多(一般是數(shù)十萬(wàn)甚至上百萬(wàn)數(shù)量級(jí)的)。這時(shí),即使采用 Canvas2D 操作,也會(huì)達(dá)到性能瓶頸,所以我們也要用 WebGL 來(lái)繪制。
第三種情況是繪制 3D 物體。因?yàn)?WebGL 內(nèi)置了對(duì) 3D 物體的投影、深度檢測(cè)等特性, 所以用它來(lái)渲染 3D 物體就不需要我們自己對(duì)坐標(biāo)做底層的處理了。那在這種情況下, WebGL 無(wú)論是在使用上還是性能上都有很大優(yōu)勢(shì)。
總結(jié)
HTML + CSS 的優(yōu)點(diǎn)是方便,不需要第三方依賴(lài),甚至不需要 JavaScript 代碼。如果我們要繪制少量常見(jiàn)的圖表,可以直接采用 HTML 和 CSS。它的缺點(diǎn)是 CSS 屬性不能直觀體現(xiàn)數(shù)據(jù),繪制起來(lái)也相對(duì)麻煩,圖形復(fù)雜會(huì)導(dǎo)致 HTML 元素多,而消耗性能。
SVG 是對(duì) HTML/CSS 的增強(qiáng),彌補(bǔ)了 HTML 繪制不規(guī)則圖形的能力。它通過(guò)屬性設(shè)置圖形,可以直觀地體現(xiàn)數(shù)據(jù),使用起來(lái)非常方便。但是 SVG 也有和 HTML/CSS 同樣的問(wèn)題,圖形復(fù)雜時(shí)需要的 SVG 元素太多,也非常消耗性能。
Canvas2D 是瀏覽器提供的簡(jiǎn)便快捷的指令式圖形系統(tǒng),它通過(guò)一些簡(jiǎn)單的指令就能快速繪制出復(fù)雜的圖形。由于它直接操作繪圖上下文,因此沒(méi)有 HTML/CSS 和 SVG 繪圖因?yàn)樵囟鄬?dǎo)致消耗性能的問(wèn)題,性能要比前兩者快得多。但是如果要繪制的圖形太多,或者處理大量的像素計(jì)算時(shí),Canvas2D 依然會(huì)遇到性能瓶頸。
WebGL 是瀏覽器提供的功能強(qiáng)大的繪圖系統(tǒng),它使用比較復(fù)雜,但是功能強(qiáng)大,能夠充分利用 GPU 并行計(jì)算的能力,來(lái)快速、精準(zhǔn)地操作圖像的像素,在同一時(shí)間完成數(shù)十萬(wàn)或數(shù)百萬(wàn)次計(jì)算。另外,它還內(nèi)置了對(duì) 3D 物體的投影、深度檢測(cè)等處理,這讓它更適合繪制 3D 場(chǎng)景。
到此這篇關(guān)于相關(guān)JavaScript在覽器中實(shí)現(xiàn)可視化的四種方式的文章就介紹到這了,更多相關(guān)JS可視化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- JavaScript可視化圖表庫(kù)D3.js API中文參考
- 如何實(shí)現(xiàn)json數(shù)據(jù)可視化詳解
- Highcharts+NodeJS搭建數(shù)據(jù)可視化平臺(tái)示例
- JS 音頻可視化插件Wavesurfer.js的使用教程
- JS實(shí)現(xiàn)可視化音頻效果的實(shí)例代碼
- JavaScript數(shù)據(jù)可視化:ECharts制作地圖
- 交互式可視化js庫(kù)gojs使用介紹及技巧
- vue使用wavesurfer.js解決音頻可視化播放問(wèn)題
- 配合Swagger使用絕佳的兩款直觀易用JSON可視化工具
- JS前端可視化GraphQL使用詳解
相關(guān)文章
js實(shí)現(xiàn)鼠標(biāo)移入移出卡片切換內(nèi)容
這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)鼠標(biāo)移入移出卡片切換內(nèi)容,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10MVVM框架下實(shí)現(xiàn)分頁(yè)功能示例
分頁(yè)這種組件,幾乎每一種框架都有這樣的組件,這篇文章主要介紹了MVVM框架下實(shí)現(xiàn)分頁(yè)功能示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-06-06JavaScript中的對(duì)象的extensible屬性介紹
這篇文章主要介紹了JavaScript中的對(duì)象的extensible屬性介紹,JavaScript中,對(duì)象的extensible屬性用于表示是否允許在對(duì)象中動(dòng)態(tài)添加新的property,需要的朋友可以參考下2014-12-12firefo xml 讀寫(xiě)實(shí)現(xiàn)js代碼
firefo xml 讀寫(xiě)實(shí)現(xiàn) 不過(guò)要是你的xml要編碼成功還得在str前面加上x(chóng)ml頭,千萬(wàn)別忘了啊。2009-06-06js實(shí)現(xiàn)移動(dòng)端tab切換時(shí)下劃線滑動(dòng)效果
這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)移動(dòng)端tab切換時(shí)下劃線滑動(dòng)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09