簡體   English   中英

創建完整的Google Chart JSON數據表-從MySQL數據-使用自定義PHP函數-提供的工作示例-我需要這樣做嗎?

[英]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個真正的原因-

  • 我在Java語言上還很新
  • JSON_ENCODE(php函數)似乎產生了日期值所需的錯誤格式。
    • 輸出日期(和日期時間)為:“ 2013-01-01 01:00:00”
    • Google的文檔似乎要求:“ Date(2013,1,1,0,0,0)”
  • 而且JSON_Encode不會為所需的列生成輸出-包括根據MySQL結果數據類型分配數據類型。

題:

在日期格式和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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM