Experimenting with flot.js, a flexible chart library →
/ 2 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.
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:
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:
- A
placeholderobject that contains properties relating to the div that contains the canvas - An
optionsobject that contains chart options that’s passed as an argument when we call$.plot() - A
methodsobject 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.
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.

can we use flot.js with require.js…
facing problem ..
please reply asap
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?