Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use javascript array elements in google.visualization graphs

I have the following bit of code that draws graphs, in a loop, using google.visualisation based on values from a SQL table which I store in 3 arrays(i.e. $TotalView, $TotalFemaleView and $TotalMaleView) in the PHP portion. I use json_encode(referred this link) so I can use these arrays in JavaScript. But I am unable to access the array elements to draw the graphs. I have tried displaying the values of the arrays and they are correct.

<?php
$servername = "localhost";
$username = "root";
$password = "root123";
$dbname = "test";

$AdName=[];
$TotalView=[];
$TotalMaleView=[];
$TotalFemaleView=[];
$rowcount=0;

// Create connection
$con = mysqli_connect($servername, $username, $password, $dbname);
// Check connection
if ($con->connect_error) {
    die("Connection failed: " . $con->connect_error);
} 

$result=mysqli_query($con,"SELECT `Ad Name`,`Total View Count`, `Total Female Viewers`, `Total Male Viewers` FROM `addata` WHERE `Disp Id`=1");

$rowcount=mysqli_num_rows($result);

if(!$result) {
      die('Could not get data: ' . mysql_error());
    }
    // output data of each row 
    for($x = 0; $x < $rowcount; $x++)
    {
        $row = $result->fetch_assoc();
        $TotalView[$x]=$row["Total View Count"];
        $TotalFemaleView[$x]=$row["Total Female Viewers"];
        $TotalMaleView[$x]=$row["Total Male Viewers"];
        $AdName[$x]=$row["Ad Name"];
    }

$con->close();
?>
<html>
  <body>

    <script src="https://www.gstatic.com/charts/loader.js"></script>
    <ul id="stats"></ul>
    <script type="text/javascript">

    var array1 = <?php echo json_encode($TotalView);?>;
    var array2 = <?php echo json_encode($TotalFemaleView);?>;
    var array3 = <?php echo json_encode($TotalMaleView);?>;
    var array4 = <?php echo json_encode($AdName);?>;

    google.charts.load('current', 
    { callback: function () 
        {   
            for ( y = 0; y < <?php echo $rowcount ?>; y++) 
            {

                var data = new google.visualization.DataTable();
                data.addColumn('string', 'list');
                data.addColumn('number', 'Viewers');
                data.addRows([ 
                                ['TotalViewers',array1[y]],
                                ['Female Viewers', array2[y]],
                                ['Male Viewers', array3[y]]
                            ]);
                var options = {title:array4[y],width:400,height:300};

                var container = document.getElementById('stats').appendChild(document.createElement('div'));
                var chart = new google.visualization.ColumnChart(container);
                chart.draw(data, options);
            }
        },
        packages: ['corechart']
    });

</script>
  </body>

</html>

Can anyone point me towards the right direction?

like image 599
Abhijith Bagepalli Avatar asked Jun 09 '26 02:06

Abhijith Bagepalli


2 Answers

Based on the information in your comments and updated PHP code, it seems that your data returned from the database queries has numbers in the form of strings. Before using eval() or the Javascript Number object, if you looked in the browser console then you might have seen errors like this:

Uncaught Error: Type mismatch. Value 12 does not match type number in column index 1

There are multiple options to resolve this (without using eval()):

  • Type cast the values as an integer or float when adding to the output arrays in PHP

    $TotalView[$x] = (float)$row["Total View Count"];
    
  • use the JSON_NUMERIC_CHECK flag with json_encode (see this answer for more info).

    var array1 = <?php echo json_encode($TotalView, JSON_NUMERIC_CHECK );?>;
    

    But beware there are drawbacks to using that constant (see this article for an example).

See this updated phpfiddle. As you can see, I created a class to simulate the database query (since I don't have a database connection in that sandbox) but allows to have the same array creation.

Please run that fiddle, and inspect the output in the browser console. Notice how the results of json_encode() produce valid arrays in Javascript, like:

var array1 = [12,10,6];
var array2 = [8,4,1];
var array3 = [4,6,5];
var array4 = ["Audi","BMW","Suzuki"];

Interestingly, the unordered list tag (i.e. <ul id="stats">), which is considered flow content, is added to the head tag in your sample code. The head tag only allows meta-data content. Move that unordered list tag to the body tag.

See the output demonstrated in the snippet below.

var array1 = [22, 16, 35, 11];
var array2 = [10, 3, 4, 9];
var array3 = [12, 13, 31, 2];

google.charts.load('current', {
  callback: function() {
    for (var y = 0; y < array1.length; y++) {

      var data = new google.visualization.DataTable();
      data.addColumn('string', 'list');
      data.addColumn('number', 'Viewers');
      data.addRows([
        ['TotalViewers', array1[y]],
        ['Female Viewers', array2[y]],
        ['Male Viewers', array3[y]]
      ]);
      var options = {
        title: 'Ad 1',
        width: 400,
        height: 300
      };
      var container = document.getElementById('stats').appendChild(document.createElement('div'));
      var chart = new google.visualization.ColumnChart(container);
      chart.draw(data, options);
    }
  },
  packages: ['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<ul id="stats"></ul>
like image 165
Sᴀᴍ Onᴇᴌᴀ Avatar answered Jun 10 '26 16:06

Sᴀᴍ Onᴇᴌᴀ


Okay, I solved it. Had to pass the arrays in the eval() function before using them in the google.visualization function.

google.charts.load('current', 
        { callback: function () 
            {   
                for ( y = 0; y < <?php echo $rowcount ?>; y++) 
                {
                    array1[y]=eval(array1[y]);  
                    array2[y]=eval(array2[y]);  
                    array3[y]=eval(array3[y]);  

                    var data = new google.visualization.DataTable();
                    data.addColumn('string', 'list');
                    data.addColumn('number', 'Viewers');
                    data.addRows([ 
                                    ['TotalViewers',array1[y]],
                                    ['Female Viewers', array2[y]],
                                    ['Male Viewers', array3[y]]
                                ]);
                    var options = {title:array4[y],width:400,height:300};

                    var container = document.getElementById('stats').appendChild(document.createElement('div'));
                    var chart = new google.visualization.ColumnChart(container);
                    chart.draw(data, options);
                }
            },
            packages: ['corechart']
        });

EDIT:

I found what was causing the problem and a better solution to the eval().

The json_encode was storing the elements as strings in the arrays(as you can see from my source here).

According to this, it is a PHP version specific problem and there are a couple of workarounds:

  • Adding the flag JSON_NUMERIC_CHECK to the json_encode function. So in my case, it will be: var array1 = <?php echo json_encode($TotalView,JSON_NUMERIC_CHECK);?>. But this, according to some of the comments, is unreliable in certain cases.
  • Another solution is fixing it in the PHP section while reading the database elements from the database. $TotalView[$x]=(int)$row['Total View Count']. So this stores the database element, Total View Count as an integer in the TotalView array.
like image 43
Abhijith Bagepalli Avatar answered Jun 10 '26 14:06

Abhijith Bagepalli