2012-06-07 11 views
6

Estoy tratando de integrar un gráfico de visualización de google en mi aplicación backbone.js. Actualmente tengo las llamadas google.load (visualización) y setOnLoadCallback (drawVisualization) en la función de renderización de una clase ChartView. Las bibliotecas de visualización de google parecen estar cargando correctamente, sin embargo, la devolución de llamada nunca se ejecuta.vista de red troncal + visualización de google api

A continuación se muestra un ejemplo que muestra el problema; si alguien pudiera ayudar, ¡estaría muy agradecido!

<!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> 

Respuesta

12

Ok, para grabar esto para la posteridad antes de que pase otro mes. Es posible establecer la devolución de llamada como una arg a la llamada de google.load en sí misma, en lugar de usar el google.set Método OnLoadCallback. También tuve que ajustar el código para obtener el primer hijo del objeto jquery y funciona bien.

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); 
    } 

}); 
+0

gracias - esto salvó el día! – necromancer

0

Actualmente estoy usando backbone.js con GoogleCharts también. En lugar de cargar visualizaciones de Google en el método render() de su Vista, puede cargar fuera de las vistas de backbone.js en el script.

<script> 
    google.load('visualization', '1', {packages:'linechart'}); 
    ChartView = Backbone.View.extend({ 

     render:function() { 
      this.drawVisualization(); 
      return this; 
     }, 
     drawVisualization:function() { 
     .... 
     chart.draw(data, null, null); 
     } 
</script> 

Esto todavía puede dar un error diferente. Me he dado cuenta de que llamar al "gráfico.dibujar" del procesamiento (momento en el que el "el" de la vista aún no forma parte del DOM hace que los Gráficos de Google muestren un error "Su navegador no admite gráficos"

me daría lugar a la función 'drawVisualization' después de asegurarse la Vista 'el' ha sido insertada en el DOM para, por ejemplo en un evento en la vista (o es modelo) Di:..

<script> 
    google.load('visualization', '1', {packages:'linechart'}); 
    ChartView = Backbone.View.extend({ 
     events:{ 
      this.model.on('change',this.drawVisualization, this); 
     }, 
     render:function() { 
      this.drawVisualization(); 
      return this; 
     }, 
     drawVisualization:function() { 
     .... 
     chart.draw(data, null, null); 
     } 
</script> 

Espero que esto ayude

3

Si está utilizando require.js para la gestión de la dependencia, he encontrado que el uso de una sola llamada para cargar módulos específicos funciona muy bien.

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); 
     } 

    } 
Cuestiones relacionadas