Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JQuery FLOT chart dynamic Y-axis

I have a flot chart that calculates the max Y-axis value based on the last 100 data points and then plots successfully... BUT Sometimes, the running total of an ongoing plot (5 second delay with new data point plotted) exceeds the current max limit. Is there a way to have the Y-axis scale dynamically while plotting new points on the chart?

This is a valid question about how to dynamically scale the Y Axis of the chart if the current Y-axis is exceeded, since the chart is plotted over time with new points being added every 5 seconds, I was asking how to scale the Y-Axis to fit the NEW plot data if it reaches above the current Max Y Axis value..

UPDATE:

here is the code I use (Json returned data) as well as the plot update timer: The "highY" takes the last 100 datapoints from a database and sets the max value to the highest count + 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>

What i am hoping to accomplish is to adjust the "$highY" (Y-axis) value real time as i plot new data points so that the chart will scale if the value of the new data plot point exceeds the current "yaxis { max: # }" set in the chart options.

like image 755
Silvertiger Avatar asked Oct 23 '12 04:10

Silvertiger


1 Answers

I'm assuming that right now you're using flot.setData and flot.draw?

The simplest solution is just to call $.plot with the new data each time you receive it. At various times, this has been recommended by the authors of the flot plugin as a reasonably efficient way of dealing with this situation. I've used this on graphs that refresh every second and found that it does not use an excessive amount of CPU on the user's computer, even with 3-4 graphs refreshing every second on one page.

EDIT based on the code you added (and your suggested edit), I would change the update function to look like this:

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);
}

Additionally, you would add code to getStr and getStr that keep the maxYaxis variable up to date.

like image 73
Ryley Avatar answered Sep 30 '22 20:09

Ryley