2012-06-07 13 views
6

Sto cercando di integrare un grafico di visualizzazione di google nella mia app backbone.js. Attualmente ho sia le chiamate google.load (visualizzazione) e setOnLoadCallback (drawVisualization) nella funzione di rendering di una classe ChartView. Le librerie di visualizzazione di Google sembrano caricarsi correttamente, tuttavia la richiamata non viene mai eseguita.backbone view + google visualization api

Di seguito è riportato un esempio che mostra il problema, se qualcuno potesse assistere sarei molto grato!

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

risposta

12

Ok, per registrare questo per i posteri prima che passi un altro mese È possibile impostare la richiamata come arg per la chiamata google.load stessa, piuttosto che utilizzare google.set Metodo OnLoadCallback. Doveva anche modificare il codice per ottenere il primo figlio dell'oggetto jQuery e funziona perfettamente.

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

grazie - questo salvato la giornata! – necromancer

0

Attualmente sto utilizzando anche backbone.js con GoogleCharts. Anziché caricare le visualizzazioni di Google nel metodo render() della tua vista, puoi caricare all'esterno delle tue viste backbone.js, nello 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> 

Questo potrebbe ancora dare un errore diverso. Ho notato che richiamare "chart.draw" dal rendering (a questo punto la vista "el" non fa ancora parte del DOM fa sì che Google Charts emetta un errore "Il tuo browser non supporta i grafici".

vorrei attivare la funzione 'drawVisualization' dopo si è sicuri della vista 'el' è stata inserita nel DOM per esempio su un evento nella Vista (o è il modello) 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> 

Spero che questo aiuti

3

Se stai usando require.js per la gestione delle dipendenze, ho trovato che utilizzando il singolo-call per il caricamento di moduli specifici funziona bene.

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

    } 
Problemi correlati