diff --git a/www/js/graph.js b/www/js/graph.js index 2971552..062f6a6 100644 --- a/www/js/graph.js +++ b/www/js/graph.js @@ -1,20 +1,36 @@ class Graph { - constructor(canvas, color) { + constructor(canvas, color, maxHeight) { this.canvas = canvas; this.ctx = this.canvas.getContext("2d"); + this.ctx.lineCap = 'round'; this.ctx.save(); - this.scale = {x: 1, y: 1}; + this.scale = {x: 1, y: (this.canvas.height / maxHeight) || 1}; this.canvas.onresize = this.onresize(); - this.setColor(color); + this.setColor(color || "#000"); this.values = []; + + 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); } setColor(color) { - this.color = color; + this.color = color || "#000"; this.ctx.fillStyle = this.color; } @@ -31,20 +47,104 @@ class Graph { } draw() { + this.preDraw(); + this._draw(); + this.postDraw(); + } + + _draw() { this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); this.ctx.beginPath(); this.ctx.moveTo(0, 0); - let step = this.canvas.width / this.values.length; - this.ctx.save(); - for (let i = 0; i < this.values.length; i++) { - this.ctx.lineTo(0, this.values[i]); - this.ctx.translate(step, 0); + 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.restore(); this.ctx.lineTo(this.canvas.width, 0); this.ctx.fill(); } + + _dummyFunc() {} +} + +class MovingGraph extends Graph { + constructor(canvas, color, maxHeight, bufferLength, bufferType, smooth) { + super(canvas, color, maxHeight); + + let _bufferType = bufferType || Float32Array; + this.buffer = new _bufferType(bufferLength || 64); + this.smooth = smooth || false; + 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; + } + + /* + _draw() { + this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); + + this.ctx.beginPath(); + this.ctx.moveTo(0, 0); + + 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.buffer.length - 1), + this.getValue(this.getLength() - 2), + step * this.buffer.length, + 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(); + } + */ } \ No newline at end of file diff --git a/www/main.html b/www/main.html index 8421b27..7352fc6 100644 --- a/www/main.html +++ b/www/main.html @@ -26,6 +26,10 @@ ". map data-hp console"; } + canvas { + background: #f00; + } + body > div { display: grid; } @@ -119,10 +123,10 @@
- - - - + + + +