ChartWrapper and Table sort event

1,696 views
Skip to first unread message

NA

unread,
Mar 26, 2012, 3:18:09 PM3/26/12
to google-visua...@googlegroups.com
I have a ChartWrapper that creates a table.  I have a sort set to "event" so that I can disable sorting for one of my columns.  The problem is that my sort event is only fired once, trying to sort a second time doesn't fire the event (it doesn't do anything).

For example, I went here:

  http://code.google.com/apis/ajax/playground/?type=visualization#sort_event

and put in the code at the end of this post.

The only way this works is to re-add the event listener from inside the event handler.  Why is that?

Also, is there a reason that I need to explicitly sort the data with the call to sortData.sort() ?  I thought that simply by setting tableWrap's sortColumn and sortAscending values, the table would sort itself.  In fact, when I create a table, this is the behavior I see.

Any ideas?

function drawVisualization() {
  var tableWrap = new google.visualization.ChartWrapper();
      tableWrap.setChartType('Table');
      tableWrap.setContainerId('table');
      tableWrap.setDataTable(sortData);
      tableWrap.setOption('allowHtml',true);
      tableWrap.setOption('sort','event');
      tableWrap.draw();
  
  google.visualization.events.addListener(tableWrap.getChart(), 'sort',
            function(ev) {
              console.log('Fired event');
              var table     = tableWrap.getChart();
              var columnIndex = ev['column'];
              var isAscending = ev['ascending'];
              sortData.sort([{column: columnIndex, desc: !isAscending}]);
              tableWrap.setOption('sortColumn',columnIndex);
              tableWrap.setOption('sortAscending',isAscending);
              tableWrap.draw();
            }                                      
   );
}

asgallant

unread,
Mar 26, 2012, 4:15:39 PM3/26/12
to google-visua...@googlegroups.com
You need to initialize the event listener after the chart exists - most likely, your code is caught trying to initialize the listener before the chart is ready.  Try wrapping the listener is a 'ready' event listener for the wrapper:

function drawVisualization({
    var tableWrap new google.visualization.ChartWrapper();
    tableWrap.setChartType('Table');
    tableWrap.setContainerId('table');
    tableWrap.setDataTable(sortData);
    tableWrap.setOption('allowHtml'true);
    tableWrap.setOption('sort''event');

    var tempListener google.visualization.events.addListener(tableWrap'ready'function ({

        google.visualization.events.addListener(tableWrap.getChart()'sort'function(ev{
            console.log('Fired event');
            var table tableWrap.getChart();
            var columnIndex ev['column'];
            var isAscending ev['ascending'];
            sortData.sort([{
                columncolumnIndex,
                desc!isAscending}]);
            tableWrap.setOption('sortColumn'columnIndex);
            tableWrap.setOption('sortAscending'isAscending);
            tableWrap.draw();
        });
        
        // remove the 'ready' event listener once it's done, so it doesn't keep adding more listeners every time the chart draws.
        google.visualization.events.removeListener(tempListener);
    });
    
    
    tableWrap.draw();

NA

unread,
Mar 26, 2012, 4:20:24 PM3/26/12
to google-visua...@googlegroups.com
What you're saying makes sense, but it didn't work.  I ran it as you posted in the same playground mentioned above, and the table only sorted one time; afterwards, no more sorting.

asgallant

unread,
Mar 27, 2012, 10:36:08 AM3/27/12
to google-visua...@googlegroups.com
Can you post your full code or a link to the page?  I'll take a look.

NA

unread,
Mar 27, 2012, 10:55:30 AM3/27/12
to google-visua...@googlegroups.com
Sure:  http://jsfiddle.net/5HagR/ 

This is the code you had above inserted into the playground, but placed in jsfiddle.

thanks!

asgallant

unread,
Mar 27, 2012, 11:45:24 AM3/27/12
to google-visua...@googlegroups.com
I updated it for jsfiddle compatibility and made some minor tweaks (mainly, you will run into problems if you try to create a DataTable object before the script finishes loading, so I moved the constructor into the drawVisualization function).  The main culprit, however, appears to be the line that removes the 'ready' event listener; comment it out and everything works.  It is conceivable that a new chart object is getting created every time the chart sorts (which would then need it's own 'sort' event listener), though I'm not sure why that would be happening.  See:  http://jsfiddle.net/5HagR/1/ 

NA

unread,
Mar 27, 2012, 1:14:07 PM3/27/12
to google-visua...@googlegroups.com

Thanks for diting the example.

Interesting you mentioned creating the DataTable object before the script finishes.  That's actually how the Google Visualization Playground is written - if you visit http://code.google.com/apis/ajax/playground/?type=visualization#sort_event and click "Edit HTML" you'll see they're creating the DataTable outside of the script loading callback. 

Is that because the DataTable is loaded in the js.api script (included before the code)?  Or is it because in the Playground they load the Google apis ahead of time anyway?  Or are they just getting lucky?

If it's not the first, GVIZ should probably update the example code to something safer.  That could be why I've seen others having problems when they execute library calls before the library loaded; they might be following this model.

Secondly, it does seem like a new chart is created.  Hooking into the wrapper's "ready" event seems like the best way to add events.  The "ready" event is with the Wrapper, which isn't recreated, but the "sort" event is with the chart, which is deleted each time the chart is redrawn.  Makes sense.

thanks,


asgallant

unread,
Mar 27, 2012, 1:28:14 PM3/27/12
to google-visua...@googlegroups.com
I don't know why they did the Playground example like that - it's not a good idea.  Given that DataTables are a subset of the Visualization API, which definitely doesn't get loaded prior to the google.load() call, then they must be counting on users either a) getting lucky or b) having the API precached.  As a general rule of thumb, you shouldn't rely on either being true.
Reply all
Reply to author
Forward
0 new messages