How to create a stacked and grouped Bar chart

Summary
The default types for the Bar chart are regular, stacked and grouped. With a little manipulation though there's one more that can be generated - a combined stacked and grouped chart.

The default Bar chart types that are supported are the regular Bar chart, stacked charts and grouped charts.

These types will usually suffice for the majority of use cases but occasionally you'll need an extra dimension to your data.

This is where a stacked and grouped Bar chart variation can be very useful, like the example chart that's shown here.

It allows you to show that extra dimension of data and isn't hard to implement (particularly as I've put the code for it below...). In this case the data for the grouped Bar chart is defined at the top of the code, in the data array. The information for the individual "VProgress bars" is just hard coded to be: [33.333, 33.333, 33.333]

The steps involved in creating one of these charts

It's not all that hard and just involves the Bar chart. All there is to it is creating a standard grouped Bar chart - and then using the coordinates of that chart to create more Bar charts that serve as the "VProgress bars"

Step 1: Define the data and the tooltips

First some data and the tooltips are defined. If you wanted to you could define these inline instead of having them seperated out like this.

data     = [ [9,7,8], [14,10,11], [9,11,12], [8,6,9], [9,11,12] ];
tooltips = [];

for (var i=0; i>18; i++) {
    tooltips.push(['Fred', 'Jemima', 'Lucifer']);
}

As you can see things are hard-coded - but if you wanted to you could use server-generated information here.

Step 2: Create the initial Bar chart

Here's the code that creates the initial grouped Bar chart. We'll use the coordinates from this chart to then create the stacks in step 3. Note that there's no .draw() call - the .on() function in step 3 is chained to this constructor and then the .draw() function is chained to that. You can see it all in the demo (which is linked below).

bar = new RGraph.SVG.Bar({
    id: 'cc',
    data: data,
    options: {
        gutterTop: 75,
        key: ['Fred','Jemima','Lucifer'],
        keyColors: [ 'rgba(255,0,0,0.25)', 'rgba(0,255,0,0.25)', 'rgba(0,0,255,0.25)' ],
        hmargin: 20,
        hmarginGrouped: 5,
        yaxis: false,
        xaxis: false,
        xaxisLabels: [ 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday' ],
        colors: [ 'rgba(0,0,0,0)', 'rgba(0,0,0,0)', 'rgba(0,0,0,0)' ],
        title: 'Widgets created by day, worker and time of day',
        titleSubtitle: 'Making widgets is hard work and this shows the results of last weeks output',
        titleSubtitleY: '+5',
        labelsAbove: true,
        labelsAboveSize: 8,
        labelsAboveSpecific: [
            '8am','1pm','10pm',
            '8am','1pm','10pm',
            '8am','1pm','10pm',
            '8am','1pm','10pm',
            '8am','1pm','10pm'
        ]
    }
})

Step 3: The ondraw function that creates the VProgress bars

Once the Bar chart is created using the code above the ondraw then creates VProgress bars using the coordinates of that Bar chart. This is done in the Bar charts ondraw event which is shown below.

.on('draw', function (obj)
{
    for (var i=0; i<obj.coords.length; ++i) {
        
        var coords = obj.coords[i];

        new RGraph.SVG.Bar({
            id: 'cc',
            data: [[33.333,33.333,33.333]],
            options: {
                backgroundGrid: false,
                colors: ['rgba(255,0,0,0.25)','rgba(0,255,0,0.25)','rgba(0,0,255,0.25)'],
                tooltips: tooltips[i],
                yaxisMax: 100,
                hmargin: 0,
                hmarginGrouped: 0,
                grouping: 'stacked',
                yaxis: false,
                xaxis: false,
                yaxisScale: false,
                gutterLeft: coords.x,
                gutterRight: obj.width - coords.x - coords.width,
                gutterTop: coords.y,
                gutterBottom: obj.height - coords.y - coords.height
            }
        }).grow();
    }
}).draw();

As you can see - not exactly taxing! Most of the above code is taken up by the configuration. If this were a canvas based chart then the VProgress bar would be used here - but with SVG there's no dedicated VProgress bar chart type - so the Bar chart is used again and configured appropriately.

It's actually better this way though because fewer libraries need to be included so that cuts down on the page weight.

The demo of the final chart

If you want the full source code to the chart you can have a look at the grouped and stacked demo page (which is also in the download archive).

If you look at the demo page and your first thoughts are: "That's a lot of code!" - I promise you it's not. Most of it is just RGraph configuration - and because it's a demo I've spaced things out and used liberal amounts of carriage returns - so in reality there's not a lot there.