Update Google Chart in real time with comet - comet

I want to use Google Chart to create a bar chart that gets updated in realtime.
When the user loads the page, I want to show the current results. But as soon as the data in my database changes, I would like to push these changes to the client and update the graph.
Here is a bar chart example from the Google Charts page:
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Year');
data.addColumn('number', 'Sales');
data.addColumn('number', 'Expenses');
data.addRows([
['2004', 1000, 400],
['2005', 1170, 460],
['2006', 660, 1120],
['2007', 1030, 540]
]);
var options = {
title: 'Company Performance',
vAxis: {title: 'Year', titleTextStyle: {color: 'red'}}
};
var chart = new google.visualization.BarChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
I guess I could use an Ajax-Request to pull the data every some seconds and redraw the chart. But maybe there is some inbuild-Method in Google Charts that I am missing. I also read a lot about Comet, but I never implemented that concept.
Has anyone else run into that issue?

Implementing AJAX on a timer is the easiest solution:
// using jQuery for simplicity, but you can implement in other libraries or vanilla javascript if you want
function drawChart() {
var options = {
title: 'Company Performance',
vAxis: {title: 'Year', titleTextStyle: {color: 'red'}}
};
var chart = new google.visualization.BarChart(document.getElementById('chart_div'));
function updateChart () {
$.ajax({
url: 'path/to/data/source/',
data: {/* any parameters you need to pass to the server to get your data back */},
dataType: /* text, json, XML, whatever your server returns */,
success: function (response) {
// use response to create/update DataTable
chart.draw(data, options);
// update the chart again in 2 seconds
setTimeout(updateChart, 2000);
},
error: function (response) {
// handle errors
}
});
}
updateChart();
}
Using a Comet service is a bit more complicated to implement, as it requires setting up something like Socket.Io in javascript and on your server.
Using a Comet service will guarantee the freshest data in the chart at all times, while AJAX is simpler to implement. Comet requires sustaining an active connection to your server while AJAX makes multiple independent requests.

Related

google.script.run to reload google chart in HTML-service page

Just like I would inject new html on a div using google.script.run on a page without reloading, I have spent countless hours trying to do the same but with a google-visualization pie chart, I want to call as many times as needed this google.run.script through a callback.
This is the button with multiple callbacks:
<button onclick="google.script.run.withSuccessHandler(refresh).report(user());">Generate report</button>
OK, this is what user do:
<script>
function user() {
var user = $("input[type=radio]:checked").val();
return user;
}
</script>
Report() simply returns a new array of data for a chart, it will change depending on user.
Finally this is my chart script.
<script>
google.load("visualization", "1", {packages:["corechart"], "callback": refresh});
google.setOnLoadCallback(refresh);
function refresh(e) {
var data = google.visualization.arrayToDataTable(e);
var options = {
title: 'Chart',
is3D: true,
pieSliceText: 'label',
};
var chart = new google.visualization.PieChart(document.getElementById('piechart_3d'));
chart.draw(data, options);
}
</script>
My script works as intended all the way, except the end where I can't get it to update the chart everytime I click the button. Which loads new array data for the chart. I have simplified the code just for this post.
I managed to make it work as intended by parsing the callback value with JSON.parse(e), very hidden for me to figure it out.

How to create google dashboard including piechart and range select filter from a spreadsheet?

Does anyone know how to bind the dashboard to a range from Google Spreadsheet?
In my current code, I am assuming that the dashboard can be bound to a range from Google Spreadsheet like so, but the setDataTable function call is giving me a hard time.
Link to the spreadsheet
Select only two columns from the sheet name and time.
<html>
<head>
<!--Load the AJAX API-->
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
// Load the Visualization API and the controls package.
google.load('visualization', '1.0', {'packages':['controls']});
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(drawDashboard);
// Callback that creates and populates a data table,
// instantiates a dashboard, a range slider and a pie chart,
// passes in the data and draws it.
function drawDashboard() {
// Create our data table.
var data = google.visualization.arrayToDataTable([
['Name', 'Donuts eaten'],
['Michael' , 5],
['Elisa', 7],
['Robert', 3],
['John', 2],
['Jessica', 6],
['Aaron', 1],
['Margareth', 8]
]);
// Create a dashboard.
var dashboard = new google.visualization.Dashboard(
document.getElementById('dashboard_div'));
// Create a range slider, passing some options
var donutRangeSlider = new google.visualization.ControlWrapper({
'controlType': 'NumberRangeFilter',
'containerId': 'filter_div',
'options': {
'filterColumnLabel': 'Donuts eaten'
}
});
// Create a pie chart, passing some options
var pieChart = new google.visualization.ChartWrapper({
'chartType': 'PieChart',
'containerId': 'chart_div',
'options': {`enter code here`
'width': 300,
'height': 300,
'pieSliceText': 'value',
'legend': 'right'
}
});
// Establish dependencies, declaring that 'filter' drives 'pieChart',
// so that the pie chart will only display entries that are let through
// given the chosen slider range.
dashboard.bind(donutRangeSlider, pieChart);
// Draw the dashboard.
dashboard.draw(data);
}
</script>
</head>
<body>
<!--Div that will hold the dashboard-->
<div id="dashboard_div">
<!--Divs that will hold each control and chart-->
<div id="filter_div"></div>
<div id="chart_div"></div>
</div>
</body>
</html>
So, all you want is to transform the Name/Time to a dataTable?
You'll have to transform the array in the google server, return to the HTML page then transform to dataTable, as such:
in code.gs
function getTimes(){
var playTimes = SpreadsheetApp.openById("1csv3OQ0IrVNyNIALcpqoLewccgYEEwErsS-Tp43IZfQ").getSheetByName("players").getRange("B1:E").getValues();
for( i in playTimes ){
playTimes[i] = [ playTimes[i].splice(0, 1)[0], playTimes[i].splice(2, 1)[0] ];
}
return playTimes;
}
in the HTML page -> change the google.setOnLoadCallback(drawDashboard); to google.setOnLoadCallback(loadPlayTimes);, also change function drawDashboard() to function drawDashboard( playTimes ) to accept a parameter:
function loadPlayTimes(){
google.script.run.withSuccessHandler(drawDashboard).getTimes();
}
And create the dataTable as such:
var data = google.visualization.arrayToDataTable( playTimes );

Google Charts Does not render for a scatter plot with multiple colors

I am plotting up data in Google Charts and continue to have trouble rendering my HTML. I could sure use a second pair of eyes to check if there is anything obviously wrong with the code below. The data has three columns, each of which is meant to be plotted a different color.
<html>
<head>
<!--Load the AJAX API-->
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
// Load the Visualization API and the piechart package.
google.load("visualization", "1", {packages:["corechart"]});
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(drawChart);
// Callback that creates and populates a data table,
// instantiates the pie chart, passes in the data and
// draws it.
function drawChart() {
// Create the data table.
var data = google.visualization.arrayToDataTable()({
[['x','Virg','Set','Versi'],
[1.0,null,null,1.0],
[2.0,null,2.0,null],
[3.0,3.0,null,null]]
});
// Set chart options
var options = {
title: "Edgar Anderson's Iris Data Set",
hAxis: {title: 'Petal Length', minValue: 0, maxValue: 7},
vAxis: {title: 'Petal Width', minValue: 0, maxValue: 2.5},
legend: ''
//series:{
// 0: { pointShape: 'circle' },
// 1: {pointShape: 'triangle'},
// 2: { pointShape: 'square'}
// }
};
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.ScatterChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
</head>
<body>
<!--Div that will hold the pie chart-->
<div id="chart_div" style="width: 900px; height: 500px;"></div>
</body>
</html>
Call to arrayToDataTable() is wrong. Instead of
var data = google.visualization.arrayToDataTable()({
[['x','Virg','Set','Versi'],
[1.0,null,null,1.0],
[2.0,null,2.0,null],
[3.0,3.0,null,null]]
});
you have to use
var data = google.visualization.arrayToDataTable([
['x','Virg','Set','Versi'],
[1.0,null,null,1.0],
[2.0,null,2.0,null],
[3.0,3.0,null,null]
]);
Instead of an object of array you have to provide an array of arrays. And unnecessary () deleted.
**Update: ** example at jsbin.

How to get multiple data series into Highcharts

The following code works:
var options1 = {
chart: {
renderTo: 'container1'
},
series: [{}]
};
$.getJSON('tokyo.jsn', function(data){
options1.series[0].data = data;
var chart = new Highcharts.Chart(options1);
});
I want to be able to add a number of data series, so I am trying to take the reference to ‘new Highcharts’ out of the getJSON, but I don't seem to get it right. This following code does not work:
$.getJSON('tokyo.jsn', function(data){
options1.series[0].data = data;
});
var chart = new Highcharts.Chart(options1);
I have also tried tackling it a different way but again the following code does not work:
var chart1 = new Highcharts.Chart({
chart: {
renderTo: 'container1'
},
series: [{}]
});
$.getJSON('tokyo.jsn', function(data){
chart1.series[0].data = data;
});
Can anyone point me in the correct direction. I need to be able to support multiple data series by doing a second getJSON call like the following:
$.getJSON('sydney.jsn', function(data){
options1.series[1].data = data;
});
The JSON code I'm using is as follows:
[ 7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6 ]
Thanks
$.getJSON is an asynchronous request. Once you receive the data, then you can pass it to Highcharts, thus you have to call that code from within the callback function of $.getJSON().
Try this, use a helper function to process your data and draw the chart, see drawChart() below:
var options1 = {
chart: {
renderTo: 'container1'
},
series: []
};
var drawChart = function(data, name) {
// 'series' is an array of objects with keys:
// - 'name' (string)
// - 'data' (array)
var newSeriesData = {
name: name,
data: data
};
// Add the new data to the series array
options1.series.push(newSeriesData);
// If you want to remove old series data, you can do that here too
// Render the chart
var chart = new Highcharts.Chart(options1);
};
$.getJSON('tokyo.jsn', function(data){
drawChart(data, 'Tokyo');
});
$.getJSON('sydney.jsn', function(data){
drawChart(data, 'Sydney');
});
See fiddle: http://jsfiddle.net/amyamy86/pUM7s/
You can use solution used by Highcharts in that example: http://www.highcharts.com/stock/demo/compare
Or first create empty chart, without any series, and then use addSeries() function in each callback, see: http://api.highcharts.com/highcharts#Chart.addSeries()

Loading Google Chart Api using Ajax in html page

I am using Ajax code to load the html page
for example:
$.ajax({
url: 'Context.html',
dataType: 'html',
timeout: 500,
success: function(html) {
$("div#mainbody").html(html);
}
});
The Context.html I am loading it in some other html page say Home.html
But I am generating pie charts using google API in Context.html
and the code for generating pie chart i.e in Context.html is
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Year', 'Count'],
['2005', 70],
['2006', 80],
['2007', 140],
['2008', 220],
['2009', 290],
['2010', 400],
['2011', 500]
]);
var options = {
title: 'Head Count-(Apple Year)',
colors:['#129212']
};
var chart = new google.visualization.ColumnChart(document.getElementById('jsf_headcount_bargraph'));
chart.draw(data, options);
}
</script>
When I am loading Context.html in Home.html page I cannot find the pie chart which is in Context.html after loading it in the Home.html
I tried by giving ALERT(""); in script where I wrote code for pie chart. I was getting alert message,so Ajax is executing javascript but I am not getting pie chart which is same script. So I was stucked with Loading pie chart in Home.html page
If you make Context.html like this
<script>
var j = 20;
alert();
</script>
Then I do get an alert (using $.ajax({success: function() {} }) etc. ).
[ Example ]
function execAjax() {
$.ajax( {
url: 'index2.html',
success: function( html ) {
$("#content").html( html );
checkJSvalue();
},
error: function() {
alert( "Error" );
}
});
}
function checkJSvalue() {
alert( j );
}
Example HTML (index2.html)
<div>
content of index2.html
</div>
<script>
var j = 20;
alert();
</script>
What I have tried to do is to put the code directly in the 'home.html' and I already got errors. You should reverse the order of usage and declaration of the drawchart function anyways.
// Bad
// google.setOnLoadCallback(drawChart);
// function drawChart() {}
// Good
function drawChart() {}
google.setOnLoadCallback(drawChart);
Other than that, I already got this error from the google.jsapi.js (copied locally)
Uncaught Error: Container is not defined format+nl,default,corechart.I.js:841
So something goes wrong there, that is not part of the actual question and it's minified etc. so I won't go there.
Hope this was helpful :)
Everything works just fine if i replace the code
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
To inline
google.load('visualization', '1.0', {'packages':['corechart'], "callback": drawChart});