Effect picture:The implementation code is as followsview <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 //Number of elements const numSlot = 4 //Total number of nodes on a line const mW = toRpx(275) //Canvas width const mCenter = mW / 2 //Center point const mAngle = Math.PI * 2 / numCount //Angle const mRadius = mCenter - toRpx(43) //Radius (the subtracted value is used to leave space for drawn text) let canvas = null // canvas let canvasCtx = null // canvas context export default { name: 'RadarChart', props: { }, methods: { // Initialize the radar chart and execute initDrawRadar() when the component is mounted { 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) }) }, // Start drawing handleDraw(radarData) { this.drawEdge() this.drawLinePoint() this.drawText(radarData) this.drawSubText(radarData) this.drawEdgeDot() this.drawRegion(radarData, 'rgba(255, 105, 81, 0.4)') }, // Draw the edge of the circle drawEdge() { canvasCtx.strokeStyle = '#EEEEEE' for (let i = 0; i < numSlot; i++) { // Calculate the radius let radius = mRadius / numSlot * (i + 1) if (i === 3) { canvasCtx.lineWidth = toRpx(4) // Set line width canvasCtx.beginPath() canvasCtx.arc(mCenter, mCenter, radius, 0, 2 * Math.PI,) // Start drawing a circle canvasCtx.stroke() } else { canvasCtx.lineWidth = toRpx(1) const space = 60 + 10 * (i+1) this.drawDashCircle(mCenter, mCenter, radius, space) } } }, // Draw the outer border dot 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() }, // Draw a dotted circle drawDashCircle(x, y, radius, space = 100) { const gap = 2 * Math.PI / space canvasCtx.lineCap = 'square' let start = 0; // Start drawing from the origin while (start <= 2 * Math.PI) { let end = start + gap canvasCtx.beginPath() //Start a new path canvasCtx.arc(x, y, radius, start, end, false) start = gap + end canvasCtx.stroke() //Stroke the current path} }, // Draw the connection point 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() }, // Draw text information drawText(mData) { canvasCtx.fillStyle = '#222325' canvasCtx.font = `bold ${toRpx(14)}px PingFangSC-Medium, PingFang SC` //Set font 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) //Adjust the display position of the text through different positions 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) } } }, // Draw text information drawSubText(mData) { canvasCtx.fillStyle = '#8D949B' canvasCtx.font = `${toRpx(11)}px PingFangSC-Medium, PingFang SC` //Set font 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) //Adjust the display position of the text through different positions 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)) } } }, //Draw the red data area (data and fill color) drawRegion(mData, color){ canvasCtx.strokeStyle = '#FF6951' canvasCtx.lineWidth = toRpx(4) // Set line width 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> It should be noted that this is encapsulated as a component call. When initializing, const query = uni.createSelectorQuery().in(this), in(this) must be added, otherwise an error message that the node cannot be found will be reported. export function toRpx(val) { const res = uni.getSystemInfoSync() const scaleRate = res.windowWidth / 375 return val * scaleRate } Call in the page <template> <!--Radar Chart--> <radar-chart :radarData="radarData" ref="radarRef"></radar-chart> </template> import RadarChart from './components/radar' export default { components: RadarChart, }, data() { return { radarData:[["Listening", 0], ["Speaking", 0], ["Grammar", 0], ["Vocabulary", 0], ["Reading", 0]], } }, methods: { getData() { // After the request data is returned, call the component method to render this.$refs.radarRef.handleDraw(this.radarData) } } } SummarizeThis is the end of this article about the uniapp encapsulated mini-program radar chart component. For more relevant uniapp encapsulated mini-program radar chart component content, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future! You may also be interested in:
|
<<: Detailed explanation of using split command to split Linux files
>>: MySQL deadlock routine: inconsistent batch insertion order under unique index
Currently I have made a project, the interface is ...
Table of contents Preface Architecture at a Glanc...
This article describes the MySQL slow query opera...
Table of contents 1. Pull the image 2. Create a R...
Cocos Creator modular script Cocos Creator allows...
Today, I will answer these newbie questions: Build...
First, let me briefly introduce what MySQL is; In...
The layout of text has some formatting requiremen...
Preface Basically, programmers in the workplace u...
When using setinterval, it is found that it will ...
Similar to the code hosting service provided by G...
This article originated from the homework assignm...
Overlay network analysis Built-in cross-host netw...
1. Find duplicate rows SELECT * FROM blog_user_re...
1 The select tag must be closed <select><...