简体   繁体   English

在使用Ajax的Flot图上行不前进

[英]Lines do not progress on Flot graph using Ajax

I want to do a line graph with live data pulled from Ajax. 我想用从Ajax提取的实时数据制作线形图。 On the Y axis is float data with one digit after the decimal point. Y轴上是浮点数据,小数点后一位。 On the X axis is a formatted timestamp, preferably "%H:%M:%S. 在X轴上是格式化的时间戳,最好是“%H:%M:%S”。

The following non-Ajax example works fine: 以下非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>

Next, a modified version using Ajax which does not work. 接下来,使用Ajax的修改版本不起作用。 Note that the labels are user-defined and the total number of datasets is variable. 请注意,标签是用户定义的,数据集的总数是可变的。 There will be only one point per dataset. 每个数据集将只有一个点。 There is no JavaScript error displayed in the Error Console, there is nothing displayed on the graph and in Firebug I can see the data was fetched once (but only once, with the setInterval I was expecting once every 3 seconds). 在错误控制台中没有显示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>

Sample datasets received: 收到的样本数据集:

    [
    {
        "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]]
    }
    ]

Thank you very much for any assistance, I already spent a frustrating day on this. 非常感谢您的协助,我已经为此度过了令人沮丧的一天。

Best regards, Bertrand 此致Bertrand

First , any code you expect to execute after the ajax call completes must be in the success handler. 首先 ,您希望在ajax调用完成后执行的任何代码都必须在成功处理程序中。 Remember the ajax call is async , so: 记住ajax调用是async ,所以:

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

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

You need to do something like this: 您需要执行以下操作:

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

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

Second , you shouldn't mix a setInterval with an AJAX calls. 其次 ,您不应将setInterval与AJAX调用混合使用。 Since you don't know when the async call will complete, the timing can not be guaranteed and you'll wind up with multiple AJAX calls happening at once. 由于您不知道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
}

Here's an example fixing it all up. 这是修复所有问题的示例

Thank you, your explanations were helpful but your example did not work. 谢谢,您的解释很有帮助,但您的示例没有用。 I could see the Ajax calls were working in Firebug, but the graph simply displayed one set of points and that was it. 我可以看到Ajax调用正在Firebug中运行,但是图形仅显示了一组点,仅此而已。

As soon as I made the array variable data global, it started working. 一旦使数组变量数据成为全局数据,它便开始工作。 The points started accumulating, however no lines and no time shown under the X axis. 点开始累积,但是X轴下没有线,也没有显示时间。 I researched a bit and multiplied the Linux UTC timestamp sent by 1000 to change microsecond to JavaScript millisecond. 我研究了一下,然后将发送的Linux UTC时间戳乘以1000,以将微秒更改为JavaScript毫秒。

It still is not working right yet: 它仍然无法正常工作:

1) There are no lines between the points; 1)点之间没有线; 2) The legend keeps getting repeated; 2)传奇不断重复; 3) The graph should keep moving left instead of bunching up, for example there should be only have 10 points shown per series at a time and the points belonging to the earliest timestamp removed every Ajax call iteration. 3)该图应保持向左移动而不是聚束,例如,每个系列一次只能显示10个点,并且在每个Ajax调用迭代中都删除了属于最早时间戳的点。

I'm pretty sure this will be useful to others, so here is the complete modified listing that sort of works. 我很确定这对其他人将很有用,因此这是经过修改的完整列表,可以正常工作。 Any additional help will be greatly appreciated. 任何其他帮助将不胜感激。

    <!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>

The JSON data received now looks like this: 现在收到的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]]
    }
    ]

Best regards and thanks again! 最好的问候,并再次感谢! Bertrand 贝特朗

Resolved. 解决。

Mark's answer was correct. 马克的回答是正确的。 What needed to be modified was the back end. 需要修改的是后端。

Instead of returning one point per series, it keeps in memory the last n points and returns n points at a time. 它没有在每个系列中返回一个点,而是将最后n个点保留在内存中,并一次返回n个点。

The JSON can be stored in a session variable. JSON可以存储在会话变量中。 To clear the graph, unset the session variable. 要清除图形,请取消设置会话变量。

To add points to a series, justn some quick string parsing does the trick: 要将点添加到序列中,只需进行一些快速的字符串解析即可:

(PHP code) /* concatenate a complete $item prior here in case this series does not exist yet */ (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'];

Hope this helps someone else. 希望这对其他人有帮助。

Thanks Mark! 谢谢马克!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM