Sponsored by

  • Intel
  • HP

HTML5How to

Create beautiful data visualisations with the SVG Google Charts API

Create beautiful data visualisations with the SVG Google Charts API

Front end developer David Smith explains how to utilise the Google Charts API to create flexible HTML5/SVG-based charts that are visually appealing and work cross browser.

  • Knowledge needed: JavaScript, PHP and HTML
  • Requires: Web browser and text editor
  • Project Time: 45 mins
  • Support file

Data is big business on the web. Each day as we browse we generate enormous amounts of data which site owners and businesses use to determine everything from the next big re-design to strategy and advertising spend.

Visually, however, data can be very boring and unless you’re a statistician, large amounts of data can be particularly difficult to digest. As web designers, semantics suggest that HTML tables should be used to present data as they provide the “language” best suited to marking up facts and figures. Nonetheless, beyond a few nice borders and “zebra striped” rows, tables offer us little in the way of the design potential we require to improve the comprehension of the data they contain.

For this reason – and others besides – there has been a big growth in the solutions available to create graphical charts and diagrams. Tools such as the original Google Image Charts API allow us to take otherwise boring tabular data and transform it into visually rich <img> based charts which complement our tabular data making it easier to comprehend and understand for users and clients alike.

Advertisement

01. A brave new world – “HTML5” charts

Until quite recently most online charting tools dynamically created static graphics using the <img> tag which you could embed on your web page.

With the advent of HTML5 however, we now have a couple of alternative technologies available which allow us to create richer, more interactive charts which take us beyond the limits of static graphics and images. Perhaps the most popular are HTML5 canvas and SVG (Scalable Vector Graphics).

<canvas> charts

According to the Mozilla Developer network, HTML5 canvas is an HTML element which can be used to draw graphics using scripting. Canvas is fast and unlike a static images can be dynamically redrawn in- page using scripting. This makes it useful for quickly generating chart visualisations from HTML tables and with clever scripting can even allow some basic interactivity.

Some excellent canvas charting tools exist. My particular favourite is the Filament Group’s jQuery Visualize plug-in, which even harnesses the magic of Google’s excanvas.js script to ensure dynamic charts can be generated in browsers as far back as Internet Explorer 6.

SVG charts – a prefered solution

While Canvas does an excellent job of rendering dynamic charts, its main drawback is that it is a pixel- based graphics API. With Canvas you can't attach event handlers or manipulated existing objects. Once it’s drawn it’s drawn.

An alternative technology is SVG. Whilst not strictly part of the HTML5 spec, it offers several advantages over Canvas for charting on the web.

Chief amongst these is that SVG is vector based and is described using an XML-based syntax. This means that it maintains a DOM whose attributes can be read and dynamically updated via scripting at any point in the page’s lifecycle. Whilst there is a performance consideration associated with the DOM – especially when working with larger files – typically I feel SVG is a more suitable technology for creating charts on the web ...

... and it appears that Google agree with me!

02. The Google Charts API

Google maintains and develops a fully featured charting library called the Google Charts API. It’s extremely powerful and being Google, well supported and documented. All in all, it’s an excellent choice for charting on the web.

While the original version relied on images, the improved API now utilises the power of HTML5 and SVG to render a range of dynamic charts which are customisable and allow complex interactivity.

Backwards compatible via VML for older versions of IE, charts will render well across a range of devices including iOS and Android phones. No plugins are required!

03. A simple chart example

It’s pretty simple to get up and running with Google Charts. This demo – based on the original over at the official docs – shows a simple Pie Chart in action. Have a look at the source before continuing.

To render the chart, we need three libraries to be available. These are loaded via <script> tags before any custom code is run:

  1. The Google JSAPI API
  2. The Google Visualization library - google.load(,'visualization' '1.0', {'packages':['corechart']});
  3. The package(s) for the chart itself - google.load('visualization', '1.0', {'packages':['corechart']});

Once the required libraries are available we reference a function to be used as a callback for when the libraries have finished loading. This callback will define our data and draw the chart.

google.setOnLoadCallback(drawChart); // drawChart is our callback

function drawChart() {
         // code for drawing our chart (see article below)
}

Defining data

Inside our drawChart() function we now need to define our data. All data to be used for our chart needs to be wrapped in a JavaScript class called google.visualization.DataTable. This is basically representation of a 2D table with rows and columns, much the same as an HTML table.

    // Create the data table.
    var data = new google.visualization.DataTable();
    data.addColumn('string', 'Answer');
    data.addColumn('number', 'Result');
    data.addRows([
           ['Developer', 28],
           ['Web Designer', 12],
           ['Designer', 18],
           ['Web Master', 14],
           ['Pixel Pusher', 5]
    ]);

In our example we define a new instance of the class. We then set columns and rows using the addColumn() and addRow() methods provided.

You can find out more about how to prepare and define data on the official docs.

Rendering the chart

Having defined our data we then set some basic configuration options for size and to set a title for our chart.

// Set chart options
var options = {
       'title':'Job titles for people working on the web',
       'width':500,
       'height':400
};

Google charts are highly configurable and we’ll be exploring this aspect in greater detail later in the tutorial.

// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.PieChart(document.getElementById ('chart_div'));
chart.draw(data, options);

We next instantiate a new instance of the “visualisation” we wish to create (in this example it’s PieChart) and call its draw() method, passing a reference to the DOM element where we would like our chart to be rendered and the options we configured above.

That’s it – our chart is up and running.

04. A more complex example - plotting tweets using area charts

With our simple example complete it’s now time to try something a little more complex. We’re going to use the Twitter API to request information about my Twitter stream and display it on an Area Graph to show the number of tweets by date I’ve sent over the past week or so. Not the most riveting data ever, but something real to work with nonetheless.

You can see the demo of this here.

05. An accessible approach

In our simple Piechart example our data was fabricated but what’s worse it was all locked away and defined inside the JavaScript. This wasn’t the most accessible of approaches.

As previously discussed, data is best represented in an HTML table as this makes it available to users of assistive technologies and those few devices aren’t supported by the Google Chart API.

Ideally our tweet data should be available in-page as an HTML table and we should use JavaScript to harvest the information and pass it to the visualisation library for use in dynamic charts.

06. Requesting and organising the tweet data

At the top of our index.php file we make a request to the Twitter API for the latest 40 tweets from my user timeline (you could switch this to yours if you wish). The JSON response is read into a string and then parsed into an associative array by passing true as the second parameter to the json_decode function.

$jsonurl = "http://twitter.com/statuses/user_timeline/get_dave.json?count=40";
$json = file_get_contents($jsonurl,0,null,null);
$json_output = json_decode($json,true);

We need to know how many tweets were sent on each particular day so we next define an array (tweet_dates) whose keys will be the various created_at dates from our Twitter stream. We then loop through our tweets comparing timestamps and incrementing the appropriate key’s value in order to build up an array of tweets sent on each date.

$tweet_dates = array();
$curr_tweet_date = '';

// Build up an array of number of Tweets by date foreach($json_output as $tweet){

     // Get workable timestamp from json
     $tweet_date = date("d/m/y",strtotime($tweet['created_at']));
 
     // if the tweets date doesn't match the previous tweets date then start a new key in the array
     if ($curr_tweet_date != $tweet_date) {
         $tweet_dates[$tweet_date] = 1; // add a new key and set value to 1
         $curr_tweet_date = $tweet_date; // set current date var
     } else { // if current tweet date matches prev
         $tweet_dates[$tweet_date]++; // increment date key value
     }
} // end foreach

Once reversed (using array_reverse), this gives us an associative array which should look something similar to:

Array
(
      [28/03/12] => 7
      [29/03/12] => 1
      [30/03/12] => 4
      [31/03/12] => 1
      [02/04/12] => 1
      [03/04/12] => 3
      [04/04/12] => 2
      [08/04/12] => 1
      [11/04/12] => 2
      [12/04/12] => 3
      [13/04/12] => 11
      [14/04/12] => 1
)

In the body of our HTML page, we can now loop through this array to create an HTML table with columns for “Date” and “Tweets”.

We could have achieved much the same via JavaScript, but using a PHP-based approach ensures that the core data is always available to users of assistive technologies as markup.

07. Harvesting data from the HTML table

Next we need to harvest the tabular data. Our functions.js file defines a function called getData() which in turn is called by the drawChart() callback function to retrieve the required data. The aim of this function is to produce a simple array structure which we can pass to the google.visualization.arrayToDataTable() method which converts it into the format required by the charting API.

There are several approaches to creating the correct data formats but arrayToDataTable() is easiest for our purposes as it’s largely automated.

The format expected is an array containing a series of arrays each of which represents a “row” of data. Within each row is the data required for each column. Column headers are automatically assumed to be the first “row” in the array unless otherwise specified.

[
    ['Date', 'Tweets'],    // column headers
    ['04/04/2012', 25],    // row of data
    ['04/04/2012', 25]     // another row of data
]

The getData() function loops through each <tr>, reads the value of each <th> or <td> and then populates the values array to match the format required. Our data is now ready to be used.

08. Rendering the Area Chart

We instantiate a new instance of the Area Chart chart type, passing our data and some basic options:

new google.visualization.AreaChart(document.getElementById ('chart_div'));
chart.draw(data, options);

09. Making it look good

Our basic chart now renders roughly as follows:

It works, personally, however, I wouldn’t be happy presenting this “out of the box” view to my users or indeed a client. Luckily Google Charts provides us with a set of options which we can configure in order to customise the appearance of our chart.

To make the chart look a bit more presentable I’ve altered a few presentation options. Perhaps the most important tweaks are:

  • I’ve set the text colour to an off-black #666 (using hAxis.textStyle.color).
  • I’ve altered the grids lines to a subtle #eee gray (using hAxis.gridlines.color).
  • I’ve altered the default line colour to Twitter blue #08C (color).
  • I’ve set the lineWidth to be a nice thick value of 4 and complemented this by increasing the pointSize (the dots/nodes) to be a larger 8.
  • I’ve set the area opacity to be more transparent (using areaOpacity).

I highly recommend you read the full list of possible configuration options to allow you customise the chart to suit your own needs.

With these options in place our chart now looks a lot more presentable:

Going responsive – a flexible chart

Our chart is now looking good but it’s still a fixed size. If we’re producing a responsive site we need to have our chart scale to match the size of its container and the viewport size changes.

I’ve found that the best way to achieve this is to bind a redraw of the chart to the window.resize event. That way when the window is resized the chat will quickly redraw to the new size.

The main problem with this approach is that the window.resize event fires multiple times on each resize event. Repeatedly (and needlessly) redraw the chart has a performance penalty which I’d like to avoid. In order to avoid this I’m using Paul Irish’s excellent Debounced resize plug-in to ensure the resize event only fires once at the end of the specified period. This limits the number of chart redraw’s per window.resize.

$(window).smartresize(function () {
   chart.draw(data, options);
});

Our final chart

In the final demo we now have a visually pleasing, accessible, cross browser compatible chart which also scales with the device viewport.

I highly recommend familiarising yourself with the Google Charts API docs in order that you can improve and build upon anything you’ve learnt here in order to make your own charts. I’d also like to draw your attention to alternative SVG-based charting solutions such as Morris.js which uses both jQuery and Raphaël to draw its charts.

This guide is by no means comprehensive and I’m positive that there are many ways to improve and enhance the final result. If you know of any please let me know in the comments.

Dave Smith is front end designer based near the beautiful city of Bath, UK. When he’s not working on new and exciting web projects he can be found playing the trumpet in everything from Big Band jazz groups to Symphony orchestras. You can catch up with Dave on Twitter as @get_dave.

Liked this? Read these!

Log in to Creative Bloq with your preferred social network to comment

OR

Log in with your Creative Bloq account

site stat collection