3

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?

2
  • A tip would be to do console.log(array1) and see what it looks like, maybe it isnt accesed by array1[0] Commented Apr 7, 2017 at 13:28
  • @Bear, I have checked it and its fine. The arrays have the right values stored. But I've solved it! Commented Apr 7, 2017 at 13:34

2 Answers 2

1

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>

Sign up to request clarification or add additional context in comments.

8 Comments

I appreciate you taking time out for this but please forgive my ignorance because I still don't see what I'm doing wrong! I'm pretty sure the SQL statements I have are right and apart from that my array creation and javascript statements also seem to be what you've used but it still doesn't display the graphs without the eval function.
I would like to see the entire HTML/JS output from the PHP... If you don't have a public URL on the internet, could you copy and paste it somewhere like pastebin.com?
do you mean the values of array1, array2 array3?
i mean the whole source. View the page in your browser, view the source, copy it all and paste it into pastebin - like I did in this paste...
pastebin.com/NkNbdDJx I see the elements in array1,array2, array3 are stored as strings, I'm guessing that's the problem. But in the SQL table, the elements are of type int
|
1

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.

2 Comments

What do the arrays look like? Please read this
@SamOnela, they are an array of numbers.(array1[]={22,17, 35,11} for eg)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.