Reputation: 5410
I have a loop that goes through data and creates several google charts. I have added a selectHandler
that does something when a bar of a chart is clicked. I have no problem getting the bar selected once I have the chart, but I do not know how to tell the handler which chart was clicked.
Here is the code:
inside the drawChart()
which is in a loop:
chart[chart_index] = new google.visualization.BarChart(document.getElementById('chart_div<%= qcount %>'));
chart[chart_index].draw(data, {width: 450, height: 300, title: 'title'});
google.visualization.events.addListener(chart[chart_index], 'select', selectHandler);
chart_index = chart_index+1;
and the selectHandler works like this:
function selectHandler(e) {
var bar_index = chart[HERE_GOES_THE_CHART_INDEX].getSelection()[0].row;
}
Thanks
Upvotes: 2
Views: 2497
Reputation: 1
Function binding to the rescue.
google.visualization.events.addListener(chart[chart_index], 'select', selectHandler.bind(chart[chart_index]));
Your handler will receive the chart always as the first argument.
If you're targeting older browsers, here's a great binding polyfill by Mozilla crew: MDN Function.prototype.bind()
Upvotes: 0
Reputation: 26340
There's no way to get the specific chart from the event handler, so you have to use another method of passing the chart to the handler. Here's one way you can do it:
function selectHandler(myChart) {
// test to see if anything was selected before you get the index
// otherwise you will get errors when the selection contains 0 elements
var selection = myChart.getSelection();
if (selection.length) {
var bar_index = selection[0].row;
// do something with bar_index
// you should also test bar_index, as the user could have clicked a legend item, which would give a null value for row
}
}
chart[chart_index] = new google.visualization.BarChart(document.getElementById('chart_div<%= qcount %>'));
// generally speaking, you should add event handlers before drawing the chart
google.visualization.events.addListener(chart[chart_index], 'select', (function (x) {
return function () {
selectHandler(chart[x]);
}
})(chart_index));
chart[chart_index].draw(data, {width: 450, height: 300, title: 'title'});
chart_index = chart_index+1;
This closure passes chart_index
to the inside of the closure, and assigns it to x
:
(function (x) {
return function () {
selectHandler(chart[x]);
}
})(chart_index)
so the value of x
is locked inside the closure, even when you increment chart_index later. The closure returns a function which becomes the event handler. This function calls selectHandler
, passing in chart[x]
when someone clicks on a chart element. If you are iterating over this in a loop, the value of x
will be unique inside each closure, giving you the ability to reference specific charts in your selectHandler
function.
Upvotes: 4
Reputation: 5442
After reading google visualization event handling...
SELECT Event:
The select event does not pass any properties or objects to the handler (your function handler should not expect any parameters to be passed to it).
So although you can use getSelection(), you need another function to determine which chart is has been acted upon. Enters another event handler:
// google.visualization.table exposes a 'page' event.
google.visualization.events.addListener(table, 'page', myPageEventHandler);
...
function myPageEventHandler(e) {
alert('The user is navigating to page ' + e['page']);
}
You need an event handler that has event object passed in param so you can determine which chart is being evented. Once you have the current chart, you can use getSelection() to see the current selection in that chart.
Upvotes: 0