I am using google visualization table to display some data in a table. And I add a listener to the table to track the user click event.
some codes like this:
// Add our selection handler.
google.visualization.events.addListener(table, 'select', selectHandler);
// The selection handler.
// Loop through all items in the selection and concatenate
// a single message from all of them.
function selectHandler() {
var selection = table.getSelection();
var message = '';
for (var i = 0; i < selection.length; i++) {
var item = selection[i];
if (item.row != null && item.column != null) {
var str = data.getFormattedValue(item.row, item.column);
message += '{row:' + item.row + ',column:' + item.column + '} = ' + str + '\n';
} else if (item.row != null) {
var str = data.getFormattedValue(item.row, 0);
message += '{row:' + item.row + ', column:none}; value (col 0) = ' + str + '\n';
} else if (item.column != null) {
var str = data.getFormattedValue(0, item.column);
message += '{row:none, column:' + item.column + '}; value (row 0) = ' + str + '\n';
}
}
if (message == '') {
message = 'nothing';
}
alert('You selected ' + message);
}
The problem is that, It seems that the listener can only detect which row it is clicked, but have no idea about the column information. Is someone know how to access a particular cell in google visualization table by user click? Or some other js library which are more powerful I can use?
There is no API-based access to the column-index, you must use the DOM.
Add a click-listener to the <table> and when it fires detect the column-index by using the index of the <td> in the childNodes of the parent <tr>
Simple example:
google.setOnLoadCallback(drawTable);
function drawTable() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Name');
data.addColumn('number', 'Salary');
data.addColumn('boolean', 'Full Time Employee');
data.addRows([
['Mike', {
v: 10000,
f: '$10,000'
},
true
],
['Jim', {
v: 8000,
f: '$8,000'
},
false
],
['Alice', {
v: 12500,
f: '$12,500'
},
true
],
['Bob', {
v: 7000,
f: '$7,000'
},
true
]
]);
var table = new google.visualization.Table(document.getElementById('table_div'));
google.visualization.events.addListener(table, 'ready', function() {
document.querySelector('#table_div tbody').addEventListener('click', function(e) {
var cell = e.srcElement || e.target,
column = null;
if (table.getSelection().length && cell !== cell.parentNode.firstChild) {
for (var i = 0; i < cell.parentNode.childNodes.length; ++i) {
if (cell.parentNode.childNodes[i] === cell) {
column = i - 1;
break;
}
}
if (column !== null) {
var msg = ['column-index is ' + column];
var selection = table.getSelection();
//if current row has been selected
if (/\bgoogle-visualization-table-tr-sel\b/.test(cell.parentNode.className)) {
msg.push('row-index is ' + selection[selection.length - 1].row);
msg.push('value of clicked cell is:' + data.getValue(selection[selection.length - 1].row, column));
} else {
msg.push('current row is not selected');
}
alert(msg.join('\n---------\n'))
}
} else {
alert('no row selected');
}
});
});
table.draw(data, {
showRowNumber: true
});
}
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1.1','packages':['table']}]}"></script>
<div id="table_div"></div>
For google.visualization.table you could consider the following approach to access column property (from table cell):
google.load('visualization', '1', {
packages: ['table']
});
google.setOnLoadCallback(drawTable);
function drawTable() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Name');
data.addColumn('number', 'Salary');
data.addColumn('boolean', 'Full Time Employee');
data.addRows([
['Mike', {
v: 10000,
f: '$10,000'
},
true
],
['Jim', {
v: 8000,
f: '$8,000'
},
false
],
['Alice', {
v: 12500,
f: '$12,500'
},
true
],
['Bob', {
v: 7000,
f: '$7,000'
},
true
]
]);
var table = new google.visualization.Table(document.getElementById('table_div'));
google.visualization.events.addListener(table, 'select', function(){
selectHandler(table);
});
table.draw(data, {
showRowNumber: false
});
}
function selectHandler(table) {
var selection = table.getSelection();
if(selection.length === 0)
return;
var cell = event.target; //get selected cell
document.getElementById('output').innerHTML = "Row: " + selection[0].row + " Column: " + cell.cellIndex;
}
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<div id="table_div"></div>
<div id="output"></div>
Related
Hello, I have a timeline made with google charts, what I want to do is update it every so often, for example every 5 seconds, I get the data from a json, I tried it this way but it didn't work for me:
setTimeout(function () {
drawChart();
}, 5000);
Is there any way to do it?
google.load("visualization", "1", {packages: ["timeline"]});
google.setOnLoadCallback(drawChart);
// google.charts.setOnLoadCallback(drawChart);
function drawChart() {
$(".timeline").each(function () {
var obje = {{ devicejson|safe }};
var elem = $(this),
id = elem.attr('id');
var container = document.getElementById(id);
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({type: 'string', id: 'Role'});
dataTable.addColumn({type: 'string', id: 'Name'});
dataTable.addColumn({type: 'date', id: 'Start'});
dataTable.addColumn({type: 'date', id: 'End'});
dataTable.addColumn({type: 'string', id: 'TimeEst'});
dataTable.addColumn({type: 'string', role: 'style'});
for (n = 0; n < obje.length; ++n) {
if (obje[n].device_id == id) {
dataTable.addRows([
['Department', obje[n].digitaloutput_user_description, new Date('"' + obje[n].startdatetime + '"'), new Date('"' + obje[n].enddatetime + '"'), obje[n].lighstate_user_description, obje[n].color],
]);
}
}
for (n = 0; n < obje.length; ++n) {
if (obje[n].device_id == id) {
console.log(obje[n].color)
}
}
var options = {
chartArea: {
height: '90%',
width: '100%',
top: 36,
right: 12,
bottom: 2,
left: 12
},
height: 100,
tooltip: {isHtml: true},
timeline: {
showRowLabels: false,
},
avoidOverlappingGridLines: false,
{#hAxis: {format: 'dd-MMM-yyyy HH:mm:ss'}#}
};
var formatTime = new google.visualization.DateFormat({
pattern: 'yyyy-MM-dd HH:mm:ss a'
});
var view = new google.visualization.DataView(dataTable);
view.setColumns([0, 1, {
role: 'tooltip',
type: 'string',
calc: function (dt, row) {
// build tooltip
var dateBegin = dt.getValue(row, 2);
var dateEnd = dt.getValue(row, 3);
var oneHour = (60 * 1000);
var duration = (dateEnd.getTime() - dateBegin.getTime()) / oneHour;
var tooltip = '<div><div class="ggl-tooltip"><span>';
tooltip += dt.getValue(row, 0) + ':</span> ' + dt.getValue(row, 1) + '</div>';
tooltip += '<div class="ggl-tooltip"><div>' + formatTime.formatValue(dateBegin) + ' - ';
tooltip += formatTime.formatValue(dateEnd) + '</div>';
tooltip += '<div><span>Duration: </span>' + duration.toFixed(0) + ' minutes</div>';
tooltip += '<div><span>Estate: </span>' + dt.getValue(row, 5) + '</div></div>';
return tooltip;
},
p: {html: true}
}, 2, 3]);
google.visualization.events.addListener(chart, 'ready', function () {
var labels = container.getElementsByTagName('text');
Array.prototype.forEach.call(labels, function (label) {
label.setAttribute('font-weight', 'normal');
});
});
chart.draw(view.toDataTable(), options);
})
setTimeout(function () {
drawChart();
}, 5000);
}
for starters, the old version of google charts should no longer be used.
replace the old library...
<script src="https://www.google.com/jsapi"></script>
with the new library...
<script src="https://www.gstatic.com/charts/loader.js"></script>
this will only change the load statement.
which can be found in the following snippet...
next, it appears you are loading the data from the server, here...
var obje = {{ devicejson|safe }};
JavaScript runs on the client.
so no matter how many times drawChart is called,
it will always use the same data received from the server on the first page load.
instead, try this...
create two pages, one that returns the data, and the other that draws the chart.
then you can use AJAX to get the data and draw the chart as many times as needed.
create a new page, and all you really need in the new page is the following line of code.
{{ devicejson|safe }}
aside from any header information, and existing code you're using to get the data to the current page.
but you don't want to assign it to a variable in the new page.
just write the data to the page using the above statement.
then you can use AJAX to get the data and draw the chart.
function getData() {
$.ajax({
url: 'get_data.url', // <-- use url to new page here
dataType: 'JSON'
}).done(function (data) {
drawChart(data);
});
}
then, wait for the chart's ready event, before calling setTimeout.
because we don't know how long it will take to get the data and draw the chart.
so let's wait for the first chart to finish, before trying again.
see following snippet...
google.charts.load('current', {
packages:['timeline']
}).then(getData); // <-- load google charts, then get the data
function getData() {
$.ajax({
url: 'get_data.url', // <-- use url to new page here
dataType: 'JSON'
}).done(function (data) {
drawChart(data); // <-- draw chart with data from new page
});
}
function drawChart(obje) {
$(".timeline").each(function () {
var elem = $(this),
id = elem.attr('id');
var container = document.getElementById(id);
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({type: 'string', id: 'Role'});
dataTable.addColumn({type: 'string', id: 'Name'});
dataTable.addColumn({type: 'date', id: 'Start'});
dataTable.addColumn({type: 'date', id: 'End'});
dataTable.addColumn({type: 'string', id: 'TimeEst'});
dataTable.addColumn({type: 'string', role: 'style'});
for (n = 0; n < obje.length; ++n) {
if (obje[n].device_id == id) {
dataTable.addRows([
['Department', obje[n].digitaloutput_user_description, new Date('"' + obje[n].startdatetime + '"'), new Date('"' + obje[n].enddatetime + '"'), obje[n].lighstate_user_description, obje[n].color],
]);
}
}
for (n = 0; n < obje.length; ++n) {
if (obje[n].device_id == id) {
console.log(obje[n].color)
}
}
var options = {
chartArea: {
height: '90%',
width: '100%',
top: 36,
right: 12,
bottom: 2,
left: 12
},
height: 100,
tooltip: {isHtml: true},
timeline: {
showRowLabels: false,
},
avoidOverlappingGridLines: false,
{#hAxis: {format: 'dd-MMM-yyyy HH:mm:ss'}#}
};
var formatTime = new google.visualization.DateFormat({
pattern: 'yyyy-MM-dd HH:mm:ss a'
});
var view = new google.visualization.DataView(dataTable);
view.setColumns([0, 1, {
role: 'tooltip',
type: 'string',
calc: function (dt, row) {
// build tooltip
var dateBegin = dt.getValue(row, 2);
var dateEnd = dt.getValue(row, 3);
var oneHour = (60 * 1000);
var duration = (dateEnd.getTime() - dateBegin.getTime()) / oneHour;
var tooltip = '<div><div class="ggl-tooltip"><span>';
tooltip += dt.getValue(row, 0) + ':</span> ' + dt.getValue(row, 1) + '</div>';
tooltip += '<div class="ggl-tooltip"><div>' + formatTime.formatValue(dateBegin) + ' - ';
tooltip += formatTime.formatValue(dateEnd) + '</div>';
tooltip += '<div><span>Duration: </span>' + duration.toFixed(0) + ' minutes</div>';
tooltip += '<div><span>Estate: </span>' + dt.getValue(row, 5) + '</div></div>';
return tooltip;
},
p: {html: true}
}, 2, 3]);
google.visualization.events.addListener(chart, 'ready', function () {
var labels = container.getElementsByTagName('text');
Array.prototype.forEach.call(labels, function (label) {
label.setAttribute('font-weight', 'normal');
});
setTimeout(getData, 5000); // <-- get data and draw again in 5 seconds
});
chart.draw(view.toDataTable(), options);
});
}
I'm facing some difficulties while trying to implement 'xAxis clickable' column chart. I'm trying to expose additional Pie charts below my column chart, based on user click on one of the element in xAxis.
The way the first graph is build:
function chartBuilder(data) {
if (data.length === 0) {
return null;
}
var categories = [];
var uniqData = [
{name : 'Fatal', data:[], color:'black', stack: 'fatal'},
{name : 'Critical', data:[], color:'red', stack: 'critical'},
];
_.each(data, function (item) {
categories = categories.concat(item.site);
var fatalValue = {};
fatalValue[item.site] = parseFloat(item.fatal || 0);
uniqData[0].data = uniqData[0].data.concat(fatalValue);
var criticalValue = {};
criticalValue[item.site] = parseFloat(item.critical || 0);
uniqData[1].data = uniqData[1].data.concat(criticalValue);
});
var chartConfig = util.basicConfigChart(categories, uniqData);
chartConfig.yAxis.title = {
text: 'Num Of Events'
};
chartConfig.xAxis.labels = {
formatter: function() {
var ret = this.value,
len = ret.length;
if (len > 10) {
ret = '<strong>' + ret.slice(0,ret.indexOf('_')) + '<br/>' + ret.slice(ret.indexOf('_') + 1, len) + '</strong>';
}
if (len > 25) {
ret = ret.slice(0,25) + '...';
}
return '<strong>' + ret + '</strong>';
},
useHTML: true
};
chartConfig.options.tooltip = {
formatter : function () {
return '<strong>' + this.series.name + '</strong>:' + this.point.y + '<br>Total: ' + this.point.total;
}
};
return chartConfig;
}
So basically, what I need is a way to determine which element in xAxis was clicked, and expose below pie charts with data relevant to this element.
If I understand you correctly, you want to add a click event on the xAxis columns. This can be done using a click event
events: {
click: function (event) {
alert(
'x index: ' + event.point.x + ', \n' +
'series.index: ' + event.point.series.index
);
}
}
This event can be added to a specific series, or to the plotOptions to affect all series.
The code above, will make an alert that shows the relevant indexes.
Working example: https://jsfiddle.net/ewolden/xr17pen6/6/
API on click event: https://api.highcharts.com/highcharts/series.column.events.click
Okay, so here's the thing.
I'm trying to solve this problem since last couple of days, but am not able to get a proper solution! If anybody could help then it would be a huge help!
The problem is-
I recently started working on geomap and I was able to plot the markers on the world map using latitudes and longitudes (as shown here). But after that I'm not able to do the following things-
Group the color of the markers for particular values.
add any event when a marker is clicked (I referred to google site and SO questions)
I have seen many different SO questions but none is helping me get a solution!
Below is the code of my index.html-
<html>
<head>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type='text/javascript' src='http://www.gstatic.com/charts/loader.js'></script>
<script type='text/javascript'>
google.charts.load('current', {'packages': ['geomap']});
google.charts.setOnLoadCallback(drawMap);
function drawMap() {
var data = google.visualization.arrayToDataTable([
['Latitude', 'Longitude','Value','Location'],
[23.0225, 72.5714, 10, 'Ahmedabad'],
[41.8781, -87.6298, 8, 'Chicago'],
[41.3851, 2.1734, 6, 'Barcelona'],
[7.9465, -1.0232, 7, 'Ghana'],
[22.5726, 88.3639, 3, 'Kolkata'],
[16.4314, 103.5059, 1, 'Kalasin Province'],
[25.930414, 50.637772, 2, 'Bahrain'],
[-25.274398, 133.775136, 6, 'Australia'],
[56.130366, -106.346771, 6, 'Canada'],
[-35.675147, -71.542969, 9, 'Chile'],
[51.165691, 10.451526, 10, 'Germany'],
[36.204824, 138.252924, 4, 'Japan']
]);
var options = {
region: 'world',
dataMode: 'markers',
displayMode: 'markers',
colorAxis: { minValue: 1, maxValue: 10, colors: ['red', 'yellow', 'green']}, // I'm bit confused if here maxValue should be 10 or 3
sizeAxis: { minValue: 0, maxValue: 3, minSize: 1, maxSize: 4},
width: 1300,
height: 600,
showZoomOut: true,
enableRegionInteractivity: true,
magnifyingGlass: {enable: true, zoomFactor: 7.5},
zoomOutLabel: 'zoomOut'
};
var container = document.getElementById('map_canvas');
var geomap = new google.visualization.GeoMap(container);
// select event
google.visualization.events.addListener(geomap, 'select', regionClick );
// another event
google.visualization.events.addListener(geomap, 'showzoomout', zoomOut);
function zoomOut (e){
alert('a random alert');
}
geomap.draw(data, options);
};
// I had initially placed below function code inside drawMap(), as told in a SO question, but that too didn't help
function regionClick() {
alert('random alert');
var selection = geomap.getSelection();
var message = '';
for (var i=0; i<selection.length; i++) {
var item = selection[i];
if (item.row != null && item.column != null) {
var str = data.getFormattedValue(item.row, item.column);
message += '{ row:' + item.row + ', column:' + item.column + '} = ' + str + '\n';
}
else if (item.row != null) {
var str = data.getFormattedValue(item.row , 0);
message += '{ row:' + item.row + ', column: null }; value = ' + str + '\n';
}
else if (item.column != null) {
var str = data.getFormattedValue(0 , item.column);
message += '{ row: null, column: ' + item.column + ' }; value = ' + str + '\n';
}
}
if (message == '') {
message = 'nothing';
}
alert('You selected: ' + message);
}
</script>
</head>
<body>
<div id='map_canvas'></div>
</body>
</html>
Please, any kind of help would be highly appreciated!
In order to add an event use a classic listener like this :
marker.addListener('click', function(){ dosomething()});
For the color read this : Google Maps API 3 - Custom marker color for default (dot) marker
Here I have a Google vizualisation datatable. I need to get values from table row.
CODE:http://jsfiddle.net/AVHY8/11/
I currently write:
new google.visualization.events.addListener(table, 'ready', function () {
google.visualization.events.addListener(table.getChart(), 'select', function () {
var selection = table.getChart().getSelection();
// iterate over all selected rows
for (var i = 0; i < selection.length; i++) {
alert(selection[i].row);
}
});
});
So now when I click on row I just get number of row... but how I can get values of that row?
I try with alert data.getValue[(selection[i].row)];
but it doesn't work? Any ideas?
UPDATE:
I also try with this code:
// Add our selection handler.
google.visualization.events.addListener(table, 'select', selectHandler);
// The selection handler.
// Loop through all items in the selection and concatenate
// a single message from all of them.
function selectHandler() {
var selection = table.getSelection();
var message = '';
for (var i = 0; i < selection.length; i++) {
var item = selection[i];
if (item.row != null && item.column != null) {
var str = data.getFormattedValue(item.row, item.column);
message += '{row:' + item.row + ',column:' + item.column + '} = ' + str + '\n';
} else if (item.row != null) {
var str = data.getFormattedValue(item.row, 0);
message += '{row:' + item.row + ', column:none}; value (col 0) = ' + str + '\n';
} else if (item.column != null) {
var str = data.getFormattedValue(0, item.column);
message += '{row:none, column:' + item.column + '}; value (row 0) = ' + str + '\n';
}
}
if (message == '') {
message = 'nothing';
}
alert('You selected ' + message);
}
It doesn't work again.
In your JSFiddle the data array is inside the drawVisualization function, so the event handlers don't have access to it. If you put it in global scope (or in a closure that includes the event handlers) it should work.
Edit:
Aha, the index of the selection refers to the current datatable, which is altered by the ControlWrapper. What you can do is instead of data.getValue(..) do table.getDataTable().getValue(..).
Also note that you don't deselect the previously selected rows, leading to some confusion.
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["table"]});
google.setOnLoadCallback(drawTable);
function drawTable() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Name');
data.addColumn('number', 'Salary');
data.addColumn('number', 'Full Time Employee');
data.addRows([
['Mike', {v: 10000, f: '$10,000'}, 10],
['Jim', {v:8000, f: '$8,000'}, 20],
['Alice', {v: 12500, f: '$12,500'}, 38],
['Bob', {v: 7000, f: '$7,000'}, 20]
]);
var table = new google.visualization.Table(document.getElementById('table_div'));
table.draw(data, { showRowNumber: true });
$("#table_div table tbody tr td").click(function () {
alert($(this).html());
});
}
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<div id="table_div">
</div>
You can use events listners to do that.
google.visualization.events.addListener(table, 'select', function () {
selectHandler(table);
});
function selectHandler(myTable) {
var selectedItem = myTable.getSelection()[0];
if (selectedItem) {
console.log(data.getValue(selectedItem.row, 0))
}
}
The number in front of the "selectedItem.row" is the column value you want to get.
On my Google Visualization web page I want both a bar chart and an area chart but I can get only one or the other to display.
Each chart requires its own data and employs its own google.visualization.Query object against my own Python-based server. My initialize function calls the function to display the first chart, and at the bottom of the query response handler for the first chart, I'm calling the function to display the second chart. (I am doing this to make sure my second data query does not start until after the first chart is done drawing.) Each chart displays correctly when I code to draw only one chart at a time. But when I try to draw both charts, only the first chart ever draws even though I am verifying that both data queries are running and returning valid json responses, at the correct times.
Thanks for any help, BH
Edit 10/27/2013:
This post solved my problem:
Google Charts - "Missing Query for request id: 0"
To anyone implementing a Python data source, parse the reqId parameter like this:
import cgi
form = cgi.FieldStorage()
tqx = form.getvalue("tqx") # tqx comes back like "reqId:1"
req_id = int(tqx[tqx.find("reqId"): ].split(":")[1])
And pass it to the ToJSonResponse call:
response = data_table.ToJSonResponse(req_id=req_id,
columns_order=("vehicle_id", "num_events"))
print "Content-type: text/plain"
print
print response
Here is my updated code, which also uses the "ready" event.
<html>
<head>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(initialize);
var timelineDate1 = "";
var messageCountsDate1 = "";
var timeline_drawn = false;
var message_count_drawn = false;
function initialize()
{
drawTimeline();
}
function drawTimeline()
{
var rows = QueryString.rows || "4";
var date1 = QueryString.date1 || "2013-9-1"; // Date start
timelineDate1 = date1;
var page = parseInt(QueryString.page) || 1;
if (page < 1)
{
page = 1;
}
// Timeline
var url_timeline = "http://localhost/emit_event_timeline.py"
+ "?date1=" + date1 + "&rows=" + rows + "&page=" + page;
var query_timeline = new google.visualization.Query(url_timeline);
query_timeline.setTimeout(14400);
query_timeline.send(handleTimelineQueryResponse);
}
function handleTimelineQueryResponse(response)
{
var stack = parseInt(QueryString.stack) || 1
var timeline_options =
{
title: 'Event Count Timeline, ' + timelineDate1 + ' to Present',
vAxis: {title: 'Date', titleTextStyle: {color: 'red'}},
hAxis: {title: 'Event Count', titleTextStyle: {color: 'blue'}},
isStacked: stack
};
if (response.isError())
{
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var timeline_data_table = response.getDataTable();
var timeline_chart = new google.visualization.AreaChart(document.getElementById('timeline_div'));
google.visualization.events.addListener(timeline_chart, 'ready', timeline_chart_ready);
google.visualization.events.addListener(timeline_chart, 'error', errorHandler);
timeline_chart.draw(timeline_data_table, timeline_options);
}
function timeline_chart_ready()
{
timeline_drawn = true;
if (!message_count_drawn)
{
drawMessagecounts();
}
}
function mc_chart_ready()
{
message_count_drawn = true;
if (!timeline_drawn)
{
drawTimeline();
}
}
function drawMessagecounts()
{
var rows = QueryString.rows || "20";
var date1 = QueryString.date1 || "2013-9-1"; // Date start
messageCountsDate1 = date1
var page = parseInt(QueryString.page) || 1;
if (page < 1)
{
page = 1;
}
// Message counts
var url_message_counts = "http://localhost/emit_all_message_counts.py"
+ "?date1=" + date1 + "&page=" + page + "&rows=" + rows;
var query_message_counts = new google.visualization.Query(url_message_counts)
query_message_counts.setTimeout(14400);
query_message_counts.send(handleMessageCountQueryResponse);
}
function handleMessageCountQueryResponse(response)
{
var stack = parseInt(QueryString.stack) || 1
var mc_options =
{
title: 'Message Counts, ' + messageCountsDate1 + ' to Present',
vAxis: {title: 'Message Source', titleTextStyle: {color: 'red'}},
hAxis: {title: 'Message Count', titleTextStyle: {color: 'blue'}},
isStacked: stack
};
if (response.isError())
{
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var mc_data_table = response.getDataTable();
var mc_chart = new google.visualization.BarChart(document.getElementById('message_count_div'));
google.visualization.events.addListener(mc_chart, 'ready', mc_chart_ready);
google.visualization.events.addListener(mc_chart, 'error', errorHandler);
mc_chart.draw(mc_data_table, mc_options);
}
// Thanks to:
// https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values
var QueryString = function ()
{
// This function is anonymous, is executed immediately and
// the return value is assigned to QueryString!
var query_string = {};
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
// If first entry with this name
if (typeof query_string[pair[0]] === "undefined") {
query_string[pair[0]] = pair[1];
// If second entry with this name
} else if (typeof query_string[pair[0]] === "string") {
var arr = [ query_string[pair[0]], pair[1] ];
query_string[pair[0]] = arr;
// If third or later entry with this name
} else {
query_string[pair[0]].push(pair[1]);
}
}
return query_string;
} ();
function errorHandler(e)
{
// Called when an error occurs during chart processing
alert('Error handler: ' + e.message);
}
</script>
</head>
<body>
<div id="timeline_div" style="width:800px;height:500px;border:1px solid gray;float:left">
</div>
<div id="message_count_div" style="width:800px;height:500px;border:1px solid gray;float:left">
</div>
<div id="control_div" style="width:80px;height:60px;float:left">
</div>
</body>
</html>
The solution was for my Python data source to pass the reqId parameter from the request back on the json reqponse. This post solved my problem:
Google Charts - "Missing Query for request id: 0"