-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathVerticalLinearBar.js
More file actions
105 lines (90 loc) · 3.95 KB
/
VerticalLinearBar.js
File metadata and controls
105 lines (90 loc) · 3.95 KB
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
// VerticalLinearBar.js
class VerticalLinearBar {
constructor(canvas, options, config) {
this.canvas = canvas;
this.ctx = this.canvas.getContext('2d');
this.options = options;
this.config = config;
}
clear() {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
drawBackground() {
const { verticalOffset, width, height, marginTop } = this.options;
this.ctx.fillStyle = '#1a1a1a';
this.ctx.fillRect(0, marginTop, width, height - marginTop);
}
drawBar(value) {
const { verticalOffset, width, height, marginTop, maxValue, color, centered, positiveOnly } = this.options;
let barHeight;
if (positiveOnly) {
// Ensure value is non-negative
value = Math.max(0, value);
barHeight = (value / maxValue) * (height - marginTop);
this.ctx.fillStyle = color;
this.ctx.fillRect(0, height - barHeight, width, barHeight);
} else if (centered) {
barHeight = (Math.abs(value) / maxValue) * (height - marginTop) / 2;
this.ctx.fillStyle = value >= 0 ? color : '#8b4513'; // Blue for positive, brown for negative
this.ctx.fillRect(0, height / 2 - (value <= 0 ? 0 : barHeight), width, barHeight);
} else {
barHeight = (Math.abs(value) / maxValue) * (height - marginTop) / 2;
this.ctx.fillStyle = value >= 0 ? color : '#8b4513'; // Blue for positive, brown for negative
this.ctx.fillRect(0, height / 2 - (value <= 0 ? 0 : barHeight), width, barHeight);
}
}
drawGraduations() {
const { verticalOffset, width, height, marginTop, maxValue, unit, centered, positiveOnly } = this.options;
const { graduationStep } = this.config;
this.ctx.strokeStyle = '#ffffff';
this.ctx.lineWidth = 1;
for (let value = -maxValue; value <= maxValue; value += graduationStep) {
if (positiveOnly && value < 0) continue; // Skip negative values if positiveOnly is true
let y;
if (centered) {
y = height / 2 - (value / maxValue) * (height - marginTop) / 2;
} else if (positiveOnly) {
y = height - (value / maxValue) * (height - marginTop);
} else {
y = height / 2 - (value / maxValue) * (height - marginTop) / 2;
}
this.ctx.beginPath();
this.ctx.moveTo(0, y);
this.ctx.lineTo(width, y);
this.ctx.stroke();
this.ctx.fillStyle = '#ffffff';
this.ctx.font = '14px Arial';
this.ctx.fillText(value, width + 5, y + 5);
this.ctx.fillStyle = '#ffffff';
this.ctx.font = '12px Arial';
this.ctx.fillText(unit, width + 5, y + 18);
}
}
drawDigitalDisplay(value) {
const { unit } = this.options;
const valueText = value.toFixed(1).padStart(5, '0');
const textWidth = this.ctx.measureText(valueText).width;
const textHeight = 20;
const boxPadding = 3;
const boxWidth = this.canvas.width - 4;
const boxHeight = textHeight * 2 + 2 * boxPadding;
const boxX = 2;
const boxY = this.canvas.height - boxHeight - 2;
this.ctx.strokeStyle = '#ffffff';
this.ctx.lineWidth = 1;
this.ctx.strokeRect(boxX, boxY, boxWidth, boxHeight);
this.ctx.fillStyle = '#00ff00';
this.ctx.font = '16px Arial';
this.ctx.fillText(valueText, (this.canvas.width - textWidth) / 2 - boxPadding - 3, boxY + boxHeight - boxPadding - textHeight);
this.ctx.fillStyle = '#ffff00';
this.ctx.fillText(unit, (this.canvas.width - textWidth) / 2 - boxPadding, boxY + boxHeight - boxPadding * 3);
}
draw(value) {
this.clear();
this.drawBackground();
this.drawBar(value);
this.drawGraduations();
this.drawDigitalDisplay(value);
}
}
export default VerticalLinearBar;