How to make a scrolling Line chart

A guide for how you can easily make a dynamic scrolling Line chart. It can be made to be smooth by minimising the delay between requests giving the appearance of a continuously updating line.

[No canvas support]

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 clear. The code that generates the chart above is shown and documented below. Browser timings are not perfect so the chart ay 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 5 to 10ms.

    // A global used by the button the changes the color
    state = {};
    window.onload = (function ()
        // Refresh rate (in milliseconds - 1000 per second)
        var delay = 40;
        // Number of points shown on the chart
        var points = 1200;
        // Create the array with all the slows set to null
        for (var data=[],i=0; i<points; ++i) {
            data[i] = null;

        // A shortcut reference to the global RGraph object
        var RG = RGraph;
        // A shortcut reference to the global Math object
        var ma = Math;
        // Max Y value on the chart
        var max = 100;
        // Min Y value on the chart
        var min = 0;
        // Halfway between the min and max
        var num = (( (max - min) / 2) + min);

        // Generate the labels that are across the X axis. Hard-coded sadly... :-(
        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
        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 on to the end of the same array
        // 4. Draws the chart again
        function draw()
            // Clear (NOT reset) the 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 += RG.random(-1 * delta, delta);

            // Limit the num variable to min - max
            num = ma.max(min, num);
            num = ma.min(max, num);

            // Remove a number from the front of the data array

            // Add the new number on to end of the data array
            // Draw the chart
            // Call this function again after the delay (using setTimeout NOT setInterval)
            setTimeout(draw, delay);


Fetching new data using AJAX

Fetching new data by AJAX is dependent on network speed and the responsiveness 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 is 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:

Another option is to use WebSockets to spawn a separate process - which again could update a queue. Though is adding 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 is quite involved and requires two charts to be created along with the clipping feature of canvas. A much simpler 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 individual color is small - and the change from on 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 because it's much simpler than using two charts/canvas tags and clipping it's worthy of trying first.

    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))'

Use the button below to set the color of the chart above to an example of this.

Another way by creating the gradient manually

An alternative is to create the gradient manually - using the canvas gradient functionality directly. Similarly 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);
obj.set('fillstyle', gradient);