Dashboard - addListener 'select' - not working

2,550 views
Skip to first unread message

Onno Benschop

unread,
Sep 20, 2011, 9:47:29 PM9/20/11
to Google Visualization API
I am using a visualisation.Dashboard to combine some controls, a map,
a table and a chart.

When the visualisation is drawn, the table reflects the markers
visible on the map as expected.

I want the ability for the user to click on a marker and have the
appropriate row highlighted and vice-versa.

The working example code without using a dashboard looks like this:

google.visualization.events.addListener(table, 'select', function()
{ map.setSelection(table.getSelection()); });
google.visualization.events.addListener(map, 'select', function()
{ table.setSelection(map.getSelection()); });

If I use this in my dashboard, nothing happens.

I've tried adding the table and the map to the global scope, like the
visualisation variable, but that made no difference.

Within my draw handler the code snippet looks like this:

new
google.visualization.Dashboard(document.getElementById('dashboard')).
bind(CyPicker, [TmPicker, NrPicker, TrPicker]).
bind(TmPicker, [map1, table1, chart1]).
draw(data);

google.visualization.events.addListener(table1, 'select', function()
{ map1.setSelection(table1.getSelection()); });
google.visualization.events.addListener(map1, 'select', function()
{ table1.setSelection(map1.getSelection()); });

How do I attach a 'select' listener to a table and a map within a
dashboard?

What am I missing?

Onno Benschop

unread,
Sep 20, 2011, 9:54:08 PM9/20/11
to Google Visualization API
Additional information, an error occurs if I click on the table or the
map:

table1.getSelection is not a function, and similarly,
map1.getSelection is not a function.

Am I missing something obvious?

Riccardo Govoni ☢

unread,
Sep 21, 2011, 4:23:23 AM9/21/11
to google-visua...@googlegroups.com
When using dashboards, you wrap the actual charts (the map, the table) in google.visualization.ChartWrapper instances. Therefore, the code to get the current selection becomes:

map1.getChart().setSelection(table1.getChart().getSelection());

(notice the 'getChart' calls that resolve the chartwrapper into the underlying wrapped chart, which contains the actual selection information).

This should get rid of the errors you are seeing. Let me know if selection propagation still doesn't work after the change and I'll investigate further.

-- R.

--
You received this message because you are subscribed to the Google Groups "Google Visualization API" group.
To post to this group, send email to google-visua...@googlegroups.com.
To unsubscribe from this group, send email to google-visualizati...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-visualization-api?hl=en.


asgallant

unread,
Sep 21, 2011, 8:51:01 AM9/21/11
to google-visua...@googlegroups.com
You may need to add a column parameter when calling setSelection on the map, as the table charts only return the row selected.

Onno Benschop

unread,
Sep 22, 2011, 7:27:07 PM9/22/11
to Google Visualization API
That worked a treat.

The code now looks like this:

new
google.visualization.Dashboard(document.getElementById('dashboard')).
bind(CyPicker, [TmPicker, NrPicker, TrPicker]).
bind(TmPicker, [map1, table1, chart1]).
draw(data);

google.visualization.events.addListener(table1, 'select', function()
{ map1.getChart().setSelection(table1.getChart().getSelection()); });
google.visualization.events.addListener(map1, 'select', function()
{ table1.getChart().setSelection(map1.getChart().getSelection()); });



While investigating I did some experimentation with the 'ready'
listener for the Dashboard, but that didn't work as expected (I got an
error about a being null). I came across the documentation that said
that I should use this method because there was no guarantee that the
listener could be added if the Dashboard wasn't ready. The document is
here:

http://code.google.com/apis/chart/interactive/docs/reference.html#chartwrapperobject

The actual error I got was:
Error: a is undefined
Source File:
http://www.google.com/uds/api/visualization/1.0/cd9282b3113b5d80b6043070ddbc00e4/default,map,controls,table,corechart.I.js
Line: 282

The code that generated that error was:
new
google.visualization.Dashboard(document.getElementById('dashboard')).
bind(CyPicker, [TmPicker, NrPicker, TrPicker]).
bind(TmPicker, [map1, table1, chart1]).
draw(data);

google.visualization.events.addListener(visualization, 'ready',
onReady);

function onReady() {
google.visualization.events.addListener(table1, 'select', function()
{ map1.getChart().setSelection(table1.getChart().getSelection()); });
google.visualization.events.addListener(map1, 'select', function()
{ table1.getChart().setSelection(map1.getChart().getSelection()); });
}

Note that I also tried with a different variable scope, I defined both
map1 and table1 in the global scope, unlike in the working code at the
beginning of this message where the scope of map1 and table1 are
within my handleQueryResponse() handler.

Riccardo Govoni ☢

unread,
Sep 23, 2011, 6:32:12 AM9/23/11
to google-visua...@googlegroups.com
I think you are attaching the 'ready' listener to the wrong object. Your line reads:

google.visualization.events.addListener(visualization, 'ready', onReady);

But I'm not sure what 'visualization' points to. Instead you should attach the listener to the dashboard, and for this you have to assign the google.visualization.Dashboard instance to an object.

var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard'));
dashboard.bind(CyPicker, [TmPicker, NrPicker, TrPicker]).

               bind(TmPicker, [map1, table1, chart1]).
               draw(data);

google.visualization.events.addListener(dashboard, 'ready', onReady);
function onReady(...) {
  ...
}

The above code reads: when the dashboard is ready (aka, it has completed drawing at least once and hence all the controls and charts part of it are guaranteed to exist), then you attach selection handlers.

Does it make sense?
-- R.

Onno Benschop

unread,
Sep 23, 2011, 7:05:28 AM9/23/11
to Google Visualization API
I appreciate your insight and I understand what you're saying. It
turns out that the visualization variable came from the original
sample code and it wasn't being used at all ;) I replaced it with
dashboard, instantiated it instead of creating an anonymous object,
then attached the listener to the dashboard variable. Same error.

I also tried using an anonymous function in the 'ready' addListener,
with no effect.

The documentation I referred to in my previous message tells me that
what I'm doing is wrong and tells me that my code won't be called, but
I'm not seeing that. I wonder if the reason it's working for me is
that I'm not calling an external function, but an anonymous one in my
addListener like this works:

google.visualization.events.addListener(table1, 'select', function()
{ map1.getChart().setSelection(table1.getChart().getSelection()); });


And this doesn't work:

dashboard = new
google.visualization.Dashboard(document.getElementById('dashboard')).
bind(CountryPicker, [TeamPicker, NearPicker, TrailorPicker]).
bind(TeamPicker, [map1, table1]).
draw(data);

google.visualization.events.addListener(dashboard, 'ready', function()
{
google.visualization.events.addListener(table1, 'select', function()
{ map1.getChart().setSelection(table1.getChart().getSelection()); });
google.visualization.events.addListener(map1, 'select', function()
{ table1.getChart().setSelection(map1.getChart().getSelection()); });
});

Riccardo Govoni ☢

unread,
Sep 23, 2011, 7:11:28 AM9/23/11
to google-visua...@googlegroups.com
Try binding the 'ready' event listener before you draw the dashboard:

var dashboard = new google.visualization.Dashboard();
google.visualization.events.addListener(dashboard, 'ready', function() {});
dashboard.bind().bind().bind().draw(data);

(I suspect the 'ready' event coming out of draw() might fire before you attach the handler to it, which may happen in some conditions).

If that doesn't work, I really need to have access to a sample page containing your dashboard to debug it to figure out what's going wrong.

-- R.

Onno Benschop

unread,
Sep 23, 2011, 7:28:41 AM9/23/11
to Google Visualization API
Let me ask the question in another way.

Is there a reason why I have to use the 'ready' mechanism, since the
table1 and map1 objects exist when I'm attaching a listener, they
might just not have been drawn and you cannot click in it until it's
drawn, so the event cannot pre-maturely fire - unless you sit there
actually wildly clicking hoping to kill the code in which case you get
what you deserve :)

Comment?

asgallant

unread,
Sep 23, 2011, 9:30:41 AM9/23/11
to google-visua...@googlegroups.com
Maybe I'm grossly misunderstanding something here, but it seems rather silly to have to attach an event listener for the 'ready' event in order to attach other listeners.  It seems like it would be a circular logic problem: I can't attach listeners unless I'm listening for the 'ready' event, but the 'ready' event is, in itself, an event that I can't attach a listener for unless I am already listening for it.

I've never had any problems attaching event listeners without waiting for the 'ready' event.  Is this something specific to the Dashboards?

T-Roy

unread,
Aug 3, 2013, 1:15:20 PM8/3/13
to google-visua...@googlegroups.com
This was good advice for me, I had to define the ready event before drawing the dashboard. After drawing, trying to add the ready event to a dashboard causes an error.
Reply all
Reply to author
Forward
0 new messages