Philipps 5 mins: Graph-Fun with AJAX and Canvas
I always searched for an efficient way add dynamic diagrams to a web-project without using flash or other plugin-based magic.
With the support of the canvas tag element in almost all mainstream browser, i thought it would be a good time for creating a short demo how things workout.
You will need at least two Parts for this demo. First of all you will need a Source JSON feed. For this demo i just hacked together a very basis PHP script:
<?php header('Content-type: application/json'); echo'{'; echo '"value":"' . rand(0, 60) . '"'; echo '}'; ?>
The result is something like:
{"value":"34"}
Secondly you need a Webpage, where you want to insert your canvas element, load the data from the json feed and draw the changing values to the canvas element.
For a better performance, we will implementing pulling the data and drawing the data within two parallel cycles. The Common data Storage will be an array of 300 value (for our diagram with a width of 300px).
We are using two additional JS Files. The first we need for creating our XHTTPRequest Object and handling the response within a callback method. The second script is for parsing the JSON Feed as a Javascript Object in a safe way (an ordinary eval works, but is to unsecury).
Our main-script works in several steps:
First we initialize an array with empty elements:
function init(){ for(var i=0; i < 300; i++){ randomValues[i] = 0; } }
This step is optional, but then you have a nice “zero line” at the beginning.
Secondly we have a method, that pushes a new value to the existing array, and drops the first entry, if the length of the array is greater than 300.
function addValue(arr, value){ if(arr.push(value) > 300){ arr.shift(); } }
The next two methods are necessary for sending our ajax-request and for handling the response in a callback method.
Basically the callback method just calls the addValue method.
The timeout variable is set to 200 ms. So the script calls our backend periodically every 200 ms and then adds a new value to our array.
function pullValue(){ sendRequest('random.php',handleRandomRequest); setTimeout(pullValue, timeout); } function handleRandomRequest(req) { var text = JSON.parse(req.responseText); addValue(randomValues, text.value); }
The last method is for the drawing functionality:
function draw(){ ctx.clearRect(0, 0, 300, 60); ctx.fillStyle = "rgba(101,101,101, 0.5)"; ctx.fillRect (0, 0, 300, 60); ctx.lineWidth = 1; ctx.strokeStyle = 'blue'; ctx.beginPath(); ctx.moveTo(1, 60-parseInt(randomValues[0])); for (var i=1; i<randomValues.length; i++){ value = 60-parseInt(randomValues[i]); ctx.lineTo(i,value); } ctx.stroke(); setTimeout(draw, timeout); }
ctx is a 2d context of the canvas element.
On every call of the draw method, all elements of the array are painted. The first element is always the start point.
Because the canvas coordinate system has the point 0,0 in the upper left corner but the 0,0 point of our diagram should be in the lower left corner, you have to subtract the array-values from 60 to get the right drawing coordinate.
This method also runs periodically every 200 ms. But it also works for two times for pulling the data an drawing it.