HOWTO: Make a scrolling Line chart
- Introduction
- Fetching new data using AJAX
- Using colors to indicate a threshold
- Another way by creating the gradient manually
Introduction
Creating a scrolling Line chart
is not an entirely simple affair if you're new to
RGraph but this explanation should help to make everything clearer. There's some
example code shown and documented below. Browser timings are
not perfect so the chart may not show exactly the amount of points that you want -
an important thing to take into consideration is the amount of time required
to draw the chart - which may be a few milliseconds.
<script> // A global used by the button that changes the color state = {}; window.onload = (function () { // Refresh rate (in milliseconds - remember that there's 1000ms per second) var delay = 40; // Number of points shown on the chart var points = 1200; // Create the array with all the values set to null for (var data=[],i=0; i<points; ++i) { data[i] = null; } // Maximum Y value on the chart var max = 100; // Minimum Y value on the chart var min = 0; // Halfway between the minimum and maximum var num = (( (max - min) / 2) + min); // Generate the labels that are across the X-axis var labels = ['60s', '55s','50s', '45s','40s','35s','30s','25s','20s','15s','10s','5s','0s']; // The increase/decrease of each iteration var delta = 2; // Create the chart. The data used is the empty array from // above - so nothing gets drawn on the chart yet. var obj = new RGraph.Line({ id: 'cvs', data: data, options: { yaxisScaleMax: max, tickmarksStyle: null, linewidth: 1, shadow: null, backgroundGridVlines: false, backgroundGridBorder: false, backgroundGridColor: '#eee', xaxisTickmarksCount: 5, axesColor: '#666', textColor: '#666', xaxisLabels: labels, xaxis: false, colors: ['#a00'], filled: true, filledColors: 'Gradient(white:red)', marginLeft: 35, textSize: 14 } }).draw(); state.object = obj; // This is the main draw function that is called multiple // times per second to update the chart with new data. It: // // 1. Clears the canvas so that it's ready to be drawn on again // 2. Shifts a piece of data off of the rear of the Line chart internal data // variable // 3. Pushes a new piece of data onto the end of the same array // 4. Draws the chart again // function draw() { // Clear (NOT reset) the canvas RGraph.clear(obj.canvas); // Generate a random number between -5 and 5 and add it to the num // variable. Adding a small change instead of generating a whole new // number results in a gentler change. num += RGraph.random(-1 * delta, delta); // Limit the num variable to min - max num = Math.max(min, num); num = Math.min(max, num); // Remove a number from the front of the data array obj.original_data[0].shift(); // Add the new number onto the end of the data array obj.original_data[0].push(num); // Draw the chart obj.draw(); // Call this function again after the delay (using setTimeout NOT setInterval) setTimeout(draw, delay); } draw(); }); </script>
Fetching new data using AJAX
Fetching new data by ajax
is dependent on network speed and the responsive
ness of the
computer providing the data - amongst other things. So as a result of this if you go
down the route of an updating chart that fetches new data via ajax
you will need to
reduce the frequency of updates (eg 1 per second).
Taking this into consideration though - it's feasible to
make a queue-like system,
where the ajax
requests happen independently of
the chart update and put data into
an array
(a queue) and the chart updates take
data from this array
every time it's
drawn.
Or perhaps something like this: http://www.rgraph.net/canvas/howto-update.html
Another option is to use WebSockets
to spawn a separate process - which again could
update a queue. Though it adds needless complexity to the whole thing.
Using colors to indicate a threshold
In the demos, there's a demo of a scrolling chart that shows different
colors above/below
a threshold. The method used in this demo requires two charts to
be created along with the clipping feature of the
canvas
tag.
Another option is to
use gradients with (for example) 10 instances of the first color and
then 10 instances
of the second color. With this many colors the vertical space allocated
to each color is small - and the change from one color to the next
will be
small too. The more colors that you use the smaller the graduation will
be. It comes
across as a bit of a kludge
but it's worthy of giving it a try if you don't want to use clip
feature.
obj.set({ colorsFill: 'Gradient(green:green:green:green:green:green:green:green:green:green:rgba(255,0,0,0.75):rgba(255,0,0,0.75):rgba(255,0,0,0.75):rgba(255,0,0,0.75):rgba(255,0,0,0.75):rgba(255,0,0,0.75):rgba(255,0,0,0.75):rgba(255,0,0,0.75):rgba(255,0,0,0.75):rgba(255,0,0,0.75))' });
An alternative way by creating the gradient manually
An alternative is to create the gradient manually - using the canvas
gradient
functionality directly. Similar to css
gradients, it allows you to set the color-stop
positions precisely - affording you a little extra control. By using this method the
change from red to green is a little more defined. As an aside - with this method, you
don't need to call the RGraph internal function parseGradients
.
var gradient = obj.context.createLinearGradient(0,0,0,250); gradient.addColorStop(0,'red'); gradient.addColorStop(0.5,'red'); gradient.addColorStop(0.5,'rgb(0,255,0)'); gradient.addColorStop(1,'rgb(0,255,0)'); obj.set('fillstyle', gradient);