ajax/json 和 PHP 的 Highcharts 数据系列问题
Posted
技术标签:
【中文标题】ajax/json 和 PHP 的 Highcharts 数据系列问题【英文标题】:Highcharts data series issue with ajax/json and PHP 【发布时间】:2011-12-24 21:08:21 【问题描述】:这是我在这里的第一个请求,我已经阅读了许多关于同一问题的其他相关帖子,但我仍然陷入困境,对此我几乎束手无策......所以任何帮助都很大感激不尽!
我在 Page1.php 上有以下 Highcharts 对象,我正在使用 AJAX 在页面加载以及下拉选项更改时从 Page2.php 获取数据。
(为便于阅读而截断):
$(document).ready(function()
var e = document.getElementById("selOption"); //<--- This is the dropdown
var domText = e.options[0].text;
var domID = e.options[e.selectedIndex].value;
var options =
chart:
renderTo: 'linechart',
type: 'line'
,
title:
text: 'Title for ' + domText
,
subtitle:
text: ''
,
xAxis:
type: 'datetime',
dateTimeLabelFormats:
month: '%b %e, %Y',
year: '%Y'
,
yAxis:
title:
text: 'Important Values'
,
reversed: true,
min: 0,
max: 100
,
tooltip:
formatter: function()
return '<b>'+ this.series.name +'</b><br/>'+
Highcharts.dateFormat('%b %e', this.x) +': '+ this.y;
,
series: []
;
$.get('Page2.php?domID=' + domID,function(data)
$.each(data, function(key,value)
//var series = ;
//series.name.push(value);
//series.data.push([value]);
options.series.push(data);
//alert(data);
);
var linechart = new Highcharts.Chart(options);
);
);
Page2.php 有以下发回的 json:
$sqlSelect = "SELECT Item1,Item2,Item3 FROM... ";
$result = mysql_query($sqlSelect);
while ($item = mysql_fetch_assoc($result))
$name = $item['Item1'];
$date = str_replace("-",",",$item['Item2']);
$pos = $item['Item3'];
$arr = array("name"=>$name,"data"=>"[Date.UTC(".$date."), ".$pos." ],");
echo json_encode($arr);
我的 json 返回如下所示:
"name":"Item1","data":"[Date.UTC(2011,11,08), 4 ],"
"name":"Item1","data":"[Date.UTC(2011,11,08), 2 ],"
当我的图表加载时,它会在底部填充 135 个系列名称 (?!?!?!),并且似乎没有显示折线图上的点。
如果我删除双引号并将结果硬编码到系列数组中,效果很好(尽管我注意到该示例似乎在对象之间没有逗号。
感谢您的所有帮助...尤其是快速回复! ;-)
【问题讨论】:
我发现我的 $.each 部分正在创建 135 个左右的“系列”,因为我的响应字符串中有很多字符。所以不知何故 $.each 正在为字符串中的每个字符创建一个新的数据对象。我应该以某种方式解析 JSON 吗?我已经准备好用 PHP 格式化我的输出并将其放入会话变量中! 【参考方案1】:已解决:
我找到了一个终于奏效的答案!令人沮丧的是,我花了好几天的时间,因为 Highcharts 没有很好地记录它(和/或者我对 jQuert 和 javascript 的理解仍然处于新手级别)。
答案是不要将 X/Y 数据作为预先形成的数组发送到您的 json 对象中,而只是发送构成日期的数字(x value) 和 Value(y 值) 作为 json 对象中的逗号分隔值列表,然后在客户端进行解析和推送。
例如:我最初是想让我的 PHP 发送类似
的东西["name":"Name 1","data":["[Date.UTC(2011,11,08), 4 ]","[Date.UTC(2011,11,09), 4 ]","[Date.UTC(2011,11,10), 4 ]","[Date.UTC(2011,11,11), 4 ]","[Date.UTC(2011,11,14), 3 ]"]
但我真正需要做的是发送类似的东西
["name":"Name 1","data":["2011,11,08, 4","2011,11,09,4"....`
第一步是确保您将“系列”选项设置为空数组series: []
(我之所以提到这一点,是因为我看到其他答案的做法不同)。
然后在您的 getJSON 函数中,您需要为要拉入的每个对象创建一个新对象,其中还包括一个空的“数据”数组(请参阅下面的“var 系列”)。
然后嵌套几个$.each
循环来解析数据并将其推送到所需的数组中,并填充每个对象的“名称”:
$.getJSON('http://exmaple.com/getdata.php?ID=' + id, function(data)
$.each(data, function(key,value)
var series = data: [];
$.each(value, function(key,val)
if (key == 'name')
series.name = val;
else
$.each(val, function(key,val)
var d = val.split(",");
var x = Date.UTC(d[0],d[1],d[2]);
series.data.push([x,d[3]]);
);
);
options.series.push(series);
);
在上面的代码之后,需要实例化图表:
var chart = new Highcharts.Chart(options);
应该就是这样!
希望其他人发现这个答案很有用,并且不需要为了弄清楚这个问题而绞尽脑汁几天。 :-)
【讨论】:
【参考方案2】:由于 Javascript UTC 方法将返回一个整数,因此最好在服务器端生成 JSON 时将 Unix 时间戳作为整数传递,而不是尝试在 JSON 中传递函数 (UTC.Date) - 这会使整个 JSON 无效!
所以
不是这个
while ($item = mysql_fetch_assoc($result))
$name = $item['Item1'];
$date = str_replace("-",",",$item['Item2']);
$pos = $item['Item3'];
$arr = array("name"=>$name,"data"=>"[Date.UTC(".$date."), ".$pos." ],");
echo json_encode($arr);
这样做:
while ($item = mysql_fetch_assoc($result))
$name = $item['Item1'];
$unix_date = date("Y-m-d", strtotime($item['Item2']));
$pos = $item['Item3'];
$arr = array("name"=>$name,"data"=>"[".($unix_date*1000).", ".$pos." ],");
echo json_encode($arr);
请注意,我们将 PHP Unix 时间戳乘以 1000 以使其与 JS 兼容。
参考:http://www.w3schools.com/jsref/jsref_utc.asp
【讨论】:
【参考方案3】:刚刚检查了一些 Highcharts 的示例代码,series
需要是一个 JSON 对象数组,每个对象都包含 "name":"Item1","data":"[Date.UTC(2011,11,08), 4 ],"
等。
主要问题是您从 page2 输出的不是数组。
你需要先修复你的 $.each,你需要推送value
,而不是data
:
$.each(data, function(key,value)
options.series.push(value);
);
这将正确地将系列中的每个项目设置为完整的 json 对象。
然后修复输出:
$output = [];
while ($item = mysql_fetch_assoc($result))
$name = $item['Item1'];
$date = str_replace("-",",",$item['Item2']);
$pos = $item['Item3'];
//I don't think there's supposed to be a comma after this square bracket
$arr = array("name"=>$name,"data"=>"[Date.UTC(".$date."), ".$pos." ]");
array_push($output, json_encode($arr));
echo "[";
foreach($output as $val)
echo $val;
if($val != end($output)) echo ",";
echo "]";
应该这样做。
【讨论】:
谢谢,生病了...你和我都想出了类似的解决方案,但我现在得到的是显示名称的图表的结果,而不是数据。 @sicks... 问题是每个“名称”在数组中都有多个数据集,其中包含 x/y 坐标的日期和数字。这是我的新 JSON:["name":"Name 1","data":["[Date.UTC(2011,11,08), 4 ]","[Date.UTC(2011,11,09), 4 ]","[Date.UTC(2011,11,10), 4 ]","[Date.UTC(2011,11,11), 4 ]","[Date.UTC(2011,11,14), 3 ]"],"name":"Name 2","data":["[Date.UTC(2011,11,08), 2 ]","[Date.UTC(2011,11,09), 2 ]","[Date.UTC(2011,11,10), 2 ]","[Date.UTC(2011,11,11), 2 ]","[Date.UTC(2011,11,14), 2 ]"]]
在图表中,我得到了不同颜色的名称,但图表中没有绘制数据。
很高兴你想出来了,我尽力了!
没关系...感谢您抽出宝贵时间查看文档以帮助我解决问题。这不容易!【参考方案4】:
在 PHP5.5 中检查
您可以简单地将其添加到带有数据系列的 json 中
$date = '31-12-2015 00:00:00';
$datetimeUTC = (strtotime($date) * 1000);
$data[] = [$datetimeUTC, (float) $value];
【讨论】:
【参考方案5】:我遇到了发送由 mktime() 生成的时间戳的问题,因为 highcharts 需要 UTC 时间,而 PHP 时间戳不是 UTC。数据可能在图表中显示错误的日期,因此您还必须考虑时区。
function _convertToUTC($timeStamp)
return (int)$timeStamp + (int)date('Z', $timeStamp);
代码示例如下:
$serie = array(
'name' => 'title',
'data' => array(
// multiply timestamp by 1000 to get milliseconds
array(_convertToUTC(mktime(0,0,0,1,1,2016)) * 1000, 15),
array(_convertToUTC(mktime(0,0,0,2,1,2016)) * 1000, 18),
array(_convertToUTC(mktime(0,0,0,3,1,2016)) * 1000, 13),
),
);
echo json_encode($serie);
【讨论】:
以上是关于ajax/json 和 PHP 的 Highcharts 数据系列问题的主要内容,如果未能解决你的问题,请参考以下文章
PHP、MySQL、jQuery、AJAX:json 数据返回正确响应但前端返回错误