使用 Ajax 的 Flot 图上的线条不前进

Lines do not progress on Flot graph using Ajax

我想用从 Ajax 中提取的实时数据做一个折线图。 Y轴是小数点后一位的浮点数据。 X轴上是格式化的时间戳,最好是“%H:%M:%S.

以下非 Ajax 示例工作正常:

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <script src="js/jquery.js"></script>
        <script src="js/jquery.flot.js"></script>
        <script src="js/jquery.flot.time.js"></script>
    </head>
    <body>
        <div id="legendcontainer" style="width: 1000px;position:"></div>
        <div id="placeholder" style="width:1000px;height:400px;"></div>
        <div id="legend" style="width:600px;height:300px;"> </div>
        <script type="text/javascript">
            var DataSet1 = [ [1341354816000, 1.1], [ 1341358185000, 2.2] , [ 1341361620000, 3.3] ];  
            var DataSet2 =[[1341354816000, 5.1], [ 1341358185000, 6.2] , [ 1341361620000, 7.3] ]

            var datasets =
            {
                "DataSet1" :{ label : "DataSet1", data: DataSet1 }, 
                "DataSet2" :{ label: "DataSet2", data: DataSet2 }
            };

            var firstTime =true;
            function plotByChoice(doAll)
            {    
                data = [];
                if (doAll != null)
                {
                    $.each(datasets, function(key, val) 
                    {
                        data.push(val);
                    });
                }   
                else
                {
                    $('#legend .legendCB').each(
                        function(){


                            if (this.checked)
                            {         

                                 data.push(datasets[this.id]);
                            }
                            else
                            {
                                 data.push({label: this.id, data: []})
                            }        
                        }
                    );
                }        

                $.plot($("#placeholder"),data, { series: 
                        {
                            lines: 
                            {
                                show: true,
                            },
                            points: 
                            {
                                show: true
                            }
                        },
                        xaxis: {mode: "time" }, 
                        yaxis: { tickDecimals: 1 },
                        yaxes: [ { min: 0 }, 
                        {
                          alignTicksWithAxis: "right",
                          position: "right",
                          min :-25,
                          max:50                          
                        } ]
            });        
        }

        plotByChoice(this);   
      </script>
    </body>
    </html>

接下来,使用 Ajax 的修改版本不起作用。请注意,标签是用户定义的,数据集的总数是可变的。每个数据集只有一个点。错误控制台中没有显示 JavaScript 错误,图表上没有显示任何内容,在 Firebug 中我可以看到数据被提取了一次(但只有一次,我期望的 setInterval 每隔3 秒)。

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
     <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <script src="js/jquery.js"></script>
        <script src="js/jquery.flot.js"></script>
        <script src="js/jquery.flot.time.js"></script>
    </head>
    <body>
        <div id="legendcontainer" style="width: 1000px;position:"></div>
        <div id="placeholder" style="width:1000px;height:400px;"></div>
        <div id="legend" style="width:600px;height:300px;"> </div>
        <script type="text/javascript">
            var datasets = {};  
            var firstTime =true;
            function plotByChoice(doAll)
            {       
                $.ajax({
                url: "graphlist.php",
                method: 'GET',
                dataType: 'text',
                success: function (data) {
                    datasets = $.parseJSON(data);}
                }); 

                data = [];
                if (doAll != null)
                {
                    $.each(datasets, function(key, val) 
                    {
                        data.push(val);
                    });
                }   
                else
                {
                    $('#legend .legendCB').each(
                        function(){

                            if (this.checked)
                            {                                   
                                 data.push(datasets[this.id]);
                            }
                            else
                            {
                                 data.push({label: this.id, data: []})
                            }        
                        }
                    );
                }        

                $.plot($("#placeholder"),data, { series: 
                        {
                            lines: 
                            {
                                show: true,
                            },
                            points: 
                            {
                                show: true
                            }
                        },
                        xaxis: {mode: "time" }, 
                        yaxis: { tickDecimals: 1 },
                        yaxes: [ { min: 0 }, 
                        {
                          alignTicksWithAxis: "right",
                          position: "right",
                          min :-25,
                          max:50                          
                        } ]
            });        
        }

        setInterval(plotByChoice(this), 3000);
      </script>
    </body>
    </html>

收到的样本数据集:

    [
    {
        "label": "s#2 ch#1 (ch un)",    "data": [[1422263853,22.7]]
    }
    ,
    {
        "label": "s#2 ch#2 (2_ch2)",    "data": [[1422263853,21.9]]
    }
    ,
    {
        "label": "s#2 ch#3 (N/A)",  "data": [[1422263853,21.7]]
    }
    ]

非常感谢您的帮助,我已经为此度过了令人沮丧的一天。

此致, 伯特兰

首先,您希望在 ajax 调用完成后执行的任何代码 必须 在成功处理程序中。记住 ajax 调用是 async,所以:

...
success: function (data) {
    datasets = $.parseJSON(data);
  }
}); 

// This part executes before the AJAX call completes
data = [];
if (doAll != null)
....

你需要做这样的事情:

success: function(data) {
    datasets = $.parseJSON(data);
    drawPlot(datasets);
  }
});

function drawPlot(datasets){
  data = [];
  if (doAll != null) {
... 

Second,您不应将 setInterval 与 AJAX 调用混用。由于您不知道 async 调用何时完成,因此无法保证时间,您最终会同时发生多个 AJAX 调用。

// again this is called in the success handler
function drawPlot(datasets){
...
  setTimeout(function(){
    plotByChoice(true)
  }, 3000); //<-- ajax success is done, now wait 3 seconds and call again
}

这里 an example 全部修复。

谢谢,您的解释很有帮助,但您的示例不起作用。我可以看到 Ajax 调用在 Firebug 中工作,但图表仅显示一组点,仅此而已。

我将数组变量数据设为全局后,它就开始工作了。点数开始累积,但是 X 轴下没有线条和时间显示。我研究了一下,将发送的 Linux UTC 时间戳乘以 1000,将微秒更改为 JavaScript 毫秒。

它仍然不能正常工作:

1) 点与点之间没有线; 2)传说不断重复; 3) 图表应该继续向左移动而不是聚在一起,例如每个系列一次应该只显示 10 个点,并且属于最早时间戳的点在每次 Ajax 调用迭代时删除。

我很确定这对其他人有用,所以这里是完整的修改后的列表,可以正常工作。任何额外的帮助将不胜感激。

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <script data-require="jquery@1.11.0" data-semver="1.11.0" src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
        <script src="http://www.flotcharts.org/flot/jquery.flot.js"></script>
        <script src="http://www.flotcharts.org/flot/jquery.flot.time.js"></script>
    </head>
    <body>
        <div id="legendcontainer" style="width: 1000px;position:"></div>
        <div id="placeholder" style="width:1000px;height:400px;"></div>
        <div id="legend" style="width:600px;height:300px;"></div>
        <script type="text/javascript">
            var datasets = {};
            var firstTime = true;
            var data = [];

            function plotByChoice(doAll) 
            {
              $.ajax({
                url: "graphlist.php",
                method: 'GET',
                dataType: 'text',
                success: function(data) 
                {
                  datasets = $.parseJSON(data);
                  drawPlot(datasets);
                }
              });

              function drawPlot(datasets)
              {
                if (doAll != null) 
                {
                  $.each(datasets, function(key, val) 
                  {
                    data.push(val);
                  });
                } 
                else 
                {
                  $('#legend .legendCB').each(
                    function() 
                    {     
                      if (this.checked) 
                      {
                        data.push(datasets[this.id]);
                      } 
                      else 
                      {
                        data.push({
                          label: this.id,
                          data: []
                        })
                      }
                    }
                  );
                }

                $.plot($("#placeholder"), data, {
                  series: {
                    lines: {
                      show: true
                    },
                    points: {
                      show: true
                    }
                  },
                  xaxis: {
                    mode: "time", minTickSize: [1, "second"], timeformat: "%H:%M:%S"
                  },
                  yaxis: {
                    tickDecimals: 1
                  },
                  yaxes: [{
                    min: 0
                  }, {
                    alignTicksWithAxis: "right",
                    position: "right",
                    min: -25,
                    max: 50
                  }]
                });
              }

              setTimeout(function()
              {
                  plotByChoice(true)
              }, 3000);
            }

            plotByChoice(this);
        </script>
    </body>
    </html>

现在收到的 JSON 数据如下所示:

    [
    {
        "label": "s#2 ch#1 (ch un)",    "data": [[1422349909000,22.8]]
    }
    ,
    {
        "label": "s#2 ch#2 (2_ch2)",    "data": [[1422349909000,22.1]]
    }
    ,
    {
        "label": "s#2 ch#3 (N/A)",  "data": [[1422349909000,22.1]]
    }
    ]

再次致以最诚挚的问候和感谢! 伯特兰

已解决。

马克的回答是正确的。需要修改的是后端。

它不会在每个系列中返回一个点,而是在内存中一次保留最后 n 个点和 returns n 个点。

JSON 可以存储在会话变量中。要清除图形,请取消设置会话变量。

要为系列添加点,只需进行一些快速字符串解析即可:

(PHP 代码) /* 在此之前连接一个完整的 $item 以防该系列尚不存在 */

    $mycharray = explode("\n", $_SESSION['JSON_STRUCTURE']);

    $_SESSION['JSON_STRUCTURE'] = "";

    $found = 0;
    $num = count($mycharray);

    for ($loop = 0; $loop < $num; ++$loop) 
    {
        $mycharray[$loop] .= "\n";                      

        if(InStr($mycharray[$loop], $mylabel) == -1)
        {
            $_SESSION['JSON_STRUCTURE'] .= $mycharray[$loop];
        }
        else
        {
            $found = 1;
            // str_replace ( mixed $search , mixed $replace , mixed $subject)
            $new = str_replace( "]\n", ",[" . $date . "," . $mytemperature . "]]\n", $mycharray[$loop]);
            $_SESSION['JSON_STRUCTURE'] .= $new;
        } 
    } 

    if($found == 0)
    {
        $_SESSION['JSON_STRUCTURE'] .= $item;
    }

    echo $_SESSION['JSON_STRUCTURE'];

希望这对其他人有帮助。

谢谢马克!