Canvas implements ring chart uni-app (including gradient, data flow form)

Basic parameters

Normal ring chart

Achieve the effect

Implementation process

1. Give the width and height of the canvas through the label, bind the canvas-id and generate it according to this

<canvas class="progress_bg" canvas-id="cpbg"></canvas>

2. The page mount calls the method to render the ring graph

The ctx.beginPath() below generates two ring diagrams before and after opening a new path. The first one represents the gray below, and the second represents blue

 var ctx = uni.createCanvasContext('cpbg', this);
let end = (50 / 100 ) * 2 * Math.PI; //Set radian
console. log(end);
ctx.setLineWidth(12); // Set the width of the ring
ctx.arc(185, 80, 40, 0, 2 * Math.PI)
ctx.setStrokeStyle('#f2f2f2');
ctx.stroke(); //Stroke the current path
// ctx.setLineCap('square'); // Set the shape of the ring endpoint without rounded corners
ctx.beginPath(); //Start a new path
ctx.setStrokeStyle('#0079fe'); // Set the color of the ring
ctx.setLineCap('round'); // Set the shape of the ring end point rounded corners
ctx.arc(185, 80, 40, 0, end, false);
ctx.stroke(); //Stroke the current path
//Set an origin (110,110), the path of a circle with a radius of 100 to the current path
ctx.stroke(); //Stroke the current path
ctx. draw();

Gradient Ring Chart

Effect

Code

 var ctx = uni.createCanvasContext('cpbar', this);
// The gradient of the progress bar (center x coordinate-radius-side width, center Y coordinate, center x coordinate + radius + side width, center Y coordinate)
var gradient = ctx. createLinearGradient(0, 0, 150, 0);

let increase = 0.05;
let end = (50 / 100) * 2 * Math.PI - Math.PI / 2; // final angle
let current = -Math.PI / 2; // starting angle
let timer = setInterval(() => {
gradient.addColorStop('0', '#00F2FE'); //gradient color
gradient.addColorStop('1.0', '#0079fe'); //gradient color
// arc thickness
ctx.setLineWidth(12);
ctx.setStrokeStyle(gradient);
ctx.setLineCap('square');
ctx.beginPath();
// The parameter step is the percentage of drawing
if (current < end) {
current = current + increase;
}
if (current >= end) {
current = end;
clearInterval(timer);
}
ctx.arc(85, 65, 40, -Math.PI / 2, current, false);
ctx.stroke();
ctx. draw();
}, 20);

Data flow ring diagram

Effect

Code


<canvas class="progress_bg" canvas-id="cpbg"></canvas>



{{ progress_txt }}%
Correct rate

mounted: function() {
this. drawProgressbg();
this.drawCircle(this.progress_txt); //The parameter is 1-100
this. drawLine();
},
methods: {
            drawProgressbg: function() {
// The custom component instance this means to find the <canvas/> with canvas-id under this custom component
var ctx = uni.createCanvasContext('cpbg', this);
ctx.setLineWidth(12); // Set the width of the ring
ctx.setStrokeStyle('#E9E9E9'); // Set the color of the ring
// ctx.setLineCap('round'); // Set the shape of the ring endpoint
ctx.setLineCap('square'); // Set the shape of the ring endpoint
ctx.beginPath(); //Start a new path
ctx.arc(85, 65, 40, 0 * Math.PI, 2 * Math.PI, false);
//Set an origin (110,110), the path of a circle with a radius of 100 to the current path
ctx.stroke(); //Stroke the current path
ctx. draw();
},
drawCircle: function(step) {
var ctx = uni.createCanvasContext('cpbar', this);
// The gradient of the progress bar (center x coordinate-radius-side width, center Y coordinate, center x coordinate + radius + side width, center Y coordinate)
var gradient = ctx.createLinearGradient(0, 0, 130, 0);

let increase = 0.05;
let end = (step / 100) * 2 * Math.PI - Math.PI / 2; // final angle
let current = -Math.PI / 2; // starting angle
let timer = setInterval(() => {
gradient.addColorStop('0', '#00F2FE');
gradient.addColorStop('1.0', '#4FACFE');
ctx.setLineWidth(12);
ctx.setStrokeStyle(gradient);
ctx.setLineCap('square');
ctx.beginPath();
// The parameter step is the percentage of drawing
if (current < end) {
current = current + increase;
}
if (current >= end) {
current = end;
clearInterval(timer);
}
ctx.arc(85, 65, 40, -Math.PI / 2, current, false);
ctx.stroke();
ctx. draw();
}, 20);
},
// draw scale
drawLine() {
var context = uni.createCanvasContext("cpline", this);
var r = 40;
var x0 = 85;
var y0 = 65;
var x;
var y;
var lineWidth = 12;

for (let i = 0; i < 60; i ++ ) {
context.beginPath();
context.setLineWidth(lineWidth);
context.setStrokeStyle("#FFFFFF");

x = x0 - r * Math.sin(((6 * (i + 1) - 3) * Math.PI) / 180);
y = y0 - r * Math. cos(((6 * (i + 1) - 3) * Math. PI) / 180);

// console.log('x0:' + x0 + ' y0:' + y0 + ' x:' + x + ' y:' + y);
context.moveTo(x, y);
context.arc(
x0,
y0,
r,
((270 - 6 * (i + 1) + 3) * Math.PI) / 180,
((270 - 6 * i) * Math.PI) / 180,
false
);
context.stroke();
context. closePath();
}
context.stroke();
context. draw();
},
}
. progress_box {
/* position: relative; */
/* width: 100%; */
height: 200upx;
/* background-color: red; */
display: inline-block;
align-items: center;
justify-content: center;
text-align: center;

}
.pcds {
margin-top: 90rpx;
color: black;
}
.progress_bg {
position: absolute;
width: 150px;
height: 150px;
}
.progress_txt {
position: absolute;
font-size: 28upx;
margin-top: 85rpx;
margin-left: 95rpx;
color: #999999;
}
.progress_bar {
position: absolute;
width: 220px;
height: 220px;
}
.progress_line {
position: absolute;
width: 220px;
height: 220px;
}
.progress_info {
font-size: 36upx;
padding-left: 16upx;
letter-spacing: 2upx;
font-size: 45upx;
color: #333333;
}