2General

Want to know more about us? Visit 2general.com »

Creating stacked bar charts with Flot

Flot is a powerful JavaScript plotting library for jQuery. It uses <canvas> tag for creating beautiful graphical plots. Out of the box it supports lines, points, filled areas, bars and any combinations of these. With plugins you get pie charts, stacked charts and more.

Today we’ll take a look at Flot’s stacked charts support. The first thing you must notice is that you have to pass the data in the right format. Also, Flot has a bug in creating stacked charts that may require some tinkering with Flot’s code. Luckily there’s a patch available.

Prerequisites

Download the Flot package and add jQuery, Flot’s core .js and stacked charts plugin to your page. excanvas.js is needed for legacy IE support.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<head>
    <link rel="stylesheet" type="text/css" href="style.css">

    <!--[if lte IE 8]>
    <script type="text/javascript" src="excanvas.min.js"></script>
    <![endif]-->
</head>
<body>
    <div id="plot"></div>

    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript" src="jquery.flot.js"></script>
    <script type="text/javascript" src="jquery.flot.stack.js"></script>
    <script type="text/javascript">
    // your code goes here...
    </script>
</body>

The package also contains the minified versions, so in production it may be advisable to use them instead.

Basic usage

The chart is created with the $.plot() method:

1
$.plot("#plot", series, options);

Flot requires you to set a height for the element, otherwise you get an error message. Set the width as well unless your layout is fixed. Flot doesn’t support dynamic resizing out of the box, but you can apparently achieve it with a plugin.

1
2
3
4
#plot {
    height: 300px;
    width: 600px;
}

Creating a simple bar chart

Show demo »

../../../_images/simple.png

Very simple, just give your datapoints as an array containing x and y pairs and Flot will do the rest.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 (function($) {
    var series = [[
        [0, 100],
        [1, 150],
        [2, 125],
        [3, 160],
        [4, 95]
    ]];

    var options = {
        xaxis: {
            minTickSize: 1
        },
        series: {
            bars: {
                show: true,
                barWidth: .9,
                align: "center"
            }
        }
    };

    $.plot("#plot", series, options);
 })(jQuery);

Creating a stacked bar chart

Show demo »

../../../_images/stack.png

This time, we’ll pass the data as an array of objects and set labels for the series.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
 (function($) {
    var series = [{
        data: [
            [0, 100],
            [1, 150],
            [2, 125],
            [3, 160],
            [4, 95]
        ],
        label: "Series 1"
    },
    {
        data: [
            [0, 20],
            [1, 35],
            [2, 20],
            [3, 35],
            [4, 35]
        ],
        label: "Series 2"
    }, {
        data: [
            [0, 55],
            [1, 40],
            [2, 60],
            [3, 10],
            [4, 20]
        ],
        label: "Series 3"
    }];

    var options = {
        xaxis: {
            minTickSize: 1
        },
        series: {
            bars: {
                show: true,
                barWidth: .9,
                align: "center"
            },
            stack: true
        }
    };

    $.plot("#plot", series, options);
 })(jQuery);

We’ll also set stack: true in the options. Flot creates us a nice stacked bar chart.

Note that Flot requires you to pass each “level” in your stacked bar chart in a separate series. You can’t build the stacked bar chart by having multiple datapoints with the same x value in the same series.

Creating a stacked bar chart with an empty series

Show demo »

This is where Flot has a hiccup. Let’s assume that we have three series, but one of them doesn’t have any datapoints in the selected range.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
 (function($) {
    var series = [{
        data: [
            [0, 100],
            [1, 150],
            [2, 125],
            [3, 160],
            [4, 95]
        ],
        label: "Series 1"
    },
    {
        data: [], // an empty series
        label: "Series 2"
    }, {
        data: [
            [0, 55],
            [1, 40],
            [2, 60],
            [3, 10],
            [4, 20]
        ],
        label: "Series 3"
    }];

    var options = {
        xaxis: {
            minTickSize: 1
        },
        series: {
            bars: {
                show: true,
                barWidth: .9,
                align: "center"
            },
            stack: true
        }
    };

    $.plot("#plot", series, options);
 })(jQuery);

Unless you patch jquery.flot.stack.js, the chart will look like this:

../../../_images/stack_empty.png

Not good. Looks like it’s not stacked at all!

The reason is that when Flot encounters a series that doesn’t have any data in it, it starts stacking from zero again, causing the bars to overlap. A bug report and a patch were filed in 2009, but for some reason this has not been fixed in Flot.

Download the patch file by Guillaume (mirrored here) and apply it to jquery.flot.stack.js (not the minified version!) or download the patched version:

$ patch -o jquery.flot.stack.patched.js jquery.flot.stack.js jquery.flot.stack.js.patch

Now, use the patched plugin:

<script type="text/javascript" src="jquery.flot.stack.patched.js"></script>

The chart will look much better:

../../../_images/stack_patched.png

Show demo »

Please note that if you update your Flot scripts, you need to patch them again. The patch works with Flot version 0.7 which was the latest one when this blog post was written.