
Displaying combined charts
Combined charts are charts that have more than one x or y axis, and may have multiple types of series (lines, bars, and areas). Sometimes, we may want to present multiple heterogeneous types of data on a single chart, usually to visualize its correlation.
In this recipe, we're going to try and visualize a mountain hike by presenting both temperature and altitude on a single chart. The altitude series will be an area chart with gradient colors reminiscent of relief maps, but the temperature series will be a line chart, which we would like to be red if above 19 degrees Celsius and blue if below that.
In order to do this, we're going to need a charting library that can handle two y axes. We're going to use the Flot charting library because it is capable of displaying charts with two or more x or y axes.
Getting ready
Like in the previous recipes, we need to download Flot from the official website at http://www.flotcharts.org/ and extract the contents to a separate folder named flot
.
How to do it...
Let's write the HTML and JavaScript code.
- Our HTML file needs a chart placeholder, jQuery, Flot, and our example script. This time we're also going to need the
threshold
plugin in order to have two temperature colors. The following is the content:<!DOCTYPE HTML> <html> <head> <title>Chart example</title> <style type="text/css"> #chart { font-family: Verdana; } </style> </head> <body> <div id="chart" style="height:200px; width:800px;"></div> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script> <script src="flot/jquery.flot.js"></script> <script src="flot/jquery.flot.threshold.js"></script> <script type="text/javascript" src="example.js"></script> </body> </html>
- Our chart is drawn in
example.js
using the following code:$(function() { function getData(cb) { var altitudes = [], temperatures = []; // Generate random but convincing-looking data. for (var k = 0; k < 20; k += 0.5) { altitudes.push([k, Math.random()*50 + 1000*Math.pow((k-15)/15,2)]); temperatures.push([k, Math.random()*0.5 + k/4 + 15]); } cb({alt:altitudes, temp:temperatures}); } getData(function(data) { $.plot("#chart", [ { data: data.alt, yaxis:1, lines: {fill:true, fillColor: { colors: ["#393", "#990", "#cc7", "#eee"] } } }, { data: data.temp, yaxis:2, color: "rgb(200, 20, 30)", threshold: { below: 19, color: "rgb(20, 100, 200)" } } ], { yaxes: [ { }, { position: "right"}], xaxis: { tickFormatter: function(km) { return km + ' km'; } }, grid: { markings: [{ xaxis: { from: 0, to: 8 }, color: "#eef" }] } }); }); });
The following screenshot shows the end result:

How it works...
With the getData
function, we generate two series for the plot, one containing temperature and the other containing altitude.
When drawing the plot, we call the getData
function first. In the provided callback, we take the data and pass it to the $.plot
function, which takes the target container element, an array of series, and plot options.
The first series in the array contains altitude data. We have two y axes so we need to declare the y axis we're going to use for this series—the first y axis. The rest of the parameters declare the fill gradient; for more information see the Creating an area chart recipe.
The second series uses the second y axis. What is new here is the threshold
property. It specifies that for values below 19 degrees, the color of the line should be different (blue rather than red).
We're going to configure the second y axis in the options
object by specifying the yaxes
property (note the plural in the name). This property is an array containing y axis options. We're going to use the defaults for the first axis, hence the empty object. We will place the second axis on the right-hand side.
The unit of the x axis is kilometers and therefore our tickformatter
function adds the string " km"
to the number.
Finally, we mark the "mountain part" (from 0 to 8 km) in blue with the grid markings option.
There's more...
Here is a simple Ajax replacement of the getData
function, sending an Ajax request to a request handler hosted on the same domain at the /charts
path to retrieve the chart data. This handler should return an object in the following format:
{alt: data1, temp: data2}
Where data1
and data2
are two-dimensional arrays containing the data.
function getData(cb) { $.get('/charts').success(cb); }