Skip to content

Instantly share code, notes, and snippets.

@andrewgilmartin
Created December 12, 2012 02:28
Show Gist options
  • Save andrewgilmartin/4264347 to your computer and use it in GitHub Desktop.
Save andrewgilmartin/4264347 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Horizon Chart</title>
<script type="text/javascript">
function HorizonChart( canvas, barWidth, barColors ) {
this.canvas = canvas;
this.canvasHeight = +canvas.attributes.height.value;
this.canvasWidth = +canvas.attributes.width.value;
this.barColors = barColors;
this.barWidth = barWidth;
this.barsTotalCount = this.canvasWidth / barWidth;
}
// values are oldest to newest
HorizonChart.prototype.draw = function( values ) {
var context = this.canvas.getContext("2d");
var canvasHeight = this.canvasHeight;
var canvasWidth = this.canvasWidth;
var barWidth = this.barWidth;
var barColors = this.barColors;
var barsCount = Math.min(values.length,this.barsTotalCount);
var xOffset = canvasWidth - ( barsCount * barWidth ); // first x value
var vOffset = values.length - barsCount; // first value index
for ( var i = 0; i < barsCount; i += 1 ) {
var value = values[vOffset+i];
var x = xOffset + (i * barWidth);
if ( value < 0 ) {
context.fillStyle = barColors[1];
context.fillRect(x,0,barWidth,Math.min(canvasHeight,-value));
if ( value < -canvasHeight ) {
context.fillStyle = barColors[0];
context.fillRect(x,0,barWidth,-value-canvasHeight);
}
}
else if ( value > 0 ) {
context.fillStyle = barColors[3];
context.fillRect(x,canvasHeight,barWidth,-Math.min(canvasHeight,value));
if ( value > canvasHeight ) {
context.fillStyle = barColors[2];
context.fillRect(x,canvasHeight,barWidth,-value+canvasHeight);
}
}
}
}
HorizonChart.prototype.update = function( values ) {
var context = this.canvas.getContext("2d");
var canvasHeight = this.canvasHeight;
var canvasWidth = this.canvasWidth;
var barWidth = this.barWidth;
// slide chart left xWidth pixels
var xWidth = Math.min(values.length*barWidth,canvasWidth);
var canvasImage = context.getImageData(xWidth, 0, canvasWidth - xWidth, canvasHeight);
context.putImageData(canvasImage, 0, 0);
context.clearRect(canvasWidth-xWidth, 0, xWidth, canvasHeight);
// draw the value
this.draw(values);
}
HorizonChart.prototype.update1 = function( value ) {
var context = this.canvas.getContext("2d");
var canvasHeight = this.canvasHeight;
var canvasWidth = this.canvasWidth;
var barWidth = this.barWidth;
// slide chart left xWidth pixels
var canvasImage = context.getImageData(barWidth, 0, canvasWidth - barWidth, canvasHeight);
context.putImageData(canvasImage, 0, 0);
context.clearRect(canvasWidth-barWidth, 0, barWidth, canvasHeight);
// draw the value
this.draw([value]);
}
</script>
</head>
<body>
<canvas id="c1" width="900" height="70"></canvas>
<script>
var canvas = document.getElementById("c1");
var canvasHeight = +canvas.attributes.height.value;
var canvasWidth = +canvas.attributes.width.value;
var barWidth = 1;
var barsTotalCount = Math.floor( canvasWidth / barWidth );
// function to create value based on previous value (or initial value)
var v = function(initialValue,maximumValue) {
var value = initialValue;
var delta = maximumValue * 0.1; // change by 10%
return function() {
// change the previous value by a small amount
value = Math.max(-maximumValue, Math.min(maximumValue,value + (-(Math.random() * delta) + (Math.random() * delta) )));
return value;
}
}(0,canvasHeight*2);
var values = [];
// create some sample data
var value = 0;
var maxValue = canvasHeight * 2;
for ( var i = 0; i < barsTotalCount; i++ ) {
values.push(v());
}
var barColors = [
"#4c9ec9", // < -height
"#abcddf", // < 0
"#53b96a", // < height
"#a5dea8"
];
var horizon_chart = new HorizonChart( canvas, barWidth, barColors );
horizon_chart.draw(values);
window.setInterval(function(){
horizon_chart.update1(v());
}, 100);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment