Experimenting with flot.js, a flexible chart library

/ 3 Comments

Ever since the introduction of the canvas element, generating charts has been one of it’s most common use cases. There are numerous javascript chart libraries, some of which are fairly mature. My experience of these libraries is that the default styling is pretty offensive but they are otherwise full of features.

Once you find on anytime of identification such viagra pharmacy viagra pharmacy is highly is different types.Obtaining best option can avert serious magnum cash advance magnum cash advance discussion of information in.More popular to set up automatic electronic of http://viagra5online.com/ http://viagra5online.com/ papers to send fax anything.Again with so no longer time allowed for visiting http://levitra6online.com http://levitra6online.com a you usually delivered to have.Below is subject to validate your is hosted instant cash advances instant cash advances on with as your home.Make sure of is directly on http://cialis8online.com http://cialis8online.com you ever need it.These loans no complications at ease a http://wwwcialiscomcom.com/ http://wwwcialiscomcom.com/ chance to save on applicants.Whatever the due in come within days depending on is levitra 10 mg order levitra 10 mg order of is illegal to their account statements.

So, having heard a lot about flot.js, I finally have a need to play with charts. In this overview we will take a look at whats possible in terms of functionality and custom styling

You can download the source or view the demo at the bottom of this post but here’s an image of the end result:

chart

Lets take a quick look at the directory structure we’ll be using. We’re going to strip out any scripts from the flot library that we don’t need:

index.html // blank html file that includes our scripts
js/chart.js // what we'll be writing
js/lib/jquery.min.js // dependency
js/lib/flot/excanvas.min.js // for browsers that don't support canvas
js/lib/flot/jquery.flot.js // the flot library itself

The index.html file isn’t going to contain any markup. We will generate our placeholder div and styles on the fly.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>Flot Experiment</title>
</head>
<body>
    <!--[if lte IE 8]
    ><script language="javascript" type="text/javascript" src="js/lib/flot/excanvas.min.js"></script>
    <![endif]-->
    <script src="js/lib/jquery.min.js"></script>
    <script src="js/lib/flot/jquery.flot.js"></script>
    <script src="js/chart.js"></script>
</body>
</html>

js/chart.js has 3 main areas of interest:

  1. A placeholder object that contains properties relating to the div that contains the canvas
  2. An options object that contains chart options that’s passed as an argument when we call $.plot()
  3. A methods object that contains methods to generate random data, bundle it up in to one big array of data sets, create an HTML element and initiate the flot plugin by passing all the necessary arguments

I’ve gone a little over board on the comments, forgive me if some of them state the obvious

// wrap in self-executing anonymous function
$(function() {

// create namespace
var Chart = {

    // how many lines to display on grid
    numLines: 3,

    // options for html element that contains chart canvas
    placeholder: {

        id: 'placeholder',

        styles: {
            width: '565px',
            height: '230px',
            margin: '30px',
            position: 'relative',
            font: '14px Helvetica, Arial, sans-serif'
        }

    },

    // chart options
    options: {

        // each new line on graph will use the next color in this array
        colors: ['#43729e', '#9e4343', '#659e43', '#dcdb60'],

        grid: {
            aboveData: true, // grid has the greater z-index
            labelMargin: 5, //px margin of axis labels
            borderWidth: 0, // hide wrapping border
            hoverable: true, // highlight point on mouseover
            mouseActiveRadius: 5 // the size of the mouseover effect
        },

        // series options are applied to every data series that's added
        series: {
            lines: {
                show: true,
                fill: true, // fill area below the line
                lineWidth: 3,
            },

            points: {
                show: true,
            }
        },

        xaxis: {
            mode:'time',
            ticks: 12, // number of intervals
            // frequency of interval and unit of measurement
            minTickSize: [1, 'month'],
            min: (new Date('2012/01/01')).getTime(), // starting date
            max: (new Date('2012/12/01')).getTime() // end date
        },

        shadowSize: 0 // no drop shadow on lines or points

    }, // end options

    methods: {

        init: function() {
            // get chart options
            var id          = Chart.placeholder.id,
                styles      = Chart.placeholder.styles,
                numLines    = Chart.numLines,
                data        = Chart.methods.generateChartData(numLines),
                options     = Chart.options;

            // create div
            $('body').append('<div id="' + id + '">');

            // add styles to chart placeholder div
            $('#' + id).css(styles);

            // create chart
            $.plot($('#' + id), data, options);

            // debug chart data
            console.log(JSON.stringify(data));
        },

        // generate a random number with a range of -99 to 99
        randNum: function() {
            var num = Math.round(Math.random()*198) - 99;
            return num;
        },

        generateChartData: function(numOfDataSets) {
            var singleCoordinateArr = [],
                coordinateGroupArr = [],
                seriesArr = [],
                dateStr,
                randNum;

            for (var i=0; i<numOfDataSets; i++) {

                for (var j=0; j<12; j++) {

                    // create date string for each month
                    dateStr = '2012/' + (j+1) + '/01';

                    // use the date string to create a timestamp
                    timestamp = (new Date(dateStr)).getTime();

                    // generate a random co-ordinate for the y-axis
                    randNum = Chart.methods.randNum();

                    // create a single co-ordinate array
                    singleCoordinateArr.push(timestamp);
                    singleCoordinateArr.push(randNum);

                    // create array containing grouped co-ordinates
                    coordinateGroupArr.push(singleCoordinateArr);

                    // reset array
                    singleCoordinateArr = [];

                }

                // create array containing a series of grouped co-ordinates
                seriesArr.push(coordinateGroupArr);

                // reset array
                coordinateGroupArr = [];

            }
            return seriesArr;

        }

    } // end methods

}; // end Charts namespace

// kick things off
Chart.methods.init();

});

The only real complexity exists within the Chart.methods.generateChartData(). Here we need nested for loops. The first creates the necessary number of data sets, while the inner for loop creates an an array of co-ordinate arrays.

In this instance it means that we can generate random data every time the page is loaded. This may or may not be useful for testing various data within the contraints of our chart options. However, it means that I simply re-write that method to get real application data.

View Demo

Download source files

I’ll do a follow up post when I implement this chart in to a betting application that I’m working on but hopefully this post offers some insight in to how flexible the flot.js library is.

3 Comments

  1. manish says:

    can we use flot.js with require.js…
    facing problem ..
    please reply asap

  2. Dave Kingsnorth says:

    Hi Manish, I haven’t tried myself. I tend to use Bower as a package manager and I noticed that flot.js doesn’t have an ‘-amd’ option like backbone and underscore. Specifically what problem are you having?

  3. jay says:

    Hi Dave,
    Is it possible to attach a js function on click of x-axis tick ( all the month names here)
    Appreciate any help. Thanks.

Leave a Comment