【问题标题】:Formatting PHP/MySQL data in correct JSON format for HighCharts为 HighCharts 以正确的 JSON 格式格式化 PHP/MySQL 数据
【发布时间】:2013-02-02 12:31:00
【问题描述】:

几天来,我一直在努力将一些数据组织成适当的 JSON 格式,以便将其绘制在 HighCharts 图表中。

我的计划是执行一个 jQuery 函数来调用一个 PHP 脚本,该脚本从 MySQL 数据库中提取几列天气数据。我可以在 JavaScript 端重新组织数据,但更愿意在 PHP 中完成所有数据组织,然后将一个正确的 JSON 结构输入到 HighCharts 引擎中。

我正在查看天气数据,因此我每分钟都会对几列数据进行采样。我从 MySQL 检索的数据列是:JSTimestamp(这是一个 unix 时间戳 * 1000 用于 JavaScript)、avgOutdoorTemperature、avgIndoorTemperature、avgOutdoorHumidity、avgIndoorHumidity。我已将这些列中的每一列填充到它们自己的数组中。

我似乎无法理解将数据处理为以下 JSON/数组格式所需的 PHP 逻辑:

[
  [
    [JSTimestamp1, avgOutdoorTemperature1],
    [JSTimestamp2, avgOutdoorTemperature2],
    [JSTimestamp3, avgOutdoorTemperature3],
    [JSTimestampN, avgOutdoorTemperatureN]
  ],
  [
    [JSTimestamp1, avgIndoorTemperature1],
    [JSTimestamp2, avgIndoorTemperature2],
    [JSTimestamp3, avgIndoorTemperature3],
    [JSTimestampN, avgIndoorTemperatureN]
  ],
  [
    [JSTimestamp1, avgOutdoorHumidity1],
    [JSTimestamp2, avgOutdoorHumidity2],
    [JSTimestamp3, avgOutdoorHumidity3],
    [JSTimestampN, avgOutdoorHumidityN]
  ],
  [
    [JSTimestamp1, avgIndoorHumidity1],
    [JSTimestamp2, avgIndoorHumidity2],
    [JSTimestamp3, avgIndoorHumidity3],
    [JSTimestampN, avgIndoorHumidityN]
  ]
]

我已经用虚拟数据填充了上述结构,它在 HighCharts 中绘制得很漂亮。这是一个示例演示,展示了图表的外观:http://highcharts.com/jsbin/afutef/11/edit#javascript,live

我当前的代码是:

<?php

include_once('./include/mysqldatabase.php');
include_once('./include/mysqlresultset.php');

date_default_timezone_set('America/New_York');

$MYSQL_HOST = 'ip_address';
$MYSQL_USER = 'username';
$MYSQL_PASS = 'password';
$MYSQL_NAME = 'weatherdata';

$db = MySqlDatabase::getInstance();
try {
    $conn = $db->connect($MYSQL_HOST, $MYSQL_USER, $MYSQL_PASS, $MYSQL_NAME);
}
catch (Exception $e) {
    die($e->getMessage());
}

$query = "
    select
        RecDate,
        unix_timestamp(RecDateTime)*1000 as JSTime,
        avgOutdoorTemperature,
        avgIndoorTemperature,
        avgOutdoorHumidity,
        avgIndoorHumidity
    from `rollup-minute-60`
    where 
        RecDate > 201301010000
    ";

$timeArray = array();
$avgOutdoorTemperatureArray = array();
$avgIndoorTemperatureArray = array();
$combinedArray = array();
$i = 0;

$seriesNames = array('Average Outdoor Temperature','Average Indoor Temperature', 'Average Outdoor Humidity', 'Average Indoor Humidity');

foreach ($db->iterate($query) as $r) {
    $jstime = $r->JSTime;
    $avgOutdoorTemperature = $r->avgOutdoorTemperature;
    $avgIndoorTemperature = $r->avgIndoorTemperature;
    $avgOutdoorHumidity = $r->avgOutdoorHumidity;
    $avgIndoorHumidity = $r->avgIndoorHumidity;

    $timeArray[$i] = (float)$jstime;
    $avgOutdoorTemperatureArray[$i] = (float)$avgOutdoorTemperature;
    $avgIndoorTemperatureArray[$i] = (float)$avgIndoorTemperature;
    $avgOutdoorHumidityArray[$i] = (float)$avgOutdoorHumidity;
    $avgIndoorHumidityArray[$i] = (float)$avgIndoorHumidity;    

    $combinedArray[$i] = array((float)$avgOutdoorTemperature, (float)$avgIndoorTemperature, (float)$avgOutdoorHumidity, (float)$avgIndoorHumidity);

    $i++;
}

echo "Combined array:<br>";
echo json_encode($combinedArray);
echo "<br><br><br>";

echo "Time array:<br>";
echo json_encode($timeArray);
echo "<br><br><br>";

$arraySize = sizeof($timeArray);
$seriesNameSize = sizeof($seriesNames);
$outputJSONArray = array();
$tempArray = array();

for ($i=0; $i<$seriesNameSize; $i++) {

    for ($j=0; $j<$arraySize; $j++) {
        $tempArray = array();

        array_push($tempArray, $timeArray[$j], $combinedArray[$j][$i]);
        echo "i=".$i.", j=".$j.", tempArray: " . json_encode($tempArray) ."<br>";

        $outputJSONArray[$i] = $tempArray;

     } 
}

echo json_encode($outputJSONArray);

?>

使用上面的当前代码,我的输出数组只显示 $outputJSONArray 中的最后一个元素,而不是多维构造。

谁能帮我指出正确的方向?我在这个网站上找到了很多很好的信息来帮助我开始,但需要一些帮助来克服最后的障碍。

谢谢!

【问题讨论】:

  • 这只是一种预感,但我认为 json_encode 只有在键为字符串时才能正常工作。试试: $outputJSONArray[(string)$i] = $tempArray;

标签: php mysql json highcharts


【解决方案1】:

查看 Highcharts 常见问题解答:http://docs.highcharts.com/#preprocessing-data-from-a-database 第二个例子告诉你如何做到这一点:

<?php
while ($row = mysql_fetch_array($result)) {
   extract $row;
   $datetime *= 1000; // convert from Unix timestamp to JavaScript time
   $data[] = "[$datetime, $value]";
}
?>
var chart = new Highcharts.Chart({
      chart: {
         renderTo: 'container'
      },
      series: [{
         data: [<?php echo join($data, ',') ?>]
      }]
});

【讨论】:

    【解决方案2】:

    感谢 Paweł 的回复。我一直在使用您发布的示例,并且对单个时间序列有很好的理解。然而,我对多个系列的正确格式感到困惑。

    我在 PHP 端处理数据以获取正确格式的数据时遇到了困难:

    [
      [
        [time1, y1],
        [time2, y2],
        [time3, y3]
      ]
      [
        [time1, z1],
        [time2, z2],
        [time3, z3]
      ]
      [
        ...
      ]
    ]
    

    但是,在今天早些时候玩了一些东西并最终在白板上画出了一个解决方案后,我发现了一个似乎可行的解决方案,并要求我为每个系列遍历收集的数据数组一次。它可能不是最佳的,但对于我测试它的几千个点来说效果很好。这是我的参考代码:

    $seriesNames = array('Average Outdoor Temperature','Average Indoor Temperature');
    
    foreach ($db->iterate($query) as $r) {
        $time = (float)$r->RecDateTime;
        $jstime = (float)($r->Timestamp*1000);
        $avgOutdoorTemperature = (float)$r->avgOutdoorTemperature;
        $avgIndoorTemperature = (float)$r->avgIndoorTemperature;
    
        $dataArray[] = array(array($jstime, $avgOutdoorTemperature), array($jstime, $avgIndoorTemperature));
    }
    
    $arraySize = sizeof($dataArray);
    $seriesNameSize = sizeof($seriesNames);
    
    for ($i=0; $i<$seriesNameSize; $i++) {
        $tempArray = array();
            for ($j=0; $j<$arraySize; $j++) {
                $tempArray[] = $dataArray[$j][$i];  
            } 
        $outputJSONArray[] = $tempArray;
    }
    
    echo json_encode($outputJSONArray);
    

    我想我可以执行多个查询并手动添加每个系列,但我最终打算使用的查询相当密集,我宁愿只调用一次。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-10
      • 1970-01-01
      • 2015-08-06
      • 2018-05-09
      • 1970-01-01
      • 2015-12-18
      • 2023-04-04
      • 1970-01-01
      相关资源
      最近更新 更多