Google Charts

Creating and Using Chart Gadgets

This document describes how to create a chart gadget. Gadgets are small, self-contained applications that can be added to certain web pages (for example, iGoogle and Google Spreadsheets). 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.

Contents

Audience

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 Charts page.

Creating a Chart Gadget

Chart gadgets are coded largely the same way as non-gadget charts, with just a few differences:

  • The code is wrapped by standard gadget XML.
  • Chart gadgets cannot fire events catchable by script on the page (although you still can respond to user events with the standard JavaScript event model). This means that your page code cannot call google.events.addListener() to listen for gadgetized chart events.
  • Chart gadgets can access user preferences, the same as other gadgets. Chart gadgets support a few chart-specific preferences, described later.
  • Chart gadgets are responsible for populating their own DataTable, either directly in code, or by making a query. (Non-gadget charts usually depend on host page code to populate the data.)

Here are the basic steps for creating a chart gadget:

  1. Start with gadget skeleton code. All gadgets use a standard XML wrapper, which can be modified for the user preferences supported by your gadget.
  2. Load the Google AJAX API. Load this API using a <script> include tag, the same as in non-gadgetized charts.
  3. Register a gadget library onLoad handler. You must wait for the gadget libraries to be loaded before you can start loading the Google Visualization API code and initializing your chart.
  4. When the gadget libraries are loaded, load the Google Visualization API. If you are using a chart package created by Google, you will load the Visualization API and the package in the same call; otherwise, add any <script> tags to load your charts right after the AJAX API tag.
  5. When the Google Visualization API is loaded, initialize and run your gadget. This means instantiating and drawing your gadget as covered in the Creating Charts page. However, you will have to populate your own data, as described next.
  6. Populate your data. In non-gadget charts, the host page is responsible for populating the data; in gadget charts, the designer is responsible for populating the data.

Here is code for a chart 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="https://www.google.com/jsapi" type="text/javascript"></script>

  <!-- Put your gadget HTML anywhere here. Don't forget the DOM element that will hold your chart -->
  <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 chart.
      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 chart 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>

Start with a Gadget Skeleton

All gadgets use the basic gadget wrapper, customized for your chart 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[

     ... chart goes here...

    ]]>
 </Content>
</Module>

Chart gadgets support two chart-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 Chart Tools Datasource. 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.

Load the Google AJAX API

Just as with non-gadget charts, you'll need to load the Google AJAX API. This is done right after the CDATA declaration. You should also load any non-Google chart libraries (those loaded with <script> tags) here.

Your CDATA section also holds the chart HTML; don't forget to add the container element for your chart!

...
<Content type="html"><![CDATA[
  <script src="https://www.google.com/jsapi" type="text/javascript"></script>
  <!-- Any non-google chart script tags can be loaded here as well -->

  <div id="tablediv" style="overflow: auto;">Loading...</div>
...
]]></Content>
...

Register a Gadget API onLoad Handler

The gadget libraries must be loaded before you can start loading and initializing your chart. 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="https://www.google.com/jsapi" type="text/javascript"></script>

<!-- Put your gadget HTML anywhere here. Don't forget the DOM element that will hold your chart -->
<div id="tablediv" style="overflow: auto;">Loading...</div>

<script>
  _IG_RegisterOnloadHandler(loadVisualizationAPI);

function loadVisualizationAPI() {
  google.load('visualization', '1', {'packages': ['table']});
  google.setOnLoadCallback(sendQuery);
}
...

Load the Google Visualization API and the Chart Libraries

Once the gadget libraries have been loaded, the rest of the procedure is similar to loading and running a non-chart gadget:

  1. Load the Google Visualization API.
  2. Load your chart library(ies). If the gadget created by Google, this can be done in the same method that loads the Visualization API. If it is a third-party chart, use <script> tags elsewhere in the CDATA section to load the chart.
  3. Register a handler to be called when the Visualization API has been loaded.

The following snippet demonstrates loading a Google table chart, 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{
...
}    

Initialize and Run Your Gadget

Once the Google Visualization API and any chart packages have been loaded, you can instantiate and draw your chart in the standard manner as described in the Creating Charts page.

However, gadget charts 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 chart -->
<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 chart.
    // _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 chart 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>

Populating Your Data

Your gadget chart is responsible for populating its own data, rather than relying on the host page to do so (as with non-gadget charts). You can populate your chart's DataTable in JavaScript or query a Chart Tools Datasource as described in Data Queries.

Querying in gadget charts is identical to querying in a non-gadget chart; 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 chart; the preceding code generates an HTML table with all the data returned by the query.

Automatic Query Refresh

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.

Getting a Google Chart Tools Datasource

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:

  1. In your Google Spreadsheet, select a range of cells as your source. Select row and column heads to specify row and column labels for your DataTable.
  2. Select 'Insert' and then 'Gadget' from the menu.
  3. Open the gadget's menu by clicking on the top-right selector.
  4. Select menu option 'Get data source URL'.

Accessing a Google Spreadsheet with a Gadget

A chart does not monitor Google Spreadsheets for changes unless specifically configured. Configuration for this feature is handled differently, depending on whether the gadget is embedded in Google Spreadsheets, or is used elsewhere. Because you don't know where a user might install your gadget, you should code for both possibilities, as described here:

Important: Gadgets with a content type of "url" (<Content type="url">) cannot make real-time data updates. To enable real-time Google Spreadsheet updates, the content type must be "html" (<Content type="html">).

  1. Add the idi and locked-domain feature requirements to your gadget configuration, as shown here:
    <ModulePrefs title="Simple Table Gadget">
      <Require feature="idi"/>
      <Require feature="locked-domain"/>
    </ModulePrefs>
          
    This is for gadgets embedded in a Google Spreadsheet. Setting this value will cause the Spreadsheet to push updates to the chart when data changes. Gadgets outside a Spreadsheet container will ignore this code.
  2. Call Query.setRefreshInterval() with a value indicating how often it should requery the Google Spreadsheet. This is for all non-Google Spreadsheet-embedded charts. If a gadget is outside of the Google Spreadsheet, it cannot get notifications when data changes, but instead must periodically query the Spreadsheet for data. (Note that calling setRefreshInterval() on a gadget inside a Spreadsheet causes unnecessary refresh requests— the gadget receives automatic updates automatically—but the extra overhead is low, if you are not calling it once per second.)

Disabling Gadget Caching

By default, gadget XML specs are cached by the gadgets server. When developing gadgets and making frequent changes to the XML spec, it is useful to disable gadget caching, so that changes are immediately reflected every time the page is refreshed.

To disable caching, append the ?nocache suffix to the URL of your gadget XML specification when entering the gadget URL. For example http://www.mydomain.com/mygadget.xml?nocache.

Example Gadget Code

This example demonstrates the complete XML for a custom gadget. The gadget encapsulates the exact chart, options and data source. It wraps the Table chart in a gadget container and hard-codes the data source and several options. Gadgets allow you to hard-code values in your chart, just as you can with non-gadget charts.

<?xml version="1.0" encoding="UTF-8"?>
<Module>
  <ModulePrefs title="Custom gadget"
      author="Google"
      author_email="visualization.api@gmail.com"
      description="Custom gadget"
      thumbnail="http://visapi-gadgets.googlecode.com/svn/trunk/image/thumbnail.png"
      screenshot="http://visapi-gadgets.googlecode.com/svn/trunk/image/screenshot.png">
    <Require feature="idi" />
    <Require feature="locked-domain" />
  </ModulePrefs>
  <Content type="html">
  <![CDATA[
  <script type="text/javascript" src="https://www.google.com/jsapi"></script>
  <script type="text/javascript">
    google.load('visualization', '1', {packages: ['table']});
    google.setOnLoadCallback(init);

    function init() {
      var container = document.getElementById('chart');
      sendQuery();
    }

    function sendQuery() {
      var query = new google.visualization.Query('http://google-visualization.appspot.com/python/dynamic_example');
      query.send(handleQueryResponse);
    }

    function handleQueryResponse(response) {
      // Default error message handling
      var gadgetHelper = new google.visualization.GadgetHelper();
      if (!gadgetHelper.validateResponse(response))
        return;

      var data = response.getDataTable();
      var chart = new google.visualization.Table(document.getElementById('chart'));
      chart.draw(data, null);
    }
  </script>
  <div id="chart">
  <img src="http://visapi-gadgets.googlecode.com/svn/trunk/image/spinner.gif" />
  </div>

  ]]>
 </Content>
</Module>

You can take this xml and use it as a gadget.

Testing Your Gadget

There are a few ways to test your gadget code:

  • You can use the Google Gadget Editor (GGE) to edit and run your gadget XML. This is very fast--you can cut and paste your code and have it rendered immediately. However, note that the live preview does not support all functionality (such as setting preferences, including _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.
  • Add it to a live page that supports gadgets. To do this, save your gadget's XML file on a publicly accessible web server, and then use that URL to embed it in a page that supports gadgets. The gadget used as the example above is stored at http://www.google.com/ig/modules/simple-table.xml. Here is how to embed your gadget in a page:
    • In Google Spreadsheets
      1. Create a Spreadsheet in the format expected by your gadget.
      2. Select the range of cells you want to display in the gadget.
      3. From the toolbar, click 'Insert' and choose 'Gadget'.
      4. Select 'Custom' as the gadget type, enter the URL of your gadget XML specification and click 'Add'.
      5. Optionally, set your gadget preferences, and add your gadget to the Spreadsheet.
    • In iGoogle, there are two ways:
      • Navigate to your iGoogle page and click "Add Stuff". The page will display an "Add feed or gadget" link; enter the URL of your gadget's XML file. OR
      • Create a link 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.

Check out our gallery of gadgetized charts where you can browse gadgetized charts.

Development Tools

The following tool can help you develop your Chart gadget:

  • Google Secure Data Connector - Enables you to use Google chart gadgets on secure data behind a firewall. SDC will protect your data when used by a chart hosted outside your firewall.

 

Authentication required

You need to be signed in with Google+ to do that.

Signing you in...

Google Developers needs your permission to do that.