PHP & MySQL with Google Timeline Chart - php

I'm trying to create Google Timeline chart using PHP & MySQL but without any success so far. So after endless hours of trying I've manage this so far:
First, I tried to create json using PHP (I believe that I've missed something here)
PHP
try {
$db = connectPDO();
$result = $db->query("SELECT naziv_plan AS name,
objava_odluke AS start_date,
datum_stupanja_glasnika AS end_date
FROM ispu_plan
WHERE datum_donosenja_plana
BETWEEN '2014-01-01'
AND CURDATE()
ORDER BY datum_donosenja_plana ASC");
$rows = array();
$table = array();
$table['cols'] = array(
array('label' => 'Godina', 'type' => 'string'),
array('label' => 'Odluka', 'type' => 'number'),
array('label' => 'glasnik', 'type' => 'number')
);
foreach($result as $r) {
$temp = array();
$temp[] = array('v' => (string) $r['naziv_plan']);
$temp[] = array('v' => (int) $r['objava_odluke']);
$temp[] = array('v' => (int) $r['datum_stupanja_glasnika']);
$rows[] = array('c' => $temp);
}
$table['rows'] = $rows;
$jsonTable = json_encode($table,JSON_NUMERIC_CHECK);
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
Using this block of code, I get this JSON (and it's valid, checked with JSONLint) But, I detected some unusual formatting and even after JSON_NUMERIC_CHECK
{"cols":[{"label":"Godina","type":"string"},{"label":"Odluka","type":"number"},{"label":"glasnik","type":"number"}],"rows":[{"c":[{"v":"Stambenog susjedstva - Stubi\u010dki Trnac - I.ID"},{"v":2014},{"v":2014}]},{"c":[{"v":"Prostorni plan ure\u0111enja Grada Krapine - IV. ID"},{"v":2013},{"v":2015}]},{"c":[{"v":"Prostorni plan ure\u0111enja Grada Donja Stubica - I ID"},{"v":2014},{"v":2015}]},{"c":[{"v":"Generalni urbanisti\u010dki plan Grada Krapine - V.ID"},{"v":2015},{"v":2016}]}]}
And here is JS:
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var container = document.getElementById('timeline');
var chart = new google.visualization.Timeline(container);
var data = new google.visualization.DataTable(<?php echo $jsonTable;?>);
chart.draw(data);
After running this whole block of code, I get this error
Cannot read property 'v' of undefined
Is there something wrong with PHP code?
1.Maybe there is problem with date formatting?
Why do I get some weirdly formatted JSON Example -- *Stambenog susjedstva - Stubi\u010dki Trnac - I.ID when I should be getting instead of this ->Stubi\u010dki this-> Stubički
When I run SQL i get something like this (example below:)
+-----------+------------------+-----------------+
| name| | start_date | end_Date |
+-----------+------------------+-----------------+
| example_1 | 2014-06-06 | 2014-12-27 |
| example_1 | 2013-12-31 | 2015-06-07 |
| example_1 | 2016-06-06 | 2015-12-31 |
+-----------+------------------+-----------------+
*
I want to get something like this:
https://jsfiddle.net/api/post/library/pure/
UPDATE 1
So, I've managed to fix some of the addressed issues:
First, problem with weirdly formatted JSON, fixed with JSON_UNESCAPED_UNICODE
So, instead of this code:
$jsonTable = json_encode($table,JSON_NUMERIC_CHECK);
I used this :
$jsonTable = json_encode($table,JSON_UNESCAPED_UNICODE);
On the timeline note I've managed to successfully render timeline chart,but on x axis, instead of years and date it shows me hours.I believe that i've missed something when transforming from query to json.
(as seen in picture below)
I used this block of PHP code:
try {
$db = connectPDO();
$result = $db->query("SELECT naziv_plan, objava_odluke, datum_stupanja_glasnika
FROM ispu_plan
WHERE datum_donosenja_plana
BETWEEN '2014-01-01'
AND CURDATE()
ORDER BY datum_donosenja_plana ASC");
$rows = array();
$table = array();
$table['cols'] = array(
array('label' => 'Naziv plana', 'type' => 'string'),
array('label' => 'Odluka', 'type' => 'datetime'),
array('label' => 'glasnik', 'type' => 'datetime')
);
foreach($result as $r) {
$temp = array();
$temp[] = array('v' => (string) $r['naziv_plan']);
$temp[] = array('v' => (int) strtotime($r['objava_odluke']));
$temp[] = array('v' => (int) strtotime($r['datum_stupanja_glasnika']));
$rows[] = array('c' => $temp);
}
$table['rows'] = $rows;
$jsonTable = json_encode($table,JSON_UNESCAPED_UNICODE);
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
And in JSON i get something like this 1402005600 for start date and in my table is formated like this 2014-06-06 and i believe that i need to get something like this 2014, 6, 6 to properly render and calculate timeline chart.
Please help with my lifetime crisis :)
UPDATE 2
Using whitehat knowledge and directions I'm feeling it that I'm one step closer to finally render this abomination :) Meanwhile, using directions and code that WhiteHat provided i created this:
$rows = array();
$table = array();
$table['cols'] = array(
array('label' => 'Godina', 'type' => 'string'),
array('label' => 'Odluka', 'type' => 'date'),
array('label' => 'glasnik', 'type' => 'date')
);
while ($row = $result->fetch(PDO::FETCH_ASSOC)){
$date1 = new DateTime();
$date2 = "Date(".date_format($date1, 'Y').", ".((int) date_format($date1, 'm') - 1).", ".date_format($date1, 'd').")";
$temp = array();
$temp[] = array('v' => (string) $row['naziv_plan']);
$temp[] = array('v' => (string) $date2);
$temp[] = array('v' => (string) $date2);
$rows[] = array('c' => $temp);
}
$table['rows'] = $rows;
$jsonTable = json_encode($table,JSON_NUMERIC_CHECK);
Output of json is this:
{"cols":[{"label":"Godina","type":"string"},{"label":"Odluka","type":"date"},{"label":"glasnik","type":"date"}],"rows":[{"c":[{"v":"Stambenog susjedstva - Stubi\u010dki Trnac - I.ID"},{"v":"Date(2016, 8, 30)"},{"v":"Date(2016, 8, 30)"}]},{"c":[{"v":"Prostorni plan ure\u0111enja Grada Krapine - IV. ID"},{"v":"Date(2016, 8, 30)"},{"v":"Date(2016, 8, 30)"}]},{"c":[{"v":"Prostorni plan ure\u0111enja Grada Donja Stubica - I ID"},{"v":"Date(2016, 8, 30)"},{"v":"Date(2016, 8, 30)"}]},{"c":[{"v":"Generalni urbanisti\u010dki plan Grada Krapine - V.ID"},{"v":"Date(2016, 8, 30)"},{"v":"Date(2016, 8, 30)"}]}]}
And i get timeline, but without lines :(
Something like this:
And this two errors:
Expected number, "MNaN,0LNaN,40.992
Error: attribute x: Expected length, "NaN"
UPDATE 3
Ok, I believe that I've manage somehow, and it works. Here is code below, hope it helps someone. Once again thank you WhiteHat :)
try {
$db = connectPDO();
$result = $db->query("SELECT naziv_plan, objava_odluke, datum_stupanja_glasnika
FROM ispu_plan
WHERE datum_donosenja_plana
BETWEEN '2014-01-01'
AND CURDATE()
ORDER BY datum_donosenja_plana ASC ");
$rows = array();
$table = array();
$table['cols'] = array(
array('label' => 'Godina', 'type' => 'string'),
array('label' => 'Odluka', 'type' => 'date'),
array('label' => 'glasnik', 'type' => 'date')
);
while ($row = $result->fetch(PDO::FETCH_ASSOC)){
// here I added rows in DateTime function, that was missing
$date1 = new DateTime($row['objava_odluke']);
$date2 = "Date(".date_format($date1, 'Y').", ".((int) date_format($date1, 'm') - 1).", ".date_format($date1, 'd').")";
$date3 = new DateTime($row['datum_stupanja_glasnika']);
$date4 = "Date(".date_format($date3, 'Y').", ".((int) date_format($date3, 'm') - 1).", ".date_format($date3, 'd').")";
$temp = array();
$temp[] = array('v' => (string) $row['naziv_plan']);
$temp[] = array('v' => (string) $date2);
$temp[] = array('v' => (string) $date4);
$rows[] = array('c' => $temp);
}
$table['rows'] = $rows;
$jsonTable = json_encode($table,JSON_NUMERIC_CHECK);
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
?>
Picture, to prove it:

Related

PHP MySQL Google chart

im trying to create a google chart using mysql and PHP, after doing an extensive research, i managed to find ways do display the charts however this work on vertical tables.
the current table that im using has the id,date on the first column, below is a sample output
+----+------------+------------+--------------+
| id | DATE | COL1 | COL2 |
+----+------------+------------+--------------+
| 1 | 18/04/2016 | 5291 | 2217 |
+----+------------+------------+--------------+
i've used the solution provided here and below is the code sample:
$result = $mysqli->query('SELECT * FROM Statistics limit 3');
$rows = array();
$table = array();
$table['cols'] = array(
array('label' => 'COL1', 'type' => 'number'),
array('label' => 'COL2', 'type' => 'number')
);
foreach($result as $r) {
$temp = array();
$temp[] = array('v' => (string) $r['COL1']);
$temp[] = array('v' => (int) $r['COL2']);
$rows[] = array('c' => $temp);
}
$table['rows'] = $rows;
$jsonTable = json_encode($table);
print $jsonTable;
however when using pi chart for example, it'll use the values from COL1 only and ignores the rest...
Thanks,
Ali

Between is working fine in SQL Server but losing starting date while fetching same query through PHP

I am having a weird problem: I fired the same query select DateSpan, PUE from GF.dbo.PUE Data where DateSpan between '2013-10-01 12:00:00.000' and '2013-10-31 12:00:00.000' in SQL Server and getting proper result.
2013-10-01 12:00:00.000 1.66402976232178
2013-10-02 12:00:00.000 1.58132003529595
..
..
However when I fetch the same query through PHP script, it loses 1st day. Don't know the reason.
SELECT DateSpan, PUE
FROM [GF].[dbo].[PUEData]
where (DateSpan >= '$stdate' AND DateSpan < '$enddate')
Probably the problem is with later array formulation -
$rows = array();
$table = array();
$table['cols'] = array(
array('label' => 'Date', 'type' => 'string'),
array('label' => $metric , 'type' => 'number')
);
$result=sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
while($r = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC))
{
$temp = array();
$temp[] = array('v' => (string) $r['DateSpan']);
$temp[] = array('v' => (float) $r[$metric]);
$rows[] = array('c' => $temp);
}
$table['rows'] = $rows;
$jsonTable = json_encode($table,JSON_NUMERIC_CHECK);
Many thanks!

Building a Google Chart with PHP and MySQL

I am pretty new at PHP and MySQL queries. I am trying to build a Google chart from a MySQL database but after searching on Google for countless hours I could not find what I need. However I found an example that could be useful but I still can't make it the way I want. Here's an example of my table.
Apple | Orange | Strawberry
--------------------------
Like | Like | Like
Dislike | Like | Like
Dislike | Dislike | Like
Like | Dislike | Dislike
Like | Like | Like
I want to count how many Like and Dislike for Apple, Orange and Strawberry. In the chart I want it to display how many people like and dislike these 3 fruits.
Here's the code I've been looking at and I've yet figured out how to attack it.
$query = mysql_query('SELECT * FROM data');
$table = array();
$table['cols'] = array(
array('label' => 'cas', 'type' => 'string'),
array('label' => 'data', 'type' => 'number')
);
$rows = array();
while($r = mysql_fetch_assoc($query)) {
$temp = array();
$temp[] = array('v' => $r['cas']);
$temp[] = array('v' => (int) $r['data']);
$rows[] = array('c' => $temp);
}
$table['rows'] = $rows;
$jsonTable = json_encode($table);
echo $jsonTable;
Any example would help! Thank you.
Try this as your PHP:
$query = mysql_query("
SELECT
'Like' as 'preference',
SUM(IF(Apple = 'Like', 1, 0)) as Apple,
SUM(IF(Orange = 'Like', 1, 0)) as Orange,
SUM(IF(Strawberry = 'Like', 1, 0)) as Strawberry
FROM data
UNION
SELECT
'Dislike' as 'preference',
SUM(IF(Apple = 'Dislike', 1, 0)) as Apple,
SUM(IF(Orange = 'Dislike', 1, 0)) as Orange,
SUM(IF(Strawberry = 'Dislike', 1, 0)) as Strawberry
FROM data
");
$table = array();
$table['cols'] = array(
array('label' => 'preference', 'type' => 'string'),
array('label' => 'Apple', 'type' => 'number'),
array('label' => 'Orange', 'type' => 'number'),
array('label' => 'Strawberry', 'type' => 'number')
);
$rows = array();
while($r = mysql_fetch_assoc($query)) {
$temp = array();
$temp[] = array('v' => $r['preference']);
$temp[] = array('v' => (int) $r['Apple']);
$temp[] = array('v' => (int) $r['Orange']);
$temp[] = array('v' => (int) $r['Strawberry']);
$rows[] = array('c' => $temp);
}
$table['rows'] = $rows;
$jsonTable = json_encode($table);
echo $jsonTable;
The SQL should return two rows of data, one a sum of likes and the other a sum of dislikes, which then gets parsed into the Google Visualization API DataTable format and echo'd as a JSON string. This is good for use as an AJAX data source for the chart, but with a minor modification, it would be suitable for directly outputting the data into the javascript for drawing a chart.
"Here's the code I've been looking at and I've yet figured out how to
attack it."
Well here's how to debug it, say these are the steps you are taking.
Get data from db
Create an array
Json encode the array
Send the Json to the chart
Try and hard code an array at step 2. above, removing step 1 from the equation for a moment.
Now, going forward from that step, does the rest of the code as it should? Can you see the chart that expect using the hard-coded values?
If yes, well now work backwards, var_dump()ing data till it matches the hard-coded values you had previously.

How to create Google Chart friendly JSON arrays from MySQL?

I think I'm close to completing the passing of MySQL data to Google Charts through JSON/AJAX. I am able to output a JSON string in the correct format but it is not outputting any SQL data. I've searched everywhere for a solution with no results. Anyone see what is missing from the code?
JSON output
{"cols":[{"id":"","label":"projid","type":"string"},{"id":"","label":"hours","type":"number"}],"rows":[{"c":[{"v":""},{"v":0}]},{"c":[{"v":""},{"v":0}]},{"c":[{"v":""},{"v":0}]},{"c":[{"v":""},{"v":0}]},{"c":[{"v":""},{"v":0}]},{"c":[{"v":""},{"v":0}]},{"c":[{"v":""},{"v":0}]},{"c":[{"v":""},{"v":0}]},{"c":[{"v":""},{"v":0}]}]}
PHP->JSON
<?php
// -----> Query MySQL and parse into JSON below. <------
// write your SQL query here (you may use parameters from $_GET or $_POST if you need them)
require_once ("Includes/session.php");
require_once ("Includes/simplecms-config.php");
require_once ("Includes/connectDB.php");
$recId = null;
$projid = null;
$hours = null;
$recId = $_GET['id'];
$projid = $_GET['projid'];
$hours = $_GET['hours'];
$query = "SELECT projid, hours FROM hours WHERE id = ?";
$statement = $databaseConnection->prepare($query);
$statement->bind_param('d', $recId);
$statement->execute();
$results = $statement->get_result();
$rows = array();
$table = array();
$table['cols'] = array(
array('id' => "",'label' => 'projid', 'type' => 'string'),
array('id' => "",'label' => 'hours', 'type' => 'number')
);
/* Extract the information from $result */
while ($r = $results->fetch_assoc()) {
$temp = array();
// The following line will be used to slice the Pie chart
$temp[] = array('v' => (string) $r['projid']);
// Values of each slice
$temp[] = array('v' => (int) $r['hours']);
$rows[] = array('c' => $temp);
}
$table['rows'] = $rows;
// convert data into JSON format
$jsonTable = json_encode($table);
echo $jsonTable;
?>
The following code returned the correct array for Google Charts. Google Charts - JSON Data
<?php
// -----> Query MySQL and parse into JSON below. <------
require_once ("Includes/connectDB.php");
$result = $databaseConnection->query("SELECT projid, hours FROM alloc_hours");
$table = array();
$table['cols'] = array(
array('id' => "", 'label' => 'projid', 'pattern' => "", 'type' => 'string'),
array('id' => "", 'label' => 'hours', 'pattern' => "", 'type' => 'number')
);
$rows = array();
while ($nt = $result->fetch_assoc())
{
$temp = array();
$temp[] = array('v' => $nt['projid'], 'f' =>NULL);
$temp[] = array('v' => $nt['hours'], 'f' =>NULL);
$rows[] = array('c' => $temp);
}
$table['rows'] = $rows;
$jsonTable = json_encode($table);
echo $jsonTable;
?>
Array
{"cols":[{"id":"","label":"projid","pattern":"","type":"string"},{"id":"","label":"hours","pattern":"","type":"number"}],"rows":[{"c":[{"v":"2","f":null},{"v":"8","f":null}]},{"c":[{"v":"1","f":null},{"v":"6","f":null}]},{"c":[{"v":"3","f":null},{"v":"20","f":null}]},{"c":[{"v":"2","f":null},{"v":"10","f":null}]},{"c":[{"v":"4","f":null},{"v":"5","f":null}]},{"c":[{"v":"1","f":null},{"v":"30","f":null}]}]}
Try replacing this line:
$statement->store_result();
with:
$results = $statement->get_result();
and replace the foreach loop with a while loop:
while ($r = $results->fetch_assoc()) {
$temp = array();
// The following line will be used to slice the Pie chart
$temp[] = array('v' => (string) $r['projid']);
// Values of the each slice
$temp[] = array('v' => (int) $r['hours']);
$rows[] = array('c' => $temp);
}
That should get the query to return results. You don't need the lines:
$statement->bind_result($projid, $hours);
$statement->fetch();

How to draw a google line chart using the below code?

I want to draw a line chart using "Google Charts" tools. I'm fetching the data required for the line chart from the MySql database. The code for it is as below:
<?php
require_once('../includes/public-application-header.php');
$con=mysql_connect("localhost","root","eywaadmin") or die("Failed to connect with database!!!!");
mysql_select_db("OCN", $con);
$sql =" SELECT DATE_FORMAT( FROM_UNIXTIME( transaction_date ) , '%d/%m/%Y') 'transaction_date', COUNT(*) 'total count', SUM(transaction_status = 'success') ";
$sql .=" success, SUM(transaction_status = 'inprocess') inprocess, SUM(transaction_status = 'fail') fail, ";
$sql .=" SUM(transaction_status = 'cancelled') cancelled FROM user_transaction WHERE ";
$sql .=" transaction_date >= 1325376000 AND transaction_date <= 1373846400 GROUP BY date(FROM_UNIXTIME(transaction_date)) ";
$r= mysql_query($sql) or die(mysql_error());
$transactions = array();
while($result = mysql_fetch_array($r, MYSQL_ASSOC)){
$transactions[] = $result;
}
$rows = array();
//flag is not needed
$flag = true;
$table = array();
$table['cols'] = array(
// Labels for your chart, these represent the column titles
// Note that one column is in "string" format and another one is in "number" format as pie chart only required "numbers" for calculating percentage and string will be used for column title
array('label' => 'Transaction Date', 'type' => 'string'),
array('label' => 'Total Count', 'type' => 'number'),
array('label' => 'Success', 'type' => 'number'),
array('label' => 'Inprocess', 'type' => 'number'),
array('label' => 'Failed', 'type' => 'number'),
array('label' => 'Cancelled', 'type' => 'number'),
);
$rows = array();
foreach($transactions as $tr) {
$temp = array();
foreach($tr as $key=>$value){
// the following line will be used to slice the Pie chart
$temp[] = array('v' => (string) $key);
// Values of each slice
$temp[] = array('v' => (int) $value);
}
$rows[] = array('c' => $temp);
}
$table['rows'] = $rows;
$jsonTable = json_encode($table);
//echo $jsonTable;
?>
<html>
<head>
<!--Load the Ajax API-->
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></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() {
// Create our data table out of JSON data loaded from server.
var data = new google.visualization.DataTable(<?=$jsonTable?>);
var options = {
title: 'User Transaction Statistics',
is3D: 'true',
width: 800,
height: 600
};
// Instantiate and draw our chart, passing in some options.
// Do not forget to check your div ID
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
</head>
<body>
<!--this is the div that will hold the pie chart-->
<div id="chart_div"></div>
</body>
</html>
I want to put the dates(i.e. transaction_date) on X-axis and Count values(i.e.10,20,30,40) from on Y-axis. But unfortunately I'm not getting the line chart in the desired format. I'm attaching the screen shot of what I got after executing the above code.
Can anyone please help me in this regard? Thanks in advance. If you want any further information I can add it to the question body.
As per the request from jmac I'm posting the json response created for your reference. If you still need ny other thing like the query output, etc. I can provide you. The screenshot of the line -chart is attached.
The main problem is that you are saving the column names as well as the column values in the data set. You should just be storing the values.
$temp = array();
foreach($tr as $key=>$value){
// Values of each slice
$temp[] = array('v' => (int) $value);
}
$rows[] = array('c' => $temp);
The second problem is that you are converting all the values to ints. If you want the date to display as an actual date, you should get rid of that conversion.
$temp = array();
foreach($tr as $key=>$value){
// Values of each slice
$temp[] = array('v' => $value);
}
$rows[] = array('c' => $temp);
I have no idea how your jsonTable looks like, but it should be formatted in this way:
['transaction date', 'Total count', 'Succes', 'In progress', 'Failed', 'Canceled'],
['19-7-2013', 50, 40, 5, 2, 3],
['20-7-2013', 60, 50, 5, 1, 4],
['21-7-2013', 50, 40, 5, 2, 3],
['22-7-2013', 60, 50, 5, 1, 4],
['23-7-2013', 50, 40, 5, 2, 3]
Are you able to send me your $jsonTable?
This link shows you an example of the table: http://jsfiddle.net/kxd2u/
I don't think you have a issue with the amount of data. I made some charts myself with a lot of data and all working fine!
You are inputting your data incorrectly. Try this:
foreach ($transactions as $tr) {
$temp = array();
$temp[] = array('v' => $tr['transaction_date']);
$temp[] = array('v' => (int) $tr['total count']);
$temp[] = array('v' => (int) $tr['success']);
$temp[] = array('v' => (int) $tr['inprocess']);
$temp[] = array('v' => (int) $tr['fail']);
$temp[] = array('v' => (int) $tr['cancelled']);
$rows[] = array('c' => $temp);
}
This will produce a chart with a discrete axis, where each row of data is evenly spaced on the chart, regardless of the distance between dates. If you want a continuous axis (see this as an example of the difference between discrete and continuous), you have to format your dates a bit differently:
in the columns:
array('label' => 'Transaction Date', 'type' => 'date')
in the rows:
$dateArray = explode('/', $tr['transaction_date']);
$year = $dateArray[2];
$month = $dateArray[1] - 1; // need to subtract 1 to convert to javascript month format
$day = $dateArray[0];
$temp[] = array('v' => "Date($year, $month, $day)", f: $tr['transaction_date']);
You can then format the date axis in the chart's options:
hAxis: {
format: 'd/M/yyyy'
}
As an aside, you can get rid of that $flag variable in PHP - it is an artifact left over from the original code that I posted as an example a long time ago in the Google Visualization API group. It keeps cropping up whenever that code gets copied, and no one ever deletes it.

Categories