How to create a multichart scrolling effect with CSS transitions

  Read comments...

Summary
A slight variation on the traditional sliding DIV/canvas this shows you how to make a multi-level carousel effect for showing mutiple charts using the space of one

[No canvas support]

This is an example of of how you can use a large canvas (1800x400) in conjunction with some CSS in order to create the scrolling effect shown here. The extra large canvas is contained within a DIV which has dimensions of 600px/200px and has its overflow CSS property set to hidden. The large canvas is then moved around by changing the left and top CSS properties with the jQuery .css() function. The animation is a result of a CSS transition having been set on the canvas. Below are the steps that are involved in setting up the effect.

1. The CSS that causes the canvas to be animated when it's moved

<style>
    canvas {
        position: relative;
        left: 0;
        top: 0;
    }
</style>

This is the CSS code that is applicable to the canvas tag. The position is set to relative, the top and left both have values of zero initially and the transition is setup.

The transition is what causes the canvas to be animated when the top or left CSS properties are changed and the transition will last two seconds. The easing function is not required but makes the effect look a little better.

2. The canvas tag

<div style="width: 600px; height: 200px; background-color: white; overflow: hidden; display: inline-block">
    <canvas id="cvs" width="1800" height="400">[No canvas support]</canvas>
</div>

Here is the canvas tag onto which the six charts are drawn. The canvas tag itself is 1800 pixels wide and 200 pixels high - enough for 6 charts that are each 600x200.

Note: In order for the charts not to take up the whole canvas the gutters have to be adjusted.

Here's a table showing the gutters that are used in each chart:

Chart position Left gutter Right gutter Top gutter Bottom gutter
Top left 25 1225 25 225
Top center 625 625 25 225
Top right 1225 25 25 225
Bottom left 25 1225 225 25
Bottom center 625 625 225 25
Bottom right 1225 25 225 25

3. The JavaScript code that makes the charts

First of all the RGraph libraries and jQuery have to be included.

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

<script src="/libraries/RGraph.common.core.js"></script>
<script src="/libraries/RGraph.line.js"></script>
<script src="/libraries/RGraph.bar.js"></script>
<script src="/libraries/RGraph.scatter.js"></script>
<script src="/libraries/RGraph.gantt.js"></script>
<script src="/libraries/RGraph.waterfall.js"></script>

Then the code that makes the charts - there's a lot of it because there are six charts in total:

<script>
    window.onload = function ()
    {
        // A global variable for maintaining state information.
        // The index is simply a number that corresponds to the chart
        // and the delay is the time between each chart (in milliseconds)
        state = {
            delay: 3500,
            index: 0,
            charts: [
                {x:0,y:0}, {x:-600,y:0}, {x:-1200,y:0},
                {x:0,y:-200}, {x:-600,y:-200}, {x:-1200,y:-200}
            ]
        };




        // The top left Line chart
        var line = new RGraph.Line({
            id: 'cvs',
            data: [8,7,6,9,8,4,6,5],
            options: {
                labels: ['John', 'Geoff', 'Lou','Kevin','Barry','John','Alex','Nick','Dave','Hoolio','Pete'],
                gutterRight:1225,
                gutterBottom: 225,
                backgroundGridVlines: false,
                backgroundGridBorder: false
            }
        }).draw();




        // The top middle Bar chart
        var bar = new RGraph.Bar({
            id: 'cvs',
            data: [4,8,6,3,5],
            options: {
                labels: ['John','Louise','Bob','Neil','Graham'],
                gutterLeft: 625,
                gutterRight: 625,
                gutterBottom: 225,
                backgroundGridVlines: false,
                backgroundGridBorder: false
            }
        }).draw();




        // The top right Scatter chart
        var scatter = new RGraph.Scatter({
            id: 'cvs',
            data: [[10,18],[16,15],[24,13],[32,56],[86,12],[90,12],[115,13]],
            options: {
                xmax: 150,
                labels: ['Q1','Q2','Q3','Q4'],
                gutterLeft: 1225,
                gutterBottom: 225,
                backgroundGridVlines: false,
                backgroundGridBorder: false
            }
        }).draw();




        // The bottom left Gantt chart
        var gantt = new RGraph.Gantt({
            id: 'cvs',
            data: [
            [
                [31, 28, null, 'Richard', 'Gradient(green:#0f0)'],
                [90,15, null, null, 'gradient(green:#0f0)']
            ],
            [
                [0, 28, null, 'Rachel', 'Gradient(green:#0f0)'],
                [30,65, null, null, 'Gradient(green:#0f0)']
            ],
                [12, 28, null, 'Fred', 'Gradient(green:#0f0)'],
                [0, 85, null, 'Barney', 'Gradient(green:#0f0)']
            ],
            options: {
                xmax: 120,
                gutterTop: 225,
                gutterRight: 1225,
                labels: ['January', 'February', 'March', 'April'],
                labelsAlign: 'bottom',
                backgroundGrid: false,
                vbars: [
                    [31,28,'#ddd'],
                    [90,30,'#ddd']
                ],
                borders: false
            }
        }).draw()




        // The bottom middle Waterfall chart
        var waterfall = new RGraph.Waterfall({
            id: 'cvs',
            data: [5,6,-4,2,3,8,-2,-1,-3],
            options: {
                gutterLeft: 625,
                gutterRight: 625,
                gutterTop: 225,
                labels: ['A','B','C','D','E','F','G','H','I'],
                numxticks: 9,
                backgroundGridVlines: false,
                backgroundGridBorder: false,
                noxaxis: true
            }
        }).draw();




        The bottom right Line chart
        var line = new RGraph.Line({
            id: 'cvs',
            data: [4,8,3,5,9,12,5,13,16,21],
            options: {
                labels: ['John', 'Geoff', 'Lou','Kevin','Barry','John','Alex','Nick','Dave','Hoolio'],
                gutterLeft: 1225,
                gutterRight: 25,
                gutterTop: 225,
                backgroundGridVlines: false,
                backgroundGridBorder: false
            }
        
        }).draw();
    }
</script>

4. The animate function

And this is the animate() function that moves the canvas around - showing each chart in turn. The function only sets the top and left CSS properties and leaves the animating to the CSS transition which is defined earlier (on the canvas tag). This results in CSS being used for the amimating which you'll find is a little bit smoother than jQuery animation.

<script>
    var animate = function ()
    {
        // This increments each time abd determines the correct chart to show
        ++state.index;
        
        if (state.index > 5) {
            state.index = 0;
        }
        
        // The x aned y positions are the offsets to move the canvas to. This makes
        // each chart visible in turn
        var chart = state.charts[state.index];
        var x     = chart.x;
        var y     = chart.y


        $('#cvs').parent().css({
            left: x + 'px',
            top: y + 'px'
        });

        setTimeout(animate, state.delay);
    };

    // Instead of using the jQuery animate() function the top and left CSS properties are set.
    // The CSS transition that's defined on the canvas DIV wrapper then handles the animation
    $('#cvs').parent().css({
        'transition': 'top 2s, left 2s',
        'transition-timing-function': 'ease-in-out'
    });

    // This sets the initial starting point of the canvas wrapper div
    $('#cvs').parent().css({
        left: 0,
        top: 0
    });


    // Call the animate function again after the delay so the cycle
    // starts again
    setTimeout(animate, state.delay);
</script>

5. Conclusion

Showing multiple charts need not take up more space than is required for one. You could also add buttons so that you can click to be taken directly to that chart. You could also easily add a feature so that the timer is cancelled when the mouseover event is triggered and restarted when the mouseout event is triggered - essentially creating a pause.

And by using CSS transitions the animation can be made to be smooth and triggered by no more than setting the top and/or the left CSS properties.

Share RGraph
X

Comments