-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
graph.js
123 lines (107 loc) · 3.12 KB
/
graph.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
function Graph(canvas, duration) {
this.canvas = canvas;
this.data = [];
this.minT = Date.now();
this.maxT = this.minT + duration * 1000;
this.maxY = 1;
}
Graph.prototype.addData = function(t, y) {
if (this.data.length === 0) {
this.minT = t;
this.maxT = t + this.maxT - this.minT;
}
if (this.data.length > 0 &&
this.data[this.data.length - 1].t === t) {
// datum with exact timestamp already exists
this.data[this.data.length - 1].y += y;
y = this.data[this.data.length - 1].y; // for maxY
} else
this.data.push({ t: t, y: y });
if (y > this.maxY)
this.maxY = y;
this.scheduleDraw();
};
Graph.prototype.scheduleDraw = function() {
var that = this;
if (!this.drawTimer)
this.drawTimer = setTimeout(function() {
delete that.drawTimer;
that.draw();
}, 50);
};
Graph.prototype.draw = function() {
var ctx = this.canvas.getContext("2d");
ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
if (this.data.length > 0) {
this.yTop = this.maxY * 5 / 4;
this.drawGrid(ctx);
this.drawData(ctx);
// // Draw a horizontal line at maxY:
// ctx.beginPath();
// ctx.moveTo(0, this.maxY);
// ctx.lineTo(this.maxT - this.minT, this.maxY);
// ctx.closePath();
// ctx.strokeStyle = 'red';
// ctx.lineWidth = this.maxY / 20;
// ctx.stroke();
}
};
Graph.prototype.getX = function(t) {
var w = this.canvas.width;
return Math.floor((t - this.minT) * w / (this.maxT - this.minT));
};
Graph.prototype.getY = function(y) {
var h = this.canvas.height;
return Math.floor(h * (1 - y / this.yTop));
};
Graph.prototype.drawData = function(ctx) {
var that = this;
var lastT;
ctx.beginPath();
ctx.moveTo(this.getX(0), this.getY(0));
var current = null;
var draw = function() {
if (current) {
ctx.lineTo(current.x, that.getY(current.y));
if (current.y > that.maxY)
that.maxY = current.y;
current = null;
}
};
var consume = function(d) {
var x = that.getX(d.t);
if (current && current.x === d.x) {
current.y += d.y;
} else {
draw();
current = { x: x, y: d.y };
}
lastT = d.t;
};
this.data.forEach(consume);
draw();
ctx.lineTo(this.getX(lastT), this.getY(0));
ctx.closePath();
ctx.fillStyle = this.fillStyle || '#777';
ctx.globalAlpha = 1;
ctx.fill();
};
Graph.prototype.drawGrid = function(ctx) {
var t;
var duration = this.maxT - this.minT;
for(t = 0; t <= duration; t += 100) {
ctx.beginPath();
ctx.moveTo(this.getX(t + this.minT), this.getY(0));
ctx.lineTo(this.getX(t + this.minT), this.getY(this.yTop));
ctx.closePath();
ctx.strokeStyle = '#333';
ctx.lineWidth = 0.4;
if (t % 1000 == 0)
ctx.globalAlpha = 1;
else if (t % 500 == 0)
ctx.globalAlpha = 0.5;
else
ctx.globalAlpha = 0.3;
ctx.stroke();
}
};