Tutorial: Flot – How to Create Bar Charts
You may feel that a bar chart is the right kind of graph to display your data. It is simple to include Flot bar charts in your HTML document, whether you want to include a simple bar chart or a more complex chart with additional series. 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 Bar Chart
We will begin by creating the above simple bar chart. First of all you will need to create an element to place your chart into, preferably a div:
<div id="placeholder"></div>
Then include the following CSS. You need to include this else Flot will fail to render the chart:
#placeholder {
width: 450px;
height: 200px;
}
After this we need to include some jQuery and JavaScript. Let’s start by creating some data to include in your chart:
var d1 = [[0, 3], [1, 3], [2, 5], [3, 7], [4, 8], [5, 10], [6, 11], [7, 9], [8, 5], [9, 13]];
The array d1 contains various elements – the first digit is where the bar will appear on the x axis and the second digit is how tall each bar will appear on the y axis.
Then we need to generate the chart:
$.plot($("#placeholder"), [
{
data: d1,
bars: {
show: true
}
}
]);
This calls the plot function which creates the chart.
This is all you need to create the simple bar chart – not forgetting to include the jQuery and Flot source files. When all of the code is put together, it should 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=iso-8859-1" />
<title>Flot Bar Chart</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 = [[0, 3], [1, 3], [2, 5], [3, 7], [4, 8], [5, 10], [6, 11], [7, 9], [8, 5], [9, 13]];
$(document).ready(function () {
$.plot($("#placeholder"), [
{
data: d1,
bars: {
show: true
}
}
]);
});
</script>
</head>
<body>
<div id="placeholder"></div>
</body>
</html>
A Customised Bar Chart
You may choose to customise your bar chart a little further, maybe adding a legend and additional series.
Here is the code for the above customised bar chart in its entirety. I’ve included an explanation of how I’ve added in each feature 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 Bar Chart</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.axislabels.js"></script>
<script type="text/javascript" language="javascript" src="jquery.flot.orderBars.js"></script>
<script type="text/javascript">
$(document).ready(function () {
var d1_1 = [
[1325376000000, 120],
[1328054400000, 70],
[1330560000000, 100],
[1333238400000, 60],
[1335830400000, 35]
];
var d1_2 = [
[1325376000000, 80],
[1328054400000, 60],
[1330560000000, 30],
[1333238400000, 35],
[1335830400000, 30]
];
var d1_3 = [
[1325376000000, 80],
[1328054400000, 40],
[1330560000000, 30],
[1333238400000, 20],
[1335830400000, 10]
];
var d1_4 = [
[1325376000000, 15],
[1328054400000, 10],
[1330560000000, 15],
[1333238400000, 20],
[1335830400000, 15]
];
var data1 = [
{
label: "Product 1",
data: d1_1,
bars: {
show: true,
barWidth: 12*24*60*60*300,
fill: true,
lineWidth: 1,
order: 1,
fillColor: "#AA4643"
},
color: "#AA4643"
},
{
label: "Product 2",
data: d1_2,
bars: {
show: true,
barWidth: 12*24*60*60*300,
fill: true,
lineWidth: 1,
order: 2,
fillColor: "#89A54E"
},
color: "#89A54E"
},
{
label: "Product 3",
data: d1_3,
bars: {
show: true,
barWidth: 12*24*60*60*300,
fill: true,
lineWidth: 1,
order: 3,
fillColor: "#4572A7"
},
color: "#4572A7"
},
{
label: "Product 4",
data: d1_4,
bars: {
show: true,
barWidth: 12*24*60*60*300,
fill: true,
lineWidth: 1,
order: 4,
fillColor: "#80699B"
},
color: "#80699B"
}
];
$.plot($("#placeholder"), data1, {
xaxis: {
min: (new Date(2011, 11, 15)).getTime(),
max: (new Date(2012, 04, 18)).getTime(),
mode: "time",
timeformat: "%b",
tickSize: [1, "month"],
monthNames: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
tickLength: 0, // hide gridlines
axisLabel: 'Month',
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial, Helvetica, Tahoma, sans-serif',
axisLabelPadding: 5
},
yaxis: {
axisLabel: 'Value',
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial, Helvetica, Tahoma, sans-serif',
axisLabelPadding: 5
},
grid: {
hoverable: true,
clickable: false,
borderWidth: 1
},
legend: {
labelBoxBorderColor: "none",
position: "right"
},
series: {
shadowSize: 1
}
});
function showTooltip(x, y, contents, z) {
$('<div id="flot-tooltip">' + contents + '</div>').css({
top: y - 20,
left: x - 90,
'border-color': z,
}).appendTo("body").show();
}
function getMonthName(newTimestamp) {
var d = new Date(newTimestamp);
var numericMonth = d.getMonth();
var monthArray = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
var alphaMonth = monthArray[numericMonth];
return alphaMonth;
}
$("#placeholder").bind("plothover", function (event, pos, item) {
if (item) {
if (previousPoint != item.datapoint) {
previousPoint = item.datapoint;
$("#flot-tooltip").remove();
var originalPoint;
if (item.datapoint[0] == item.series.data[0][3]) {
originalPoint = item.series.data[0][0];
} else if (item.datapoint[0] == item.series.data[1][3]){
originalPoint = item.series.data[1][0];
} else if (item.datapoint[0] == item.series.data[2][3]){
originalPoint = item.series.data[2][0];
} else if (item.datapoint[0] == item.series.data[3][3]){
originalPoint = item.series.data[3][0];
} else if (item.datapoint[0] == item.series.data[4][3]){
originalPoint = item.series.data[4][0];
}
var x = getMonthName(originalPoint);
y = item.datapoint[1];
z = item.series.color;
showTooltip(item.pageX, item.pageY,
"<b>" + item.series.label + "</b><br /> " + x + " = " + y + "°C",
z);
}
} else {
$("#flot-tooltip").remove();
previousPoint = null;
}
});
});
</script>
</head>
<body>
<h1>Average Maximum Temperatures</h1>
<div id="placeholder"></div>
</body>
</html>
This may seem like a lot of code but once we break it down it becomes a lot simpler.
Here are the features I have added in:
- Tooltips for each bar
- Additional data series
- A legend
- Labels for each axis
- Custom colours for each series
- Data labels on the x axis
- Removed the vertical gridlines
Tooltips For Each Bar
To add tooltips there are a few sections of code. The first is to include the grid option. Including this ensures that the chart responds to hover events.
$.plot($("#placeholder"), data1, {
grid: {
hoverable: true
}
});
See the next few lines of code:
function getMonthName(newTimestamp) {
var d = new Date(newTimestamp);
var numericMonth = d.getMonth();
var monthArray = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
var alphaMonth = monthArray[numericMonth];
return alphaMonth;
}
$("#placeholder").bind("plothover", function (event, pos, item) {
if (item) {
if (previousPoint != item.datapoint) {
previousPoint = item.datapoint;
$("#flot-tooltip").remove();
var originalPoint;
if (item.datapoint[0] == item.series.data[0][3]) {
originalPoint = item.series.data[0][0];
} else if (item.datapoint[0] == item.series.data[1][3]){
originalPoint = item.series.data[1][0];
} else if (item.datapoint[0] == item.series.data[2][3]){
originalPoint = item.series.data[2][0];
} else if (item.datapoint[0] == item.series.data[3][3]){
originalPoint = item.series.data[3][0];
} else if (item.datapoint[0] == item.series.data[4][3]){
originalPoint = item.series.data[4][0];
}
var x = getMonthName(originalPoint);
y = item.datapoint[1];
z = item.series.color;
showTooltip(item.pageX, item.pageY,
"<b>" + item.series.label + "</b><br /> " + x + " = " + y + "°C",
z);
}
} else {
$("#flot-tooltip").remove();
previousPoint = null;
}
});
This binds the chart to Flot’s inbuilt plothover event so it will respond to hover events. Firstly, the code under the bind function removes any tooltips that are currently displayed (being the div #flot-tooltip).
Once the date is formatted using the functions getMonthName() and convertToDate(), the function showTooltip() is called to insert the tooltip into our chart. Note that the top of the tooltip is positioned 20px above the top of the bar and the left side of the tooltip is positioned 90px to the left of the bar:
function showTooltip(x, y, contents, z) {
$('<div id="flot-tooltip">' + contents + '</div>').css({
top: y - 20,
left: x - 90,
'border-color': z,
}).appendTo("body").show();
}
All that remains is to include the 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
For this you will need a plugin – include jquery.flot.orderBars.js underneath the jquery.flot.js file 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.orderBars.js"></script>
After this include the following bars option within each data series. For example:
var data1 = [
{
bars: {
show: true,
barWidth: 12*24*60*60*300
}
}
];
It’s important here to note the width of the bars is calculated in milliseconds, not pixels. If you’re not sure what numbers to use, it is probably best to experiment with the last number in the calculation (e.g. 12*24*60*60*300 – so change the 300 figure) to get the right column width.
Then you need to add the extra data series:
var d1_1 = [ [1325376000000, 120], [1328054400000, 70], [1330560000000, 100], [1333238400000, 60], [1335830400000, 35] ]; var d1_2 = [ [1325376000000, 80], [1328054400000, 60], [1330560000000, 30], [1333238400000, 35], [1335830400000, 30] ]; var d1_3 = [ [1325376000000, 80], [1328054400000, 40], [1330560000000, 30], [1333238400000, 20], [1335830400000, 10] ]; var d1_4 = [ [1325376000000, 15], [1328054400000, 10], [1330560000000, 15], [1333238400000, 20], [1335830400000, 15] ];
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: "Product 1", data: d1_1, ...
{label: "Product 2", data: d1_2, ...
{label: "Product 3", data: d1_3, ...
{label: "Product 4", data: d1_4, ...
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: 'Value',
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial, Helvetica, Tahoma, sans-serif',
axisLabelPadding: 5
}
});
Custom Colours For Each Series
Add the following to each data series. Here is an example just one data series:
{
bars: {
show: true,
fill: true,
fillColor: "#AA4643"
},
color: "#AA4643"
}
To add colour to the border of each bar, include color. To add a fill to each of the bars, include fillColor.
Data Labels on the X Axis
Include the following within xaxis to include data labels for each point on the x axis:
$.plot($("#barchart"), data1, {
xaxis: {
mode: "time",
timeformat: "%b",
tickSize: [1, "month"],
monthNames: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
}
});
Removed Vertical Gridlines
All this requires is an additional line in the xaxis option:
$.plot($("#placeholder"), data1, {
xaxis: {
tickLength: 0
}
});
Also do the same with yaxis if you want to remove horizontal gridlines.
Thanks for the tutorial!
I can’t see the “customized” one in Safari on my PC or iPad. Any ideas?
Thanks for your feedback Ape!
The customised graph wasn’t displaying properly because it uses dates. Safari (and IE 8 ) didn’t like the JavaScript date objects in the code, whereas this was no problem in other browsers. I’ve updated the graph to use Unix timestamps instead (and I’ve updated the tutorial). Hope this has solved it for you.
Thank you for this tutorial. I’m especially you used dates, because flot.js has a few hoops to jump through when you want to display date data. Also glad the subject of Safari & dates was touched on.