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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

手动实现一个速度仪表盘

發布時間:2025/3/20 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 手动实现一个速度仪表盘 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

最近正在學習數據可視化, 這里記錄一下一些心得與成果, 采用的技術是 (svg + react + d3)。 這種實現可視化方式本人個人感覺超級不錯,如果你是有一定的基礎的同學,強烈推薦一下。

效果

整體效果如下:

這個是普通的速度儀表盤,有沒有開發太多的動態交互,唯一的交互是點擊圖片最上面的加速與減速就能夠調整速度了。

開發思路

搭建開發環境

使用create-react-app創建一個新的項目,添加依賴d3

yarn add d3

初始化數據

這里速度范圍是[0, 200], 對應角度范圍個人設置是[150, 390], 很明顯這是一個線性比例尺。速度間隔是2。代碼如下

const scale = d3.scaleLinear().domain([0, 200]).range([150, 360 + 30]) const ticks = scale.ticks(100) // 200 / 2 => 100

構建外部圈

function Chart(props) {const { width, height, margin } = propsreturn (<svg width={width} height={height}><g transform={`translate(${margin.left}, ${margin.top})`}>{props.children}</g></svg>) }...... export default class Meter extends Component { ... render () {// config => {width: xxx, height: xxx, margin: xxx}return (<div className={'container'}><Chart {...config}><g><circle cx={0} cy={0} r={204} fill={'rgba(158, 158, 158, .4)'}></circle><circle cx={0} cy={0} r={196} fill={'#FFF'}></circle><circle cx={0} cy={0} r={200} fill={'transparent'} stroke={'#000'}></circle></g></Chart></div>)} }

上面其實是繪畫了三個圓, 利用SVG后面的繪制的圖畫,會覆蓋前面的圖畫的特性。先畫最外面,然后最里面,最后中間的圓。 就把最外層的圈給描繪出來了,效果如下:

描繪刻度尺

接著上面的代碼結構,我們開始刻畫刻度尺

...... export default class Meter extends Component { ... render () {// config => {width: xxx, height: xxx, margin: xxx}return (<div className={'container'}><Chart {...config}><g><circle cx={0} cy={0} r={204} fill={'rgba(158, 158, 158, .4)'}></circle><circle cx={0} cy={0} r={196} fill={'#FFF'}></circle><circle cx={0} cy={0} r={200} fill={'transparent'} stroke={'#000'}></circle></g><g fill={'transport'} stroke={'#000000'}>{ticks.map((tick) => {let IS_20_TIME = tick % 20 === 0let title = IS_20_TIME ? <text x={160} dominantBaseline={'middle'} textAnchor={'end'}>{tick}</text> : ''return (<g transform={`rotate(${scale(tick)})`} key={tick}><path d={`M165, 0L185,0`} strokeWidth={IS_20_TIME ? 3 : 1}></path>{title}</g>)})}</g></Chart></div>)} }

這里刻畫刻度尺,我的思路很簡單,刻度尺是對速度大小的描述,而速度跟角度又是線性相關,反過來,速度對應角度。所以,我只是需要根據速度所對應的角度,而對水平刻度進行旋轉即可。效果大家可以看到:

指向針

指向針其實就是一個圓 + 三角形的組合,代碼如下:

<circle cx={0} cy={0} r={10} fill={'#'}></circle><path d={`M-20, 5L-20, -5L130, 0Z`} transform={`rotate(150)`}><animateTransform ></animateTransform></path>

上面本人實現的比較粗糙,大家可以把這個封裝成一個shape, 以后可以直接復用的,后面如果需要旋轉,可以通過<g>元素來實現。

到這一步,一個簡單的儀表盤就初具原型了

控制指針轉動

指針的轉動是根據速度來的,所以我們需要先定義一個speed的狀態。

constructor(props) {super(props)this.state = {speed: 0}}

接下來,我們需要把speed映射到指針上面。怎么處理呢
還記得前面定義的scale,這個是一個線性比例尺,通過它我們能夠獲取不同速度對應的角度
我們把上面的指向針代碼進行改造

const {speed} = this.state ...... <circle cx={0} cy={0} r={10} fill={'#'}></circle> <path d={`M-20, 5L-20, -5L130, 0Z`} transform={`rotate(${scale(speed)})`}><animateTransform ></animateTransform> </path>

這樣我們設置不同的speed就能在頁面控制指針指向不同的刻度尺。

速度標識區間

所謂的速度標識區間,其實就是幾段圓弧,通過不同的顏色來告知進入不同的速度區間。
這里我對圓弧進行了封裝,底層通過d3的arc方法來創建圓弧。

function LArc(props) {const { start, end, color } = propslet _arc = d3.arc()({innerRadius: 165,outerRadius: 185,startAngle: Math.PI * 2 * (scale(start) + 90) / 360,endAngle: Math.PI * 2 * (scale(end) + 90) / 360})return (<path d={_arc} fill={color}></path>) }

這里其實還有一個問題,就是需要先加載速度標識區間,然后再去添加刻度尺,不然標識區間會覆蓋刻度尺(切記)。
這樣一個基本速度儀表盤就出來了

如果你能明白上面的實現思路,我覺得你可以自己實現一個時鐘了

如果你想了解更多:比如指示器如何實現的
請參考
https://github.com/cookhot/i-...
(本人會在里面不定期增加新圖表哦)

總結

以上是生活随笔為你收集整理的手动实现一个速度仪表盘的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。