This document describes how to create a visualization gadget. Gadgets are small, self-contained applications that can be added to certain web pages (for example, iGoogle and Google Spreadsheets) or on the desktop, using Google Desktop. Gadgets are simpler for users to embed: they don't require the user to modify any code on the host page, and can typically be added with a menu click on the host page. They can also store user preference values persistently.
This documentation is designed for people familiar with JavaScript programming and object-oriented programming concepts. There are many JavaScript tutorials available on the Web.
This document also assumes you have some prior knowledge of developing gadgets. If you are not familiar with writing gadgets, read the Getting Started guide for gadgets. You should also read the Using Visualizations page.
Visualization gadgets are coded largely the same way as non-gadget visualizations, with just a few differences:
DataTable,
either directly in code, or by making a query. (Non-gadget visualizations usually
depend on host page code to populate the data.)Here are the basic steps for creating a visualization gadget:
<script> include
tag, the same as in non-gadgetized visualizations.<script> tags
to load your visualizations right after the AJAX API tag.Here is code for a visualization gadget. This code has been trimmed from a full, working gadget file posted here. We'll go over the previous steps and explain how it applies to each section of the code.
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<UserPref name="_table_query_url" display_name="Data source url" required="true"/>
<Content type="html"><![CDATA[
<!-- Load the Google AJAX API. -->
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<!-- Put your gadget HTML anywhere here. Don't forget the DOM element that will hold your visualization -->
<div id="tablediv" style="overflow: auto;"></div>
<script>
var gadgetHelper = null;
var table = null;
_IG_RegisterOnloadHandler(loadVisualizationAPI);
// Load the Google Visualization API
function loadVisualizationAPI() {
google.load('visualization', '1', {'packages': ['table']});
google.setOnLoadCallback(sendQuery);
}
// Send a data query.
function sendQuery() {
// Instantiate our Table visualization.
var tableDiv = _gel('tablediv'); // A gadget convenience method for getElementById
tableDiv.style.width = document.body.clientWidth + 'px';
tableDiv.style.height = document.body.clientHeight + 'px';
table = new google.visualization.Table(tableDiv);
// The query src URL is stored in the user prefs.
// This GadgetHelper convenience method loads it into a
// query for you.
gadgetHelper = new google.visualization.GadgetHelper();
var query = gadgetHelper.createQueryFromPrefs(prefs);
query.send(handleQueryResponse);
}
// Get a query response.
function handleQueryResponse(response) {
// Use the visualization GadgetHelper class to validate the data, and
// for error handling.
if (!gadgetHelper.validateResponse(response)) {
// Default error handling was done, just leave.
return;
};
var data = response.getDataTable();
table.draw(data, options);
};
</script>
]]>
</Content>
</Module>
All gadgets use the basic gadget wrapper, customized for your visualization with preferences. The following snippet shows the standard gadget wrapper, expanded with a few extra user preferences (trimmed from the sample above):
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<UserPref name="_table_query_url" display_name="Data source url" required="true"/>
<UserPref name="_table_query_refresh_interval" display_name="Data refresh interval (minutes)"
default_value="0" datatype="enum" required="false">
<EnumValue value="0" display_value="Do not refresh"/>
<EnumValue value="60" display_value="1"/>
<EnumValue value="300" display_value="5"/>
<EnumValue value="1800" display_value="30"/>
</UserPref>
<Content type="html"><![CDATA[
... visualization goes here...
]]>
</Content>
</Module>
Visualization gadgets support two visualization-specific user preferences values:
_table_query_url to identify a data source URL. Setting
the data source as a configurable parameter enables the gadget to visualize data
from any Google Visualization data source. When your gadgets use configurable
data source URLs, always use the preference _table_query_url. This
will be discussed more later._table_query_refresh_interval to set a standard query refresh
interval. This will be discussed more later.You can add any additional preferences that you need for your gadget.
Just as with non-gadget visualizations, you'll need to load the Google AJAX API.
This is done right after the CDATA declaration. You should also load any non-Google
visualization libraries (those loaded with <script> tags) here.
Your CDATA section also holds the visualization HTML; don't forget to add the container element for your visualization!
...
<Content type="html"><![CDATA[
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<!-- Any non-google visualization script tags can be loaded here as well -->
<div id="tablediv" style="overflow: auto;">Loading...</div>
...
]]></Content>
...
The gadget libraries must be loaded before you can start loading and initializing your visualization. Therefore, you'll need to register a hander to be called when the gadget library has finished loading.
Create a <script> block and call the _IG_RegisterOnloadHandler(handling_function) method
from the Gadget API, passing in the name of your handler function. Your handler
should load the Google Visualization API and then register another callback when
that is finished loading.
The following snippet demonstrates registering a handler (called loadVisualizationAPI) to be called when the gadget libraries have loaded:
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<!-- Put your gadget HTML anywhere here. Don't forget the DOM element that will hold your visualization -->
<div id="tablediv" style="overflow: auto;">Loading...</div>
<script>
_IG_RegisterOnloadHandler(loadVisualizationAPI);
function loadVisualizationAPI() {
google.load('visualization', '1', {'packages': ['table']});
google.setOnLoadCallback(sendQuery);
}
...
Once the gadget libraries have been loaded, the rest of the procedure is similar to loading and running a non-visualization gadget:
<script> tags
elsewhere in the CDATA section to load the visualization.The following snippet demonstrates loading a Google table visualization, and specifying a callback function, named sendQuery, when it finishes.
_IG_RegisterOnloadHandler(loadVisualizationAPI);
/**
* Load the Google Visualization API
*/
function loadVisualizationAPI() {
google.load('visualization', '1', {'packages': ['table']});
google.setOnLoadCallback(sendQuery);
}
function sendQuery{
...
}
Once the Google Visualization API and any visualization packages have been loaded, you can instantiate and draw your visualization in the standard manner as described in the Creating Visualizations page.
However, gadget visualizations are responsible for populating their own data, rather than relying on code in the host page to do it. This is covered in the next section.
<!-- Element to hold the visualization -->
<div id="tablediv" style="overflow: auto;">Loading...</div>
<script>
var table = null;
_IG_RegisterOnloadHandler(loadVisualizationAPI);
function loadVisualizationAPI() {
google.load('visualization', '1', {'packages': ['table']});
google.setOnLoadCallback(sendQuery);
}
function sendQuery() {
// Get a handle to the host element and instantiate your visualization.
// _gel() is identical to getElementById(). Use either.
var tableDiv = _gel('tablediv');
table = new google.visualization.Table(tableDiv);
gadgetHelper = new google.visualization.GadgetHelper();
var query = gadgetHelper.createQueryFromPrefs(prefs);
query.send(handleQueryResponse);
}
function handleQueryResponse(response) {
// Use the visualization GadgetHelper class to validate the data, and
// for error handling.
if (!gadgetHelper.validateResponse(response)) {
// Default error handling was done, just leave.
return;
};
var data = response.getDataTable();
// Take the data table from the response, and format it.
var options = {showRowNumber: true};
table.draw(data, options);
};
</script>
Your gadget visualization is responsible for populating its own data, rather
than relying on the host page to do so (as with non-gadget visualizations). You
can populate your visualization's DataTable in JavaScript as discussed in the non-gadget
visualization page,
or query a data source as described in Data Queries.
Querying in gadget visualizations is identical to querying in a non-gadget visualization; however, the Visualization API exposes a few useful helper methods:
Here are some details on both of these helper methods:
Retrieving your data source URL
This code creates an instance of google.visualization.Query by
using the google.visualization.GadgetHelper.createQueryFromPrefs() method.
The query is automatically populated with the _table_query_url preference
value. Once created, send the query by calling the send()
method, which takes the name of your response listener, as shown here:
function sendQuery() {
// Create and send the query.
var prefs = new _IG_Prefs(); // User preferences
table = new google.visualization.Table(_gel('tablediv'));
gadgetHelper = new google.visualization.GadgetHelper();
var query = gadgetHelper.createQueryFromPrefs(prefs);
query.send(handleQueryResponse); // Send the query with a callback function
}
Checking for query success
Your query response will be called with a google.visualization.QueryResponse object
that describes success or failure, plus a DataTable object
populated by the source, if successful. Check whether the request was successful
by calling the google.visualization.GadgetHelper.validateResponse() method,
as shown here::
function handleQueryResponse(response)
gadgetHelper = new google.visualization.GadgetHelper();
// Default error message handling
if (!gadgetHelper.validateResponse(response))
return;
var data = response.getDataTable();
table.draw(data, {showRowNumber: true});
}
After receiving a successful response, your code should draw the visualization; the preceding code generates an HTML table with all the data returned by the query.
You can set your gadget to periodically reload the data from its data source,
by setting the refresh interval (in seconds) as the preference variable _table_query_refresh_interval.
For example, to let the user configure the refresh interval from a predefined
set of options, add the following to your gadget header:
<UserPref name="_table_query_refresh_interval" display_name="Data refresh interval (minutes)" default_value="0" datatype="enum" required="false"> <EnumValue value="0" display_value="None"/> <EnumValue value="60" display_value="1"/> <EnumValue value="300" display_value="5"/> <EnumValue value="1800" display_value="30"/> </UserPref>
Refreshes will be handled for you by the Google Visualization API code.
You can use a Google spreadsheet as a data source. Create a publicly accessible spreadsheet, add data, and then get the data source URL by following these steps:
DataTable.There are a few ways to test your gadget code:
_table_query_url). To set the query url value, you'll
have to post the gadget using the tool, or else add a default_value property
in your <UserPref name="_table_query_url"> tag.http://www.google.com/ig/adde?moduleurl=some_url.xml where some_url is
the URL of your gadget. Navigate to that link in your browser, and you
will be offered the chance to add it to your iGoogle page.