手动实现一个速度仪表盘
前言
最近正在學(xué)習(xí)數(shù)據(jù)可視化, 這里記錄一下一些心得與成果, 采用的技術(shù)是 (svg + react + d3)。 這種實現(xiàn)可視化方式本人個人感覺超級不錯,如果你是有一定的基礎(chǔ)的同學(xué),強烈推薦一下。
效果
整體效果如下:
這個是普通的速度儀表盤,有沒有開發(fā)太多的動態(tài)交互,唯一的交互是點擊圖片最上面的加速與減速就能夠調(diào)整速度了。
開發(fā)思路
搭建開發(fā)環(huán)境
使用create-react-app創(chuàng)建一個新的項目,添加依賴d3
yarn add d3初始化數(shù)據(jù)
這里速度范圍是[0, 200], 對應(yīng)角度范圍個人設(shè)置是[150, 390], 很明顯這是一個線性比例尺。速度間隔是2。代碼如下
const scale = d3.scaleLinear().domain([0, 200]).range([150, 360 + 30]) const ticks = scale.ticks(100) // 200 / 2 => 100構(gòu)建外部圈
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后面的繪制的圖畫,會覆蓋前面的圖畫的特性。先畫最外面,然后最里面,最后中間的圓。 就把最外層的圈給描繪出來了,效果如下:
描繪刻度尺
接著上面的代碼結(jié)構(gòu),我們開始刻畫刻度尺
...... 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>)} }這里刻畫刻度尺,我的思路很簡單,刻度尺是對速度大小的描述,而速度跟角度又是線性相關(guān),反過來,速度對應(yīng)角度。所以,我只是需要根據(jù)速度所對應(yīng)的角度,而對水平刻度進行旋轉(zhuǎn)即可。效果大家可以看到:
指向針
指向針其實就是一個圓 + 三角形的組合,代碼如下:
<circle cx={0} cy={0} r={10} fill={'#'}></circle><path d={`M-20, 5L-20, -5L130, 0Z`} transform={`rotate(150)`}><animateTransform ></animateTransform></path>上面本人實現(xiàn)的比較粗糙,大家可以把這個封裝成一個shape, 以后可以直接復(fù)用的,后面如果需要旋轉(zhuǎn),可以通過<g>元素來實現(xiàn)。
到這一步,一個簡單的儀表盤就初具原型了
控制指針轉(zhuǎn)動
指針的轉(zhuǎn)動是根據(jù)速度來的,所以我們需要先定義一個speed的狀態(tài)。
constructor(props) {super(props)this.state = {speed: 0}}接下來,我們需要把speed映射到指針上面。怎么處理呢
還記得前面定義的scale,這個是一個線性比例尺,通過它我們能夠獲取不同速度對應(yīng)的角度
我們把上面的指向針代碼進行改造
這樣我們設(shè)置不同的speed就能在頁面控制指針指向不同的刻度尺。
速度標(biāo)識區(qū)間
所謂的速度標(biāo)識區(qū)間,其實就是幾段圓弧,通過不同的顏色來告知進入不同的速度區(qū)間。
這里我對圓弧進行了封裝,底層通過d3的arc方法來創(chuàng)建圓弧。
這里其實還有一個問題,就是需要先加載速度標(biāo)識區(qū)間,然后再去添加刻度尺,不然標(biāo)識區(qū)間會覆蓋刻度尺(切記)。
這樣一個基本速度儀表盤就出來了
如果你能明白上面的實現(xiàn)思路,我覺得你可以自己實現(xiàn)一個時鐘了
如果你想了解更多:比如指示器如何實現(xiàn)的
請參考
https://github.com/cookhot/i-...
(本人會在里面不定期增加新圖表哦)
總結(jié)
以上是生活随笔為你收集整理的手动实现一个速度仪表盘的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql binlog2sql闪回数据
- 下一篇: i-i.me:网址导航真的是伪需求吗?