I'm trying to integrate a google visualisation chart into my backbone.js app. Currently I have both the google.load(visualization) and setOnLoadCallback(drawVisualization) calls in the render function of a ChartView class. The google visualisation libraries seem to be loading correctly, however the callback is never executed.
Below is a example that shows the problem, if someone could assist I'd be very grateful!
<!doctype html>
<html>
<head>
<title>App</title>
<meta charset="utf-8">
</head>
<body>
<div id="content"></div>
<script src="lib/jquery-1.7.2.min.js"></script>
<script src="lib/underscore.js"></script>
<script src="lib/backbone.js"></script>
<script src="http://www.google.com/jsapi"></script>
<script>
ChartView = Backbone.View.extend({
render:function () {
$(this.el).html('<p>gviz line chart:</p>' +
'<div id="gviz" style="width:600px; height:300px;"></div>');
google.load('visualization', '1', {packages:'linechart'});
google.setOnLoadCallback(this.drawVisualization);
return this;
},
//This never gets called
drawVisualization:function () {
console.log("In draw visualization");
var data = this.createDataTable('date');
var chart = new google.visualization.LineChart(this.$('#gviz'));
chart.draw(data, null, null);
},
createDataTable:function (dateType) {
console.log("Creating datatable");
var data = new google.visualization.DataTable();
data.addColumn(dateType, 'Date');
data.addColumn('number', 'Column A');
data.addColumn('number', 'Column B');
data.addRows(4);
data.setCell(0, 0, new Date("2009/07/01"));
data.setCell(0, 1, 1);
data.setCell(0, 2, 7);
data.setCell(1, 0, new Date("2009/07/08"));
data.setCell(1, 1, 2);
data.setCell(1, 2, 4);
console.log("Created datatable " + data.toJSON());
return data;
}
});
var AppRouter = Backbone.Router.extend({
routes:{
"":"chart"
},
chart:function () {
console.log("Showing chart");
$("#content").append(new ChartView().render().el);
}
});
router = new AppRouter();
Backbone.history.start();
</script>
</body>
</html>
Ok, to record this for posterity before another month goes by. It's possible to set the callback as an arg to the google.load call itself, rather than use the google.setOnLoadCallback method. Also had to tweak the code to get the first child of the jquery object and it works fine.
ChartView = Backbone.View.extend({
render:function () {
$(this.el).html('<p>gviz line chart:</p>' +
'<div id="gviz" style="width:600px; height:300px;"></div>');
google.load('visualization', '1', {'callback':this.drawVisualization,
'packages':['linechart']});
return this;
},
drawVisualization:function () {
console.log("In draw visualization");
var data = new google.visualization.DataTable();
data.addColumn('date', 'Date');
data.addColumn('number', 'Column A');
data.addColumn('number', 'Column B');
data.addRows(4);
data.setCell(0, 0, new Date("2009/07/01"));
data.setCell(0, 1, 1);
data.setCell(0, 2, 7);
data.setCell(1, 0, new Date("2009/07/08"));
data.setCell(1, 1, 2);
data.setCell(1, 2, 4);
var chart = new google.visualization.LineChart(this.$('#gviz').get(0));
chart.draw(data, null, null);
}
});
If you're using require.js for dependency management, I've found that using the single-call for loading specific modules works nicely.
define(
[
'backbone'
, 'socialPages/data/statCollection'
, 'date'
, 'https://www.google.com/jsapi?autoload={"modules":[{"name":"visualization","version":"1","packages":["corechart","table"]}]}'
], function(
Backbone
, StatsCollection
) {
return Backbone.View.extend({
initialize: function() {
_.bindAll( this
, '_chartDataChanged'
, '_drawChart'
, '_fetchStats'
, '_generateFields'
, '_generateRows'
, '_generateStatsTotals'
, '_lineChartOptions'
, '_onItemSelected'
, '_padWithZeroValues'
, '_setChartDimensions'
, 'clean'
, 'render'
);
this._firstRender = true;
this._sampleRate = 'month';
this.statsCollection = new StatsCollection();
this.dimensions = this._setChartDimensions();
this.statsCollection.bind( 'all' , this._chartDataChanged );
this._fetchStats();
if( window.google ) {
google.setOnLoadCallback( this._drawChart );
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With