Milos Radosavljevic Milos Radosavljevic - 1 month ago 9
Javascript Question

After 3rd call the function works perfectly [ Google Charts]

I have created a Google chart and the first time I call the function i get this error:


Cannot read property 'arrayToDataTable' of undefined

drawChart callDraw onclick


the second time i call it i says:


Uncaught Error: Not an array
in this line:


var data = google.visualization.arrayToDataTable(inputData);


Head:



var array1 = [[80,100,120,130,140,120,105,60],[70,90,100,115,130,120,102,65]];
var array2 = [[12,14,16,17,18,17,16,9],[10,13,14,17,17,16,14,11]];
var size = 8;
var size2 = 2;


function callDraw(array1,array2,size,size2){
google.charts.load('current', {'packages':['corechart'], callback: drawChart});
var i=0,j=0;
var both ={};

for(i= 0; i < size2 ; i++)
for(j=0; j < size; j++)
both[array1[i][j]] = array2[i][j];

var count=0;
for(var key in both)
count ++;

var inputData = [];
for(i=0;i<count+1;i++)
inputData[i]=[];
inputData[0][0] = "Number of staff";
inputData[0][1] = "Number of traffic";

var counter=1;
for(var key in both){
inputData[counter][0] = key;
inputData[counter][1] = both[key];
counter++
console.log(key + " " + both[key]);
}
drawChart();

function drawChart() {

console.log("I am here");
var data = google.visualization.arrayToDataTable(inputData);

var options = {
title: 'Company Performance',
hAxis: {title: 'No. of traffic', titleTextStyle: {color: '#333'}},
vAxis: {title: 'No. of staff' ,minValue: 0}
};

var chart = new google.visualization.AreaChart(document.getElementById('chart_div'));
chart.draw(data, options);
inputData = [];
}
}
</script>


Body:

<div id="chart_div" style="width: 100%; height: 500px;"></div>
<p id="test"></p>
<button onclick="callDraw(array1,array2,size,size2)">Click me</button>


If I deleted the draChart() call from callDraw the first error disappears and it only works one time. I need to be able to call the function multiple time because later i will change the input not to be a static array of arrays but something dinamic.
Does anyone know how to fix this?

Answer

OK, as I mentioned in my comment, the problem is that you have to wait until google visualization is loaded and then draw your chart. so you have to use google.charts.setOnLoadCallback() callback.

Also when you have arrays, you can use something like this array1.length to get the array length. so you do not need to set a fixed value for the variable as the array length.

So with all these changes, your code would look something like this:

HTML

<div id="chart_div" style="width: 100%; height: 500px;"></div>
<p id="test"></p>
<button onclick="javascript:callDraw(array1,array2,size,size2);">Click me</button>

JavaScript

var array1 = [[80,100,120,130,140,120,105,60],[70,90,100,115,130,120,102,65]];
var array2 = [[12,14,16,17,18,17,16,9],[10,13,14,17,17,16,14,11]];
var size = array1[0].length;
var size2 = array1.length;

function callDraw(array1,array2,size,size2){
    google.charts.load('current', {'packages':['corechart']});
    var i=0,j=0;
    var both ={};

    for(i= 0; i < size2 ; i++)
        for(j=0; j < size; j++)
            both[array1[i][j]] = array2[i][j];

    var count=0;
    for(var key in both)
        count ++;

    var inputData = [];
    for(i=0;i<count+1;i++)
        inputData[i]=[]; 

    inputData[0][0] = "Number of staff";
    inputData[0][1] = "Number of traffic";

    var counter=1;
    for(var key in both){
        inputData[counter][0] = key;
        inputData[counter][1] = both[key];
        counter++
        console.log(key + " " + both[key]);
    }  
    google.charts.setOnLoadCallback(drawChart);

    function drawChart() {
        console.log("I am here");
        var data = google.visualization.arrayToDataTable(inputData);

        var options = {
            title: 'Company Performance',
            hAxis: {title: 'No. of traffic',  titleTextStyle: {color: '#333'}},
            vAxis: {title: 'No. of staff' ,minValue: 0}
        };

        var chart = new google.visualization.AreaChart(document.getElementById('chart_div'));
        chart.draw(data, options);
        inputData = [];
    }
}