Using Google Visualization DataTables

javaScript: creating google visualization DataTables   get it now

This relates to Data Driven Mapping applications and the javaScript 'howTo' section.

Google Visualization Tables

I have covered Google Visualization in various forms with an 'Excel slant' on this site. Let's take a look at some useful google visualization related functions.

waiting for the document to load

A typical technique for waiting for the whole page to load before calling your javascript is to use the <body "onload=foo()"> type of technique. Since the <body> part of my application is tailorable,  I didn't really want to expose that to random editing, so I used the very useful google.load.  This means it can get underway loading the packages I needed right away, calling back  'mcpherDrawEverything()' when ready to go.

 function mcpherInitialize() {
    google.load('visualization', '1', 
              {packages:['table','imagebarchart']});
    google.setOnLoadCallback(mcpherDrawEverything);
 };


Creating a master data table

The way this works is that I create a google dataTable containing all the item data, and then create google dataView visualizations of that for each tab of each infoWindow. All this is done on initialization, then the selection of infowindow and tab data is simply a case of changing the CSS attributes of each element so they are display: block or display: none. Here is how to create the master table

 mcpherVizMap.prototype.masterTable = function() {
   // create a master google viz table
        gTable = new google.visualization.DataTable();
        for ( key in this.dictionary)  
              gTable.addColumn (this.columnType(key), key);
        var currentCol;
        
        for (var i = 0 ; i < this.cJobject.length ; i++){
          var currentRow = gTable.addRow();
           for ( var key in this.cJobject[i]){
             if ( (currentCol = this.columnIndex (gTable,key)) >= 0)
                gTable.setCell(currentRow,currentCol,
                     this.columnValue(key,this.cJobject[i][key]));
             else 
                alert ("Unknown column name " + key + " at row " +
                      currentRow + " in cJobject data");       
           }
        }
        return (gTable);
  };

Find a column index by its name

Columns in a google DataTable are accessed by their column Index. I wanted to access them by their column header, so I needed a function that would return a column Index, given a column heading

 mcpherVizMap.prototype.columnIndex = function (gTab,label) {
   for (var i=0; i < gTab.getNumberOfColumns() ;i++) {
    if (gTab.getColumnLabel(i) == label) return (i);
   }
   return (-1);
  };

Validating input data

The VizMap Dictionary contains a list of all the data items and their type. Since the dictionary and data might have been generated separately outside Excel, there is a chance that their type would not match, which would cause the google dataTable load to fail, since the incoming jSon data string may be representing the data as a string. Here are a few couple of functions to check that data type is good.  A dictionary will look like this.

"dictionary":{
         "Latitude":"number",
         "Longtitude":"number",
         "SpotID":"number",
         "Title":"string",
         "Content":"string",
         "Code":"string",
         "Country":"string",
         "Venue":"string",
         "State":"string",
         "City":"string",
         "Address":"string",
         "Shows":"number",
         "ID":"number",
         "Average Price":"number",
         "Price":"number",
         "Date":"date",
         "Artist":"string",
         "Artist Photo":"string",
         "Venue Photo":"string"
      },

These are the validating and converting functions.
 mcpherVizMap.prototype.columnType = function(key) {
   return (this.dictionary[key]); 
   };
 
 mcpherVizMap.prototype.columnValue = function(key,value) {
   var x;
   switch (  this.columnType(key)  ){
    case 'number':
        if (!(x=mcpherToNumber(value)))
          alert (key + ' has invalid value ' + value + 
            ' for type'  + this.columnType(key) );
        break;
   
    case 'date':
         if (!(x=mcpherToDate(value)))
           alert (key + ' has invalid value ' + value + 
              ' for type' + this.columnType(key) );
          break;
     
    default:
          x=value;
          break;
    }  
   return (x);
   };

   function mcpherIsNumber(x){
      return (!isNaN(parseFloat(x))); 
   }
   function mcpherToNumber(x) {
      if (mcpherIsNumber(x))
          return (parseFloat(x));
      else
          return (null);
    }
    function mcpherToDate(x) {
       if (mcpherIsDate(x))
          return (new Date(Date.parse(x)));
       else
          return (null);
    }
    function mcpherIsImage(url) {
       return ((/http:\/\/.+?\.jpg|jpeg|png|gif/).test (url) );

    }
    function mcpherSize(o) {
      var s=0;
      for (var key in o) if (o.hasOwnProperty(key))s++;
      return (s);
    }
    function mcpherIsDate(s){
      return (!isNaN(Date.parse(s))); 
    }


Getting dataView aggregation types

Aggregation types for google dataView tables are some named google constants. Since VizMap Measures contain textual description of how to aggregate, I needed a simple function to convert them to their google equivalents.

function mcpherGag(x){
 switch (x) {
  case 'average':
   return (google.visualization.data.avg);
  case 'count':
   return (google.visualization.data.count);
  case 'sum':
   return (google.visualization.data.sum);
  case 'min':
   return (google.visualization.data.min);
  case 'max':
   return (google.visualization.data.max);
  default:
   alert('Unknown google aggregation request ' + x);
   return (null);
 }


Comments