owadays, more and more data live in the cloud in multiple formats and locations. In light of this trend, visual analysis, the ability to extract key information from the data and present it at a glance, becomes more important. And developers often are the ones tasked with aggregating, parsing, and exposing these data in coherent forms such as dashboards, reports, and charts. Thank goodness for the expressive power of images and graphic representations.
For these new demands, the Google Visualization API offers a unified way for developers to deliver visual analysis and provides a rich set of graphic and charting components to handle the majority of visualization scenarios. The Google Visualization API is a data interchange specification and a set of libraries that developers can use to represent structured data as graphic visualizations and interactive charts inside their web applications. This article describes the recently released API, from its basic concepts to its more advanced parts. You will learn how to embed a simple visualization component into your web pages, how to feed it with data from external sources, and finally how to implement your own data sources to add your data to the dozens of visualizations already available in the public Visualization Gallery.
Anatomy of a Visualization
Visualizations created with the Google Visualization API typically are JavaScript or Flash components that live inside a web page. They range from static images and charts to interactive timelines, maps, and motion charts. They conform to a specific interface dictated by the API, and their job is to transform structured data they receive as input into graphical representations. They can also talk to other parts of the web page (including other visualizations on the page) using a simple mechanism based on events and callbacks. With a bit of JavaScript, you can create new visualizations and contribute them to the public gallery for other users’ benefit.
You either assemble the data you plan to represent locally on the client using the JavaScript functions provided by the API or fetch them from remote servers via AJAX calls. The API also covers the structure of these calls as well as the expected requests and responses. In this way, you can easily wrap any server-side data source, such as SQL databases, spreadsheets, or proprietary storage formats, into a format that is immediately compatible with client-side visualizations.
The openness of the Google Visualization API’s interchange format benefits both the server and client sides. Server-side data sources exposed through the API can immediately be displayed by any of the dozens of visualizations that already exist. On the client side, when creating a new visualization, you don’t have to worry about compatibility issues among a multitude of sources; you need to care about only one format, while still being able to read data from all the compliant providers. In effect, you can display data from any data source connected to the web. The API manages the whole cycle from the data production to its consumption.
Preparing the Data for Your Visualizations
The easiest way to get started with the Google Visualization API is to use a visualization among the ones available in the public gallery. As a first step, you will create a web page to display an organizational chart. The chart will be rendered by a Google Visualization and you will feed it with local data via some JavaScript.
To begin, create a new HTML file with your preferred editor and paste in the following contents:
This page demonstrates using an existing OrgChart visualization, with locally created data.
The above code shows all the required elements for using a Google Visualization:
- Load the Google jsapi script, which contains the basic functions to interact with Google libraries.
- Load the visualization package via the google.load() function.
- Specify the visualizations you intend to use. (In this case, you are interested only in the orgchart package. If you wanted to use more visualizations, you would enumerate them in the packages parameter. You can get the whole list of available packages from the visualization gallery.)
- Use the setOnLoadCallback() function to register a callback that will be invoked as soon as all the libraries have been loaded.
Inside the drawVisualization() function, you can assemble the data to visualize and then display them. To define where in the web page you want to put the visualization, you can use a DOM element as a placeholder (orgchartdiv, in this case). Listing 1 shows the contents of the drawVisualization() function.
The main elements to consider in Listing 1 are google.visualization.DataTable and google.visualization.OrgChart. The former is a generic tabular container to fill with the data you want to display in the visualization. The latter is the visualization itself.
DataTable behaves like a bi-dimensional table, indexed by rows and columns. Each row represents an item of your visualization, and each column represents an attribute of your items. DataTable exposes many methods you can use to enter and describe your data. (The official documentation describes all of them in detail.) The most pertinent ones, which you will always use, are addRows(), addColumn(), and setCell(). You call them respectively to specify the number of items (rows of data) you want to display in the visualization, the number and kind of attributes they have, and the actual values for each item-attribute pair. Columns have defined types. Supported ones are string, number, boolean, date, datetime, and timeofday.
Instantiating Your Visualizations
Once your data is ready, you can instantiate the visualization, specifying the placeholder DOM element where you want the visualization to live, and then drawing it by passing the DataTable instance as a parameter.
Figure 1. The Organizational Chart Visualization: Here is the final result for the organizational chart you created and displayed in your web page. |
The draw() method requires two parameters. The first is the DataTable you will use; the second is a list of customization options wrapped in the form of a JavaScript object, with each property representing a customization key. Each visualization supports different options, so be sure to check your chosen visualization’s documentation to verify which options it supports. The example in Listing 1 uses the selectionColor option to customize the color used to highlight chart nodes when the user selects them.
Additionally, each visualization expects the DataTable to contain specific columns. In the case of the organizational chart, it requires two string columns: the first one representing the name of each tree node, and the second representing the name of the parent node. Different visualizations may require different columns to be defined. For example, a pie chart requires a string column for the label and a numeric column for the value of each pie slice. Refer to the documentation for each visualization to verify the required columns.
Figure 1 shows the final result for the organizational chart you just created and displayed in your web page.
Creating Your Own Visualizations
All the visualizations adhere to the same method signature and they are all used in the same way. Therefore, creating new visualizations is easy. You need only create a JavaScript object that follows the signature in the following listing and make it available to other developers:
// namespace, to avoid conflicts with other visualizations and javascript objects
// living in the same page as this visualization.var my_domain = {};// constructor for the MyVisualization object. The 'container'// parameter is the placeholder DOM element into which // you will draw your visualization.my_domain.MyVisualization = function(container) { // store the container into an instance variable for later use. this.container = container;};// The draw() method receives a DataTable and an options object.my_domain.MyVisualization.prototype.draw = function(data, options) { // ... implement your visualization code here.}
Once you define this stub, you can implement the draw() method with the specific code required for your visualization.
For example, at the time of writing, the visualization gallery still did not contain a visualization to display treemaps. Treemaps are a method for displaying tree-structured data using nested rectangles. They are especially useful when each node in the tree is associated with a scalar value. It therefore seems a useful exercise to implement treemaps as a new Google Visualization.
To keep the example simple, it will not implement the drawing code from scratch. Instead, it will reuse Js-Treemap, a JavaScript library created by David Cowie that is dedicated to drawing treemaps, and wrap it in a visualization. Figure 2 shows how the same data shown in the organizational chart (see Figure 1) may appear when wrapped inside a treemap, provided you set a quantity value for each leaf node in the tree.
Figure 2. A Sample Treemap: Here is how the data shown in the organizational chart may appear when wrapped inside a treemap. |
Drawing a treemap using the Js-Treemap library is relatively easy. You just have to perform the following steps:
- Create some HTML elements that contain the main drawing and its navigational controls.
- Transform the visualization DataTable into a set of nested TreeNode objects to represent the hierarchical structure. The TreeNode class is defined by the Js-Treemap library.
- Create a DivTreeMap instance that takes care of drawing the treemap itself in the container DOM element you specify. DivTreeMap is defined inside Js-Treemap too.
- Optionally, bind event listeners for clicks on the treemap to navigational controls, such as zooming in and out on different parts of the map.
Listing 2 shows how all of this can be embedded into a Google visualization, reusing the stub presented previously.
Figure 3. Embedding a Custom Treemap Visualization on a Web Page: Here is the web page example with the visualization you created. |
Note how the code parses options to customize the width and height of the generated visualization and uses defaults in case some options are left unspecified by the user. Also, note how all the drawing is generated inside the container object received in the constructor. The parsing of the DataTable object received by the draw() function occurs inside the createTree() method. Listing 3 shows the visualization’s implementation.
The code uses various functions exposed by DataTable to navigate through its contents; GetNumberOfRows(), getNumberOfColumns(), and getValue() can be used to iterate over all the cells in the dataset and read their values. Other functions, such as getDistinctValues(), compute aggregations over rows and columns.
The treemap visualization expects the DataTable to contain three columns. The first two contain the name of each node and its parent name, just like the organizational chart. The last column is a numeric one, associating a scalar value to each leaf node.
You can then update the drawVisualization() function to include the extra column in the DataTable and add the newly created treemap visualization to the page, along with the organizational chart from the previous example. Listing 4 shows the final version.
Figure 3 shows the web page example with the visualization you just created.
Events Handling
Visualizations must be able to communicate and exchange information with the rest of the page. This is an even more vital function when you create dashboards that use multiple visualizations on the same page, all of them based on the same data. Users expect visualizations to react to changes that occur somewhere else in the page or inside another visualization.
To handle these cases, the Google Visualization API includes functions to fire and respond to events. Each visualization can fire events using the google.visualization.events.trigger() function, which takes three parameters:
- The source of the event (typically the visualization itself)
- A string representing the name of the event
- An object representing the event details (in the form of a key/value map)
Visualization users can listen to events using the google.visualization.events.addListener() function. It also takes three parameters:
- The visualization to which you want to listen
- The name of the events in which you are interested
- A callback function to handle the event (The event details will be passed as parameters to the function.)
The Select Event
The select event is a special case. Visualizations use it to notify others that the user has selected a particular element of the underlying DataTable and instructs them to react to selections that occur elsewhere. A visualization that wants to handle the select event has to:
- fire events with the select name and no details whenever a user selects an item that maps to a particular cell, row, or column in the underlying DataTable.
- expose a getSelection() method that returns an array of selected items. Each selected item must be an object with row and/or column properties referring to the selected cell in the data. You can leave row or column set to null if the user selected an entire column or row.
- expose a setSelection() method if it wants to react to selections occurring outside itself. It receives a list of objects in the same format as the ones returned by getSelection().
Listing 5 illustrates how to extend the treemap visualization to fire select events.
You can now bind the treemap visualization and the organizational chart together by adding the following snippet to the web page example:
google.visualization.events.addListener( treemap, 'select', function() { orgchart.setSelection(treemap.getSelection());});
Now, whenever a user clicks on a treemap node, the corresponding entry in the organizational chart will be highlighted.
Loading Data from an External Source
So far, all the examples rely on data created locally with JavaScript. In a production scenario, you are more likely to fetch the data from a remote data source. Of course, the data source must emit data in a format compliant with the Google Visualization API.
Google Spreadsheets are capable of emitting data in such a format, so let’s start by moving the sample data out of the web page and into a Google Spreadsheet. Create a Google Spreadsheet with the contents shown in Figure 4. Once you have inserted the data, use these instructions to compute a URL that exposes them in the form of a data source that is compliant with the Visualization API.
Figure 4. A Google Spreadsheet Containing the Data to Visualize: Here is a Google Spreadsheet with the contents you inserted. |
You can now replace the