日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

D3可视化:(1)初次见面,SVG与D3的魅力

發(fā)布時間:2025/4/16 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 D3可视化:(1)初次见面,SVG与D3的魅力 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

D3.js是一個基于HTML/SVG/CSS的數(shù)據(jù)可視化庫,是領(lǐng)域內(nèi)非常強大的存在了。

今后會在工作使用,也因此開始了自學(xué)之旅。學(xué)習(xí)過程中,我主要通過Curran Kelleher老師的系列教程進行學(xué)習(xí),這個筆記用于學(xué)習(xí)、整理和分享,陸續(xù)學(xué)習(xí)、更新和記錄中....

原文鏈接

學(xué)習(xí)目的:

  • 熟悉和認識D3.js
  • 練習(xí)使用SVG畫圖,熟悉操作
  • 練習(xí)D3.js的基本函數(shù)和操作

完成效果圖: 在線demo

D3初印象

選擇集

D3是實現(xiàn)數(shù)據(jù)可視化,仍然離不開傳統(tǒng)DOM的選擇和操作,也因此,D3提供了類似Jquery的DOM操作指令:

  • d3.select:選擇第一個指定元素
  • d3.selectAll : 選擇所有的元素
const svg = d3.select('svg') //選擇svg const p = svg.selectAll('p') //選擇svg下所有的p標(biāo)簽復(fù)制代碼

當(dāng)然,可以使用#id 以及 .class 對id和類進行選擇

查看狀態(tài)

d3.select和d3.selectAll返回的都是選擇集,添加、刪除以及修改都需要用到選擇集,查看狀態(tài)有三個函數(shù)可以使用:

  • selection.empty() 選擇集為空,返回true,否則返回false
  • selection.node() 返回第一個非空元素,如果選擇集為空,返回null
  • selection.size() 返回選擇集中的元素個數(shù)

設(shè)定和獲取屬性

使用select或selectAll選擇后,可以通過attr獲取和設(shè)定屬性,可以使用append方法添加元素

const svg = select('svg'); svg.append('circle').attr('r','30')復(fù)制代碼

使用D3和SVG畫圖

html文件

<html lang="en"> <head><title>Smile face with d3</title> </head> <body><svg width="960" height="500"></svg><script src="https://d3js.org/d3.v5.min.js"></script><script src="index.js"></script> </body> </html> 復(fù)制代碼

主要內(nèi)容通過index.js實現(xiàn):

第一步:通過d3選擇SVG,使用circle構(gòu)建輪廓

const svg = d3.select('svg'); const height = +svg.attr('height'); const width = +svg.attr('width'); svg.append('circle').attr('r',height / 2).attr('cx', width / 2).attr('cy', height / 2).attr('fill', 'yellow').attr('stroke','black')const leftEye = svg.append('circle').attr('r', 30).attr('cx', width / 2 - 100).attr('cy', height / 2 - 80).attr('fill', 'black')const rightEye = svg.append('circle').attr('r', 30).attr('cx', width / 2 + 100).attr('cy', height / 2 - 80).attr('fill', 'black') 復(fù)制代碼

要點:

  • 通過attr獲取的屬性是string類型的,通過parseFloat或者+轉(zhuǎn)換為number類型
  • 對圓形circle的屬性cx cy等,使用變量作為其大小設(shè)置的值,而不用一個數(shù)字,方便日后的維護
  • leftEye和RightEye用類似的方法,創(chuàng)造出來,并將眼睛放置在合適的位置。

代碼優(yōu)化

1)可以發(fā)現(xiàn),對三個圓圓心的操作cx和cy出現(xiàn)了多次,而作用也僅僅是為了將圓放在中心。因此,可以通過SVG中的<g>來分組來實現(xiàn)一次性操作。

const g = svg.append('g').attr('transform',`translate(${ width / 2}, ${ height / 2})`)//這樣,在畫圓的時候,就可以去掉對其圓心的操作,因為默認的位置就在中心了 const circle = g.append('circle').attr('r',height / 2).attr('fill', 'yellow').attr('stroke','black') 復(fù)制代碼

2)同樣的,對于眼睛的操作,也有點繁瑣,可以通過變量和分組,提高代碼的可維護性能。

const eyeSpacing = 100; const eyeYoffset = -80 const eyeRadius = 30;const eyesG = g.append('g').attr('transform', `translate(0, ${eyeYoffset})`);const leftEye = eyesG.append('circle').attr('r', eyeRadius).attr('cx', - eyeSpacing)const rightEye = eyesG.append('circle').attr('r', eyeRadius).attr('cx', + eyeSpacing) 復(fù)制代碼

第二步 嘴巴

嘴巴實際上是一個弧線,使用SVG中的path進行繪制。熟悉path的,當(dāng)然可以直接給參數(shù)進行繪制,但是d3對圓弧有更好的支持,可以使用d3.arc函數(shù),方便的繪制圓弧。

arc函數(shù)

根據(jù)官方的API手冊,函數(shù)的使用方法如下:

var arc = d3.arc();arc({innerRadius: 0,outerRadius: 100,startAngle: 0,endAngle: Math.PI / 2 }); // "M0,-100A100,100,0,0,1,100,0L0,0Z" 復(fù)制代碼

其中,innerRadius是內(nèi)圓半徑,outerRadius是外圓半徑,startAngle和endAngle分別是開始和結(jié)束的弧度(完整的圓是0~2PI)

笑臉的實現(xiàn)

根據(jù)以上內(nèi)容,代碼如下:

const mouth = g.append('path').attr('d',d3.arc()({innerRadius: 150,outerRadius: 170,startAngle: Math.PI /2,endAngle: Math.PI * 3 / 2})) 復(fù)制代碼

眉毛

眉毛用簡單的長方形來代替,也就是svg中的<rect>,使用前文的編程風(fēng)格,將眉毛歸為一個group,并將位置設(shè)定。

const eyebrowWidth = 50; const eyebrowHeight = 10; const eyebrowYoffset = -150; const BrowG = g.append('g').attr('transform',`translate(${-eyebrowWidth / 2},${eyebrowYoffset})`);const leftEyebrow = BrowG.append('rect').attr('width',eyebrowWidth).attr('height',eyebrowHeight).attr('x',-eyeSpacing)const rightEyebrow = BrowG.append('rect').attr('width', eyebrowWidth).attr('height', eyebrowHeight).attr('x', eyeSpacing) 復(fù)制代碼

加入動畫

使用transition函數(shù)設(shè)置眉毛的動畫,讓笑臉動起來

const BrowG = g.append('g').attr('transform',`translate(${-eyebrowWidth / 2},${eyebrowYoffset})`); BrowG.transition().duration(2000).attr('transform', `translate(${-eyebrowWidth / 2},${eyebrowYoffset - 50})`).transition().duration(2000).attr('transform', `translate(${-eyebrowWidth / 2},${eyebrowYoffset})`).duration(2000)復(fù)制代碼

注意點:

  • transition函數(shù)要對號入座,即如果加在了<g>上,對應(yīng)的增加的屬性動畫應(yīng)該在transform上; 如果動畫在<rect>上,動畫應(yīng)該在y屬性上。
  • 添加動畫不能在append函數(shù)之后連接,比如BrowG.append('g').attr(...).transition()是不行的。因為過度動畫無法綁定在append的元素上,需要分別操作。

完整代碼

code downlaod here

const svg = d3.select('svg'); const height = +svg.attr('height'); const width = +svg.attr('width'); const g = svg.append('g').attr('transform',`translate(${ width / 2}, ${ height / 2})`)const circle = g.append('circle').attr('r',height / 2).attr('fill', 'yellow').attr('stroke','black')const eyeSpacing = 100; const eyeYoffset = -80 const eyeRadius = 30; const eyebrowWidth = 50; const eyebrowHeight = 10; const eyebrowYoffset = -150;const eyesG = g.append('g').attr('transform', `translate(0, ${eyeYoffset})`);const leftEye = eyesG.append('circle').attr('r', eyeRadius).attr('cx', - eyeSpacing)const rightEye = eyesG.append('circle').attr('r', eyeRadius).attr('cx', + eyeSpacing)const mouth = g.append('path').attr('d',d3.arc()({innerRadius: 150,outerRadius: 170,startAngle: Math.PI /2,endAngle: Math.PI * 3 / 2}))const BrowG = g.append('g').attr('transform',`translate(${-eyebrowWidth / 2},${eyebrowYoffset})`); BrowG.transition().duration(2000).attr('transform', `translate(${-eyebrowWidth / 2},${eyebrowYoffset - 50})`).transition().duration(2000).attr('transform', `translate(${-eyebrowWidth / 2},${eyebrowYoffset})`).duration(2000)const leftEyebrow = BrowG.append('rect').attr('width',eyebrowWidth).attr('height',eyebrowHeight).attr('x',-eyeSpacing)const rightEyebrow = BrowG.append('rect').attr('width', eyebrowWidth).attr('height', eyebrowHeight).attr('x', eyeSpacing)復(fù)制代碼

總結(jié)

以上是生活随笔為你收集整理的D3可视化:(1)初次见面,SVG与D3的魅力的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。