uniapp封裝小程序雷達(dá)圖組件的完整代碼
效果圖:
實(shí)現(xiàn)代碼如下
view
<canvas id="radar-canvas" class="radar-canvas" type="2d"></canvas>
style
.radar-canvas width 550rpx height 550rpx margin 0 auto
script
<script> import { toRpx } from "@/utils/common" const numCount = 5 //元素個(gè)數(shù) const numSlot = 4 //一條線上的總節(jié)點(diǎn)數(shù) const mW = toRpx(275) //Canvas的寬度 const mCenter = mW / 2 //中心點(diǎn) const mAngle = Math.PI * 2 / numCount //角度 const mRadius = mCenter - toRpx(43) //半徑(減去的值用于給繪制的文本留空間) let canvas = null // canvas let canvasCtx = null // canvas context export default { name: 'RadarChart', props: { }, methods: { // 初始化雷達(dá)圖,在組件掛載的時(shí)候執(zhí)行 initDrawRadar() { console.log('init') const query = uni.createSelectorQuery().in(this) query.select('#radar-canvas').fields({ node: true, size: true }).exec((res) => { canvas = res[0].node canvasCtx = canvas.getContext('2d') const dpr = uni.getSystemInfoSync().pixelRatio canvas.width = res[0].width * dpr canvas.height = res[0].height * dpr canvasCtx.scale(dpr, dpr) }) }, // 開(kāi)始執(zhí)行繪制 handleDraw(radarData) { this.drawEdge() this.drawLinePoint() this.drawText(radarData) this.drawSubText(radarData) this.drawEdgeDot() this.drawRegion(radarData, 'rgba(255, 105, 81, 0.4)') }, // 繪制圓邊 drawEdge() { canvasCtx.strokeStyle = '#EEEEEE' for (let i = 0; i < numSlot; i++) { // 計(jì)算半徑 let radius = mRadius / numSlot * (i + 1) if (i === 3) { canvasCtx.lineWidth = toRpx(4) // 設(shè)置線寬 canvasCtx.beginPath() canvasCtx.arc(mCenter, mCenter, radius, 0, 2 * Math.PI,) // 開(kāi)始畫(huà)圓 canvasCtx.stroke() } else { canvasCtx.lineWidth = toRpx(1) const space = 60 + 10 * (i+1) this.drawDashCircle(mCenter, mCenter, radius, space) } } }, // 繪制外邊框圓點(diǎn) drawEdgeDot(x, y) { canvasCtx.fillStyle = '#EEEEEF' canvasCtx.beginPath() for (let k = 0; k < numCount; k++) { let x = mCenter + mRadius * Math.cos(mAngle * k - Math.PI / 2) let y = mCenter + mRadius * Math.sin(mAngle * k - Math.PI / 2) canvasCtx.arc(x, y, toRpx(5), Math.PI * 2, 0, true) canvasCtx.closePath() } canvasCtx.fill() }, // 繪制虛線圓 drawDashCircle(x, y, radius, space = 100) { const gap = 2 * Math.PI / space canvasCtx.lineCap ='square' let start = 0; //從原點(diǎn)開(kāi)始畫(huà) while (start <= 2 * Math.PI) { let end = start + gap canvasCtx.beginPath() //開(kāi)始一個(gè)新的路徑 canvasCtx.arc(x, y, radius, start, end, false) start = gap + end canvasCtx.stroke() //對(duì)當(dāng)前路徑進(jìn)行描邊 } }, // 繪制連接點(diǎn) drawLinePoint() { canvasCtx.lineWidth = toRpx(1) canvasCtx.beginPath() for (let k = 0; k < numCount; k++) { let x = mCenter + mRadius * Math.cos(mAngle * k - Math.PI / 2) let y = mCenter + mRadius * Math.sin(mAngle * k - Math.PI / 2) canvasCtx.moveTo(mCenter, mCenter) canvasCtx.lineTo(x, y) } canvasCtx.stroke() }, // 繪制文本信息 drawText(mData) { canvasCtx.fillStyle = '#222325' canvasCtx.font = `bold ${toRpx(14)}px PingFangSC-Medium, PingFang SC` //設(shè)置字體 for (let n = 0; n < numCount; n++) { let x = mCenter + mRadius * Math.cos(mAngle * n - Math.PI / 2) let y = mCenter + mRadius * Math.sin(mAngle * n - Math.PI / 2) //通過(guò)不同的位置,調(diào)整文本的顯示位置 const text = mData[n][0] if (n === 0) { canvasCtx.fillText(text, x - toRpx(12), y - toRpx(30)) } if (n === 1) { canvasCtx.fillText(text, x + toRpx(12), y) } if (n === 2) { canvasCtx.fillText(text, x + toRpx(12), y + toRpx(20)) } if (n === 3) { canvasCtx.fillText(text, x - toRpx(36), y + toRpx(20)) } if (n === 4) { canvasCtx.fillText(text, x - toRpx(40), y) } } }, // 繪制文本信息 drawSubText(mData) { canvasCtx.fillStyle = '#8D949B' canvasCtx.font = `${toRpx(11)}px PingFangSC-Medium, PingFang SC` //設(shè)置字體 for (let n = 0; n < numCount; n++) { const x = mCenter + mRadius * Math.cos(mAngle * n - Math.PI / 2) const y = mCenter + mRadius * Math.sin(mAngle * n - Math.PI / 2) //通過(guò)不同的位置,調(diào)整文本的顯示位置 const text = `(${mData[n][1]})` if (n === 0) { canvasCtx.fillText(text, x - canvasCtx.measureText(text).width / 2, y - toRpx(10)) } if (n === 1) { canvasCtx.fillText(text, x + canvasCtx.measureText(text).width, y + toRpx(16)) } if (n === 2) { canvasCtx.fillText(text, x + canvasCtx.measureText(text).width - toRpx(4), y + toRpx(40)) } if (n === 3) { canvasCtx.fillText(text, x - canvasCtx.measureText(text).width - toRpx(12), y + toRpx(40)) } if (n === 4) { canvasCtx.fillText(text, x - canvasCtx.measureText(text).width - toRpx(16), y + toRpx(16)) } } }, //繪制紅色數(shù)據(jù)區(qū)域(數(shù)據(jù)和填充顏色) drawRegion(mData, color){ canvasCtx.strokeStyle = '#FF6951' canvasCtx.lineWidth = toRpx(4) // 設(shè)置線寬 canvasCtx.beginPath() for (let m = 0; m < numCount; m++){ let x = mCenter + mRadius * Math.cos(mAngle * m - Math.PI / 2) * mData[m][1] / 100 let y = mCenter + mRadius * Math.sin(mAngle * m - Math.PI / 2) * mData[m][1] / 100 canvasCtx.lineTo(x, y) } canvasCtx.closePath() canvasCtx.fillStyle = color canvasCtx.fill() canvasCtx.stroke() }, }, mounted() { this.initDrawRadar() } } </script>
要注意的點(diǎn)是,這里是封裝成組件調(diào)用,在初始化的時(shí)候,const query = uni.createSelectorQuery().in(this),要加上in(this),否則會(huì)報(bào)找不到node節(jié)點(diǎn)的錯(cuò)誤信息
export function toRpx(val) { const res = uni.getSystemInfoSync() const scaleRate = res.windowWidth / 375 return val * scaleRate }
在頁(yè)面中調(diào)用
<template> <!--雷達(dá)圖--> <radar-chart :radarData="radarData" ref="radarRef"></radar-chart> </template> import RadarChart from './components/radar' export default { components: { RadarChart, }, data() { return { radarData:[["聽(tīng)力", 0], ["口語(yǔ)",0], ["語(yǔ)法",0], ["詞匯",0], ["閱讀",0]], } }, methods: { getData() { // 請(qǐng)求數(shù)據(jù)返回后,調(diào)用組件方法渲染 this.$refs.radarRef.handleDraw(this.radarData) } } }
總結(jié)
到此這篇關(guān)于uniapp封裝小程序雷達(dá)圖組件的文章就介紹到這了,更多相關(guān)uniapp封裝小程序雷達(dá)圖組件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
HTTP?HEAD請(qǐng)求的使用場(chǎng)合實(shí)例詳解
這篇文章主要為大家介紹了HTTP?HEAD請(qǐng)求的使用場(chǎng)合實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12JavaScript canvas復(fù)刻蘋(píng)果發(fā)布會(huì)環(huán)形進(jìn)度條
canvas 真是一個(gè)好東西,它給前端插上了想象的翅膀,伴隨著 h5 而來(lái),將 web 代入了新的領(lǐng)域。本文將利用anvas復(fù)刻蘋(píng)果發(fā)布會(huì)環(huán)形進(jìn)度條,感興趣的可以嘗試一下2022-07-07JavaScript提高網(wǎng)站性能優(yōu)化的建議(二)
這篇文章主要介紹了JavaScript提高網(wǎng)站性能優(yōu)化的建議(二)的相關(guān)資料,需要的朋友可以參考下2016-07-07JavaScript中yield實(shí)用簡(jiǎn)潔實(shí)現(xiàn)方式
原以為是一個(gè)蠻復(fù)雜的題目,想了許久沒(méi)思路,當(dāng)然要實(shí)現(xiàn)絕對(duì)能實(shí)現(xiàn),但如果分析JavaScript腳本或是動(dòng)態(tài)產(chǎn)生代碼,都太復(fù)雜了。2010-06-06如何實(shí)現(xiàn)修改密碼時(shí)密碼框顯示保存到cookie的密碼
修改密碼時(shí)密碼框顯示保存到cookie的密碼,只要在input框中加入AUTOCOMPLETE="OFF" 即可,感興趣的朋友可以了解下2013-12-12如何在selenium中使用js實(shí)現(xiàn)定位
這篇文章主要介紹了如何在selenium中使用js實(shí)現(xiàn)定位,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08