JQuery FLOT 图表动态 Y 轴

9
我有一个flot图表,它基于最后100个数据点计算最大Y轴值,然后成功绘制......但是,有时正在运行的图表(每5秒延迟一个新数据点)的累加总数超过了当前的最大限制。是否有一种方法可以在绘制图表上的新点时动态缩放Y轴比例尺?
这是一个关于如何在当前Y轴被超过时动态调整图表Y轴比例尺的有效问题,由于图表随时间绘制并且每5秒添加一个新点,因此我想知道如何调整Y轴以适应新的绘图数据,如果它达到了当前的最大Y轴值以上。
更新:以下是我使用的代码(返回Json数据)以及绘图更新定时器: "highY"从数据库中获取最后100个数据点,并将最大值设置为最高计数+ 10%。
        <script type="text/javascript">
            $(function () {
                var str1 = [], totalPoints = 300;
                var str2 = [], totalPoints = 300;
                var pts1 = '';
                var pts2 = '';
                if (pts1 == "" || pts == null) { pts = '2012-10-02 17:17:02'; }
                if (pts2 == "" || pts == null) { pts = '2012-10-02 17:17:02'; }
                var maxYaxis = <?PHP echo $highY; ?>;
                function getStr1() {
                    var ts1 = new Date().getTime();
                    var json1 = (function () {
                        var json1 = null;
                        var myURL = '<?PHP echo $updateURL; ?>?s=1&ts=' + ts1;
                        $.ajax({
                            'async': false,
                            'global': false,
                            'url': myURL,
                            'dataType': "json",
                            'success': function (data) {
                                json1 = data;
                            }
                        });
                        return json1;
                    })(); 
                    var y1 = json1['data']['avgpersec'];
                    var total_1 = json1['data']['running_total'];
                    document.getElementById('<?PHP echo $string1; ?>Total').innerHTML = total_1;
                    if (str1.length > 0) { str1 = str1.slice(1); }

                    while (str1.length < totalPoints) {
                        var prev = str1.length > 0 ? str1[str1.length - 1] : 50;
                        str1.push(y1);
                    }

                    // zip the generated y values with the x values
                    var res = [];
                    for (var i = 0; i < str1.length; ++i){ res.push([i, str1[i]]) }
                    return res;
                }

                function getStr2() {
                    var ts2 = new Date().getTime();
                    var json2 = (function () {
                        var json2 = null;
                        var myURL = '<?PHP echo $updateURL; ?>?s=2&ts=' + ts2;
                        $.ajax({
                            'async': false,
                            'global': false,
                            'url': myURL,
                            'dataType': "json",
                            'success': function (data) {
                                json2 = data;
                            }
                        });
                        return json2;
                    })(); 
                    var y2 = json2['data']['avgpersec'];
                    var total_2 = json2['data']['running_total'];
                    document.getElementById('<?PHP echo $string2; ?>Total').innerHTML = total_2;
                    if (str2.length > 0) { str2 = str2.slice(1); }

                    while (str2.length < totalPoints) {
                        var prev = str2.length > 0 ? str2[str2.length - 1] : 50;
                        str2.push(y2);
                    }

                    // zip the generated y values with the x values
                    var res = [];
                    for (var i = 0; i < str2.length; ++i){ res.push([i, str2[i]]) }
                    return res;
                }

                // setup control widget
                var updateInterval = 5000;
                $("#updateInterval").val(updateInterval).change(function () {
                    var v = $(this).val();
                    if (v && !isNaN(+v)) {
                        updateInterval = +v;
                    if (updateInterval < 1)
                        updateInterval = 1;
                    if (updateInterval > 2000)
                        updateInterval = 2000;
                        $(this).val("" + updateInterval);
                    }
                });

                // setup plot
                var options = {
                    series: { shadowSize: 0 }, // drawing is faster without shadows
                    yaxis: { min: 0, max: maxYaxis},
                    xaxis: { show: false },
                    colors: ["<?PHP echo $string1Color; ?>","<?PHP echo $string2Color; ?>"]
                };
                var plot = $.plot($("#placeholder"), [ getStr1(), getStr2() ], options);

                function update() {
                    plot.setData([ getStr1(), getStr2() ]);
                    plot.draw();
                    setTimeout(update, updateInterval);
                }

                update();
            });
        </script>

我希望能够实时调整"$highY"(Y轴)值,以便在绘制新数据点时自适应图表,如果新数据绘图点的值超过了当前图表选项中设置的"yaxis {max: #}"。请注意保留HTML标记。

展示你接受新数据并重新绘制的代码会很有帮助(特别是你如何处理y轴最大值)。 - Ryley
1个回答

8
我假设您现在正在使用flot.setDataflot.draw?最简单的解决方案就是每次收到新数据时调用$.plot。在不同的情况下,flot插件的作者都建议这种方法作为处理此情况的一种相当有效的方式。我已经在每秒刷新的图表上使用了这个方法,并发现即使在一个页面上有3-4个图表每秒刷新,它也不会在用户的计算机上使用过多的CPU。根据您添加的代码(和您提出的编辑),我会将更新函数更改为以下内容:
function update() {
   var data = [ getStr1(), getStr2() ];

   //modify options to set the y max to the new y max
   options.yaxis.max = maxYaxis;
   $.plot($("#placeholder"), data, options);
   setTimeout(update, updateInterval);
}

此外,您需要在getStrgetStr中添加代码来保持maxYaxis变量的最新状态。

感谢您的反馈。这正是我已经在使用的,我遇到的问题是如何调整y轴的值,使其成为更高的数字,如果我的新绘图点超过了当前y轴最大值(而不重新加载页面,因为那样会清除数据集)。 - Silvertiger
我以为我已经尝试过了,但由于在绘制y轴的过程中选项没有被重新定义,所以它不会自动调整到新的更高值。我将尝试在实际绘图之前在update()函数下重新定义选项,并查看是否可以以这种方式工作。 - Silvertiger
好的,你的绘图语句和我的更新选项解决了问题。我更改了getStr1()和getStr2()函数以检查平均值是否高于最初设置的“maxYaxis”,然后更新变量值为新的最大值,并在update函数中重新定义选项,然后就可以工作了。我将更新问题和你的答案以包含我的更新。 - Silvertiger
你能帮我一下吗?http://stackoverflow.com/questions/23181653/jquery-flot-draws-points-in-200-thought-it-says-the-value-is-100 - user3432257
不必重新初始化您的图表,您可以尝试使用flot.setupGrid()flot.setDataflot.draw结合使用。这样可以在不进行完整初始化的情况下更改轴上的最大值。 - CaptainBli

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接