-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
90 lines (75 loc) · 2.26 KB
/
index.ts
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
const canvas = document.querySelector(".my-canvas") as HTMLCanvasElement;
const width = (canvas.width = window.innerWidth);
const height = (canvas.height = window.innerHeight);
interface GraphOptions {
gap: number;
columnWidth: number;
maxSize: number;
legend: boolean;
title: boolean;
}
interface Data {
title: string;
values: number[];
}
type Point = [number, number];
class GraphRendering {
ctx: CanvasRenderingContext2D;
base: Point;
data: Data;
options: GraphOptions | {};
max: number;
scale: number;
constructor(x: number, y: number, data: Data) {
this.ctx = canvas.getContext("2d") as CanvasRenderingContext2D;
this.ctx.font = "10px 'Varela Round'";
this.base = [x, y];
this.data = data;
this.options = {};
this.max = this.scale = 0;
}
drawData(options: GraphOptions): void {
this.options = options;
this.max = Math.max(...this.data.values.map((item) => Math.abs(item)));
this.scale = (this.options as GraphOptions).maxSize / this.max;
if (options.title) {
this.ctx.font = '32px "Varela Round"';
this.ctx.fillText(
this.data.title,
this.base[0],
this.base[1] - this.max * this.scale - 40
);
this.ctx.font = '10px "Varela Round"';
}
const { columnWidth, gap } = options;
for (let value of this.data.values) {
this.renderValue(value);
this.base[0] += columnWidth + gap;
}
}
renderValue(value: number): void {
const { columnWidth, legend, maxSize, title } = this
.options as GraphOptions;
let [x, y] = this.base;
const size = this.scale * value; // scaled size
this.ctx.fillRect(x, y, columnWidth, -size);
if (legend) {
if (value > 0) y = y - size;
else if (value === 0) return;
y -= 10;
this.ctx.fillText(String(value), x, y);
}
}
}
const data: Data = {
title: "Appetite for life",
values: [2, 4, 1, -99, 3, 100],
};
const graph = new GraphRendering(200, 400, data);
graph.drawData({
gap: 10,
columnWidth: 30,
legend: true,
maxSize: 300,
title: true,
});