




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
對(duì)于可視化來(lái)說(shuō),SVG非常重要的圖形系統(tǒng)。它既可以用JavaScript作繪制各種幾何圖形,還可以作為瀏覽器支持的一種格式,來(lái)獨(dú)立使用img加載或者通過(guò)Canvas制。即使我們選擇使用HTMLCSS、Canvas2D者WebGL方式來(lái)實(shí)現(xiàn)可視化,但我們依然可以且很有可能會(huì)使用到SVG圖像。所以,關(guān)于SVG我們得好好那這一節(jié)課,我們就來(lái)聊聊SVG怎么繪制可視化圖表的,以及它的局限性是什么。希望通過(guò)今天的講解,你能掌握SVG的基本用法和使用場(chǎng)景。SVG在第1節(jié)課我們講過(guò),SVG屬于式繪圖系統(tǒng),它的繪制方式和Canvas不同,它不需要用JavaScript操作繪圖指令,只需要和HTML一樣,一些就可以實(shí)現(xiàn)繪圖了。那SVG究竟是如何繪圖的呢?我們先來(lái)看一個(gè)SVG的例子1234<svg"<circlecx="100"cy="50"r="40"stroke="black"stroke-width="2"fill="orange"/>在上面的代碼中,svg元素是SVG的根元素,屬性xmlns是xml的名字空間。那第一行代碼就表示,svg元素的xmlns屬性值是" 據(jù)這個(gè)屬性值就能夠識(shí)別出這是一段SVG的內(nèi)容了。svg素下的circle素表示這是一個(gè)繪SVG像中的圓形cxcy標(biāo),表示圓心的位置在圖像的x=100、y=50處。屬性r表示半徑,r=40表示圓的半徑為 因?yàn)镾VG坐標(biāo)系和Canvas坐標(biāo)系完全一樣,都是以圖像左上角為原點(diǎn),x軸向右,y軸向下的左手坐標(biāo)系。而且在默認(rèn)情況下,SVG坐標(biāo)與瀏覽器像素對(duì)應(yīng),所以、、的單位就是px,也就是像素,不需要特別設(shè)置說(shuō)到這,你還記得嗎?在Canvas,為了讓繪制出來(lái)的圖形適配不同的顯示設(shè)備,我們要設(shè)置Canvas畫(huà)布坐標(biāo)。同理,我們也可以通過(guò)給svg元素設(shè)置viewBox屬性,來(lái)改變SVG坐標(biāo)系。如果設(shè)置了viewBox那SVG部的繪制就都是相SVG標(biāo)系好,現(xiàn)在我們已經(jīng)知道上面這段代碼的含義了。那接下來(lái),我們把它寫(xiě)入HTML檔中,黑色外框的圓現(xiàn)在,我們已經(jīng)知道了SVG的基本用法了??偟膩?lái)說(shuō),它和HTML的用法基本一樣,你可以參考HTML的用法。那接下來(lái),我還是以上一節(jié)課實(shí)現(xiàn)的層次關(guān)系圖為例,來(lái)看看使用SVG該怎么實(shí)現(xiàn)。SVG我們先來(lái)回憶一下,上一節(jié)課我們要實(shí)現(xiàn)的層次關(guān)系圖,是在一組給出的層次結(jié)構(gòu)數(shù)據(jù)中,體現(xiàn)出同屬于一個(gè)省的城市。數(shù)據(jù)源和前一節(jié)課相同,所以數(shù)據(jù)的獲取部分并沒(méi)有什么差別。這里我就不列出來(lái)了,我們直接來(lái)講繪制的過(guò)程。首先,我們要將獲取Canvas對(duì)象改成獲取SVG對(duì)象,方法是一樣的,還是通過(guò)選擇實(shí)現(xiàn)1constsvgroot代然后,我們同樣實(shí)現(xiàn)draw方法從root遍歷數(shù)據(jù)對(duì)象。不過(guò),在draw方法里,我們不是像上一講那樣,通過(guò)Canvas的2D上下文調(diào)用繪圖指令來(lái)繪圖,而是通過(guò)創(chuàng)建SVG元素,將元素添加到DOM文檔里,讓圖形顯1constsvgroot代123456789functiondraw(parent,node,{fillStyle='rgba(0,0,0,0.2)',textColor=const{x,y,r}=constcircle',circle.setAttribute('cx',x);circle.setAttribute('cy',y);circle.setAttribute('r',r);circle.setAttribute('fill',fillStyle);}draw(svgroot, .createElementNS方法來(lái)創(chuàng)建SVG .createElement方法創(chuàng)建普通的HTML元素不同,SVG元素要使用 .createElementNS方法來(lái)創(chuàng)建。其中,第一個(gè)參數(shù)是名字空間,對(duì)應(yīng)SVG名字空間。第二個(gè)參數(shù)是要?jiǎng)?chuàng)建的元素名,因?yàn)橐L制圓型,所以我們還是創(chuàng)建circle元素。然后我們將x、y、r分別賦給circle元素的cx、cy、r屬性,將fillStyle賦給circle元素的fill屬性。最后,circle元素添加到它的parent元素上去。接著,我們遍歷下一級(jí)數(shù)據(jù)。這次,我們創(chuàng)建一個(gè)SVGg素,遞歸地調(diào)用draw123if(children)constgroup',for(leti=0;i<children.length;i++)}draw(group,children[i],{fillStyle,}4567SVG的g元素表示一個(gè)分組,我們可以用它來(lái)對(duì)SVG元素建立起層級(jí)結(jié)構(gòu)。而且,如果我們給g元素設(shè)置屬性,那么}draw(group,children[i],{fillStyle,}4567最后,如果下一級(jí)沒(méi)有數(shù)據(jù)了,那我們還是需要給它添加文字。在SVG中添加文字,只需要?jiǎng)?chuàng)建text元素,然后給這個(gè)元素設(shè)置屬性就可以了。操作非常簡(jiǎn)單,你看我給出的代碼123456789elseconsttext',text.setAttribute('fill',textColor);text.setAttribute('font-family','Arial');text.setAttribute('font-size','1.5rem');text.setAttribute('text-anchor','middle');text.setAttribute('x',x);text.setAttribute('y',y);constname=text.textContent=name;}這樣,我們就實(shí)現(xiàn)了SVG版的層次關(guān)系圖。你看,它是不是看起來(lái)和前一節(jié)利用Canvas層次關(guān)系SVGCanvas那么問(wèn)題就來(lái)了,既然SVG和Canvas最終的實(shí)現(xiàn)效果沒(méi)什么差別,那在實(shí)際使用的時(shí)候,我們?cè)撊绾芜x擇呢?這就需要我們了解SVGCanvas使用上的不同點(diǎn)。知道了這SVGCanvas使用上的不同主要可以分為兩點(diǎn),分別是寫(xiě)法上的不同和用戶交互實(shí)現(xiàn)寫(xiě)法上的不第1講我們,SVG是以創(chuàng)建圖形元素繪圖的“式”繪圖系統(tǒng),Canvas是執(zhí)行繪在繪制層次關(guān)系圖的過(guò)程中,SVG首先通過(guò)創(chuàng)建來(lái)表示圖形元素,circle表示圓,g表示分組,text示文字。接著,SVG元素的setAttribute圖形元素賦屬性值,這個(gè)和操作HTML元素是一樣的。而Canvas先是通過(guò)上下文執(zhí)行繪圖指令來(lái)繪制圖形,畫(huà)圓是調(diào)用context.arc指令,然再調(diào)用context.fill繪制,畫(huà)文字是調(diào)用context.fillText指令。另外,Canvas還通過(guò)上文設(shè)置狀態(tài)屬性,context.fillStyle置填充顏色,conext.font置元素的字體。我們?cè)O(shè)從寫(xiě)法上來(lái)看,因?yàn)镾G的式類似于TML書(shū)寫(xiě)方式,本身對(duì)前端工程師會(huì)更加友好。但是,SG圖形需要由瀏覽器負(fù)責(zé)渲染和管理,將元素節(jié)點(diǎn)在DOM樹(shù)中。這樣做的缺點(diǎn)是,在一些動(dòng)態(tài)的場(chǎng)景中,也就是需要頻繁地增加、刪除圖形元素的場(chǎng)景中,與一般的TML元素一樣會(huì)帶來(lái)DOM操作的開(kāi)銷,所以SG的渲染性能相對(duì)比較低。那除了寫(xiě)法不同以外,SVGCanvas其他區(qū)別嗎?當(dāng)然是有的,不過(guò)我要先賣一個(gè)用戶交互實(shí)現(xiàn)我們嘗試給這個(gè)SVG的層次關(guān)系圖添加一個(gè)功能,也就是當(dāng)鼠標(biāo)移動(dòng)到某個(gè)區(qū)域時(shí),這個(gè)區(qū)域會(huì)高亮,并且顯示出對(duì)應(yīng)的省-市信息。因?yàn)镾VG的一個(gè)圖形對(duì)應(yīng)一個(gè)元素,所以我們可以像處理DOM元素一樣,很容易地SVG圖形元素添加對(duì)應(yīng)的鼠標(biāo)。具體怎么做呢?我們一起來(lái)看首先,我們要給SVG的根元素添加mousemove,添加代碼的操作很簡(jiǎn)單,你可以letactiveTarget=svgroot.addEventListener('mousemove',(evt)=>lettarget=if(target.nodeName==='text')target=if(activeTarget!==target)if(activeTarget)activeTarget.setAttribute('fill','rgba(0,0,0, target.setAttribute('fill','rgba(0,128,0,activeTarget= 就像是我們熟悉的HTML用法一樣,我們通過(guò)冒泡可以處理每個(gè)圓上的鼠標(biāo)。然后,我們把當(dāng)前鼠標(biāo)所在的圓的顏色填充成’rgba(0,128,0,0.1)’,這個(gè)顏色是帶透明的接著,我們要實(shí)現(xiàn)顯示對(duì)應(yīng)的省信息。在這里,我們需要修改一下draw法。具體的第一步,是把省、市信息通過(guò)擴(kuò)展屬性data-name設(shè)置到svg的circle元素上,這樣我1123456789functiondraw(parent,node,{fillStyle='rgba(0,0,0,0.2)',textColor=constcircle',circle.setAttribute('data-name',if(children){constgroup=',group.setAttribute('data-name',}else}}第二步,我們要實(shí)現(xiàn)一個(gè)getTitle方法,從當(dāng)前鼠標(biāo)的target往上找parent元素,拿到“省-市”信息,把它賦給titleEl元素。這個(gè)titleEl元素是我們添加到網(wǎng)頁(yè)上的一個(gè)h1元素,用來(lái)顯示省、市信息。代代12345678consttitleEl functiongetTitle(target)constname=target.getAttribute('data-name');if(target.parentNode&&target.parentNode.nodeName==='g'){constparentName=target.parentNode.getAttribute('data-name');return`${parentName}-${name}`;}}return9最后,我們就可以在mousemove中更新titleEl的文}return9代代123456svgroot.addEventListener('mousemove',(evt)=>titleEl.textContent=碼我放在 其實(shí),我們上面講的鼠標(biāo)控制功能就是一個(gè)簡(jiǎn)單的用戶交互功能??偨Y(jié)來(lái)說(shuō),利用SVG的一個(gè)圖形對(duì)應(yīng)一個(gè)svg元素的機(jī)制,我們就可以像操作普通的HTML元素那樣,給svg元素添加實(shí)現(xiàn)用戶交互了。所以,SVG有一個(gè)非常大的優(yōu)點(diǎn),那就是可以讓圖形的用戶交互非常簡(jiǎn)單。和SVG相比,利用Canvas對(duì)圖形元素進(jìn)行用戶交互就沒(méi)有那么容易了。不過(guò),對(duì)于圓形的層次關(guān)系圖來(lái)說(shuō),在Cavas圖形上定位鼠標(biāo)處于哪個(gè)圓中并不難,我們只需要計(jì)算一下鼠標(biāo)到每個(gè)圓的圓心距離,如果這個(gè)距離小于圓的半徑,我們就可以確定鼠標(biāo)在某個(gè)圓內(nèi)部了。這實(shí)際上就是上一節(jié)課我們留下的思考題,相信現(xiàn)在你應(yīng)該可以做出來(lái)了。但是試想一下,如果我們要繪制的圖形不是圓、矩形這樣的規(guī)則圖形,而是一個(gè)復(fù)雜得多的多邊形,我們又該怎樣確定鼠標(biāo)在哪個(gè)圖形元素的內(nèi)部呢?這對(duì)于Cavas來(lái)說(shuō),就是一個(gè)比較復(fù)雜的問(wèn)題了。不過(guò)這也不是不能解決的,在后續(xù)的課程中,我們就會(huì)討論如何用數(shù)學(xué)計(jì)算的辦法來(lái)解決這個(gè)問(wèn)題。SVG雖然使用SVG繪圖能夠很方便地實(shí)現(xiàn)用戶交互,但是有得必有失,SVG這個(gè)設(shè)計(jì)給用戶交互帶來(lái)便利性的同時(shí),也帶來(lái)了局限性。為什么這么說(shuō)呢?因?yàn)樗虳OM元素一樣,以節(jié)點(diǎn)的形式呈現(xiàn)在HTML文本內(nèi)容中,依靠瀏覽器的DOM樹(shù)渲染。如果我們要繪制的圖形非常復(fù)雜,這些元素節(jié)點(diǎn)的數(shù)量就會(huì)非常多。而節(jié)點(diǎn)數(shù)量多,就會(huì)大大增加DOM樹(shù)渲就比如說(shuō),在繪制如上的層次關(guān)系圖時(shí),我們只需要繪制數(shù)十個(gè)節(jié)點(diǎn)。但是如果是更復(fù)雜的應(yīng)用,比如我們要繪制數(shù)百上千甚至上萬(wàn)個(gè)節(jié)點(diǎn),這個(gè)時(shí)候,DOM樹(shù)渲染就會(huì)成為性能瓶頸。事實(shí)上,在一般情況下,當(dāng)VG節(jié)點(diǎn)超過(guò)一千個(gè)的時(shí)候,你就能很明顯感覺(jué)到性能問(wèn)題了。幸運(yùn)的是,對(duì)于SVG的性能問(wèn)題,我們也是有解決方案的。比如說(shuō),我們可以使用虛擬DOM方案來(lái)盡可能地減少重繪,這樣就可以優(yōu)化SVG的渲染。但是這些方案只能解決一部分問(wèn)題,當(dāng)節(jié)點(diǎn)數(shù)太多時(shí),這些方案也為力。這個(gè)時(shí)候,我們還是得依靠Canvas和WebGL來(lái)繪圖,才能徹底解決問(wèn)題。那在上萬(wàn)個(gè)節(jié)點(diǎn)的可視化應(yīng)用場(chǎng)景中,SVG就真的一無(wú)是處了嗎?當(dāng)然不是。SVG除了嵌入HTML文檔的用法,還可以直接作為一種圖像格式使用。所以,即使是在用Canvas和WebGL染的應(yīng)用場(chǎng)景中,我們也依然可能會(huì)用到SVG,將它作為一些局部的圖形使這一節(jié)課我們學(xué)習(xí)了SVG的基本用法、優(yōu)點(diǎn)和局限我們知道,SVG為一種瀏覽器支持的圖像格式,既可以作為HTML嵌元素使用,也可以作為圖像通過(guò)img元素加載,或者繪制到Canvas內(nèi)。而用SVG繪制可視化圖形與用Canvas繪制有明顯區(qū)別,SVG通過(guò)創(chuàng)建來(lái)表示圖形元素,然后將圖形元素添加到DOM樹(shù)中,交給DOM完成渲染。使用DOM樹(shù)渲染可以讓圖形元素的用戶交互實(shí)現(xiàn)起來(lái)非常簡(jiǎn)單,因?yàn)槲覀兛梢灾苯訉?duì)圖形元素。但是這也帶來(lái)問(wèn)題,如果圖形復(fù)雜,那么SVG的圖形
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 廠區(qū)道路橫平豎直施工方案
- 湖南舊鋼煙囪防腐施工方案
- 帶視頻的數(shù)學(xué)試卷
- 電纜線下作業(yè)施工方案
- 杭州日式屋頂花園施工方案
- 數(shù)控加工工藝與編程技術(shù)基礎(chǔ) 教案 模塊二 項(xiàng)目三 自動(dòng)編程(3-4)
- 智能制造與傳統(tǒng)制造的區(qū)別
- 石油化工靜電接地的接地網(wǎng)設(shè)計(jì)
- 健全公共衛(wèi)生體系的策略及實(shí)施路徑
- 環(huán)保與可持續(xù)發(fā)展在新型城鎮(zhèn)化中的作用
- 生豬行業(yè)pest分析
- 2024內(nèi)蒙古烏審旗圖克鎮(zhèn)圖克工業(yè)園區(qū)中天合創(chuàng)化工分公司招聘20人高頻考題難、易錯(cuò)點(diǎn)模擬試題(共500題)附帶答案詳解
- 五年級(jí)上冊(cè)小數(shù)乘除練習(xí)300道及答案
- 《新概念英語(yǔ)第二冊(cè)》電子書(shū)、單詞、筆記、練習(xí)冊(cè)(附答案)匯編
- 學(xué)校心理健康教育的目標(biāo)體系課件
- 控制加班改善對(duì)策培訓(xùn)課件
- 功能材料-智能材料
- 《信息科技》學(xué)科新課標(biāo)《義務(wù)教育信息科技課程標(biāo)準(zhǔn)(2022年版)》
- 合同智能審核與風(fēng)險(xiǎn)預(yù)警
- 2024年中興通訊股份有限公司招聘筆試參考題庫(kù)含答案解析
- 中醫(yī)跟師總結(jié)論文3000字(通用3篇)
評(píng)論
0/150
提交評(píng)論