Highcharts异步服务器加载多个系列

Posted

技术标签:

【中文标题】Highcharts异步服务器加载多个系列【英文标题】:Highcharts async Server Loading with multiple series 【发布时间】:2014-02-03 21:13:42 【问题描述】:

我正在尝试按照其示例使用 Highcharts 的延迟加载

http://www.highcharts.com/stock/demo/lazy-loading

和他们的php代码

https://github.com/highslide-software/highcharts.com/blob/master/samples/data/from-sql.php

但我唯一得到的是一个空白图表,其中包含 2011 年的 2 天(示例数据)。 我的php代码:

<?php


// get the parameters

$callback = $_GET['callback'];
if (!preg_match('/^[a-zA-Z0-9_]+$/', $callback)) 
        die('Invalid callback name');


$start = $_GET['start'];
if ($start && !preg_match('/^[0-9]+$/', $start)) 
        die("Invalid start parameter: $start");


$end = $_GET['end'];
if ($end && !preg_match('/^[0-9]+$/', $end)) 
        die("Invalid end parameter: $end");

if (!$end) $end = mktime() * 1000;



// connect to mysql
$link = mysqli_connect('localhost:3306', 'root', 'elektra','telegestione');
// set UTC+1 time
//mysql_query("SET time_zone = '+01:00'");

// set some utility variables
$range = $end - $start;
//$startTime = gmstrftime('%Y-%m-%d %H:%M:%S', $start / 1000);
$startTime= date('Y-m-d H:i:s', strtotime(gmstrftime('%Y-%m-%d %H:%M:%S', $start / 1000) . ' - 1 day'));
//$endTime = gmstrftime('%Y-%m-%d %H:%M:%S', $end / 1000);
$endTime= date('Y-m-d H:i:s', strtotime(gmstrftime('%Y-%m-%d %H:%M:%S', $end / 1000) . ' + 0 day'));

// find the right table
// two days range loads minute data
if ($range < 2 * 24 * 3600 * 1000) 
        if (!$link)     
                        die('Could not connect: ' . mysqli_error());;  
                        echo "minute data2" ;
            $result = mysqli_query($link,"select 1000*unix_timestamp(q1.time) as time, q1.kwhg, q1.kwhc, q1.kwhi, q1.kwhfm, q2.test from (
SELECT
      (t1.dt) AS time,(case
     when t1.value>t2.value AND t2.value>0
          then abs(t1.value - t2.value)
     when t1.value>t2.value AND t2.value=0
          then t2.value
          else t1.value END)kwhg, 
     (case
     when t1.value1>t2.value1 AND t2.value1>0
          then abs(t1.value1 - t2.value1)
     when t1.value1>t2.value1 AND t2.value1=0
          then t2.value1
     when t1.value1=t2.value1 AND t1.value1>0 
        then abs(t1.value1 - t2.value1)
      else 0 END) kwhc, 
      (case
     when t1.value2>t2.value2 AND t2.value2>0
          then abs(t1.value2 - t2.value2)
     when t1.value2>t2.value2 AND t2.value2=0
          then t2.value2
     when t1.value2=t2.value2 AND t1.value2>0 
        then abs(t1.value2 - t2.value2)
      else 0 END)kwhi,
    (case
     when t1.value3>t2.value3 AND t2.value3>0
          then abs(t1.value3 - t2.value3)
     when t1.value3>t2.value3 AND t2.value3=0
          then t2.value3
     when t1.value3=t2.value3 AND t1.value3>0 
        then abs(t1.value3 - t2.value3)
      else 0 END) kwhfm
    FROM 
        (SELECT (dataora) dt, MAX(kwhg) value, MAX(kwhc) value1, MAX(kwhi) value2, MAX(kwhfm) value3  FROM misure where dataora between '$startTime' and '$endTime' GROUP BY date(dt),hour(dt)) t1
        JOIN
        (SELECT (dataora) dt, MAX(kwhg) value, MAX(kwhc) value1, MAX(kwhi) value2, MAX(kwhfm) value3  FROM misure where dataora between '$startTime' and '$endTime' GROUP BY date(dt),hour(dt)) t2
        on t1.dt = t2.dt + interval 15 minute) as q1
JOIN
    (select dataora, AVG(Test) as test from temperature where dataora between '$startTime' and '$endTime' GROUP BY date(dataora),hour(dataora))  as q2
    ON q1.time=q2.dataora");

 //one week range loads hourly data
 elseif ($range < 7 * 24 * 3600 * 1000) 
        if (!$link)     
            die('Could not connect: ' . mysqli_error());;  
            echo "hourly data1" ;
    $result = mysqli_query($link,"select 1000*unix_timestamp(q1.time) as time, q1.kwhg, q1.kwhc, q1.kwhi, q1.kwhfm, q2.test from (
SELECT
      (t1.dt) AS time,(case
     when t1.value>t2.value AND t2.value>0
          then abs(t1.value - t2.value)
     when t1.value>t2.value AND t2.value=0
          then t2.value
          else t1.value END)kwhg, 
     (case
     when t1.value1>t2.value1 AND t2.value1>0
          then abs(t1.value1 - t2.value1)
     when t1.value1>t2.value1 AND t2.value1=0
          then t2.value1
     when t1.value1=t2.value1 AND t1.value1>0 
        then abs(t1.value1 - t2.value1)
      else 0 END) kwhc, 
      (case
     when t1.value2>t2.value2 AND t2.value2>0
          then abs(t1.value2 - t2.value2)
     when t1.value2>t2.value2 AND t2.value2=0
          then t2.value2
     when t1.value2=t2.value2 AND t1.value2>0 
        then abs(t1.value2 - t2.value2)
      else 0 END)kwhi,
    (case
     when t1.value3>t2.value3 AND t2.value3>0
          then abs(t1.value3 - t2.value3)
     when t1.value3>t2.value3 AND t2.value3=0
          then t2.value3
     when t1.value3=t2.value3 AND t1.value3>0 
        then abs(t1.value3 - t2.value3)
      else 0 END) kwhfm
    FROM 
        (SELECT (dataora) dt, MAX(kwhg) value, MAX(kwhc) value1, MAX(kwhi) value2, MAX(kwhfm) value3  FROM misure where dataora between '$startTime' and '$endTime' GROUP BY date(dt),hour(dt)) t1
        JOIN
        (SELECT (dataora) dt, MAX(kwhg) value, MAX(kwhc) value1, MAX(kwhi) value2, MAX(kwhfm) value3  FROM misure where dataora between '$startTime' and '$endTime' GROUP BY date(dt),hour(dt)) t2
        on t1.dt = t2.dt + interval 1 hour) as q1
JOIN
    (select dataora, AVG(Test) as test from temperature where dataora between '$startTime' and '$endTime' GROUP BY date(dataora),hour(dataora))  as q2
    ON q1.time=q2.dataora");

// one month range loads hourly data
 elseif ($range < 31 * 24 * 3600 * 1000) 
        if (!$link)     
            die('Could not connect: ' . mysqli_error());;  
            echo "hourly data2" ;
    $result = mysqli_query($link,"select 1000*unix_timestamp(q1.time) as time, q1.kwhg, q1.kwhc, q1.kwhi, q1.kwhfm, q2.test from (
SELECT
      (t1.dt) AS time,(case
     when t1.value>t2.value AND t2.value>0
          then abs(t1.value - t2.value)
     when t1.value>t2.value AND t2.value=0
          then t2.value
          else t1.value END)kwhg, 
     (case
     when t1.value1>t2.value1 AND t2.value1>0
          then abs(t1.value1 - t2.value1)
     when t1.value1>t2.value1 AND t2.value1=0
          then t2.value1
     when t1.value1=t2.value1 AND t1.value1>0 
        then abs(t1.value1 - t2.value1)
      else 0 END) kwhc, 
      (case
     when t1.value2>t2.value2 AND t2.value2>0
          then abs(t1.value2 - t2.value2)
     when t1.value2>t2.value2 AND t2.value2=0
          then t2.value2
     when t1.value2=t2.value2 AND t1.value2>0 
        then abs(t1.value2 - t2.value2)
      else 0 END)kwhi,
    (case
     when t1.value3>t2.value3 AND t2.value3>0
          then abs(t1.value3 - t2.value3)
     when t1.value3>t2.value3 AND t2.value3=0
          then t2.value3
     when t1.value3=t2.value3 AND t1.value3>0 
        then abs(t1.value3 - t2.value3)
      else 0 END) kwhfm
    FROM 
        (SELECT (dataora) dt, MAX(kwhg) value, MAX(kwhc) value1, MAX(kwhi) value2, MAX(kwhfm) value3  FROM misure where dataora between '$startTime' and '$endTime' GROUP BY date(dt),hour(dt)) t1
        JOIN
        (SELECT (dataora) dt, MAX(kwhg) value, MAX(kwhc) value1, MAX(kwhi) value2, MAX(kwhfm) value3  FROM misure where dataora between '$startTime' and '$endTime' GROUP BY date(dt),hour(dt)) t2
        on t1.dt = t2.dt + interval 1 hour) as q1
JOIN
    (select dataora, AVG(Test) as test from temperature where dataora between '$startTime' and '$endTime' GROUP BY date(dataora),hour(dataora))  as q2
    ON q1.time=q2.dataora");

// one year range loads daily data
 elseif ($range < 15 * 31 * 24 * 3600 * 1000) 
        if (!$link)     
            die('Could not connect: ' . mysqli_error());;  
            echo "daily data2" ;
    $result = mysqli_query($link,"select 1000*unix_timestamp(q1.time) as time, q1.kwhg, q1.kwhc, q1.kwhi, q1.kwhfm, q2.test from (
SELECT
      (t1.dt) AS time,(case
     when t1.value>t2.value AND t2.value>0
          then abs(t1.value - t2.value)
     when t1.value>t2.value AND t2.value=0
          then t2.value
          else t1.value END)kwhg, 
     (case
     when t1.value1>t2.value1 AND t2.value1>0
          then abs(t1.value1 - t2.value1)
     when t1.value1>t2.value1 AND t2.value1=0
          then t2.value1
     when t1.value1=t2.value1 AND t1.value1>0 
        then abs(t1.value1 - t2.value1)
      else 0 END) kwhc, 
      (case
     when t1.value2>t2.value2 AND t2.value2>0
          then abs(t1.value2 - t2.value2)
     when t1.value2>t2.value2 AND t2.value2=0
          then t2.value2
     when t1.value2=t2.value2 AND t1.value2>0 
        then abs(t1.value2 - t2.value2)
      else 0 END)kwhi,
    (case
     when t1.value3>t2.value3 AND t2.value3>0
          then abs(t1.value3 - t2.value3)
     when t1.value3>t2.value3 AND t2.value3=0
          then t2.value3
     when t1.value3=t2.value3 AND t1.value3>0 
        then abs(t1.value3 - t2.value3)
      else 0 END) kwhfm
    FROM 
        (SELECT (dataora) dt, MAX(kwhg) value, MAX(kwhc) value1, MAX(kwhi) value2, MAX(kwhfm) value3  FROM misure where dataora between '$startTime' and '$endTime' GROUP BY date(dt)) t1
        JOIN
        (SELECT (dataora) dt, MAX(kwhg) value, MAX(kwhc) value1, MAX(kwhi) value2, MAX(kwhfm) value3  FROM misure where dataora between '$startTime' and '$endTime' GROUP BY date(dt)) t2
        on t1.dt = t2.dt + interval 1 day) as q1
JOIN
    (select dataora, AVG(Test) as test from temperature where dataora between '$startTime' and '$endTime' GROUP BY date(dataora))  as q2
    ON q1.time=q2.dataora");

// greater range loads monthly data
 else 
        if (!$link)     
            die('Could not connect: ' . mysqli_error());;
                echo "monthly data2" ;
    $result = mysqli_query($link,"select 1000*unix_timestamp(q1.time) as time, q1.kwhg, q1.kwhc, q1.kwhi, q1.kwhfm, q2.test from (
SELECT
      (t1.dt) AS time,(case
     when t1.value>t2.value AND t2.value>0
          then abs(t1.value - t2.value)
     when t1.value>t2.value AND t2.value=0
          then t2.value
          else t1.value END)kwhg, 
     (case
     when t1.value1>t2.value1 AND t2.value1>0
          then abs(t1.value1 - t2.value1)
     when t1.value1>t2.value1 AND t2.value1=0
          then t2.value1
     when t1.value1=t2.value1 AND t1.value1>0 
        then abs(t1.value1 - t2.value1)
      else 0 END) kwhc, 
      (case
     when t1.value2>t2.value2 AND t2.value2>0
          then abs(t1.value2 - t2.value2)
     when t1.value2>t2.value2 AND t2.value2=0
          then t2.value2
     when t1.value2=t2.value2 AND t1.value2>0 
        then abs(t1.value2 - t2.value2)
      else 0 END)kwhi,
    (case
     when t1.value3>t2.value3 AND t2.value3>0
          then abs(t1.value3 - t2.value3)
     when t1.value3>t2.value3 AND t2.value3=0
          then t2.value3
     when t1.value3=t2.value3 AND t1.value3>0 
        then abs(t1.value3 - t2.value3)
      else 0 END) kwhfm
    FROM 
        (SELECT (dataora) dt, MAX(kwhg) value, MAX(kwhc) value1, MAX(kwhi) value2, MAX(kwhfm) value3  FROM misure where dataora between '$startTime' and '$endTime' GROUP BY date(dt),hour(dt)) t1
        JOIN
        (SELECT (dataora) dt, MAX(kwhg) value, MAX(kwhc) value1, MAX(kwhi) value2, MAX(kwhfm) value3  FROM misure where dataora between '$startTime' and '$endTime' GROUP BY date(dt),hour(dt)) t2
        on t1.dt = t2.dt + interval 1 month) as q1
JOIN
    (select dataora, AVG(Test) as test from temperature where dataora between '$startTime' and '$endTime' GROUP BY date(dataora),hour(dataora))  as q2
    ON q1.time=q2.dataora");
;

$rows = array();
while ($row = mysqli_fetch_assoc($result)) 
        //echo $a= "hello";
        extract($row);

        $rows[] = "[$time,$test,$kwhg,$kwhc,$kwhi,$kwhfm]";
                                            

// print it
header('Content-Type: text/javascript');
//echo $range;
//echo $startTime;
//echo $end;
echo "/* console.log(' range = $range, start = $start, end = $end, startTime = $startTime, endTime = $endTime '); */";
echo $callback ."([\n" . join(",\n", $rows) ."\n]);";

?>

如演示所示,highcharts 的输出数据应该是正确的,但我无法初始化图表或显示任何系列...

$(function() 

    // See source code from the JSONP handler at https://github.com/highslide-software/highcharts.com/blob/master/samples/data/from-sql.php
    $.getJSON('grafico_nuovo.php?callback=?', function(data) 

        // Add a null value for the end date 
        data = [].concat(data, [[Date.GMT(2013, 9, 14, 19, 59), null, null, null, null]]);

        // create the chart
        $('#container').highcharts('StockChart', 
            chart : 
                type: 'spline',
                zoomType: 'xy'
            ,

            navigator : 
                adaptToUpdatedData: false,
                series : 
                    data : data
                
            ,

            scrollbar: 
                liveRedraw: false
            ,

            title: 
                text: 'AAPL history by the minute from 1998 to 2011'
            ,

            subtitle: 
                text: 'Displaying 1.7 million data points in Highcharts Stock by async server loading'
            ,

            rangeSelector : 
                buttons: [
                    type: 'hour',
                    count: 1,
                    text: '1h'
                , 
                    type: 'day',
                    count: 1,
                    text: '1d'
                , 
                    type: 'month',
                    count: 1,
                    text: '1m'
                , 
                    type: 'year',
                    count: 1,
                    text: '1y'
                , 
                    type: 'all',
                    text: 'All'
                ],
                inputEnabled: true, // it supports only days
                selected : 2 // day
            ,

            xAxis : 
                events : 
                    afterSetExtremes : afterSetExtremes
                ,
                minRange: 3600 * 1000 // one hour
            ,

            series : [
                data : data,
                dataGrouping: 
                    enabled: false
                
            ]
        );
    );
);


/**
 * Load new data depending on the selected min and max
 */
function afterSetExtremes(e) 

    var currentExtremes = this.getExtremes(),
        range = e.max - e.min,
        chart = $('#container').highcharts();

    chart.showLoading('Loading data from server...');
    $.getJSON('grafico_nuovo.php?start='+ Math.round(e.min) +
            '&end='+ Math.round(e.max) +'&callback=?', function(data) 

        chart.series[0].setData(data[0]);
        chart.hideLoading();
    );


感谢任何帮助或建议 乔治

【问题讨论】:

【参考方案1】:

$callback ."([\n" . join(",\n", $rows) ."\n]);"; 返回什么回声?我建议通过 json_encode() 将您的数组转换为 json,然后在 javascript 中使用。

编辑:

您无法访问脚本中的图表,而且您只能在现有系列上使用 setData,而不能在不存在的系列上使用,例如 chart.series[2]。你应该打电话给addSeries

 val1 = [];
    val2 = [];
    val3 = [];
    val4 = [];
    val5 = [];
    $.each(data, function (key, value) 
        val1.push([value[0], value[1]]);
        val2.push([value[0], value[2]]);
        val3.push([value[0], value[3]]);
        val4.push([value[0], value[4]]);
        val5.push([value[0], value[5]]);
    );
chart.series[0].setData(val1);
    chart.addSeries(
        data: val2
    );

    chart.addSeries(
        data: val3
    );

    chart.addSeries(
        data: val4
    );

    chart.addSeries(
        data: val5
    );



    chart.hideLoading();

http://jsfiddle.net/4knAX/2/

【讨论】:

这是回调的返回: /* console.log(' start = 1318621440000, end = 1318625040000, startTime = 2011-10-14 19:44:00, endTime = 2011-10- 14 20:44:00'); */jQuery18208912840717552396_1389783951004([ ]);在 highcharts 示例中,此回调有效,在我的情况下...不! :( 我会尝试在 json 中编码所有内容,我希望这可能会有所帮助,谢谢 这是现在回调的返回:daily data2/* console.log(' range = 2680999000, start = 1383264000000, end = 1385944999000, startTime = 2013-10-31 00:00:00,结束时间 = 2013-12-02 00:43:19 '); * / jQuery18208912840717552396_1380585600([1383260585600([1383260400,14.45208,32.50,7.40,1.80,18.10],[1383346800,14.49792,28.00,4.00,2.10,17.90],[1383433200,16.25417,7.80,3.90,2.00,17.40],[1383519600] [1383519600],[1383519600], 14.10208,64.90,10.20,20.90,27.10],[1383606000,14.67083,62.60,8.20,20.60,28.70],等等……]); 现在它可以工作了,但我只得到一个空白图表,因为日期被固定在 1970 年......我无法通过范围选择器或数据选择器更改它,它们不起作用跨度> 您需要将时间戳乘以 1000,因为它是 unix 时间戳。 是的,现在它可以工作了,导航器显示了第一组数据,但图表中显示了任何内容......但我越来越近了

以上是关于Highcharts异步服务器加载多个系列的主要内容,如果未能解决你的问题,请参考以下文章

highcharts error #16

Highcharts 跳过大型数据集的共享工具提示点

Highcharts:使用 JSON 数据创建多个系列

在循环中在 Highcharts 中创建多个系列

Highcharts:使用 JSON 数据创建多个系列,将我的月份和年份分组

在 x 轴和图例中显示 HighCharts 系列名称