Basic canvas graphing
Created
October 26, 2015 05:34
-
-
Save stevommmm/7aba3e43fcabbb9f2840 to your computer and use it in GitHub Desktop.
basic time series graph
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Graph = function(canvasid, height, width, title, fontsize, maxlabels) { | |
this.canvas = document.getElementById(canvasid); | |
this.ctx = this.canvas.getContext("2d"); | |
this.padding = [10, 60, 10, 10]; | |
this.width = width || 1000; | |
this.height = height || 100; | |
this.title = title || "Time Series"; | |
this.fontsize = fontsize || 11; | |
this.maxlabels = maxlabels || null; | |
this.data = []; | |
this.canvas.width = this.width + this.padding[0] + this.padding[2]; | |
this.canvas.height = this.height + this.padding[1] + this.padding[3]; | |
}; | |
Graph.prototype.addPoint = function(d) { | |
if (typeof(d) === "number") { | |
this.data.push(d); | |
} | |
// We presume that we will be using a font size of 11px | |
if (this.data.length > this.width) { | |
this.data = this.data.splice(this.data.length - this.width, this.data.length); | |
} | |
}; | |
Graph.prototype.addPoints = function(d) { | |
if (d instanceof Array) { | |
Array.prototype.push.apply(this.data, d); | |
} | |
if (this.data.length > this.width) { | |
this.data = this.data.splice(this.data.length - this.width, this.data.length); | |
} | |
}; | |
Graph.prototype.w = function() { | |
return Math.floor(this.width / (this.data.length - 1)); | |
}; | |
Graph.prototype.h = function(h) { | |
var max = Math.max.apply(null, this.data); | |
var per = this.height / max; | |
return Math.floor(this.height - (h * per)); | |
}; | |
Graph.prototype.render = function() { | |
// Magic variables for label spacing | |
if (this.maxlabels === null) { | |
this.maxlabels = Math.floor(this.width / (this.fontsize)); | |
} | |
this.ctx.font = this.fontsize + "px Courier New, Courier, monospace"; | |
this.ctx.textAlign = 'end'; | |
// Draw our graph, may contain more plot points than labels | |
this.ctx.beginPath(); | |
this.ctx.strokeStyle = 'rgba(140, 40, 40, 0.2)'; | |
this.ctx.lineCap = 'butt'; | |
this.ctx.lineWidth = 2; | |
for(var i = 0; i < this.data.length; i++) { | |
var x = (i * this.w()) + this.padding[0]; | |
var y = this.h(this.data[i]) + this.padding[1]; | |
this.ctx.lineTo(x, y); | |
} | |
this.ctx.stroke(); | |
// Draw our labels and their vertical strokes for visability | |
this.ctx.strokeStyle = 'rgba(140, 40, 40, 0.1)'; | |
this.ctx.lineWidth = 1; | |
this.ctx.beginPath(); | |
for(var i = 0; i < this.data.length; i++) { | |
var x = (i * this.w()) + this.padding[0]; | |
var y = this.h(this.data[i]) + this.padding[1]; | |
// If we limit labels don't draw them | |
var s = this.data.length / this.maxlabels; | |
if (Math.floor(i % s) && i !== this.data.length - 1) { | |
continue; | |
} | |
// Our height offset without the label length | |
this._drawDataLabel(this.data[i], i); | |
// Draw our vertical lines | |
this.ctx.moveTo(x, this.padding[1]); | |
this.ctx.lineTo(x, y - 10); | |
} | |
this.ctx.stroke(); | |
this.ctx.fillStyle = 'rgba(140, 40, 40, 0.4)'; | |
for(var i = 0; i < this.data.length; i++) { | |
var x = (i * this.w()) + this.padding[0]; | |
var y = this.h(this.data[i]) + this.padding[1]; | |
this._drawDataDot(x, y); | |
} | |
// Draw our graph title in the top padding space | |
this._drawGraphLabel(this.title); | |
}; | |
Graph.prototype._drawDataDot = function(x, y) { | |
this.ctx.moveTo(x, y); | |
this.ctx.beginPath(); | |
this.ctx.arc(x, y, 2, 0, 2 * Math.PI); | |
this.ctx.fill(); | |
}; | |
Graph.prototype._drawDataLabel = function(label, offset) { | |
var x = (offset * this.w()) + this.padding[0]; | |
var w = this.ctx.measureText(label).width; | |
this.ctx.save(); | |
this.ctx.fillStyle = 'rgb(0, 0, 0)'; | |
this.ctx.translate(x, this.padding[1] - w - 10); | |
this.ctx.rotate(-90 * Math.PI / 180); | |
this.ctx.fillText(label, 0, 3); | |
this.ctx.restore(); | |
}; | |
Graph.prototype._drawGraphLabel = function(label) { | |
var x = (this.width / 2) + this.padding[0]; | |
var w = this.ctx.measureText(label).width; | |
this.ctx.save(); | |
this.ctx.font = (this.fontsize + 2) + "px bold Helvetica, Helvetica Neue, Arial"; | |
this.ctx.textAlign = 'center'; | |
this.ctx.fillStyle = 'rgb(0, 0, 0)'; | |
this.ctx.translate(x, this.fontsize); | |
this.ctx.fillText(label, 0, 0); | |
this.ctx.restore(); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment