Google chart show visualization out of form input - php

I am actually working on a project to visualize measurement values. Right know I had the ability to visualize all the values from the database, but going further to make it possible to use checkbox so it will be easier to choose what the user want to see. I am stuck how to make it possible for the user to firstly use checkbox, one solution was to make many if for each of the checkbox and them together if one or more as checked.
Things i need help with:
Giving the user opportunity to choose what they want to see out of the checkbox.
Sort data out of date and time.
This is the goal:
So far have I came:
Code:
<?php
$con=mysql_connect("localhost","root","") or die("Failed to connect with database!!!!");
mysql_select_db("chart", $con);
$sth = mysql_query("SELECT * FROM googlechart");
$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' => 'Time', 'type' => 'number'),
array('label' => 'PH', 'type' => 'number'),
array('label' => 'temperature','type' => 'number'),
array('label' => 'Chlorine','type' => 'number') );
$rows = array();
while($r = mysql_fetch_assoc($sth)) {
$temp = array();
$temp[] = array('v' => (string) $r['Time']);
$temp[] = array('v' => (string) $r['PH']);
$temp[] = array('v' => (string) $r['temperature']);
$temp[] = array('v' => (string) $r['Chlorine']);
$temp[] = array('v' => (int) $r['Time']);
$rows[] = array('c' => $temp);
}
$table['rows'] = $rows;
$jsonTable = json_encode($table);
echo $jsonTable;
?>
<html>
<head>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable(<?=$jsonTable?>);
var options = {
/*width: 900, height: 900, */
title: 'Visualization',
/* curveType: 'function', */
legend: { position: 'bottom' },
pointSize: 10,
vAxis: {title: "Values", titleTextStyle: {italic: false}},
hAxis: {title: "Time", titleTextStyle: {italic: false}},
};
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
</head>
<body>
<div id="chart_div" style="width: 900px; height: 500px;"></div>
</body>
</html>
Phpmyadmin:

You can always sanitize your DataTable by using removeColumn. You dont have a fiddle nor give example of the JSON, so here is an example with some other values - but the technique is very simple.
Suppose you have 3 rows with data : Cats, blanket1 and blanket2. Then implement checkboxes for each data column :
<input type="checkbox" id="cats" checked="checked">
<label for="cats">cats</label>
<input type="checkbox" id="blanket1" checked="checked">
<label for="blanket1">blanket2</label>
...
In your drawChart method, examine the checked state for each checkbox and remove the corresponding data column if it is not :
//remember reverse order!
if (!blanket2.checked) data.removeColumn(3);
if (!blanket1.checked) data.removeColumn(2)
...
Reverse order is nessecary, you have to check for the last column first, then the second last column and so on.
Finally, assign a click handler to each checkbox, redrawing the chart each time a checkbox is clicked :
cats.onchange = drawChart;
blanket1.onchange = drawChart;
...
See demo -> http://jsfiddle.net/rJHtA/
Off course - in your case I would not ruin the original <?=$jsonTable?> each and every time. Hold the original <?=$jsonTable?> in a global variable and create the chart out of a local copy of that.
To order data by date (time) you must reload the page or use AJAX to get a new <?=$jsonTable?>. This should not be done along with the show / hide of the columns (no need to reload data you allready have). It is impossible to deliver a concrete example since you are not telling how the dates are inputted in the (supposed) form, how you intend to process the PHP or even what format time has in the table. Is it strings? We dont know. But assuming you have two <input>'s on a form, and Date is of type DATE :
<input type="text" name="from">
<input type="text" name="to">
Then on the server :
$SQL = 'SELECT * FROM googlechart '.
'WHERE `Date` BETWEEN "'.$_GET['from'].'" AND "'.$_GET['to'].'"';
$sth = mysql_query($SQL);

Related

How to graphically represent my database (mysql phpmyadmin)

I would like to take student's exam results and represent it as a chart for student's supervisor.
So I will fetch the database information (which is student's result and represent it graphically to the supervisor to notice student's progress)
I have been looking for a way to represent that either by php coding or js but I couldn't.
I found google API that drawing charts in a very nice way but it accepts only JSON tables...
Thank you
If you are working with a PHP backend, you can query the database to get a result set and put that result set into a format the Google Visualization API can understand, then draw charts based on it. There is no need to export the data every time you need to draw a chart:
<?php
$username = 'mysqlusername';
$password = 'password';
$databasename = 'school';
try {
$db = new PDO("mysql:dbname=$databasename", $username, $password);
}
catch (PDOException $e) {
die ($e->getMessage());
}
$query = $db-> prepare('SELECT student, grade FROM myClass WHERE year = :year AND semester = :semester');
// 'year' and 'semester' here get substituted into the query for ':year' and ':semester' respectively
// this is a secure way of passing in parameters to the query so that a malicious user cannot use SQL injection to penetrate your security
$query->execute(array('year' => 2013, 'semester' => 1));
$results = $query->fetchAll(PDO::FETCH_ASSOC);
$data = array(
// create whatever columns are necessary for your charts here
'cols' => array(
array('type' => 'string', 'label' => 'Student Name'),
array('type' => 'number', 'label' => 'Grade')
)
'rows' => array()
);
foreach ($results as $row) {
// 'student' and 'grade' here refer to the column names in the SQL query
$data['rows'][] = array('c' => array(
array('v' => $row['student']),
array('v' => $row['grade'])
});
}
?>
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
function drawChart() {
var data = new google.visualization.DataTable(<?php echo json_encode($data, JSON_NUMERIC_CHECK); ?>);
var chart = new google.visualization.ColumnChart(document.querySelector('#chart_div'));
chart.draw(data, {
height: 400,
width: 600
});
}
google.load('visualization', '1', {packages:['corechart'], callback: drawChart});
</script>
</head>
<body>
<div id="chart_div"></div>
</body>
</html>
Just use the export function in phpmyadmin (here you can find which formats are supported). Select the EXPORT button in the top of the page (of the table you'd like to export) and then change the format from SQL to JSON.
If you want to export data automatically (don't tag phpmyadmin), you should just excract them from the database and then encode them in json format (json_encode()). Then just take them to Google API and retrieve the charts.
If the phpMyAdmin charting features are not advanced enough, and you don't need a web-interface, you could also use Excel PowerPivot to connect to your MySQL (or any other) database.
There is a very good HOWTO on setting up the link here:
http://www.joyofdata.de/blog/how-to-set-up-powerpivot-and-make-it-talk-to-mysql/
phpMyAdmin (version 3.4.0) can generate simple charts, see https://docs.phpmyadmin.net/en/latest/charts.html.

How do I set a date range variable dynamically and redraw a Google chart?

I am using PHP to set a date range for creating a Google Line Chart. For each date in the range a variable is set ($running_balance) to create the points on the line chart using data in a database. I would like to be able to set the variable $end, which essentially determines the date range, dynamically, but I am not sure how to do this so that the chart would be redrawn according to this new range. I am aware that I could create a new function that includes drawChart(); to redraw the chart, and I would be using three buttons to either set the date range to 1 year, 3 months, or 1 month, but I am not sure how to put all this together. Here is the code that I currently have:
$begin = new DateTime(date('Y-m-d', strtotime('+1 days')));
$end = new DateTime(date('Y-m-d', strtotime('+365 days')));
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($begin, $interval, $end);
foreach ( $period as $dt ) {
$date_display = $dt->format("D j M");
..... code to generate $running_balance .....
$temp = array();
$temp[] = array('v' => (string) $date_display);
$temp[] = array('v' => (string) $running_balance);
$temp[] = array('v' => (string) $running_balance);
$rows[] = array('c' => $temp);
}
$table['rows'] = $rows;
$jsonTable = json_encode($table);
<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);
var table = <?php echo $jsonTable; ?>;
function drawChart() {
var data = new google.visualization.DataTable(table);
// Create our data table out of JSON data loaded from server.
// var data = new google.visualization.DataTable(<?=$jsonTable?>);
var formatter = new google.visualization.NumberFormat({fractionDigits:2,prefix:'\u00A3'});
formatter.format(data, 1);
var options = {
pointSize: 5,
legend: 'none',
hAxis: { showTextEvery:31 },
series: {0:{color:'2E838F',lineWidth:2}},
chartArea: {left:50,width:"95%",height:"80%"},
backgroundColor: '#F7FBFC',
height: 400
};
// Instantiate and draw our chart, passing in some options.
//do not forget to check ur div ID
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
OK, if I'm understanding you correctly, you're having trouble conceiving and designing what parts of these actions are server-side (PHP) and what parts are client side (Javascript) and then the client-server communication strategy. This is a common speedbump. There's several ways to deal with it.
First (and less preferred) you could create a form and reload the whole page with the new date range:
// we're looking for '+1 year', '+3 months' or '+1 month'. if someone really
// wants to send another value here, it's not likely to be a security risk
// but know your own application and note that you might want to validate
$range = isset($_GET['range'])&&$_GET['range']?$_GET['range']:'+1 year';
$begin = new DateTime(date('Y-m-d', strtotime('+1 days')));
$end = new DateTime(date('Y-m-d', strtotime($range)));
// ... the rest of your code to build the chart.
?>
<form action="<?= $_SERVER['PHP_SELF']; ?>" method="get">
<select name="range" size="1">
<option value="+1 year">1 year</option>
<option value="+3 months">3 months</option>
<option value="+1 month">1 month</option>
</select>
<input type="submit" name="action" value="Redraw Chart">
</form>
... the reason that's the less preferred is because it causes a whole refresh of the page.
If you want to avoid a whole page refresh, you're doing pretty much the same thing, but do it with ajax. The setup is almost identical, just a couple minor changes:
// between building the data table and the javascript to build the chart...
$jsonTable = json_encode($table);
if (isset($_GET['ajax']) && $_GET['ajax']) {
echo json_encode(array('table' => $table));
exit;
}
// remainder of your code, then our new form from above
?>
<form id="redraw_chart_form" action="<?= $_SERVER['PHP_SELF']; ?>" data-ajaxaction="forecast.php" method="get">
<? foreach ($_GET as $key => $val) { ?>
<input type="hidden" name="<?= $key; ?>" value="<?= $val; ?>">
<? } ?>
<input type="hidden" name="ajax" id="redraw_chart_form_ajax" value="0">
<select name="range" size="1">
<option value="+1 year">1 year</option>
<option value="+3 months">3 months</option>
<option value="+1 month">1 month</option>
</select>
<input type="submit" name="action" value="Redraw Chart">
</form>
<script>
// I'm assuming you've got jQuery installed, if not there are
// endless tutorials on running your own ajax query
$('#redraw_chart_form').submit(function(event) {
event.preventDefault(); // this stops the form from processing normally
$('#redraw_chart_form_ajax').val(1);
$.ajax({
url: $(this).attr('data-ajaxaction'),
type: $(this).attr('method'),
data: $(this).serialize(),
complete: function() { $('#redraw_chart_form_ajax').val(0); },
success: function(data) {
// referring to the global table...
table = data.table;
drawChart();
},
error: function() {
// left as an exercise for the reader, if ajax
// fails, attempt to submit the form normally
// with a full page refresh.
}
});
return false; // if, for whatever reason, the preventDefault from above didn't prevent form processing, this will
});
</script>
Edit for clarity:
Don't forget to use the following block of code from the first (page refresh) example, otherwise you're not using the form at all:
$range = isset($_GET['range'])&&$_GET['range']?$_GET['range']:'+1 year';
$begin = new DateTime(date('Y-m-d', strtotime('+1 days')));
$end = new DateTime(date('Y-m-d', strtotime($range)));
Ajax will only work if the only data you're sending back is the json encoded block, which means your chart building data needs to be at the top of the script before any HTML output is started, including your page template. If you can't put the chart building code at the top of the script, then you'll have to add it to a whole separate script that all it does is calculate the data for the chart, and then you can have it return the ajax data without all of the other HTML on the page. If you can't do either of those things, you'll just have to turn off the Ajax bit and do a whole page refresh.
Edit 2: I added the data-ajaxaction attribute to the <form> element, this is a user defined attribute that I made up to provide a different action just for ajax. I also changed the $.ajax() call to use this attribute rather than the action attribute.

Using PHP with charts and MySQL data

I'm using google charts to output a very simple pie chart
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Games', 'Number'],
['Win', 11],
['Lose', 2]
]);
var options = {
title: 'Win/Lose Ratio'
};
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
However, in place of the values for Win and Lose, I want to pull 2 numbers out of my database. This doesn't need any kind of loop, just a way to reference 2 specific fields on a row instead of the values 11 and 2. This is the SQL query I'm using to get those two values
$qry =("SELECT games_won, games_lost FROM Members where member_id = '".$_SESSION['SESS_MEMBER_ID']."'");
$result = mysql_query($qry);
$row = mysql_fetch_array($result);
$won = $row[games_won];
$lost = $row[games_lost];
Does anyone know how to do this?
I've had a look at a lot of other FAQ's on the subject but they all deal with a collection of values in the same field and looping through severals rows of data, as opposed to referencing specific entries in the database.
Thanks in advance!
Have you tried this:
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Games', 'Number'],
['Win', <?php echo($won); ?>],
['Lose', <?php echo($lost); ?>]
]);
var options = {
title: 'Win/Lose Ratio'
};
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
All you are doing is grabbing the values, then echoing them out into your JavaScript. Please do note that I am not error checking, that is something you will need to think about when directly injecting values into HTML or JavaScript!
A better way of doing this is writing your code as a RESTful API. Have your SQL code in a place that you can send a member_id as a GET request. That, in turn, can print out the games won/lost inside JSON. Than, you can preform an AJAX request and grab those values to populate your table (just reference the values inside the returned JSON as regular JavaScript variables).

creating dynamic charts using google charts, mysql, and php

I need some help. I want to create a dynamic line chart using Google's chart api and data obtained via MySql. I'm using PHP to create the pages. I was able to create a simple chart with hard-coded values no problem. Now I am trying to use some MySql data instead, but with no luck. My webpage looks like this:
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart()
{
var jsonData = $.ajax({
url: "graphData.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 options = {'title':'Ticket Sales',
'width':500,
'height':400};
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(data,options);
}
</script>
<?
PrintHeader($buf,$username,$userid,$session);
echo("<div id='chart_div'></div>");
?>
</html>
Then my graphData.php page looks like this:
$sql = "SELECT MONTHNAME(DATE_SOLD), COUNT(*) FROM TICKET_SALES WHERE YEAR(DATE_SOLD) = 2012 GROUP BY MONTHNAME(DATE_SOLD) ORDER BY MONTH(DATE_SOLD);";
$result = mysql_query($sql, $conn) or die(mysql_error());
//start the json data in the format Google Chart js/API expects to recieve it
$JSONdata = "{
\"cols\": [
{\"label\":\"Month\",\"type\":\"string\"},
{\"label\":\"Ticket Sales\",\"type\":\"number\"}
],
\"rows\": [";
//loop through the db query result set and put into the chart cell values
while($row = mysql_fetch_row($result))
{
$JSONdata .= "{\"c\":[{\"v\": " . $row[0] . "}, {\"v\": " . $row[1] ."}]},";
}
//end the json data/object literal with the correct syntax
$JSONdata .= "]}";
echo $JSONdata;
?>
When I load the page in my browser I just get a red box that says "Table has no columns." Can anyone tell me what I am doing wrong? Or perhaps a better/easier method? Any help would be greatly appreciated!!
Do not construct the JSON data that way, create a PHP array and use json_encode() to send the data back.
<?php
$sql = "SELECT MONTHNAME(DATE_SOLD), COUNT(*) FROM TICKET_SALES WHERE YEAR(DATE_SOLD) = 2012 GROUP BY MONTHNAME(DATE_SOLD) ORDER BY MONTH(DATE_SOLD);";
$result = mysql_query($sql, $conn) or die(mysql_error());
//start the json data in the format Google Chart js/API expects to recieve it
$data = array('cols' => array(array('label' => 'Month', 'type' => 'string'),
array('label' => 'Ticket Sales', 'type' => 'string')),
'rows' => array());
while($row = mysql_fetch_row($result)) {
$data['rows'][] = array('c' => array(array('v' => $row[0]), array('v' => $row[1])));
}
echo json_encode($data);
I have not checked the JSON output is what is wanted, only made it the same as what you were trying to generate. Also, you should get the die() to return an invalid state in a JSON object, so you can tell it failed.
Yes, use the json_encode function. It will save you lots of headaches. I'd also make sure you run your numbers through an intval() or something.
My experience with the Google charts API is that if you send a number in quotes, the chart will fail to draw, so the data types in your PHP array must be correct so the json_encode result is correct in syntax.

Google Area Chart

Im trying to using Google Area Chart and PHP to display some data. problem is i just cant get it to work. if anyone can help it will be most appriciated.
Here is my code:
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Date');
data.addColumn('number', 'hits');
data.addRows([
<?php
$query = mysql_query("SELECT * FROM hits WHERE url='$url' GROUP BY date");
while ($row = mysql_fetch_array($query)){
$hits=mysql_num_rows($query);
$date=$row['date'];?>
['<?php echo "$date";?>', <?php echo ".$hits.";?>],
<?php } ?>
]);
var chart = new google.visualization.AreaChart(document.getElementById('chart_div'));
chart.draw(data, {width: 400, height: 240, title: 'Company Performance',
hAxis: {title: 'Date', titleTextStyle: {color: '#FF0000'}}
});
}
</script>
<div id="chart_div"></div>
I would definitely suggest separating your PHP (server side) code from your JavaScript/html (client side) code.
The nice thing about the Google chart and graph APIs is there are several examples one can draw from, but it becomes much harder to reproduce something you're viewing when you embed PHP with MySQL queries within the blocks that contain your JavaScript and UI elements.
The following is a rough example of how you "might" go about dividing these things. In reality you would want your server side code (PHP in your case) in a totally separate file from your display/user interface code (HTML and JavaScript).
The 'DATE' and 'HITS' in the "Front end code" block are not actually variables or values, I'm simply indicating this is where you would input your values. Ideally you would pass the data from your MySQL query through the PHP server code to the JavaScript code, and then iterate through it there to build your graph. The passing things back and forth from PHP to JS can be done nicely using the JSON data interchange format. Both PHP and JavaScript (jQuery) have functions for encoding and decoding to/from JSON.
Front End Code:
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Date');
data.addColumn('number', 'hits');
data.addRows(
['DATE', 'HITS']
);
var chart = new google.visualization.AreaChart(document.getElementById('chart_div'));
chart.draw(data, {width: 400, height: 240, title: 'Company Performance',
hAxis: {title: 'Date', titleTextStyle: {color: '#FF0000'}}
});
}
</script>
<div id="chart_div"></div>
Back End Code:
<?php
$query = mysql_query("SELECT * FROM hits WHERE url='$url' GROUP BY date");
$data_to_return = array();
while ($row = mysql_fetch_array($query))
{
$hits=mysql_num_rows($query);
$date=$row['date'];
$data_to_return[$date] = $hits; //building array of date=>hits data
}
$data_to_send_to_front_end = json_encode($data_to_return); //ridiculous variable name
?>

Categories