views:

79

answers:

3

Hey everyone, so I am working on creating a small class to help me work with the Google visualization API. You can see how it works here...

http://code.google.com/apis/visualization/documentation/gallery/annotatedtimeline.html

Here is google's implementation.

google.load('visualization', '1', {'packages':['annotatedtimeline']});
      google.setOnLoadCallback(drawChart);
      function drawChart() {
        var data = new google.visualization.DataTable();
        data.addColumn('date', 'Date');
        data.addColumn('number', 'Sold Pencils');
        data.addColumn('string', 'title1');
        data.addColumn('string', 'text1');
        data.addColumn('number', 'Sold Pens');
        data.addColumn('string', 'title2');
        data.addColumn('string', 'text2');
        data.addRows([
          [new Date(2008, 1 ,1), 30000, undefined, undefined, 40645, undefined, undefined],
          [new Date(2008, 1 ,2), 14045, undefined, undefined, 20374, undefined, undefined],
          [new Date(2008, 1 ,3), 55022, undefined, undefined, 50766, undefined, undefined],
          [new Date(2008, 1 ,4), 75284, undefined, undefined, 14334, 'Out of Stock','Ran out of stock on pens at 4pm'],
          [new Date(2008, 1 ,5), 41476, 'Bought Pens','Bought 200k pens', 66467, undefined, undefined],
          [new Date(2008, 1 ,6), 33322, undefined, undefined, 39463, undefined, undefined]
        ]);

        var chart = new google.visualization.AnnotatedTimeLine(document.getElementById('chart_div'));
        chart.draw(data, {displayAnnotations: true});

Here is the class I made that I am having issues with. The class makes adding data to the graph a little easier and better for what I am trying to do. Basically, instead of making columns with a bunch of undefined values, the class does it for you, and you don't have to keep track of the location/value of each column.

 function GraphManager(dataTable)
 {
     this.graphData = new Array();
     this.dataTable = dataTable;

     this.titleFinder = new Object(); // used to keep track of the indices

     this.dataTable.addColumn('date', 'Date');

     this.addSet = function(title)
     {

         var setCount = (this.dataTable.getNumberOfColumns() -1) / 3; //used for the column name
         var place = this.dataTable.getNumberOfColumns(); 

         this.titleFinder[title] = place; //the title of the column and its location

         this.dataTable.addColumn('number', title);
         this.dataTable.addColumn('string', 'title' + setCount);
         this.dataTable.addColumn('string', 'text' + setCount); 

     }

     this.addPoint = function(title, date, number)
     {
         //this function finds the location of the category
         //and inserts a column with data at the location


         var place = titleFinder[title]; //get the location

         var column = new Array(dataTable.getNumberOfColumns()); 
         column[0] = date;
         column[place] = number;

         for (var i = 0;i<place; i++)
         {
            column[i] = undefined; 
         }

         for (var i = place + 1; i<dataTable.getNumberOfColumns(); i++)
         {
             column[i] = undefined;
         }

         var next = this.graphData.length;
         this.graphData[next] = column;
         data.addRows(graphData);

     }


 }

And then this code can be used to do the same thing with a fewer amount of code. function printGraph() { var data = new google.visualization.DataTable();

     var gm = new GraphManager(data);
     var title = "testcategory";


     gm.addSet(title);
     gm.addPoint(title, new Date[2010, 5, 10], 100);
     gm.addPoint(title, new Date[2010, 6, 10], 200);


     var chart = new google.visualization.AnnotatedTimeLine(document.getElementById('chart_div'));
     chart.draw(gm.dataTable, {displayAnnotations: true});

}

With this HTML body

<input type="button" onclick="printGraph()" value="Draw Graph">
<div id='chart_div' style='width: 800px; height: 350px;'></div>

The issue: I am getting an "Object expected" error on the line gm.addSet(title). Basically, I am not able to use the class GraphManager. What am I doing wrong here?

A: 

Isn't supposed to be "dataTable" instead of "tableData"?

for (var i = place + 1; i<tableData.count; i++)
{
    column[i] = undefined;
}
R. Hill
Yes, stupid mistake. However, it doesn't help my issue.
imagineblue
A: 

I don't know, as per:

http://code.google.com/apis/visualization/documentation/reference.html#DataTable

count is not an attribute, but I see you referring to it many places in your code:

var column = new Array(dataTable.count)

There is dataTable.getNumberOfColumns() however

R. Hill
Thanks, that's right, I have fixed this but I still have the "object expected" error
imagineblue
A: 

Ok, I figured out the problem. Basically I had left out a bunch of "this" statements, and when I created a new date I used a bracket instead of a parentheses. I also realized that when I added a new set of data, I needed to go through the old data to add the empty columns. Here is the finished code if anyone is interested... It's pretty useful if you are adding data at different dates or if you don't know how many data sets you will have.

 function GraphManager(adataTable)
 {
     this.graphData = new Array();
     this.dataTable = adataTable;

     this.titleFinder = new Object(); // used to keep track of the indices

     this.dataTable.addColumn('date', 'Date');

     this.addSet = function(title)
     {

         var setCount = (this.dataTable.getNumberOfColumns() -1) / 3; //used for the column name
         var pointsCount = this.graphData.length;
         var place = this.dataTable.getNumberOfColumns();

         this.titleFinder[title] = place; //the title of the column and its location

         this.dataTable.addColumn('number', title);
         this.dataTable.addColumn('string', 'title' + setCount);
         this.dataTable.addColumn('string', 'text' + setCount);

         var newCount = this.dataTable.getNumberOfColumns();



         for (var i = 0; i<pointsCount; i++)
         {
             for (var j=place; j<newCount; j++)
             {
                 this.graphData[i][j] = undefined;
             }


         }  

     }

     this.addPoint = function(title, date, number)
     {
         //this function finds the location of the category
         //and inserts a column with data at the location


         var place = this.titleFinder[title]; //get the location

         var column = new Array(this.dataTable.getNumberOfColumns()); 
         column[0] = date;
         column[place] = number;

         for (var i = 1;i<place; i++)
         {
            column[i] = undefined; 
         }

         for (var i = place + 1; i<this.dataTable.getNumberOfColumns(); i++)
         {
             column[i] = undefined;
         }

         var next = this.graphData.length;
         this.graphData[next] = column;
         this.dataTable.addRows(this.graphData);

     }


 }

And its as easy to use as this:

     var data = new google.visualization.DataTable();
     var gm = new GraphManager(data);

     var title = "testcategory";
     var title2 = "cat";

     gm.addSet(title);
     gm.addPoint(title, new Date(2010, 5, 10), 100);
     gm.addPoint(title, new Date(2010, 6, 10), 200);
     gm.addPoint(title, new Date(2010, 2, 10), 300);


     gm.addSet(title2);
     gm.addPoint(title2, new Date(2010, 6, 10), 100);
     gm.addPoint(title2, new Date(2010, 2, 10), 500);

     var chart = newgoogle.visualization.AnnotatedTimeLine(document.getElementById('chart_div'));
     chart.draw(gm.dataTable, {displayAnnotations: true});
imagineblue