I'm creating a table using Google Table Charts and PHP.
The table code is:
google.charts.load('current', {'packages':['table']});
google.charts.setOnLoadCallback(drawTable);
function drawTable() {
var data = google.visualization.arrayToDataTable([
<?php echo $dados; ?>
]);
var table = new google.visualization.Table(document.getElementById('table_div'));
data.sort({column: 0, desc: true});
table.draw(data, {showRowNumber: false, width: '100%', height: '100%'});
}
The PHP code (that gets the data) is:
$dados = "['Data','InfoX','InfoY'],";
for($i = 0; $i < count($vet); $i++){
$original_Date = $vet[$i][0];
$New_Date = date("d/m/Y", strtotime($original_Date));
$dados .= "['".$New_Date."',".$vet[$i][2].",".$vet[$i][3].','."]";
if ($i+1 < count($vet)){
$dados .= ",";
}
Currently, the table looks like this:
As you can see, I have a problem with the way the first column is sorted (right now, it is ordering first by the day, then the month and the year).
I need to order the first column chronologically (year-month-day), but show it in a dd/mm/yyyy format (in HTML, it is like when you use data-search and data-order). Is there any option custom propriety or option that I need to use to solve my issue?
Thanks in advance for the answers and feel free to ask for more details if you need it.
the problem is the dates are coming across as strings.
with real dates, the sort function will work correctly.
try using the following php...
$New_Date = date("m/d/Y", strtotime($original_Date));
$dados .= "[new Date('".$New_Date."'),".$vet[$i][2].",".$vet[$i][3].','."]";
then in javascript, use a date formatter to format the date column...
google.charts.load('current', {'packages':['table']});
google.charts.setOnLoadCallback(drawTable);
function drawTable() {
var data = google.visualization.arrayToDataTable([
<?php echo $dados; ?>
]);
var table = new google.visualization.Table(document.getElementById('table_div'));
data.sort({column: 0, desc: true});
var formatDate = new google.visualization.DateFormat({pattern: 'dd/MM/yyyy'});
formatDate.format(data, 0);
table.draw(data, {showRowNumber: false, width: '100%', height: '100%'});
}
Related
I am using google charts to display a line graph on my locally hosted web page. I am using mysqli to take the data from my phpmyadmin database then echoing this into the row spaces in the javascript.
This is the code within my html body:
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
<script>
google.charts.load('current', {packages: ['corechart', 'line']});
google.charts.setOnLoadCallback(drawBasic);
function drawBasic() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Date');
data.addColumn('number', 'Speed');
data.addRows([
<?php
$sql = "SELECT id_rides, speed, date_completed FROM rides_done WHERE (id_users = $_SESSION[id])";
$result = mysqli_query($link, $sql);
while($row = mysqli_fetch_assoc($result)) {
$date = $row['date_completed'];
$speed = floatval($row['speed']);
echo "['".$date."', ".$speed."],";
}
?>
]);
var options = {
hAxis: {
title: 'Ride date'
},
vAxis: {
title: 'Average speed'
}
};
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
The problem is that nothing is being displayed on the web page.
I know that the query works as I tried this on it's own outside of the javascript and this was output: results of sql query
Before I added the dynamic element of the chart it was working fine with just random lists of data.
I was expecting to see a line graph with 'Average Speed' on the y-axis and 'Ride date' on the x-axis with 7 datapoints but nothing was displayed.
It seems that js is particular about datatypes here so I'm wondering if it is something to do with either of the following lines - both of which I have been fiddling around with to no avail.
echo "['".$date."', ".$speed."],";
data.addColumn('string', 'Date');
data.addColumn('number', 'Speed');
Thank you very much. All suggestions and ideas are very welcome. As is probably evident I am very new to Javascript so likely to be making some stupid mistakes.
A couple of things I would say: As you appear to wish to use a date within the dataTable perhaps setting that as a date type column would be better and casting the value from the db query as a date using new Date(str). I'd also suggest that you use json_encode once you have run the db query to create a JSON object rather than manually building a string as you do above - one downside to that approach is the trailing comma which might cause issues.
I rattle together a working demo using bogus data from my db to emulate what you were trying to do here. The SQL query uses aliases to take arbitrary data and name it as you do so the Javascript remains fairly much the same.
With the JSON data it is easy to iterate through the Object using Object.keys( json ).forEach() type structure ( I apologise if this is new to you )
<?php
#add a db connection
chdir('../../dbo');
require 'db-conn-details.php';
require 'mysqli-conn.php';
?>
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<script src='//www.gstatic.com/charts/loader.js'></script>
<script></script>
<title>Google charts.....</title>
<style>
#chart_div{
width:800px;height:600px
}
</style>
</head>
<body>
<div id='chart_div'></div>
<script>
<?php
$sql = 'SELECT `speed`, `date_completed` FROM `rides_done` WHERE ( `id_users` = $_SESSION[id] )';
$sql = 'select `dr` as `speed`, date(`lasteditdate`) as `date_completed` from `testtable` limit 20'; # example sql...
$result = $link->query( $sql );
$json = json_encode( $result->fetch_all( MYSQLI_ASSOC ) );
printf('const json=%s;', $json );
?>
google.charts.load('current', { packages: ['corechart'] } );
google.charts.setOnLoadCallback( drawBasic );
function drawBasic() {
var data = new google.visualization.DataTable();
data.addColumn('date', 'Date');
data.addColumn('number', 'Speed');
Object.keys( json ).forEach( key=>{
let obj=json[ key ];
data.addRow( [ new Date( obj.date_completed ), parseFloat( obj.speed ) ] );
})
var options = {
hAxis: {
title: 'Ride date'
},
vAxis: {
title: 'Average speed'
}
};
var chart = new google.visualization.LineChart( document.getElementById('chart_div') );
chart.draw( data, options );
}
</script>
</body>
</html>
The above yielded a chart like this:
I have a PHP array of country names -
<?php
$countries_array = array("Russia", "Australia", "Chile");
?>
I need to show these countries on map via the Google Geochart map in Javascript and using this code -
function drawRegionsMap() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Country');
<?php
foreach ($countries_array as $cty) {
echo "data.addRow(['Country', " . $cty . "]);";
}
?>
var options = {backgroundColor: '#E7F2F4'};
var chart = new google.visualization.GeoChart(document.getElementById('regions_div'));
chart.draw(data, options);
}
I guess I'm passing the countries array in a wrong way, because the map doesn't show these countries.
How can I correct it ?
Note PHP serves $countries_array so you need to be within PHP script tags to output the array. It is probably easier to add each data using addRow(), it makes the syntax simpler.
function drawRegionsMap() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Country');
<?php
foreach ($countries_array as $cty) {
print "data.addRow(['" . $cty . "']);" . PHP_EOL;
}
?>
var options = {backgroundColor: '#cccccc'};
var chart = new google.visualization.GeoChart(document.getElementById('regions_div'));
chart.draw(data, options);
}
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?
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>
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.
I am trying to use a MySQL TimeStamp for the X Axis on a Scatter graph using Google Charts. Currently, the only way I have managed to get the graph displaying it using the strtotime() Function. This confuses the graph or me as strtotime() Function shows a number of seconds from 1st Jan 1970.
new Date(2017-03-07 02:03:12)] YYYY-MM-DD HH:ii:SS this is the format of the date coming from my timestamp if I leave it like this then I get the error. only if I change the time to the strtotime() this works. But the Graph does not show the time properly. Is there another way to display the timestamp. As the Documentation on google does not make much sense.
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'Distance');
data.addColumn('datetime', 'time');
data.addRows([
<?php
$query = "SELECT * FROM iot_sensors WHERE Sensor_ID ='Ultra_Dist'";
$execute = mysqli_query($conn, $query);
while ($row = mysqli_fetch_array($execute)){
$date = strtotime($row['Time_Stamp']);
echo "[".$row['Sensor_1'].", new Date(".$date.")],";
$Trimmed = trim($row['Time_Stamp']);
//echo $Trimmed;
}
?>
]);
var options = {
width: 800,
height: 500,
chart: {
title: 'Frequency of movement by time',
subtitle: 'Frequency of movement'
},
hAxis: {title: 'Distance'},
vAxis: {title: 'time'}
};
This is my code which retrieves the Time_Stamp and other value from my table and puts it in an array for the chart to use.
<?php
$query = "SELECT * FROM iot_sensors WHERE Sensor_ID ='Ultra_Dist'";
$execute = mysqli_query($conn, $query);
while ($row = mysqli_fetch_array($execute)){
$date = ($row['Time_Stamp']);
$date2 = new DateTime($date);
$date3 = date_format($date2, 'Y,m,d,H,i,s');
echo "[new Date(".$date3."),".$row['Sensor_1']."],";
}
?>
Put the date in a new Date() object then reformat it to the accepted format and then echo the date in the array.
I started to learn how to use Google Charts today and I'm a bit stuck.
I have dynamic data (changes about 3-4 times a day) to pump into the chart (Pie Chart). I'm using AJAX as the data source and PHP as my backend.. I tried to do it this way but to no avail:
AJAX:
<?php
include $_SERVER['DOCUMENT_ROOT'].'/includes/galaxy-connect.php';
$database = new Connection();
$database = $database->Connect();
$statement = $database->Prepare(" SELECT COUNT(Membership_Level_Name) AS MemTotal, Membership_Level_Name
FROM membership AS M
LEFT JOIN membership_levels AS L
ON M.`Membership_Level_Id` = L.`Membership_Level_Id`
LEFT JOIN membership_status AS S
ON M.`MembershipStatusId` = S.MembershipStatusId
WHERE M.`MembershipStatusId` = 1
GROUP BY L.`Membership_Level_Name`
ORDER BY L.`Membership_Level_Id` ");
$statement->execute();
$MembershipTotals = $statement->fetchall(PDO::FETCH_ASSOC);
if (!empty($MembershipTotals)) {
foreach ($MembershipTotals as $MembershipTotal) {
$data[] = array(
"cols" => array("id"=>"Membership_Level_Name", "label"=>"Membership Level", "type"=>"varchar"),
array("id"=>"MemTotal", "label"=>"Total", "pattern"=>"", "type"=>"number"),
"rows" => array($MembershipTotal['Membership_Level_Name'], $MembershipTotal['MemTotal'])
);
}
}
echo json_encode($data);
so thats my ajax, and it produces:
(ok wont let me post an image but heres the results)
[{"cols":{"id":"Membership_Level_Name","label":"Membership Level","type":"varchar"},"0":{"id":"MemTotal","label":"Total","pattern":"","type":"number"},"rows":["Start Up","24"]},{"cols":{"id":"Membership_Level_Name","label":"Membership Level","type":"varchar"},"0":{"id":"MemTotal","label":"Total","pattern":"","type":"number"},"rows":["Member","131"]},{"cols":{"id":"Membership_Level_Name","label":"Membership Level","type":"varchar"},"0":{"id":"MemTotal","label":"Total","pattern":"","type":"number"},"rows":["Member Plus","170"]},{"cols":{"id":"Membership_Level_Name","label":"Membership Level","type":"varchar"},"0":{"id":"MemTotal","label":"Total","pattern":"","type":"number"},"rows":["Premier Member","31"]},{"cols":{"id":"Membership_Level_Name","label":"Membership Level","type":"varchar"},"0":{"id":"MemTotal","label":"Total","pattern":"","type":"number"},"rows":["Bronze","97"]},{"cols":{"id":"Membership_Level_Name","label":"Membership Level","type":"varchar"},"0":{"id":"MemTotal","label":"Total","pattern":"","type":"number"},"rows":["Silver","145"]},{"cols":{"id":"Membership_Level_Name","label":"Membership Level","type":"varchar"},"0":{"id":"MemTotal","label":"Total","pattern":"","type":"number"},"rows":["Gold","188"]},{"cols":{"id":"Membership_Level_Name","label":"Membership Level","type":"varchar"},"0":{"id":"MemTotal","label":"Total","pattern":"","type":"number"},"rows":["Affiliate","3"]},{"cols":{"id":"Membership_Level_Name","label":"Membership Level","type":"varchar"},"0":{"id":"MemTotal","label":"Total","pattern":"","type":"number"},"rows":["Charity\/Education","4"]}]
So the next step is to call that data, I took the code from Google Charts "Connecting to a database" (or something like that) page:
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
// Load the Visualization API and the piechart package.
google.load('visualization', '1', {'packages':['corechart']});
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(drawChart);
function drawChart() {
var jsonData = $.ajax({
url: "/ajax/charts/membershiptotals.php",
dataType:"json",
async: false
}).responseText;
// Create our data table out of JSON data loaded from server.
var data = new google.visualization.DataTable(jsonData);
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
chart.draw(data, {width: 400, height: 240});
}
</script>
Reload the web page and it produces the error:
Table has no columns
I don't understand why though.. I looked at other solutions and posted on Quora and the Google group for the API but to no avail.. could someone tell me whats wrong with the code??
I found the answer:
AJAX was changed to:
<?php
include $_SERVER['DOCUMENT_ROOT'].'/includes/galaxy-connect.php';
$database = new Connection();
$database = $database->Connect();
$statement = $database->Prepare(" SELECT COUNT(Membership_Level_Name) AS MemTotal, Membership_Level_Name
FROM membership AS M
LEFT JOIN membership_levels AS L
ON M.`Membership_Level_Id` = L.`Membership_Level_Id`
LEFT JOIN membership_status AS S
ON M.`MembershipStatusId` = S.MembershipStatusId
WHERE M.`MembershipStatusId` = 1
GROUP BY L.`Membership_Level_Name`
ORDER BY L.`Membership_Level_Id` ");
$statement->execute();
$MembershipTotals = $statement->fetchall(PDO::FETCH_OBJ);
$col1=array();
$col1["id"]="";
$col1["label"]="Membership Type";
$col1["pattern"]="";
$col1["type"]="string";
$col2=array();
$col2["id"]="";
$col2["label"]="Total";
$col2["pattern"]="";
$col2["type"]="number";
$cols = array($col1,$col2);
$rows=array();
foreach ($MembershipTotals AS $MembershipTotal) { //foreach ($Event->TrainingTotals['ConfirmedTotal'] AS $Key => $Value) {
$cell0["v"]=$MembershipTotal->Membership_Level_Name;
$cell1["v"]=intval($MembershipTotal->MemTotal);
$row0["c"]=array($cell0,$cell1);
array_push($rows, $row0);
}
$data=array("cols"=>$cols,"rows"=>$rows);
echo json_encode($data);
which made it a bit easier and then on the actual page:
<script type="text/javascript">
// Load the Visualization API and the piechart package.
google.load('visualization', '1', {'packages':['corechart']});
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(drawChart);
function drawChart() {
var jsonData = $.ajax({
url: "/ajax/charts/membershiptotals.php",
dataType:"json",
async: false
}).responseText;
// Create our data table out of JSON data loaded from server.
var data = new google.visualization.DataTable(jsonData);
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
chart.draw(data, {title:'Membership Bookings', width: 800, height: 500});
}
</script>
Basically I had to clearly declare the columns, and the intval is to turn it into a integer, otherwise it returns the number as a string which Google doesn't like.. hope this helps anyone :)
thanks to Harish for an answer but I needed it more dynamic :-)
this is the format of the array to be passed.
javascript:
var jsondata; //json data recived from php script
var data = google.visualization.arrayToDataTable(jsondata);
php:
$data = array(
array('Membership Level', 'MemTotal'),
array('Member Plus', 170),
array('Member', 131)
);
echo json_encode($data);
Your have to pass Json array not object.