当前位置:网站首页>Draw a circular radar chart with canvas
Draw a circular radar chart with canvas
2022-07-24 08:14:00 【Sock is a dog】
First, the requirements design draft is as follows , among 3 A little bit ( The arrow points to ) You need to move on the solid line radius according to the data score , At the same time, the area of the shadow triangle changes .
1 First try whether there are ready-made wheels ,echarts I'm looking for , Have the same , But change it to exactly the same , Some trouble Need to modify the source code , It itself provides API Not satisfied with needs . Of course, if the time is urgent , Can communicate with product design , Make them compromise .
2 Draw by yourself , First, I used the front end canvas. stay html Add a dom
<canvas id='radar-img' style="width:170;height:170" />
The width and height of the canvas need to be css Definition .
Then there is the basic code , establish canvas, Put the bottom picture on , Then put some bitmap , I won't write the code because it's hard to use .
shortcoming 1 Adjust the canvas to match the size of the original picture , The picture is also blurred
shortcoming 2 The width, height and coordinates of the image cannot be consistent with the logic of the code , Debugging is very difficult .
So I didn't think much , Gave up , There have been before html2canvas Of bug, The compatibility between different devices is not good .
The final plan is to use node-canvas, Draw pictures on the server , The send interface returns a base64 Picture to the front , The front end only needs to send data to the interface , Interface returns a drawn picture . There is no problem of device compatibility on the server , Drawing and debugging are also in place .
Because of the fixed 3 Score data of dimensions , So the map directly puts all the rings and 120 Cut the degree line directly , So I let the design give me 2 Pictures ( Of course, a picture can be drawn without , It mainly takes time )
as follows :
At this point, we can use a larger figure , The canvas is also a little bigger , So it's clear
I have thought about the realization idea before painting , It mainly uses a mathematical formula
The coordinates of a coordinate point after rotating a certain angle around the dot
Right triangle functions come in handy here
The final code is as follows :( The code is complete , Installation dependency can run independently )
var app = express();
const {
createCanvas, loadImage } = require('canvas');
// Using middleware body-parser obtain post Parameters
app.use(bodyParser.urlencoded({
extended: false}));
app.use(bodyParser.json());
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", req.headers.origin);
res.header("Access-Control-Allow-Credentials", "true");
res.header("Access-Control-Allow-Methods", "GET, POST, PUT,DELETE,OPTIONS,PATCH");
res.header("Access-Control-Allow-Headers", "channel, mch_id, cache-control, authorization, client, x-cookie, content-type");
res.header("Access-Control-Request-Headers", "Origin, X-Requested-With, content-Type, Accept, Authorization");
res.header("X-Powered-By", ' 3.2.1');
res.header("Content-Type", "application/json;charset=utf-8");
console.log(req.query.score_1,req.query.score_2,req.query.score_3);
var bgImg = 'https://jdxl-img.jdxlt.com/uploads/7f92fb1b31dd45d9aef6892001bae3f4.png';
var pointImg = 'https://jdxl-img.jdxlt.com/uploads/cc614fbdd32a49da827cdf201a7f43c7.png';
const canvas = createCanvas(680, 680);
const ctx = canvas.getContext('2d');
var promise_1 = new Promise(function(resolve, reject){
loadImage(bgImg).then((image) => {
resolve(image);
})
})
var promise_2 = new Promise(function(resolve, reject){
loadImage(pointImg).then((image) => {
resolve(image);
})
})
const calculateRotate = (point, degree) => {
let x = point.x * Math.cos(degree * Math.PI / 180) + point.y * Math.sin(degree * Math.PI / 180);
let y = -point.x * Math.sin(degree * Math.PI / 180) + point.y * Math.cos(degree * Math.PI / 180);
let relativeOriginPoint = {
x: Math.round(x * 100) / 100,
y: Math.round(y * 100) / 100
};
return relativeOriginPoint;
};
Promise.all([promise_1,promise_2]).then(function(data){
var point_2 = calculateRotate({
x:0,y:Math.round(340-(340*req.query.score_2/100))},120);
var point_3 = calculateRotate({
x:0,y:Math.round(340-(340*req.query.score_3/100))},240);
// Triangle shadow
ctx.beginPath();
ctx.moveTo(340,(340-Math.round(340*(100-req.query.score_1)/100))); // Because dot 1 No degrees of rotation y The axis is positive
ctx.lineTo(340+point_2.x,340-point_2.y);
ctx.lineTo(340+point_3.x,340-point_3.y);
ctx.fillStyle='rgba(109, 128, 157, 0.3)';
// Transparency fill
ctx.globalAlpha=0.5;
ctx.fill();
// Restore transparency Draw on 3 A little bit
ctx.globalAlpha=1;
ctx.drawImage(data[0],0,0,680,680); // Background map
ctx.drawImage(data[1],(340-24),(340-Math.round(340*(100-req.query.score_1)/100))-24,48,48); // Image point
ctx.drawImage(data[1],(point_2.x+340-24),(340-point_2.y-24),48,48); // Image point
ctx.drawImage(data[1],(point_3.x+340-24),(340-point_3.y-24),48,48); // Image point
let result = {
code: 0,
msg: '',
data:canvas.toDataURL()
}
res.send(JSON.stringify(result));
})
})
app.listen(1320,function(){
console.log('port 1320 is running!');
});
It needs to be noted that
1 Cross domain solution code
res.header("Access-Control-Allow-Origin", req.headers.origin);
res.header("Access-Control-Allow-Credentials", "true");
res.header("Access-Control-Allow-Methods", "GET, POST, PUT,DELETE,OPTIONS,PATCH");
res.header("Access-Control-Allow-Headers", "channel, mch_id, cache-control, authorization, client, x-cookie, content-type");
res.header("Access-Control-Request-Headers", "Origin, X-Requested-With, content-Type, Accept, Authorization");
res.header("X-Powered-By", ' 3.2.1');
res.header("Content-Type", "application/json;charset=utf-8");
2 The coordinate method after a coordinate point rotates a certain angle around the dot ( use 0, 90 rotate 90 Degree has been verified , Later practice is really useful )
const calculateRotate = (point, degree) => {
let x = point.x * Math.cos(degree * Math.PI / 180) + point.y * Math.sin(degree * Math.PI / 180);
let y = -point.x * Math.sin(degree * Math.PI / 180) + point.y * Math.cos(degree * Math.PI / 180);
let relativeOriginPoint = {
x: Math.round(x * 100) / 100,
y: Math.round(y * 100) / 100
};
return relativeOriginPoint;
};
The rest is canvas Basic function api, Check it all :
1 How to draw a triangle
2 How to set transparency
3 When drawing, you can define coordinates and width and height
4 The upper left corner is the coordinate point (0,0) And the normal coordinate system y The axis is reversed , And the point of rotation is not the origin , Is one of the coordinates So you need to calculate
The final results :
边栏推荐
- P1739 expression bracket matching problem solution
- P1135 strange elevator problem solution
- Learning dynamic Siamese network for visual object tracking full text translation
- Example of dictionary
- SIFT feature point extraction
- Digital twin demonstration project -- Talking about simple pendulum (3) solid model exploration
- Shared lock, exclusive lock, mutex lock, pessimistic lock, optimistic lock, row lock, table lock, page lock, non repeatable read, lost modification, read dirty data
- Jetson AgX Orin source change
- What is NFT? An article to understand the concept of NFT
- [Linux] Oracle VirtualBox installation CentOS 8
猜你喜欢

Figure New Earth: how the RVT format BIM model modeled by Revit can accurately match the map with texture

MySQL -- subquery scalar subquery

The vision group of Hegong University Sky team trained Day1 - machine learning, and learned to use the Yolo model
![[target detection] IOU (intersection and combination ratio)](/img/16/d1bd89582e0e04a627e7909eb4f31d.png)
[target detection] IOU (intersection and combination ratio)

33 introduction to sparksql, dataframe and dataset

Robert operator, Sobel operator, Laplace operator

图新地球:如何导入修改了高程基准(椭球)的CAD文件
![[redis] how much do you know about bloom filter and cuckoo filter?](/img/f0/8bcbe82bd6d412e68d85450f5894e3.png)
[redis] how much do you know about bloom filter and cuckoo filter?

FPGA综合项目——图像边缘检测系统

What is the NFT concept.. Fully understand NFT market, technology and cases
随机推荐
NFT概念究竟是怎么回事。。全面了解NFT市场、技术和案例
CNN-VINS
图新地球:如何导入修改了高程基准(椭球)的CAD文件
避坑,职场远离PUA,PUA常见的套路与话术你得了解一下!
MySQL uses explain to analyze SQL execution plans to help find performance bottlenecks
Database | simple hospital patient appointment system based on opengauss
Assembly | screen display numbers
MySQL update uses case when to update the value of another field according to the value of one field
[redis] how much do you know about bloom filter and cuckoo filter?
45. Jumping game II
【MATLAB】(四)MATLAB在线性代数中的应用
生成模型与判别模型
Learn - use do... While loop according to the formula e=1+1/1+ 1/2!+ 1/3!+…+ 1/n! Calculate the value of E (accuracy is 1e-6)
Figure New Earth: how to import CAD files with modified elevation datum (ellipsoid)
Digital twin demonstration project -- Talking about simple pendulum (2) vision exploration and application scenarios
基于thinkphp将execle表格上传并插入数据库
Kotlin coroutine (I): foundation and deepening
Natural language processing hanlp
[database] complete SQL statement
[Beijiao] image processing: basic concepts, image enhancement, morphological processing, image segmentation