HOWTO: Create a multi-chart scrolling effect
- The CSS that causes the canvas to be animated when it's moved
- The canvas tag
- The JavaScript code that makes the charts
- The animate function
- Conclusion
This is an example of how you can use a large canvas
(1800x400) in
conjunction with some css
to create a scrolling effect.
The extra-large canvas
is contained within a div
which has
dimensions of 600 x 200
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.
The CSS that causes the canvas to be animated when it's moved
<style> canvas { position: relative; left: 0; top: 0; transition: top 2s, left 2s; transition-timing-function: ease-in-out; } </style>
This is the css
code that applies to the canvas
tag. The position is
set to relative, the top
and left
both have values of zero initially and
the transition
is set up.
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.
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: For the charts not to take up the whole
canvas
the margins have to be adjusted.
Here's a table showing the margins that are used in each chart:
Chart position | Left margin | Right margin | Top margin | Bottom margin |
---|---|---|---|---|
Top left | 35 | 1235 | 35 | 235 |
Top center | 635 | 635 | 35 | 235 |
Top right | 1235 | 35 | 35 | 235 |
Bottom left | 35 | 1235 | 235 | 35 |
Bottom center | 635 | 635 | 235 | 35 |
Bottom right | 1235 | 35 | 235 | 35 |
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: { xaxisLabels: ['John', 'Geoff', 'Lou','Kevin','Barry','John','Alex','Nick','Dave','Hoolio','Pete'], marginRight:1235, marginBottom: 235, backgroundGridVlines: false, backgroundGridBorder: false } }).draw(); // The top middle Bar chart var bar = new RGraph.Bar({ id: 'cvs', data: [4,8,6,3,5], options: { xaxisLabels: ['John','Louise','Bob','Neil','Graham'], marginLeft: 635, marginRight: 635, marginBottom: 235, 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: { xaxisScaleMax: 150, xaxisLabels: ['Q1','Q2','Q3','Q4'], marginLeft: 1235, marginBottom: 235, backgroundGridVlines: false, backgroundGridBorder: false } }).draw(); // The bottom left Gantt chart var gantt = new RGraph.Gantt({ id: 'cvs', data: [ [ {start: 31, duration: 28, label: 'Richard', color:'Gradient(green:#0f0)'}, {start: 90, duration: 15, color: 'gradient(green:#0f0)'} ], [ {start: 0, duration: 28, label: 'Rachel', color: 'gradient(green:#0f0)'}, {start: 30, duration: 65, label: '', color: 'gradient(green:#0f0)'} ], {start: 12, duration: 28, label: 'Fred', color: 'gradient(green:#0f0)'}, {start: 0, duration: 85, label: 'Barney', color: 'gradient(green:#0f0)'} ], options: { xaxisScaleMax: 120, marginTop: 235, marginRight: 1235, xaxisLabels: ['January', 'February', 'March', 'April'], backgroundGrid: false, backgroundVbars: [ [31,28,'#ddd'], [90,30,'#ddd'] ], borders: false, textSize: 14 } }).draw(); // The bottom middle Waterfall chart var waterfall = new RGraph.Waterfall({ id: 'cvs', data: [5,6,-4,2,3,8,-2,-1,-3], options: { marginLeft: 635, marginRight: 635, marginTop: 235, xaxisLabels: ['A','B','C','D','E','F','G','H','I'], backgroundGridVlines: false, backgroundGridBorder: false, xaxis: false } }).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: { xaxisLabels: ['John', 'Geoff', 'Lou','Kevin','Barry','John','Alex','Nick','Dave','Hoolio'], marginLeft: 1235, marginTop: 235, backgroundGridVlines: false, backgroundGridBorder: false } }).draw(); } </script>
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 animating which
you'll find is a little bit smoother than jquery
animation.
<script>
animate = function ()
{
// This increments each time and determines the correct chart to show
++state.index;
if (state.index > 5) {
state.index = 0;
}
// The X and 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').css({
left: x + 'px',
top: y + 'px'
});
setTimeout(animate, state.delay);
};
// Call the animate function again after the delay so the
// cycle starts again
setTimeout(animate, state.delay);
</script>
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 canceled 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
or the left
css
properties.