/
renderPureRadar.js
171 lines (156 loc) · 4.71 KB
/
renderPureRadar.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
let canvasHeight = 540;
let canvasWidth = 540;
function ratio(num) {
return canvasWidth * num;
}
function titleCase(str) {
const arr = str.split(' ');
for (let i = 0; i < arr.length; i++) {
arr[i] = arr[i].slice(0, 1).toUpperCase() + arr[i].slice(1).toLowerCase();
}
return arr.join(' ');
}
function getTopics(init, ctx, canvas) {
const topics = init.scores;
const angle = Math.floor(360 / topics.length);
const offsetAngle = -angle / 4;
const startX = canvas.width / 2;
const startY = canvas.height / 2;
for (let i = 0; i < topics.length; i++) {
const angleCur = angle * (i + 1) + offsetAngle;
// 获取角坐标
const pointCoordinate = getValuePoint(startX, startY, 115, angleCur);
const topic = topics[i];
// 文本
const text1 = titleCase(`${topic.type}`);
ctx.font = `bold ${ratio(0.04)}px Arial`;
ctx.fillStyle = '#671fc5';
ctx.textAlign = 'center';
ctx.fillText(text1, pointCoordinate.x, pointCoordinate.y);
const text2 = titleCase(`${topic.score}`);
ctx.font = `bold ${ratio(0.04)}px Arial`;
ctx.fillStyle = '#671fc5';
ctx.textAlign = 'center';
ctx.fillText(text2, pointCoordinate.x, pointCoordinate.y + ratio(0.04));
}
}
/**
* 绘制雷达地图
* @param ctx
* @param canvas
* @param length
*/
function getPentagon(ctx, canvas, length) {
// 按照实际数组大小进行360的n等分
const angle = Math.floor(360 / length);
// 便宜角度,用于和雷达底图角度对齐
const offsetAngle = -angle / 4;
const startX = canvas.width / 2;
const startY = canvas.width / 2;
for (let i = 0; i < 5; i++) {
let radius = 100; // 这个为外圈的半径
radius = radius / 5 * (i + 1); // 5等分半径
ctx.beginPath();
for (let i = 0; i < length; i++) {
const value = getValuePoint(startX, startY, radius, angle * (i + 1) + offsetAngle);
if (i === 0) {
ctx.moveTo(value.x, value.y);
} else {
ctx.lineTo(value.x, value.y);
}
}
ctx.closePath();
ctx.strokeStyle = "#b04119";
ctx.strokeWidth = ratio(1 / 640 * 3);
ctx.stroke();
}
}
/**
* 根据分数获取需要移动的坐标
* @param xDef 中心点x
* @param yDef 中心点y
* @param value 数值
* @param angle 偏移角度
* @returns {{x: *, y: *}}
*/
function getValuePoint(xDef, yDef, value, angle) {
const rat = ratio(0.3) / 100 * value;
const x = xDef + rat * Math.cos(angle * Math.PI / 180);
const y = yDef + rat * Math.sin(angle * Math.PI / 180);
return {
x,
y,
};
}
/**
* 绘制数值图
* @param init
* @param ctx
* @param canvas
*/
function getValues(init, ctx, canvas) {
const topics = init.scores;
// 按照实际数组大小进行360的n等分
const angle = Math.floor(360 / topics.length);
// 便宜角度,用于和雷达底图角度对齐
const offsetAngle = -angle / 4;
// 绘制不规则图形
ctx.beginPath();
const startX = canvas.width / 2;
const startY = canvas.height / 2;
for (let i = 0; i < topics.length; i++) {
const value = getValuePoint(startX, startY, topics[i].score, angle * (i + 1) + offsetAngle);
if (i === 0) {
ctx.moveTo(value.x, value.y);
} else {
ctx.lineTo(value.x, value.y);
}
}
ctx.closePath();
ctx.fillStyle = "#2c00b0";
ctx.stroke = '#ffc71d';
ctx.strokeWidth = ratio(1 / 640 * 3);
ctx.globalAlpha = 0.6;
ctx.fill();
ctx.globalAlpha = 1;
}
/**
* 绘制canvas
* @param init 雷达图数据结构
* @param offsetWidth canvas画布宽度
* @param offsetHeight canvas画布高度
* @returns {Konva.Stage}
*/
function initScene(canvasContainer, init, offsetWidth, offsetHeight) {
canvasHeight = offsetHeight;
canvasWidth = offsetWidth;
const container = document.getElementById(canvasContainer);
const canvas = document.createElement('canvas');
container.appendChild(canvas);
canvas.height = canvasHeight;
canvas.width = canvasWidth;
// console.log('canvas', canvas.width);
if (canvas.getContext) {
const ctx = canvas.getContext('2d');
console.log('ctx', ctx);
console.log('drawing code here');
// 绘制雷达底图
getPentagon(ctx, canvas, init.scores.length);
// 绘制雷达数值图
getValues(init, ctx, canvas);
// 绘制文字
ctx.font = `italic bold ${ratio(1 / 640 * 28)}px Arial`;
ctx.fillStyle = '#b04119';
ctx.textAlign = 'center';
ctx.fillText(init.label, canvasHeight / 2, canvasWidth / 2 - ratio(0.1));
ctx.font = `italic bold ${ratio(1 / 640 * 160)}px Arial`;
ctx.fillStyle = '#ffda1d';
ctx.textAlign = 'center';
ctx.fillText(init.score, canvasHeight / 2, canvasWidth / 2 + ratio(0.1));
// 绘制各角文字
getTopics(init, ctx, canvas);
} else {
console.log('canvas-unsupported code here');
}
}
export { initScene };