Search code examples
javascriptgoogle-visualization

TypeError: google.visualization is undefined


I'm trying to work with Google charts API, but I get an error I can't understand:

Here is my code:

<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript" src="js/statistics/overview.js"></script>

And the code from overview.js is like this:

var statisticsOverview = {
    init: function() {
        google.load("visualization", "1", {packages: ["corechart"]});
        google.setOnLoadCallback(this.drawIncomeChart());
        google.setOnLoadCallback(this.drawExpensesChart());
        google.setOnLoadCallback(this.drawEconomiesChart());
    },
    drawIncomeChart: function() {
        var data = [
            ['Year', 'Income'],
            ['October 2013', 1000],
            ['January 2014', 1170],
            ['March 2014', 660]
        ];
        var options = {
            title: 'Income Performance',
            colors: ['green']
        };
        var id = 'chart_income';

        this.drawLineChart(data, options, id);
    },
    drawExpensesChart: function() {
        var data = [
            ['Year', 'Expense'],
            ['October 2013', 1000],
            ['January 2014', 1170],
            ['March 2014', 660]
        ];
        var options = {
            title: 'Expense Performance',
            colors: ['red']
        };
        var id = 'chart_expenses';
        this.drawLineChart(data, options, id);
    },
    drawEconomiesChart: function() {
        var data = [
            ['Year', 'Savings'],
            ['2004', 1000],
            ['2005', 1170],
            ['2006', 660],
            ['2007', 1030]
        ];

        var options = {
            title: 'Savings Performance',
            colors: ['orange']
        };

        var id = 'chart_economies';
        this.drawLineChart(data, options, id);
    },
    drawLineChart: function(data, options, id) {
        console.log(google.visualization);
        var chartData = google.visualization.arrayToDataTable(data);

        var chart = new google.visualization.LineChart(document.getElementById(id));
        chart.draw(chartData, options);
    }
};

statisticsOverview.init();

This is strange, because console.log() will give me the google object with the property visualization. What am I doing wrong?


Solution

  • Timing problem. Typically you call google chart like

      google.load("visualization", "1", {packages:["corechart"]});
      google.setOnLoadCallback(drawChart);
      function drawChart() {
      ...
      }
    

    So, when visualization package is loaded function to draw is called.

    Now, in your case everything is done later, so you have to do:

    google.load("visualization", "1", {packages: ["corechart"]});
    
    function doStats() {
    
    var statisticsOverview = {
        init: function() {
            console.log('init');
            this.drawIncomeChart();
            this.drawExpensesChart();
            this.drawEconomiesChart();
        },
        ...
    };    
    
    statisticsOverview.init()
    }
    
    google.setOnLoadCallback(doStats);
    

    Similar result can be get using

    setTimeout(function() {
        statisticsOverview.init();
    }, 3000);
    

    without wrapper function.