Tutorial: Flot – How to Create Line Graphs
It is easy to create line graphs in Flot, whether you just need a simple graph or a more complex and customised graph. In this tutorial I’ve provided examples of both.
For a more in depth introduction to Flot and how to use it in your web pages, take a look at the tutorial how to add charts to your web pages using Flot.
A Simple Line Graph
Using the above graph as an example, let’s begin creating a simple line graph by putting an element in your document that will contain your graph, preferably a div. This is called #placeholder:
<div id="placeholder"></div>
The following CSS gives #placeholder a width and a height. It is important to remember to include this else Flot will not render the graph at all:
#placeholder {
width: 450px;
height: 200px;
}
Then we will need to include some jQuery and JavaScript. Let’s start by creating some data to include in the graph. Here is an array containing a few data points:
var d1 = [[1, 300], [2, 600], [3, 550], [4, 400], [5, 300]];
For each element in the array, the first digit is where the point will appear on the x axis and the second digit is where the point will appear on the y axis.
The next step is to include the code to generate the graph:
$(document).ready(function () {
$.plot($("#placeholder"), [d1]);
});
This calls the plot function which creates the graph. It has 2 parameters: the first is #placeholder, the div element where your graph will be created, and the second is the data to be included in the graph.
When you’ve put it all together, you should now see a graph – not forgetting to include the jQuery and Flot source files. Here’s all the code in its entirety:
<!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=iso-8859-1" />
<title>Flot Line Graph</title>
<style type="text/css">
body { font-family: Verdana, Arial, sans-serif; font-size: 12px; }
#placeholder { width: 450px; height: 200px; }
</style>
<!--[if lte IE 8]><script type="text/javascript" language="javascript" src="excanvas.min.js"></script><![endif]-->
<script type="text/javascript" language="javascript" src="jquery-1.7.2.min.js"></script>
<script type="text/javascript" language="javascript" src="jquery.flot.js"></script>
<script type="text/javascript">
var d1 = [[1, 300], [2, 600], [3, 550], [4, 400], [5, 300]];
$(document).ready(function () {
$.plot($("#placeholder"), [d1]);
});
</script>
</head>
<body>
<div id="placeholder"></div>
</body>
</html>
A Customised Line Graph
You may feel that a simple line graph isn’t enough and you need some extra features and customisations.
Here is the code for the above graph in its entirety. I’ve provided an explanation of each additional feature I’ve added in below 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=iso-8859-1" />
<title>Flot Line Graph</title>
<style type="text/css">
body { font-family: Verdana, Arial, sans-serif; font-size: 12px; }
h1 { width: 450px; margin: 0 auto; font-size: 12px; text-align: center; }
#placeholder { width: 450px; height: 200px; position: relative; margin: 0 auto; }
.legend table, .legend > div { height: 82px !important; opacity: 1 !important; right: -55px; top: 10px; width: 116px !important; }
.legend table { border: 1px solid #555; padding: 5px; }
#flot-tooltip { font-size: 12px; font-family: Verdana, Arial, sans-serif; position: absolute; display: none; border: 2px solid; padding: 2px; background-color: #FFF; opacity: 0.8; -moz-border-radius: 5px; -webkit-border-radius: 5px; -khtml-border-radius: 5px; border-radius: 5px; }
</style>
<!--[if lte IE 8]><script type="text/javascript" language="javascript" src="excanvas.min.js"></script><![endif]-->
<script type="text/javascript" language="javascript" src="jquery-1.7.2.min.js"></script>
<script type="text/javascript" language="javascript" src="jquery.flot.js"></script>
<script type="text/javascript" language="javascript" src="jquery.flot.symbol.js"></script>
<script type="text/javascript" language="javascript" src="jquery.flot.axislabels.js"></script>
<script type="text/javascript">
//Rome, Italy
var d1 = [[1262304000000, 12], [1264982400000, 13], [1267401600000, 15], [1270080000000, 18], [1272672000000, 23], [1275350400000, 27], [1277942400000, 30], [1280620800000, 30], [1283299200000, 27], [1285891200000, 22], [1288569600000, 16], [1291161600000, 13]];
// Paris, France
var d2 = [[1262304000000, 6], [1264982400000, 7], [1267401600000, 12], [1270080000000, 16], [1272672000000, 20], [1275350400000, 23], [1277942400000, 25], [1280620800000, 24], [1283299200000, 21], [1285891200000, 16], [1288569600000, 10], [1291161600000, 7]];
// Madrid, Spain
var d3 = [[1262304000000, 11], [1264982400000, 13], [1267401600000, 16], [1270080000000, 18], [1272672000000, 22], [1275350400000, 28], [1277942400000, 33], [1280620800000, 32], [1283299200000, 28], [1285891200000, 21], [1288569600000, 15], [1291161600000, 11]];
// London, UK
var d4 = [[1262304000000, 7], [1264982400000, 7], [1267401600000, 10], [1270080000000, 13], [1272672000000, 16], [1275350400000, 20], [1277942400000, 22], [1280620800000, 21], [1283299200000, 19], [1285891200000, 15], [1288569600000, 10], [1291161600000, 8]];
var data1 = [
{label: "Rome, Italy", data: d1, points: { symbol: "circle", fillColor: "#058DC7" }, color: '#058DC7'},
{label: "Paris, France", data: d2, points: { symbol: "diamond", fillColor: "#AA4643" }, color: '#AA4643'},
{label: "Madrid, Spain", data: d3, points: { symbol: "square", fillColor: "#50B432" }, color: '#50B432'},
{label: "London, UK", data: d4, points: { symbol: "triangle", fillColor: "#ED561B" }, color: '#ED561B'}
];
$(document).ready(function () {
$.plot($("#placeholder"), data1, {
xaxis: {
min: (new Date(2009, 11, 18)).getTime(),
max: (new Date(2010, 11, 15)).getTime(),
mode: "time",
tickSize: [1, "month"],
monthNames: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
tickLength: 0,
axisLabel: 'Month',
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial, Helvetica, Tahoma, sans-serif',
axisLabelPadding: 5
},
yaxis: {
axisLabel: 'Temperature (C)',
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial, Helvetica, Tahoma, sans-serif',
axisLabelPadding: 5
},
series: {
lines: { show: true },
points: {
radius: 3,
show: true,
fill: true
},
},
grid: {
hoverable: true,
borderWidth: 1
},
legend: {
labelBoxBorderColor: "none",
position: "right"
}
});
function showTooltip(x, y, contents, z) {
$('<div id="flot-tooltip">' + contents + '</div>').css({
top: y - 30,
left: x - 135,
'border-color': z,
}).appendTo("body").fadeIn(200);
}
function getMonthName(numericMonth) {
var monthArray = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
var alphaMonth = monthArray[numericMonth];
return alphaMonth;
}
function convertToDate(timestamp) {
var newDate = new Date(timestamp);
var dateString = newDate.getMonth();
var monthName = getMonthName(dateString);
return monthName;
}
var previousPoint = null;
$("#placeholder").bind("plothover", function (event, pos, item) {
if (item) {
if ((previousPoint != item.dataIndex) || (previousLabel != item.series.label)) {
previousPoint = item.dataIndex;
previousLabel = item.series.label;
$("#flot-tooltip").remove();
var x = convertToDate(item.datapoint[0]),
y = item.datapoint[1];
z = item.series.color;
showTooltip(item.pageX, item.pageY,
"<b>" + item.series.label + "</b><br /> " + x + " = " + y + "mm",
z);
}
} else {
$("#flot-tooltip").remove();
previousPoint = null;
}
});
});
</script>
</head>
<body>
<h1>Average Maximum Temperatures</h1>
<div id="placeholder"></div>
</body>
</html>
At first glance all of this code may seem a little overwhelming but if we break it down it’s quite simple.
Here are the additional features I have added in:
- Tooltips for each data point
- Additional data series
- Custom shapes for the data points
- A legend
- Labels for each axis
- Custom colours for each series
- Data labels on the x axis
- Removed the vertical gridlines
Tooltips For Each Data Point
There are a few sections of code to do this, the first being to include the grid option. You need to include this to enable hover events in the graph:
$.plot($("#placeholder"), data1, {
grid: {
hoverable: true
}
});
Then see the code below:
function getMonthName(numericMonth) {
var monthArray = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
var alphaMonth = monthArray[numericMonth];
return alphaMonth;
}
function convertToDate(timestamp) {
var newDate = new Date(timestamp);
var dateString = newDate.getMonth();
var monthName = getMonthName(dateString);
return monthName;
}
$("#placeholder").bind("plothover", function (event, pos, item) {
if (item) {
if ((previousPoint != item.dataIndex) || (previousLabel != item.series.label)) {
previousPoint = item.dataIndex;
previousLabel = item.series.label;
$("#flot-tooltip").remove();
var x = convertToDate(item.datapoint[0]),
y = item.datapoint[1];
z = item.series.color;
showTooltip(item.pageX, item.pageY,
"<b>" + item.series.label + "</b><br /> " + x + " = " + y + "mm",
z);
}
} else {
$("#flot-tooltip").remove();
previousPoint = null;
}
});
This binds the graph to Flot’s inbuilt plothover event so the graph will respond to hover events. The code underneath this firstly removes any tooltips that are displayed (being the div #flot-tooltip).
Then after formatting the date using the functions getMonthName() and convertToDate(), the function showTooltip() is called to insert the tooltip into our graph. Note that the top of the tooltip is positioned 30px above the data point and the left side of the tooltip is positioned 135px to the left of the data point:
function showTooltip(x, y, contents, z) {
$('<div id="flot-tooltip">' + contents + '</div>').css({
top: y - 30,
left: x - 135,
'border-color': z,
}).appendTo("body").fadeIn(200);
}
Then just include the following CSS:
#flot-tooltip {
font-size: 12px;
font-family: Verdana, Arial, sans-serif;
position: absolute;
display: none;
border: 2px solid;
padding: 2px;
background-color: #FFF;
opacity: 0.8;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
-khtml-border-radius: 5px;
border-radius: 5px;
}
Additional Data Series
This should be fairly self-explanatory – additional datasets have been included:
var d1 = [[1262304000000, 12], [1264982400000, 13], [1267401600000, 15], [1270080000000, 18], [1272672000000, 23], [1275350400000, 27], [1277942400000, 30], [1280620800000, 30], [1283299200000, 27], [1285891200000, 22], [1288569600000, 16], [1291161600000, 13]];
var d2 = [[1262304000000, 6], [1264982400000, 7], [1267401600000, 12], [1270080000000, 16], [1272672000000, 20], [1275350400000, 23], [1277942400000, 25], [1280620800000, 24], [1283299200000, 21], [1285891200000, 16], [1288569600000, 10], [1291161600000, 7]];
var d3 = [[1262304000000, 11], [1264982400000, 13], [1267401600000, 16], [1270080000000, 18], [1272672000000, 22], [1275350400000, 28], [1277942400000, 33], [1280620800000, 32], [1283299200000, 28], [1285891200000, 21], [1288569600000, 15], [1291161600000, 11]];
var d4 = [[1262304000000, 7], [1264982400000, 7], [1267401600000, 10], [1270080000000, 13], [1272672000000, 16], [1275350400000, 20], [1277942400000, 22], [1280620800000, 21], [1283299200000, 19], [1285891200000, 15], [1288569600000, 10], [1291161600000, 8]];
var data1 = [
{label: "Rome, Italy", data: d1, points: { symbol: "circle", fillColor: "#058DC7" }, color: '#058DC7'},
{label: "Paris, France", data: d2, points: { symbol: "diamond", fillColor: "#AA4643" }, color: '#AA4643'},
{label: "Madrid, Spain", data: d3, points: { symbol: "square", fillColor: "#50B432" }, color: '#50B432'},
{label: "London, UK", data: d4, points: { symbol: "triangle", fillColor: "#ED561B" }, color: '#ED561B'}
];
Custom Shapes For Each Data Point
All you need for this is a plugin – include jquery.flot.symbol.js underneath jquery.flot.js in the head section of your HTML document:
<!--[if lte IE 8]><script type="text/javascript" language="javascript" src="excanvas.min.js"></script><![endif]--> <script type="text/javascript" language="javascript" src="jquery-1.7.2.min.js"></script> <script type="text/javascript" language="javascript" src="jquery.flot.js"></script> <script type="text/javascript" language="javascript" src="jquery.flot.symbol.js"></script>
Then include the following in the points option within the series option:
$.plot($("#placeholder"), data1, {
series: {
points: {
show: true
}
}
});
Finally, you will need to include an additional symbol option for each of your data series. Permitted shape types are diamond, square, triangle and cross, and also the standard circle. You can also colour the symbols if you wish using fillColor:
{data: d1, points: { symbol: "circle", fillColor: "#058DC7" }, ...
{data: d2, points: { symbol: "diamond", fillColor: "#AA4643" }, ...
{data: d3, points: { symbol: "square", fillColor: "#50B432" }, ...
{data: d4, points: { symbol: "triangle", fillColor: "#ED561B" }, ...
A Legend
In the options parameter, include a legend option:
$.plot($("#placeholder"), data1, {
legend: {
labelBoxBorderColor: "none",
position: "right"
}
});
Then for each data series, give them a label option:
{label: "Rome, Italy", data: d1, ...
{label: "Paris, France", data: d2, ...
{label: "Madrid, Spain", data: d3, ...
{label: "London, UK", data: d4, ...
Finally, add the following CSS:
.legend table, .legend > div {
height: 82px !important;
opacity: 1 !important;
right: -55px;
top: 10px;
width: 116px !important;
}
.legend table {
border: 1px solid #555;
padding: 5px;
}
Labels For Each Axis
If you want to include the data labels on the axes, you will need a plugin – include jquery.flot.axislabels.js underneath jquery.flot.js in the head section of your HTML document:
<!--[if lte IE 8]><script type="text/javascript" language="javascript" src="excanvas.min.js"></script><![endif]--> <script type="text/javascript" language="javascript" src="jquery-1.7.2.min.js"></script> <script type="text/javascript" language="javascript" src="jquery.flot.js"></script> <script type="text/javascript" language="javascript" src="jquery.flot.axislabels.js"></script>
Then you will need to look at xaxis and yaxis in the options parameter and include the following:
$.plot($("#placeholder"), data1, {
xaxis: {
axisLabel: 'Month',
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial, Helvetica, Tahoma, sans-serif',
axisLabelPadding: 5
},
yaxis: {
axisLabel: 'Temperature (C)',
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial, Helvetica, Tahoma, sans-serif',
axisLabelPadding: 5
}
});
Custom Colours For Each Series
The colour for each series is defined in the data series options:
{data: d1, color: '#058DC7', ...
{data: d2, color: '#AA4643', ...
{data: d3, color: '#50B432', ...
{data: d4, color: '#ED561B', ...
Data Labels on the X Axis
This involves adding some additional options to the xaxis option:
$.plot($("#placeholder"), data1, {
xaxis: {
mode: "time",
tickSize: [1, "month"],
monthNames: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
}
});
Removed Vertical Gridlines
This is probably the most simple feature I have added in – under the xaxis option, add the tickLength property:
$.plot($("#placeholder"), data1, {
xaxis: {
tickLength: 0
}
});
Also do the same with the yaxis if you want to remove horizontal gridlines.