<!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