2019-08-15 18:57:50 +02:00
|
|
|
class Graph {
|
2019-08-20 11:27:14 +02:00
|
|
|
constructor(canvas, color, maxHeight) {
|
2019-08-15 18:57:50 +02:00
|
|
|
this.canvas = canvas;
|
|
|
|
|
|
|
|
this.ctx = this.canvas.getContext("2d");
|
2019-08-20 11:27:14 +02:00
|
|
|
this.ctx.lineCap = 'round';
|
2019-08-15 18:57:50 +02:00
|
|
|
this.ctx.save();
|
|
|
|
|
2019-08-20 11:27:14 +02:00
|
|
|
this.scale = {x: 1, y: (this.canvas.height / maxHeight) || 1};
|
2019-08-15 18:57:50 +02:00
|
|
|
|
|
|
|
this.canvas.onresize = this.onresize();
|
2019-08-20 11:27:14 +02:00
|
|
|
this.setColor(color || "#000");
|
2019-08-15 18:57:50 +02:00
|
|
|
|
|
|
|
this.values = [];
|
2019-08-20 11:27:14 +02:00
|
|
|
|
|
|
|
this.preDraw = this._dummyFunc;
|
|
|
|
this.postDraw = this._dummyFunc;
|
|
|
|
}
|
|
|
|
|
|
|
|
getValue(i) {
|
|
|
|
return this.values[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
getLength() {
|
|
|
|
return this.values.length;
|
|
|
|
}
|
|
|
|
|
|
|
|
add(v) {
|
|
|
|
this.values.push(v);
|
2019-08-15 18:57:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
setColor(color) {
|
2019-08-20 11:27:14 +02:00
|
|
|
this.color = color || "#000";
|
2019-08-15 18:57:50 +02:00
|
|
|
this.ctx.fillStyle = this.color;
|
|
|
|
}
|
|
|
|
|
|
|
|
updateScale() {
|
|
|
|
this.onresize();
|
|
|
|
}
|
|
|
|
|
|
|
|
onresize() {
|
|
|
|
this.ctx.restore();
|
|
|
|
this.ctx.save();
|
|
|
|
this.ctx.fillStyle = this.color;
|
|
|
|
this.ctx.translate(0, this.canvas.height);
|
|
|
|
this.ctx.scale(this.scale.x, -this.scale.y);
|
|
|
|
}
|
|
|
|
|
|
|
|
draw() {
|
2019-08-22 12:17:16 +02:00
|
|
|
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
|
|
|
|
|
|
this.preDraw(this);
|
2019-08-20 11:27:14 +02:00
|
|
|
this._draw();
|
2019-08-22 12:17:16 +02:00
|
|
|
this.postDraw(this);
|
2019-08-20 11:27:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
_draw() {
|
2019-08-15 18:57:50 +02:00
|
|
|
this.ctx.beginPath();
|
|
|
|
this.ctx.moveTo(0, 0);
|
|
|
|
|
2019-08-20 11:27:14 +02:00
|
|
|
let step = this.canvas.width / (this.getLength() - 1);
|
|
|
|
|
|
|
|
if (this.smooth) {
|
|
|
|
for (let i = 0; i < this.getLength() - 2; i++) {
|
|
|
|
let xc = (this.getValue(i) + this.getValue(i + 1)) / 2;
|
|
|
|
this.ctx.quadraticCurveTo(
|
|
|
|
step * i,
|
|
|
|
this.getValue(i),
|
|
|
|
(step * i + step * (i + 1)) / 2,
|
|
|
|
xc
|
|
|
|
);
|
|
|
|
}
|
|
|
|
this.ctx.quadraticCurveTo(
|
|
|
|
step * (this.getLength() - 1),
|
|
|
|
this.getValue(this.getLength() - 2),
|
|
|
|
step * this.getLength(),
|
|
|
|
this.getValue(this.getLength() - 1)
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
for (let i = 0; i < this.getLength(); i++) {
|
|
|
|
this.ctx.lineTo(step * i, this.getValue(i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.ctx.lineTo(this.canvas.width, 0);
|
|
|
|
this.ctx.fill();
|
|
|
|
}
|
|
|
|
|
2019-08-22 12:17:16 +02:00
|
|
|
_dummyFunc(_) {}
|
2019-08-20 11:27:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
class MovingGraph extends Graph {
|
2019-08-21 07:48:12 +02:00
|
|
|
constructor(canvas, color, maxHeight, bufferLength, bufferType) {
|
2019-08-20 11:27:14 +02:00
|
|
|
super(canvas, color, maxHeight);
|
|
|
|
|
|
|
|
let _bufferType = bufferType || Float32Array;
|
|
|
|
this.buffer = new _bufferType(bufferLength || 64);
|
|
|
|
this.offset = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
getValue(i) {
|
|
|
|
return this.buffer[(this.offset + i) % this.buffer.length];
|
|
|
|
}
|
|
|
|
|
|
|
|
getLength() {
|
|
|
|
return this.buffer.length;
|
|
|
|
}
|
|
|
|
|
|
|
|
add(v) {
|
|
|
|
this.buffer[this.offset] = v;
|
|
|
|
this.offset = (this.offset + 1) % this.buffer.length;
|
|
|
|
}
|
2019-08-15 18:57:50 +02:00
|
|
|
}
|