2013-05-23 5 views
5

In questo modo il mio istogramma funziona correttamente, quando lo carico come durante il caricamento della pagina.Perché google graph non funziona quando si carica dal controller di AngularJS. Il browser diventa bianco senza errori nella console

$(document).ready() 
{ 
x = new Array(10); 
for (var i = 0; i < 10; i++) { 
    x[i] = new Array(2); 
    x[i][0]="txt"; 
    x[i][1]=100; 

} 
loadChart2(x); 
} 

Google Codice istogramma: (adottato da Google charting api)

function loadChart2 (histValues) 
{ 
    console.log('histValues:'+histValues); 
    google.load("visualization", "1", {packages:["corechart"]}); 
    google.setOnLoadCallback(drawChart); 
    function drawChart() { 
     var data = google.visualization.arrayToDataTable(histValues); 

     var options = { 
      hAxis: {title: 'Score', titleTextStyle: {color: 'red'}} 
     }; 

     var chart = new google.visualization.ColumnChart(document.getElementById('chart_div')); 
     chart.draw(data, options); 
    } 
}; 

Il mio problema:

Ma quando chiamo loadChart2() da dentro il mio controller angularJS, intero schermo diventa bianco e nessun errore viene mostrato nella console del browser.

$http({method: 'GET', url: urlGetHistogramData, timeout: maxTime}) 
      .success(function (data) { 
      x=new Array(data.score_hist.length); 
      var i=0; 
      $.each(data.score_hist, function(){ 
       x[i] = new Array(2); 
       x[i][0]=this.interval_start; 
       x[i][1]=this.count; 
       i++; 
       }); 


       loadChart2(x); 

});

informazioni di debug:

posso vedere in console che interval_start e count valori vengono stampate, quindi il servizio è la restituzione di valori pregiati

Inoltre, posso vedere histValues attesa stampata sulla console da loadChart() funzione.

Ecco una questione connessa, nel caso in cui si desidera più informazioni dettagliate e approfondite How to create a historgram from json

Appena ho messo loadChart2() funzione in qualsiasi AngularJS onClick o di qualsiasi funzione, ottengo schermo bianco totale, senza errore nella console . Sembra, nessuno ha commenti sul mio problema, terrò questa pagina aggiornata con le mie conclusioni su questo.

Edit io sto inseguendo una soluzione a questo problema, ho fatto una domanda relativa a questo problema https://stackoverflow.com/questions/16816782/how-set-charts-data-in-google-chart-tool-directive-module-from-a-dynamically-po

+1

Sembra che tu stia cercando di manipolare il DOM nel punto sbagliato nello stack di esecuzione. Mi chiedo quali risultati otterresti se tu chiamassi 'loadChart2()' da una direttiva. –

+1

+ 1. Hai ragione riguardo alla manipolazione del DOM (ho fatto come ultima risorsa a causa della limitazione con l'API grafica di Google). Forse usare la direttiva sarebbe un modo per farlo. Sono nuovo di AngularJS non so molto di direttiva, per favore può dare qualche indizio, come utilizzare la direttiva in questo caso. Grazie!! – Watt

+0

quindi? hai provato a fare il bootstrap angolare in google.setOnLoadCallback come ti ho già spiegato? perché provare a caricare la libreria del grafico dopo l'avvio angolare è la causa di quello strano errore della pagina bianca. Quindi, le cose bianche -> caricamento della libreria dei grafici errato, l'errore "Non un array" -> qualunque cosa tu stia passando non è un array (prova a testarlo con Array.isArray). – coma

risposta

9

La chiave è di bootstraping il modulo angolare manuale dopo il Google la creazione di grafici carico biblioteca:

http://jsfiddle.net/nCFd6/22/

App

var app = angular.module('app', []); 

direttiva

app.directive('chart', function() { 

    return { 
     restrict: 'E', 
     replace: true, 
     scope: { 
      data: '=data' 
     }, 
     template: '<div class="chart"></div>', 
     link: function(scope, element, attrs) { 

      var chart = new google.visualization.LineChart(element[0]); 
      var options = {}; 

      scope.$watch('data', function(v) { 

       var data = google.visualization.arrayToDataTable(v); 
       chart.draw(data, options); 

      }); 

     } 
    }; 

}); 

controller

app.controller('ChartController', function($scope) { 

    $scope.scoreHistory = []; 
    $scope.loadDataFromServer = function() { 

     var x = [ 
      ['interval', 'count'] 
     ]; 

     var scoreHistory = [ 
      { 
       intervalStart: 12, 
       count: 20 
      }, 
      { 
       intervalStart: 100, 
       count: 200 
      }, 
      { 
       intervalStart: 200, 
       count: 50 
      }, 
      { 
       intervalStart: 250, 
       count: 150 
      } 
     ]; 

     angular.forEach(scoreHistory, function(record, key) { 

      x.push([ 
       record.intervalStart, 
       record.count 
      ]); 

     }); 

     $scope.scoreHistory = x; 

    }; 

}); 

Vodoo

google.setOnLoadCallback(function() { 

    angular.bootstrap(document, ['app']); 

}); 

google.load('visualization', '1', {packages: ['corechart']}); 

View

<div ng-controller="ChartController"> 
    <button ng-click="loadDataFromServer()">load data</button> 
    <chart data="scoreHistory"></chart> 
</div> 

Come si può vedere in questo esempio, ho fatto una direttiva grafico in modo da poterlo riutilizzare.

+0

Grazie! Andando a provare questo nel mio progetto – Watt

+0

Ho aggiunto un "clic" per simulare il tuo callback Ajax. – coma

+0

Sto cercando di eseguire il debug in seguito all'errore durante il tentativo del codice nel mio progetto 'Errore: non un array all'errore () presso Object.b [come arrayToDataTable] (https://www.google.com/uds /api/visualization/1.0/e0ebcb36e2905f30852752301c93f500/format+en,default,corechart.I.js:357:85) ' – Watt

1

sto ancora facendo la mia strada attraverso il processo di apprendimento di AngularJS troppo. Questo (https://stackoverflow.com/a/15012542/2406758) mi ha fatto impazzire oggi e penso che farò molti più progressi nelle prossime settimane.

È un compagno eccellente per i tutorial di AngularJS e spiega Servizi, Controller e Direttive, in un modo che non ho trovato da nessun'altra parte. Ci sono anche alcuni buoni esempi di Direttiva, per aiutare a capire cosa sta spiegando.

Non sono sicuro che questa sarà la risposta al tuo problema, ma è un buon punto di partenza.

mi aspetto che ritroverete con qualcosa di simile

<div id='chart' chart-view>

.directive('chartView', function () { 
    return { 
    scope: true, 
    link: function (scope, element, attrs) { 
     x = new Array(10); 
     for (var i = 0; i < 10; i++) { 
      x[i] = new Array(2); 
      x[i][0]="txt"; 
      x[i][1]=100; 
     } 
     loadChart2(x); 
    } 
    }; 
}); 
+1

Grazie! Ci proverò. A proposito, ho trovato un altro fantastico tutorial http://www.adobe.com/devnet/html5/articles/angularjs-directives-and-the-computer-science-of-javascript.html – Watt

+0

l'ho testato a fondo. Sfortunatamente non ha funzionato. Nessun grafico viene visualizzato sullo schermo quando utilizzo la direttiva che hai fornito. +1 per un ottimo tutorial e provando però. – Watt

2

Ecco un'alternativa che offre una certa flessibilità nel caso in cui è già stato definito un modulo creato alla base di il documento (il tag <html>) e alcuni controller e direttive già impostati.

In application.js

var app = angular.module("chartApp", []); 

app.controller("ChartCtrl", function($scope) { 

$scope.buildTable = function() { 
    var dataTable = new google.visualization.DataTable(); 
    dataTable.addColumn('string', 'Name'); 
    dataTable.addColumn('string', 'Address'); 

    var options = {showRowNumber: true}; 

    var table = new google.visualization.Table(angular.element("div#chart")[0]); 

    var rows = [...]; //Table data here 

    dataTable.addRows(rows); 

    table.draw(dataTable, options); 
} 

//Other existing controllers and directives 

Nel index.html

<div id="container" ng-controller="ChartCtrl"> 
<div id="chart">Loading...</div> 
</div> 

<script type="text/javascript" src="angular.js"></script> 
<script type="text/javascript" src="application.js"></script> 
<script type="text/javascript" src="google/charts/api"></script> 
<script type="text/javascript"> 
google.setOnLoadCallback(function() { 
      angular.element("div#container").scope().buildTable(); 
     }); 
google.load('visualization', '1', {packages:['table']}); 
</script> 

Con questo approccio, si rimuove la complessità di comunicazione tra i moduli angolari se il componente Grafici Google è solo una caratteristica di una molto più grande applicazione che hai già in corso.

Problemi correlati