[英]Create Complete Google Chart JSON Data Table - From MySQL Data - Using custom PHP Function - Provided Working Example - Did I need to do this?
我正在一個個人項目上-使用php從MySQL獲取數據,然后將其編碼為JSON格式(包括列),然后再通過Ajax將其加載到google數據表中以進行可視化。
項目進展順利,但我通過php中的純字符串操作完成了JSON編碼。 只需一條SQL和php函數即可為圖表創建多個數據源。
我覺得我需要這個的原因是1個不好的原因,以及2個真正的原因-
題:
在日期格式和JSON列輸出的上下文中(包括基於結果的數據類型)-我能比純字符串操作更輕松地解決這些問題嗎?
我在下面張貼了我的代碼-雖然很丑陋-但它的工作就像一種魅力。 如果出於某種原因我確實做了一些好事,歡迎社區使用它。
它是3個php文件(盡管最后一個可能是html),第一個文件只是填充了要在第二頁中使用的自定義函數。
第二個php文件以JSON / GoogleChart格式從My_SQL(回顯DATA;)中轉儲數據。
最后一個文件/頁面使用ajax從第二頁獲取數據,並將其插入帶注釋的時間軸中。 jQuery設置在第三頁上,MySQL連接在第一頁上,您的SQL在第二頁上。
<?php
// First Page/File: mysql_gc_functions.php
function mysql_loadresult($sql, $type){
// $sql - a string containing SQL to run against database
// $type - 0 for standard array load, 1 for JSON formatted string
$debug = false;
$result = mysql_query($sql) or die(mysql_error());
$numfields = mysql_num_fields($result);
$numrows = mysql_num_rows($result);
$br = '</br>';
$arr; // Array to Load Data Into where first index will contain headers
// Where x is the column and y is the row
// Row '0' contains Header Names
$datatypes; // Array to Load in Data Types
// Standard Array Loading
// Load Field Names
for ($x=0; $x < $numfields; $x++){
$arr[$x][0] = mysql_field_name($result,$x);
$datatypes[$x] = mysql_field_type($result,$x);
if($debug == true){echo 'data type for ' . $arr[$x][0] . ': ' . $datatypes[$x] . '</br>';}
}
$y = 0; // Row Index
while ($data = mysql_fetch_array($result, MYSQL_NUM)) {// For Each Row
$y++;
for ($x=0; $x<$numfields; $x++){ // For Each Field
$arr[$x][$y] = $data[$x]; // Load Query into php array
}
}
// JSON formatted string
if ($type == 1) {
/* JSON Format Example
{
"cols": [
{"label":"Topping","type":"string"},
{"label":"Slices","type":"number"}
],
"rows": [
{"c":[{"v":"Mushrooms"},{"v":3},
{"c":[{"v":"Onions"},{"v":1}]},
{"c":[{"v":"Olives"},{"v":1}]},
{"c":[{"v":"Zucchini"},{"v":1}]},
{"c":[{"v":"Pepperoni"},{"v":2}]}
]
}
mysql data type / google field type / Json value example:
date: date: "Date(2012,12,1)"
datetime: datetime: "Date(2012,12,1,23,59,59)" <- Y,M,D,H,M,S - can do milliseconds as well (but not built)
number: int/real: 123456
everything else: string: "EXAMPLE TEXT"
*/
$sColJason = '{"cols":[';
$eColJason = '],';
$ColExprS = '{"label":"';
$ColExprE = '","type":"XXX"}';
$colbuild = '';
// Build Column Structure for JSON
for ($x=0;$x<$numfields;$x++){
if ($datatypes[$x] == 'date'){
$tvar = str_replace('XXX', 'date', $ColExprE);
} else if ($datatypes[$x] == 'int' OR $datatypes[$x] == 'real'){
$tvar = str_replace('XXX','number',$ColExprE);
} else if ($datatypes[$x] == 'datetime'){
$tvar = str_replace('XXX','datetime',$ColExprE);
} else {
$tvar = str_replace('XXX','string',$ColExprE);
}
$str = $ColExprS . $arr[$x][0] . $tvar;
if ($x != ($numfields - 1)){
$str = $str . ",";
}
$colbuild = $colbuild . $str;
}
if($debug == true){echo $sColJason . $colbuild . $eColJason . '</br>';}
$sRowJason = '"rows": [';
$eRowJason = ']}';
$RowExpr = '{"v":"XXX"}';
$RowStart = '{"c":[';
$RowEnd = ']}';
$RowBuild = '';
// Build Row Structure for JSON
for ($y = 1; $y<$numrows;$y++){
// build each column of row (field of record)
$RowFieldBuild = '';
for ($x=0;$x<$numfields;$x++){
$var = $arr[$x][$y];
// assess how the data type needs to be treated
if ($datatypes[$x] == 'date'){
$var = mysql_googledate($var);
} else if ($datatypes[$x] == 'int' OR $datatypes[$x] == 'real'){
$var = $var;
} else if ($datatypes[$x] == 'datetime') {
$var = mysql_googleDtTm($var);
} else {
$var = '"' . $var . '"';
}
// concatenate the row string with populated values
$RowFieldBuild = $RowFieldBuild . str_replace('"XXX"',$var,$RowExpr);
if ($x != ($numfields-1)){
$RowFieldBuild = $RowFieldBuild . ',';
}
}
// Encapsulate the Record
$RowBuild = $RowBuild . $RowStart . $RowFieldBuild . $RowEnd;
if($y != ($numrows-1)){
$RowBuild = $RowBuild . ',';
}
}
// Encapsulate Entire Row Data
$RowBuild = $sRowJason . $RowBuild . $eRowJason;
if($debug == true){echo $RowBuild . '</br>';}
return ($sColJason . $colbuild . $eColJason . $RowBuild);
} else { // Return Standard Array of Table Data
return $arr;
}
}
function mysql_googledate($var){
$arr = preg_split("/-/",$var);
$month = intval($arr[1]);
$newStr = '"Date(' . $arr[0] . ',' . $month . ',' . $arr[2] . ')"';
return $newStr;
}
function mysql_googleDtTm($var){
$arr = preg_split("/-/",$var);
$tmArr = preg_split("/:/",$arr[2]);
$cm = ',';
$yr = intval($arr[0]);
$mon = intval($arr[1]);
$day = intval(substr($arr[2],0,2));
$hr = intval(substr($tmArr[0],-2));
$min = intval($tmArr[1]);
$sec = intval($tmArr[2]);
$newStr = '"Date(' . $yr . $cm . $mon . $cm . $day . $cm . $hr . $cm . $min . $cm . $sec . ')"';
return $newStr;
}
function mysql_localcon(){
$con = mysql_connect("localhost","root","1234");
if (!$con) {
die('Could not connect: ' . mysql_error());
}
return $con;
}
?>
<?php
// Second Page/File: data_ATL.php
Include('mysql_gc_functions.php');
$sql = 'SELECT DATE_FIELD, VALUE_FIELD FROM DATABASE.TABLE';
$con=mysql_localcon();
$dataJason = mysql_loadresult($sql, 1);
echo $dataJason;
?>
// THIS IS THE FINAL (3rd) OUTPUT FILE/PAGE - DISPLAYS ANNOTATED TIME LINE
<html>
<head>
<script type='text/javascript' src='http://www.google.com/jsapi'></script>
<script type="text/javascript" src="jquery.js"></script>
<script type='text/javascript'>
google.load('visualization', '1', {'packages':['annotatedtimeline']});
google.setOnLoadCallback(drawChart);
function drawChart() {
var jsonData = $.ajax({
url: "data_ATL.php",
dataType:"json",
async: false
}).responseText;
var data = new google.visualization.DataTable(jsonData);
var chart = new google.visualization.AnnotatedTimeLine(document.getElementById('chart_div'));
chart.draw(data,
{
displayAnnotations: true,
annotationsWidth: 20,
scaleType: 'maximized'
}
);
}
</script>
</head>
<body>
<div id='chart_div' style='width: 700px; height: 240px;'></div>
</body>
</html>
我最近完成了完全相同的任務,並且能夠創建一個函數,該函數根據MySQL查詢返回的任何數據生成Google數據表。 我僅使用json_encode()構造了JSON有效負載-無需特殊的字符串操作。 注意,我使用的是mysqli而不是mysql,因此以下某些內容可能與mysql略有不同。
以下是一些不太明顯的方面:
為了確定Google DataTable列的“類型”,我使用了mysqli_fetch_fields()返回的數組的“類型”值(http://php.net/manual/en/mysqli-result.fetch-fields.php) 。 然后,我編寫了一個小函數,將這種mysqli類型與Google的DataTable API的等效函數進行匹配。 因此,例如,如果mysqli_fetch_fields()返回了:
[0] => stdClass Object ( [name] => Date [orgname] => date [table] => c [orgtable] => users [def] => [db] => main [catalog] => def [max_length] => 10 [length] => 10 [charsetnr] => 63 [flags] => 20617 [type] => 10 [decimals] => 0 )
您可以看到類型值為10,它對應於MYSQLI_TYPE_DATE 。 可以在這里找到類型常量的完整列表: http : //php.net/manual/en/mysqli.constants.php
日期類型確實需要進行一些操作,因為JSON不支持Javascript Date對象(但是您指出的Google的API確實支持“ Date(Y,m,d,[h,i,s])”)。要注意的一件事是MySQL日期的month參數應該減少1,因為Javascript Date對象從Month 0開始。要提取日期,我使用了以下方法:
$mysql_date = explode("-", $row[$i]); $mysql_date[1] = $mysql_date[1] - 1; if ($mysql_date[1] < 0) $mysql_date[1] = 11; $mysql_date = implode(",", $mysql_date); $value = "Date(" . $mysql_date . ")"; array_push($c, array("v" => $value));
preg_split可以正常工作,但請注意,它速度較慢(如果數據集非常大,這只是一個問題)。 此處的更多信息: http : //micro-optimization.com/explode-vs-preg_split
到目前為止,唯一的字符串操作是用於處理日期,其他所有內容都存儲在PHP數組中。 收集完所有數據后,可以調用json_encode()。 問題在於,對於定義為Google Table的“數字”的列,json_encode()傾向於返回用雙引號引起來的數字。 為了強制如此對待數字,我使用了一個簡單的正則表達式:
$json = json_encode($j); $json = preg_replace('/"(-?\\d+\\.?\\d*)"/', '$1', $json);
希望這可以幫助!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.