How to use Google Visualization API

From Data-gov Wiki

Jump to: navigation, search
Infobox (How-To) edit with form
  • name: How to use Google Visualization API

  • description: This tutorial is intend to teach anyone who is interesting in learning the process of converting data in CSV form to RDF form, dump rdf data to triple store using the tools provided in data-gov group and finally using Google Visualization to visualize the data.
  • creator(s): Jin Guang Zheng,
  • created: 2010/02/25
  • modified: 2010-4-27


Contents

Audience

This tutorial assumes that the reader is familiar with RDF, Javascript (+HTML), SPARQL, and some XSLT.

Using Google Visualization API

Google Visualization API [1] establishes two conventions:

  1. a common interface to expose data on the web.
  2. a common interface to provide data to visualizations.

Because the Google Visualization API provides a platform that can be used to create, share and reuse visualizations written by the developer community at large, you can create reports and dashboards as well as analyze and display your data through the wealth of available visualization applications. To see the kinds of visualizations that are available, see http://code.google.com/apis/ajax/playground/?type=visualization#data_source_request.

http://code.google.com/apis/charttools/docs/choosing.html describes the distinction between image charts and interactive charts. The bottom links to the list of each:

Data formats that Google Visualization accepts

All Google visualization constructs accept an instance of the Javascript object google.visualization.DataTable, which can be instantiated in one of two ways. (See the full DataTable API Reference)

Direct construction of a DataTable within Javascript

var data = new google.visualization.DataTable();
data.addColumn('string', 'Task');
data.addColumn('number', 'Hours per Day');
data.addRows([
  ['Work',    11],
  ['Eat',      2],
  ['Commute',  2],
  ['Watch TV', 2],
  ['Sleep',   {v:7, f:'7.000'}]
]);

In the case above, a data table is constructed and stored in variable data. For this data table, two columns are added and 5 rows are added. Each row contains two columns as specified.

Construction of a DataTable using a JSON literal object

var data = new google.visualization.DataTable(
     {
       cols: [{id: 'task',  label: 'Task',          type: 'string'},
              {id: 'hours', label: 'Hours per Day', type: 'number'}],
       rows: [{c:[{v: 'Work'},     {v: 11}]},
              {c:[{v: 'Eat'},      {v: 2}]},
              {c:[{v: 'Commute'},  {v: 2}]},
              {c:[{v: 'Watch TV'}, {v:2}]},
              {c:[{v: 'Sleep'},    {v:7, f:'7.000'}]}
             ]
     },
   0.6
)

In the case above, a data table in constructed with JSON of a certain structure and using specific attributes. In this JSON format, cols corresponds to addColumns in case 1, and rows corresponds to addRows in case 1. The structure of this JSON format is the convention that Google API data sources are expected to return. So, a google.visualization.DataTable can be created using the results of an AJAX response.

How to present your data on Google visualization

First, create a <div> within your HTML. The visualization construct will draw into this region:

<div id="my_Visualization_DIV" style="height: 400px; width: 400px;"></div>

Then, load the Google Visualization API in your Javascript:

google.load('visualization', '1', {packages: ['geomap']});
google.setOnLoadCallback(googleVisualizationPackagesLoaded);
function googleVisualizationPackagesLoaded() {
   // This function is called when the Google Visualization API has been successfully loaded.
   // You can do the next two steps in here.
}

Next, populate a google.visualization.DataTable, as described in the previous section.


Finally, instantiate the visual construct, providing it the data to visualize and the div element you created in your HTML:

var visualization = new google.visualization.GeoMap(document.getElementById('my_Visualization_DIV'));
visualization.draw(data);

Hook up Google Visualization with RDF data

The previous section described how to create a visualization using Google's Visualization API. This pattern works for any compliant data source and visualization construct. So, it can be applied to retrieve and visualize RDF data. As long as the URL you retrieve returns Google Visualization JSON, you can create a DataTable and give it to the visual construct to draw().

SPARQL endpoints return SPARQL XML Bindings, which can be converted into the Google Visualization JSON using an xsl like sparqlxml2googlejson.xsl. Tetherless World Constellation set up SparqlProxy, which performs these steps for a client with a single HTTP request. If you provide the URL of a sparql endpoint that you want to query (using service_uri), a query (using query or query-uri), and a specification for return format as Google Visualization JSON (using output=gvds), SparqlProxy will return the SPARQL bindings in the Google Visualization JSON format (shown in use case 2 above).

The request to SparqlProxy can be made using any AJAX method, such as JQuery's .getJSON() function. Google's google.visualization.Query object can also be used.

Construct SPARQL query

Constructing a query is fairly easy: write the sparql query and make sure it can be accessed through a url. Construct the query to SparqlProxy by concatenating the SPARQL service endpoint url and the sparql query url, and pass the query url to the visualization's query function.

For example:

http://data-gov.tw.rpi.edu/ws/sparqlproxy.php?query-uri=http://data-gov.tw.rpi.edu/sparql/quakemap.sparql&output=gvds

var query = new google.visualization.Query($url)

For Data-gov project, you would like to set service_uri to http://data-gov.tw.rpi.edu:8080/joseki/sparql/tdb-datagov?

Convert SPARQL query result to Google Visualization Input

In the above case, SparqlProxy processed the SPARQL query http://data-gov.tw.rpi.edu/sparql/quakemap.sparql on the SPARQL endpoint http://data-gov.tw.rpi.edu:8080/joseki/sparql/tdb-datagov, got the SPARQL XML Bindings, applied sparqlxml2googlejson.xsl, and returned the results as Google Visualization JSON.

The last line in above example is how you construct the query.

Once the query is constructed, you can send the query to get result by

query.send(handleQueryResponse);

Where handleQueryResponse is a function defined how would you like to handle the result.

Then in the function handleQueryResponse, you can get the data table by calling this function (Note: a 'response' parameter is needed for defining this function):

var data = response.getDataTable();

In here, response is parameter for function "handleQueryResponse".

function handleQueryResponse(response) {
...
}

Complete Code Example

GeoMap of Earthquakes

Here is complete code of a Google Visualization GeoMap using the SPARQL query discussed above: (Note: In order to use Google Map, you need to get a Google Map Key.)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head> 
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/> 

    <title>Google Visualization</title> 

    <script type="text/javascript" src="http://www.google.com/jsapi"></script> 

    <script type="text/javascript"> 
       google.load('visualization', '1', {packages: ['geomap']});
 
       function drawVisualization() {
          // To see the data that this visualization uses, browse to
          // http://data-gov.tw.rpi.edu/raw/33/data-33.rdf 
          var query = new google.visualization.Query('http://data-gov.tw.rpi.edu/ws/sparqlproxy.php?'+
                                                     'query-uri=http%3A%2F%2Fdata-gov.tw.rpi.edu%2Fsparql%2Fquakemap.sparql'+
                                                     '&output=gvds');
          // Send the query with a callback function.
          query.send(handleQueryResponse);
       }
    
       function handleQueryResponse(response) {
          if (response.isError()) {
             alert('Error in query: ' + 
                   response.getMessage() + ' ' + 
                   response.getDetailedMessage());
             return;
          }
          var data = response.getDataTable();
 
          var options = {'dataMode': 'markers'};
          visualization = new google.visualization.GeoMap(document.getElementById('my_visualization_DIV'));
          visualization.draw(data, options);
       }
       google.setOnLoadCallback(drawVisualization);

    </script> 
  </head>

  <body style="font-family: Arial;border: 0 none;">
    <div id="my_visualization_DIV" style="height: 400px; width: 400px;"></div>
  </body>

</html>

Timeline

Here is an timeline visualization using hard-coded JSON format as input:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
  <meta http-equiv="content-type" content="text/html; charset=utf-8" /> 

  <title>Google Visualization API Sample</title> 

  <script type="text/javascript" src="http://www.google.com/jsapi"></script> 

  <script type="text/javascript"> 
    google.load('visualization', '1', {packages: ['annotatedtimeline']});
    google.setOnLoadCallback(googleVisualizationAPILoaded);
    function googleVisualizationAPILoaded() {
      var JSONObject = {
         cols:[{id:'date',label:'date',type:'date'},
               {id:'ozone',label:'Ozone_content_value:',type:'number'}],
         rows:[{c:[{v:new Date('2009/03/11')},{v:52}]},
               {c:[{v:new Date('2009/03/12')},{v:52}]},
               {c:[{v:new Date('2009/04/11')},{v:45}]},
               {c:[{v:new Date('2009/04/18')},{v:51}]},{c:[{v:new Date('2009/04/04')},{v:51}]},{c:[{v:new Date('2009/05/12')},{v:56}]},{c:[{v:new Date('2009/04/05')},{v:57}]},{c:[{v:new Date('2009/04/06')},{v:56}]},{c:[{v:new Date('2009/04/20')},{v:51}]},{c:[{v:new Date('2009/03/19')},{v:53}]},{c:[{v:new Date('2009/05/16')},{v:57}]},{c:[{v:new Date('2009/03/15')},{v:53}]},{c:[{v:new Date('2009/03/24')},{v:52}]},{c:[{v:new Date('2009/03/07')},{v:55}]},{c:[{v:new Date('2009/03/05')},{v:56}]},{c:[{v:new Date('2009/03/03')},{v:47}]},{c:[{v:new Date('2009/04/19')},{v:53}]},{c:[{v:new Date('2009/04/01')},{v:62}]},{c:[{v:new Date('2009/03/13')},{v:53}]},{c:[{v:new Date('2009/03/27')},{v:60}]},{c:[{v:new Date('2009/03/20')},{v:48}]},{c:[{v:new Date('2009/05/07')},{v:50}]},{c:[{v:new Date('2009/04/27')},{v:60}]},{c:[{v:new Date('2009/03/22')},{v:55}]},{c:[{v:new Date('2009/05/17')},{v:56}]},{c:[{v:new Date('2009/04/02')},{v:51}]},{c:[{v:new Date('2009/03/10')},{v:56}]},{c:[{v:new Date('2009/03/30')},{v:63}]},{c:[{v:new Date('2009/03/31')},{v:54}]},{c:[{v:new Date('2009/04/12')},{v:52}]},{c:[{v:new Date('2009/03/16')},{v:52}]},{c:[{v:new Date('2009/05/06')},{v:54}]},{c:[{v:new Date('2009/04/14')},{v:49}]},{c:[{v:new Date('2009/05/09')},{v:58}]},{c:[{v:new Date('2009/04/08')},{v:61}]},{c:[{v:new Date('2009/03/04')},{v:56}]},{c:[{v:new Date('2009/05/02')},{v:33}]},{c:[{v:new Date('2009/03/21')},{v:57}]},{c:[{v:new Date('2009/04/21')},{v:54}]},{c:[{v:new Date('2009/04/10')},{v:48}]},{c:[{v:new Date('2009/03/26')},{v:45}]},{c:[{v:new Date('2009/04/22')},{v:57}]},{c:[{v:new Date('2009/05/14')},{v:56}]},{c:[{v:new Date('2009/03/28')},{v:56}]},{c:[{v:new Date('2009/04/09')},{v:60}]},{c:[{v:new Date('2009/03/18')},{v:50}]},{c:[{v:new Date('2009/05/19')},{v:56}]},{c:[{v:new Date('2009/05/08')},{v:56}]},{c:[{v:new Date('2009/03/06')},{v:57}]},{c:[{v:new Date('2009/04/13')},{v:51}]},{c:[{v:new Date('2009/04/15')},{v:53}]},{c:[{v:new Date('2009/03/17')},{v:49}]},{c:[{v:new Date('2009/05/15')},{v:54}]},{c:[{v:new Date('2009/03/23')},{v:55}]},{c:[{v:new Date('2009/03/01')},{v:52}]},{c:[{v:new Date('2009/05/11')},{v:56}]},{c:[{v:new Date('2009/05/05')},{v:51}]},{c:[{v:new Date('2009/04/17')},{v:41}]},{c:[{v:new Date('2009/05/04')},{v:63}]},{c:[{v:new Date('2009/03/09')},{v:56}]},{c:[{v:new Date('2009/04/07')},{v:53}]},{c:[{v:new Date('2009/04/30')},{v:48}]},{c:[{v:new Date('2009/03/14')},{v:52}]},{c:[{v:new Date('2009/05/10')},{v:42}]},{c:[{v:new Date('2009/04/16')},{v:37}]},{c:[{v:new Date('2009/03/02')},{v:47}]},{c:[{v:new Date('2009/05/03')},{v:56}]},{c:[{v:new Date('2009/04/23')},{v:60}]},{c:[{v:new Date('2009/05/01')},{v:39}]},{c:[{v:new Date('2009/03/25')},{v:51}]}
              ]};
    
      var data = new google.visualization.DataTable(JSONObject, 0.5);
    
      var annotatedtimeline = new google.visualization.AnnotatedTimeLine(document.getElementById('visualization'));
      annotatedtimeline.draw(data, {'displayAnnotations': true});
    }
  </script> 
</head> 

<body style="font-family: Arial;border: 0 none;"> 
   <span style="font-weight: bold;">Annotated Time line for Ozone content at site ROM406</span> 
   <div id="visualization" style="width: 800px; height: 400px;"></div> 
</body> 

</html>

Here is a multiple chart visualization example:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
  <head> 
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/> 
    <title> 
US Government Agencies' Dataset Contribution   
	</title> 
    
    <script type="text/javascript" src="http://www.google.com/jsapi"></script> 
    <script type="text/javascript"> 
		google.load('visualization', '1', {packages: ['table','barchart','columnchart','linechart','piechart']});
    </script> 
 
 
    <script type="text/javascript"> 
    var visualization;
 
    function drawVisualization() {
      var query = new google.visualization.Query(
          'http://data-gov.tw.rpi.edu/ws/sparqlproxy.php?query-uri=http%3A%2F%2Fdata-gov.tw.rpi.edu%2Fsparql%2Fselect_count_agency_from.sparql&output=gvds');
      
     
      // Send the query with a callback function.
      query.send(handleQueryResponse);
    }
    
    function handleQueryResponse(response) {
      if (response.isError()) {
        alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
        return;
      }
    
      var data = response.getDataTable();
      visualization = new google.visualization.Table(document.getElementById('visualization_Table'));
      visualization.draw(data, {height:500, 'allowHtml': true});
      visualization = new google.visualization.BarChart(document.getElementById('visualization_BarChart'));
      visualization.draw(data, {height:500});
      visualization = new google.visualization.ColumnChart(document.getElementById('visualization_ColumnChart'));
      visualization.draw(data, {height:500});
      visualization = new google.visualization.LineChart(document.getElementById('visualization_LineChart'));
      visualization.draw(data, {height:500});
      visualization = new google.visualization.PieChart(document.getElementById('visualization_PieChart'));
      visualization.draw(data, {height:500, pieMinimalAngle: 1,is3D: true});
      
	}
    google.setOnLoadCallback(drawVisualization);
    </script> 
 
<style type="text/css"> 
div.example {border: #603 dotted; padding: 0.6em; margin: 1em 2em}
 
/* First example */
div.items p:not(:target) {display: none}
div.items p:target {display: block}
p.menu {margin: 0; padding: 0.4em; background: silver; color: black}
p.menu a {color: black; border: thin outset silver; padding: 0.1em 0.3em}
div.items p {height: 6em; overflow: auto; text-align: center; margin: 0}
#item1 {color: red}
#item2 {color: green}
#item3 {color: blue}
 
/* Tabbed example */
div.tabs {
  min-height: 7em;		/* No height: can grow if :target doesn't work */
  position: relative;		/* Establish a containing block */
  line-height: 1;		/* Easier to calculate with */
  z-index: 0}			/* So that we can put other things behind */
div.tabs > div {
  display: inline}		/* We want the buttons all on one line */
div.tabs > div > a {
  color: black;			/* Looks more like a button than a link */
  background: #CCC;		/* Active tabs are light gray */
  padding: 0.2em;		/* Some breathing space */
  border: 0.1em outset #BBB;	/* Make it look like a button */
  border-bottom: 0.1em solid #CCC} /* Visually connect tab and tab body */
div.tabs > div:not(:target) > a {
  border-bottom: none;		/* Make the bottom border disappear */
  background: #999}		/* Inactive tabs are dark gray */
div.tabs > div:target > a,	/* Apply to the targeted item or... */
:target #default2 > a {		/* ... to the default item */
  border-bottom: 0.1em solid #CCC; /* Visually connect tab and tab body */
  background: #CCC}		/* Active tab is light gray */
div.tabs > div > div {
  background: #CCC;		/* Light gray */
  z-index: -2;			/* Behind, because the borders overlap */
  left: 0; top: 1.3em;		/* The top needs some calculation... */
  bottom: 0; right: 0;		/* Other sides flush with containing block */
  overflow: auto;		/* Scroll bar if needed */
  padding: 0.3em;		/* Looks better */
  border: 0.1em outset #BBB}	/* 3D look */
div.tabs > div:not(:target) > div { /* Protect CSS1 & CSS2 browsers */
  position: absolute }		/* All these DIVs overlap */
div.tabs > div:target > div, :target #default2 > div {
  position: absolute;		/* All these DIVs overlap */
  z-index: -1}			/* Raise it above the others */
</style> 
<STYLE TYPE="text/css"> 
<!--
 img { border: 0; }
 
.logoimg{
  height:64px;
  width:64px;
  float:left;
  position:relative;
  margin-right:15px;
  top:-10px;
}
.menuimg{
  height:32px;
  width:32px;
  position:relative;
  top:0px;
  border:0px;
}
.normal {
  font-family:Helvetica,Arial,sans-serif;
  font-size:24px;
  margin:0px 0px 3px 2px;
  padding: 1px;
  display:block;
}
h3 {
  font-family:Arial,Helvetica,sans-serif;
  font-size:16px;
  margin:0px 0px 3px 2px;
  padding: 1px;
  display:block;
}
h2 {
  font-family:Helvetica,Arial,sans-serif;
  font-size:18px;
  margin:0px 0px 3px 2px;
  padding: 1px;
  display:block;
}
h1 {
  font-family:Arial,Helvetica,sans-serif;
  font-size:32px;
  margin:0px 0px 3px 2px;
  padding: 1px;
  display:block;
  color:#333;
}
 
 
--> 
</STYLE> 
 
  
  </head> 
  <body style="font-family: Arial;border: 0 none;"> 
<table width="100%"> 
<tr> 
<td width="70%" valign="bottom"> 
 
<a href='http://data-gov.tw.rpi.edu' alt='Data-gov Wiki'> 
<img src='http://data-gov.tw.rpi.edu/images/logo-data-gov.png' class="logoimg"/></a> 
 
<center> 
<h2>US Government Agencies' Dataset Contribution</h2> 
</center> 
 
</td> 
<td align="right"> 
 
<a class"=info" href="http://data-gov.tw.rpi.edu/demo/static/agency_dataset.php"> 
<img src="http://data-gov.tw.rpi.edu/images/blue_home.png" alt="Go to demo page" class="menuimg"/></a> 
 
   
 
<a class"=info" href="http://data-gov.tw.rpi.edu/wiki/Demo:_Agencies%27_Dataset_Contribution_on_Data.gov"> 
<img src='http://data-gov.tw.rpi.edu/images/blue_info.png' class="menuimg" alt='go to this demo wiki page'/></a> 
 
<!--
   
<a class"=info" href="#description">
<img src='http://data-gov.tw.rpi.edu/images/blue_folder.png' class="menuimg" alt='go to demo description'/></a>
--> 
 
   
<a class"=info" href="mailto:tw-webmaster@tw.rpi.edu"> 
<img src='http://data-gov.tw.rpi.edu/images/blue_mail.png' class="menuimg" alt='Contact us'/> 
</a> 
 
</td> 
</tr> 
</table> 
  
  
  <div class=tabs style="height:550px"> 
  <div id=tab_Table>   <a href="#tab_Table">Table</a> 
<div id="visualization_Table" style="height:520px"></div> 
  </div> 
  <div id=tab_BarChart>   <a href="#tab_BarChart">BarChart</a> 
<div id="visualization_BarChart" style="height:520px"></div> 
  </div> 
  <div id=tab_ColumnChart>   <a href="#tab_ColumnChart">ColumnChart</a> 
<div id="visualization_ColumnChart" style="height:520px"></div> 
  </div> 
  <div id=tab_LineChart>   <a href="#tab_LineChart">LineChart</a> 
<div id="visualization_LineChart" style="height:520px"></div> 
  </div> 
  <div id=tab_PieChart>   <a href="#tab_PieChart">PieChart</a> 
<div id="visualization_PieChart" style="height:520px"></div> 
  </div> 
  </div> 
<hr/> 
<div>This demo was created by <a href='http://www.cs.rpi.edu/~dingl'>Li Ding</a> and Sarah Magidson. It queries the data.gov catalog to get all the agencies that have submitted data to data.gov and then sums them up. The result is a pie chart of agencies according to how many datasets they have submitted to data.gov. This demo is based on the following datasets from <a href='http://data.gov/'>data.gov</a>: <ul><li><a href='http://data-gov.tw.rpi.edu/wiki/Dataset_92'>Dataset 92</a> - Data.gov Catalog</li></ul></div>   
  </body> 
</html> 

More Examples

More examples/code can be found at the interactive demo: http://code.google.com/apis/ajax/playground/?type=visualization#data_source_request

Or at the Google visualization api: http://code.google.com/apis/visualization/documentation/examples.html

TW SPARQL Code Camp: http://tw.rpi.edu/wiki/tw:TW_SPARQL_code_camp

A list of demonstrations by Tetherless World Constellation: Demos

Tools and Resources

1. RDF document: in order to present your data through Google Visulization, a source of RDF document is needed. RDF versions of data.gov datasets are listed at http://data-gov.tw.rpi.edu/wiki/Data.gov_Catalog

2. SPARQL query endpoint: a Sparql query endpoint is needed to process your queries and get the results. Several SPARQL endpoints hosted by Tetherless World Constellation are listed at http://data-gov.tw.rpi.edu/joseki/

3. The page http://code.google.com/apis/visualization/ has documentation on how to visualize data using different visualization packages provide by Google.

Facts about How to use Google Visualization APIRDF feed
Dcterms:created25 February 2010  +
Dcterms:creatorJin Guang Zheng  +
Dcterms:descriptionThis tutorial is intend to teach anyone wh This tutorial is intend to teach anyone who is interesting in learning the process of converting data in CSV form to RDF form, dump rdf data to triple store using the tools provided in data-gov group and finally using Google Visualization to visualize the data. oogle Visualization to visualize the data.
Dcterms:modified2010-4-27
Foaf:nameHow to use Google Visualization API
Skos:altLabelHow to use Google Visualization API  +, how to use google visualization api  +, and HOW TO USE GOOGLE VISUALIZATION API  +
Personal tools
internal pages