There are a lot of tutorials on how to make CSS bar graphs. But sometimes, bar graphs aren't enough. What if our data tracks change over time and a line graph is more appropriate? Or maybe we're not satisfied with just a bar graph. Enter Flot, ajQuery plugin that lets us make good looking graphs with ease.
In a data centric world, we often have to display large amounts of data on the web. Generally we show a table of values with headings and if we really wanted to get fancy we would use a picture of a graph. People like pictures. I like pictures. Why? Because it is far easier to interpret data when it is in visual form. However, creating a picture graph and updating it with new data can be a pain. In this tutorial, we’re going to use a jQuery plugin called Flot to create graphs on the fly.
Step 1
To start, we need some data. For this tutorial, we’re going to be using some GDP data for a few different countries I found on Wikipedia. Unfortunately the data only goes to 2003 but since this isn’t a lesson on economics, it will suffice. Let’s put the data into a simple table and add a few lines to describe it.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Flot Tutorial</title> </head> <body> <div id="plotarea"> <table> <caption>GDP, based on exchange rates, over time. Values in billion USDs.</caption> <tr> <td></td> <th scope="col">2003</th> <th scope="col">2002</th> <th scope="col">2001</th> <th scope="col">2000</th> <th scope="col">1999</th> <th scope="col">1998</th> </tr> <tr> <th scope="row">USA</th> <td>10,882</td> <td>10,383</td> <td>10,020</td> <td>9,762</td> <td>9,213</td> <td>8,720</td> </tr> <tr> <th scope="row">EU</th> <td>10,970</td> <td>9,040</td> <td>8,303</td> <td>8,234</td> <td>8,901</td> <td>8,889</td> </tr> <tr> <th scope="row">UK</th> <td>1,765</td> <td>1,564</td> <td>1,430</td> <td>1,438</td> <td>1,460</td> <td>1,423</td> </tr> <tr> <th scope="row">China</th> <td>1,575</td> <td>1,434</td> <td>1,345</td> <td>1,252</td> <td>1,158</td> <td>1,148</td> </tr> <tr> <th scope="row">India</th> <td>599</td> <td>510</td> <td>479</td> <td>457</td> <td>447</td> <td>414</td> </tr> </table> </div> <p>GDP, based on exchange rates, over time. Values in billion USDs.</p> </body> </html>
Notice that the table is contained in a div with an id of “plotarea.” The graph we will be creating later will replace the table contained inside this div. The table looks a bit ugly at the moment so let’s add some CSS to make it more presentable.
<style type="text/css">
body { font-family: Arial, Helvetica, sans-serif; }
table { border-collapse: collapse; }
td, th { border: 1px solid #222; padding: 5px; }
/* Fix the legend */
.legend td, .legend th { border: 0; padding: 2px; }
</style>
You should have something that looks like this.

Now that we have all the data in a table, we can start adding in the JavaScript that will create a graph for us. Technically, we don’t have to have a table, but it’s nice to have for two reasons:
- Accessibility. There are many blind web users out there and it is important to make everything on your website screen reader friendly. Screen readers cannot interpret graphs created by Flot.
- Degradability. A small number of web users disable JavaScript. Although this is a very small minority, it is not much more work to add a table so that they can view the data as well.
Step 2
Link the required JavaScript libraries. There are two of them, plus one more for IE support. We need to link jQuery first and then the Flot library since it depends on jQuery. Since Flot uses the canvas element to draw the graphs, we need to include the ExplorerCanvas script which emulates the canvas element in IE. Firefox, Opera and Safari users don’t need this so we’ll use conditional comments to make sure only IE users download it.
<script src="jquery.js" language="javascript" type="text/javascript"></script> <script src="jquery.flot.pack.js" language="javascript" type="text/javascript"></script> <!--[if IE]><script language="javascript" type="text/javascript" src="excanvas.pack.js"></script><![endif]-->
Creating a graph with Flot is quite simple because many of the options have sensible default values. This means you can create a good looking graph with minimal work, but can also tweak it to your liking. To make a basic graph, we need to specify a container element and the data to be graphed. The container element also needs to have a specified width and height, so we’ll use jQuery to set the “plotarea” div to have a width of 500px and a height of 250px.
<script language="javascript" type="text/javascript">
$(function() {
var plotarea = $("#plotarea");
plotarea.css("height", "250px");
plotarea.css("width", "500px");
$.plot( plotarea , data );
});
</script>
The first parameter is a jQuery object of the container element. The second element is a 3-dimensional array where the first child arrays are datasets and the "grandchild" arrays are ordered pairs specifying an X and Y value for a Cartesian plane. Let’s graph the GDP data for the US first.
<script language="javascript" type="text/javascript">
$(function () {
var data = [ [[2003, 10882],
[2002, 10383],
[2001, 10020],
[2000, 9762],
[1999, 9213],
[1998, 8720]] ];
var plotarea = $("#plotarea");
plotarea.css("height", "250px");
plotarea.css("width", "500px");
$.plot( plotarea , data );
});
</script>

The data table we had before should be replaced with a nice look graph. As you can see, the array containing the dataset is contained in another parent array. To graph another dataset, we just add it as another element to the parent array. Let’s add the data for the other countries we had in our table.
var data = [ [[2003, 10882], [2002, 10383], [2001, 10020], [2000, 9762], [1999, 9213], [1998, 8720]], [[2003, 10970], [2002, 9040], [2001, 8303], [2000, 8234], [1999, 8901], [1998, 8889]], [[2003, 1795], [2002, 1564], [2001, 1430], [2000, 1438], [1999, 1460], [1998, 1423]], [[2003, 1575], [2002, 1434], [2001, 1345], [2000, 1252], [1999, 1158], [1998, 1148]], [[2003, 599], [2002, 510], [2001, 479], [2000, 457], [1999, 447], [1998, 414]] ];

We now have a fairly good looking graph, but we don’t know which line is which country! What we need is a legend. Fortunately, Flot supports this and is a matter of putting our datasets in a JSON object and adding a label element.
var data = [
{
label: "USA",
data: [[2003, 10882],
[2002, 10383],
[2001, 10020],
[2000, 9762],
[1999, 9213],
[1998, 8720]]
},
{
label: "EU",
data: [[2003, 10970],
[2002, 9040],
[2001, 8303],
[2000, 8234],
[1999, 8901],
[1998, 8889]]
},
{
label: "UK",
data: [[2003, 1795],
[2002, 1564],
[2001, 1430],
[2000, 1438],
[1999, 1460],
[1998, 1423]]
},
{
label: "China",
data: [[2003, 1575],
[2002, 1434],
[2001, 1345],
[2000, 1252],
[1999, 1158],
[1998, 1148]]
},
{
label: "India",
data: [[2003, 599],
[2002, 510],
[2001, 479],
[2000, 457],
[1999, 447],
[1998, 414]]
}
];

Step 3
I mentioned before that although Flot has many sensible defaults. While they’re probably be fine for most people, the legend partially obscures some of the data. Flot has a third parameter for passing in options in a JSON object.
$.plot( plotarea , data, options );
To make the data at the far end of the graph a little more visible, we’ll adjust the background opacity and margins of the legend.
var options = {
legend: {
show: true,
margin: 10,
backgroundOpacity: 0.5
}
};

Some people (like me) like being able to see exactly where the data points are, so let’s specify in the options to mark each point with a circle of a specified radius.
var options = {
legend: {
show: true,
margin: 10,
backgroundOpacity: 0.5
},
points: {
show: true,
radius: 3
}
};

Great, we have data points, but where’d the lines go?! Let’s explicitly turn them back on.
var options = {
legend: {
show: true,
margin: 10,
backgroundOpacity: 0.5
},
points: {
show: true,
radius: 3
},
lines: {
show: true
}
};

Our final code looks something like this:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Flot Tutorial</title>
<style type="text/css">
body { font-family: Arial, Helvetica, sans-serif; }
table { border-collapse: collapse; }
td, th { border: 1px solid #222; padding: 5px; }
/* Fix the legend */
.legend td, .legend th { border: 0; padding: 2px; }
</style>
<script src="jquery.js" language="javascript" type="text/javascript"></script>
<script src="jquery.flot.pack.js" language="javascript" type="text/javascript"></script>
<!--[if IE]><script language="javascript" type="text/javascript" src="excanvas.pack.js"></script><![endif]-->
<script language="javascript" type="text/javascript">
$(function () {
var data = [
{
label: "USA",
data: [[2003, 10882],
[2002, 10383],
[2001, 10020],
[2000, 9762],
[1999, 9213],
[1998, 8720]]
},
{
label: "EU",
data: [[2003, 10970],
[2002, 9040],
[2001, 8303],
[2000, 8234],
[1999, 8901],
[1998, 8889]]
},
{
label: "UK",
data: [[2003, 1795],
[2002, 1564],
[2001, 1430],
[2000, 1438],
[1999, 1460],
[1998, 1423]]
},
{
label: "China",
data: [[2003, 1575],
[2002, 1434],
[2001, 1345],
[2000, 1252],
[1999, 1158],
[1998, 1148]]
},
{
label: "India",
data: [[2003, 599],
[2002, 510],
[2001, 479],
[2000, 457],
[1999, 447],
[1998, 414]]
}
];
var options = {
legend: {
show: true,
margin: 10,
backgroundOpacity: 0.5
},
points: {
show: true,
radius: 3
},
lines: {
show: true
}
};
var plotarea = $("#plotarea");
plotarea.css("height", "250px");
plotarea.css("width", "500px");
$.plot( plotarea , data, options );
});
</script>
</head>
<body>
<div id="plotarea">
<table>
<caption>GDP, based on exchange rates, over time. Values in billion USDs.</caption>
<tr>
<td></td>
<th scope="col">2003</th>
<th scope="col">2002</th>
<th scope="col">2001</th>
<th scope="col">2000</th>
<th scope="col">1999</th>
<th scope="col">1998</th>
</tr>
<tr>
<th scope="row">USA</th>
<td>10,882</td>
<td>10,383</td>
<td>10,020</td>
<td>9,762</td>
<td>9,213</td>
<td>8,720</td>
</tr>
<tr>
<th scope="row">EU</th>
<td>10,970</td>
<td>9,040</td>
<td>8,303</td>
<td>8,234</td>
<td>8,901</td>
<td>8,889</td>
</tr>
<tr>
<th scope="row">UK</th>
<td>1,765</td>
<td>1,564</td>
<td>1,430</td>
<td>1,438</td>
<td>1,460</td>
<td>1,423</td>
</tr>
<tr>
<th scope="row">China</th>
<td>1,575</td>
<td>1,434</td>
<td>1,345</td>
<td>1,252</td>
<td>1,158</td>
<td>1,148</td>
</tr>
<tr>
<th scope="row">India</th>
<td>599</td>
<td>510</td>
<td>479</td>
<td>457</td>
<td>447</td>
<td>414</td>
</tr>
</table>
</div>
<p>GDP, based on exchange rates, over time. Values in billion USDs.</p>
</body>
</html>
Concluding Thoughts
There are many possibilities with Flot. The Flot API details all the different options that are available for tweaking your graphs including specifying different graph types, colors, axes, and even enabling interactive features like selection and zooming. Another possibility is to make the entire thing fully dynamic and generate the JavaScript code dynamically with data from a database using PHP.
- Subscribe to the NETTUTS RSS Feed for more daily web development tuts and articles.
Related Posts
Check out some more great tutorials and articles that you might like
Plus Members
Source Files, Bonus Tutorials and
More for $9 a month for all TUTS+
sites in one subscription.












User Comments
( ADD YOURS )insic October 23rd
this is very use tutorial. i love it. I have to use it in my web application im working right now, perfect timing.
( )Julien L October 23rd
Nice tuts ! I think in the growing world of web app’, it coul be very usefull for enterprises.
( )Thanks !
Ben Griffiths October 23rd
This is absolutely fantastic – I didn’t even know of this tool, it looks great. Thanks for showing us how to use it
( )Jim October 23rd
I second the comment regarding useful for corporates, they love visualizing data and htis is perfect especially since it is JQ
( )Gareth October 23rd
Great tutorial, I just wish that you didn’t have to enter the data in twice..
( )realone October 23rd
if data are negative,result will be wrong
( )Chris Gedrim October 23rd
Great tutorial, but is there any way to get the data from the table?
Could each td be iterated through to get the data without setting id’s or class’s?
If so then you could pull data using PHP/ASP and plot in semi-realtime.
( )Adam October 23rd
Not the normal sort of tutorial I must say, but it’s great how Nettuts shows diversity. I love this tutorial and think it gives a great perspective to the the site and it’s ethos.
Great work.
( )Shane October 23rd
I’ve used flot on a recent project, and found it to be pretty impressive.
( )Mark Henderson October 23rd
Excellent tutorial, exactly what I have been looking to get into, thanks you’ve saved me so much research time!!!
More Jquery / Asp.net tutorials like this please!!!!
( )Christian Dalsvaag October 23rd
Wow, this tutorial is on an excellent subject. I’ve never even heard of this tool before. Thank you! Good job.
( )JamesS October 23rd
Great find, thanks.
I have been using FusionCharts recently, which is really excellent too – It’s based on Flash and XML rather than jQuery, but I can highly recommend it: http://www.fusioncharts.com/ … It’s almost infinitely customisable.
James
( )John October 23rd
Looks nice.
But with other similar tools I want to see examples of it handling thousands of data points.
( )Patrick October 23rd
yay, nice tutorial. very helpful for graphical site statistics
( )Thomas Milburn October 23rd
Another great tutorial especially as you’ve covered the issues of accessibility and usability by users who don’t have JavaScript.
Flot looks like a neat tool for producing on the fly graphs, I’ll certainly remember this for projects in future. I’ve also been doing some research on the canvas element. People are doing loads of other wicked stuff with it like this:
( )http://azarask.in/projects/algorithm-ink/
Lamin Barrow October 23rd
WOW, what a cool and interesting tut. This is uncharted territory man. Many thanks.
( )Lamin Barrow October 23rd
There is also another JS library call Raphael (http://raphaeljs.com/) that does similar things as this Jquery Plugin for those of you interested in checking out what other options are available.
( )Furley October 23rd
very interesting.
google charts is faster and easier though. unless you feel like splitting hairs over the design of the chart, id use googles API.
( )Jeff October 23rd
awsome, this is great. just what i needed for my current asp.net mvc project (wich now ships with jquery
). I was trying to write this myself, next time i will remember to look for plugins first.
( )rrealinho October 23rd
Wow. Excellent tutorial!
( )Robert October 23rd
Totally deserves a tweet
nice job…
( )Pablo Matamoros October 23rd
Awesome!!!
Javascript keeps surprising me…. Who dares to say that client scripting is not a powerful tool! And free ;P
( )Steve October 24th
Very nice! Gonna come in handy for a few projects I’ve got cooking now!
( )Jim Jamesson October 24th
Wow this is awesome! We are sooo trying this today
( )Freeware Collection October 26th
How beautiful it is. It’s really wonderful. Thank you very much.
( )Khurram October 26th
Really KOOOll 0-o : )
( )montana flynn October 27th
wow that was great! thanks a bunch
( )Reza Budi Prabowo October 28th
this is just what i need. thanks!
( )muneefvc October 30th
Bravo!
( )just what i am looking for ..!!
uSreX-man October 31st
Thanx very much!!!Makasih banget y source code nya!!!
God Bless You….!!!!He….!!!
uSreX-man
( )highblood October 31st
Hi James! First of all thanks for sharing this great tutorial. I have a couple of question regarding this tutorial since I wan to apply it in my work.
1) What would be the code if the countries be like check boxes where I have the option to choose which country I to appear on the chart?
2) How do you show up the actual values when I mouse-over certain points on the data?
Thanks in advance
( )Busby November 1st
Wow! Great! I have tried to create a bar graph using php with one of our client but im not that happy with the results. Maybe i will use ajax next time
( )dh November 6th
Very, very cool. One question: Does it print too?
( )Gatot Wibowo December 5th
Terima kasih…. how does it print in paper?
( )siubie December 19th
flot weakpoint is the graph cannot be printed CMIIW
but how to dynamically add data from php to flot ?
( )Bugsy January 22nd
Installed FLOT over the last couple days. AMAZING!
I see that Siubie asked about how to add data from php….
I have an SQL query that draws the data and insrts it into the data tag using repeat around [x1, y2], through all of the records. And boom live updated data.
I made a few charts so far based of my Daily Fruit blog…
http://www.fruuit.com/graphs/one/
( )Mehran Khajavi(sinoohe) January 24th
It’s so great and powerful
( )thanks again
Spike January 31st
Great article! One question… is there a way to save the graph as a PNG? When I try to view the image all i see is a blank “canvas” image.
Thanks!
( )MarcusT February 3rd
I like the article, but I don’t like the way it duplicates the data within the table AND JavaScript – this is completely unnecessary! Instead, the code should have read the data from the table and displayed it as a graph – in fact, it would make sense to encapsulate the functionality into a reusable plugin which could be applied to any data table, while accepting configuration parameters of course. Perhaps this article could be revised or revisited in a new article to show how this could be done? I know how, but it would be a useful tutorial for many.
( )Tom February 8th
I made an interesting piece of code.
var myways = [];
var mydata = [];
$(”#src”).find(”th[scope='col']“).each(function(){
myways.push($(this).html());
});
$(”#src tr”).each(function(){
var thiszone;
var zone = $(this).find(”th[scope='row']“).html();
var zonex = [];
$(this).find(”td”).each(function(){
var aval = parseInt($(this).html());
zonex.push(aval);
});
if(zone != null){
var zonedata = [];
for(var i=0;i<myways.length;i++){
zonedata.push([myways[i], zonex[i]]);
}
thiszone = {label: zone, data: zonedata};
mydata.push(thiszone);
}
});
Now, you don’t have to write all data stuff, just do the table, assign an ID and you will see the results! In order to make this thing work, you need to have numbers without commas or dots. And add the class row to labels and class col to data labels. Enjoy!
( )wpdigger June 3rd
Nice tuts ! I think in the growing world of web application.
( )Thanks for showing us how to use it
rajan June 12th
Great man…i tried so many other javascript framework,,,but flot is so simple and useful,…thanks for tutorial
( )diego June 13th
hii
( )can flot plot live streaming charts like stock charts without completely reloading itself.please do help me with the code i am new to flot. thankyou
Jeremie July 13th
Hi, great article. I found this tutorial useful too:
( )http://www.eremiya.net/
If it could help…