Search code examples
javascriptjquerychartsflot

Issues with JQuery Flot when activating the threshold


I'm trying to make a plot for a project requiring a threshold and tracking.

So I follow these examples as a reference

  1. http://flotcharts.org/flot/examples/tracking/index.html
  2. http://flotcharts.org/flot/examples/threshold/index.html

without the threshold, the plot with tracking working perfectly without-threshold

but when activated the threshold, the tracking didn't work on the 3rd & 4th line, just work on the first 2 lines, everything else didn't work without-threshold

here is my code,

    <script src="../../plugins/flot/jquery.flot.min.js" type="text/javascript"></script>
    <!-- FLOT RESIZE PLUGIN - allows the chart to redraw when the window is resized -->
    <script src="../../plugins/flot/jquery.flot.resize.min.js" type="text/javascript"></script>
     <!-- FLOT crosshair PLUGIN - allows the chart to be tracking -->
    <script src="../../plugins/flot/jquery.flot.crosshair.min.js" type="text/javascript"></script>
    <script src="../../plugins/flot/jquery.flot.threshold.min.js" type="text/javascript"></script>
    <script src="../../plugins/flot/jquery.flot.time.min.js" type="text/javascript"></script>
........
........    
plot = $.plot("#PH-chart", [
            { data: PH1, color: "#3c8dbc", label: "PH1(x) = 0.00"},
            { data: PH2, color: "#00c0ef", label: "PH2(x) = 0.00" },
            { data: PH3, color: "#3cffff", label: "PH3(x) = 0.00"},
            { data: PH4, color: "#0ff0ef", label: "PH4(x) = 0.00" }
        ], {
            series: {
                threshold: {
                    below: 7,
                    color: "rgb(200, 20, 30)"
                },
                lines: {
                    show: true
                }
            },
            crosshair: {
                mode: "x"
            },
            grid: {
                hoverable: true,
                autoHighlight: true,
                borderColor: "#f3f3f3",
                borderWidth: 1,
                tickColor: "#f3f3f3"
            },
            yaxis: {
                max: 14
            },
            xaxis: {
                show: true,
                mode: "time",
                minTickSize: [1, "hour"],
                twelveHourClock: true
            }
        });

        var legends = $("#PH-chart .legendLabel");

        var updateLegendTimeout = null;
        var latestPosition = null;

        function updateLegend() {

            updateLegendTimeout = null;

            var pos = latestPosition;

            var axes = plot.getAxes();
            if (pos.x < axes.xaxis.min || pos.x > axes.xaxis.max ||
                pos.y < axes.yaxis.min || pos.y > axes.yaxis.max) {
                return;
            }

            var i, j, dataset = plot.getData();
            for (i = 0; i < dataset.length; ++i) {

                var series = dataset[i];

                // Find the nearest points, x-wise

                for (j = 0; j < series.data.length; ++j) {
                    if (series.data[j][0] > pos.x) {
                        break;
                    }
                }

                // Now Interpolate

                var y,
                    p1 = series.data[j - 1],
                    p2 = series.data[j];

                if (p1 == null) {
                    y = p2[1];
                } else if (p2 == null) {
                    y = p1[1];
                } else {
                    y = p1[1] + (p2[1] - p1[1]) * (pos.x - p1[0]) / (p2[0] - p1[0]);
                }

                legends.eq(i).text(series.label.replace(/x.*/,  + series.data[j][0] + ") = " + y.toFixed(2)));
            }
        }

        $("#PH-chart").bind("plothover",  function (event, pos, item) {
            latestPosition = pos;
            if (!updateLegendTimeout) {
                updateLegendTimeout = setTimeout(updateLegend, 50);
            }
        });

another issue, I have written a function which take a the current time in a timestamp and return time with readable form

1431964050616 >> May 18, 2015 5:47:31 PM , I have tested it and it's working perfectly but when added it the chart it isn't !!!

function displayTime(currentTime) {
        var str = "";
        var hours = currentTime.getHours()
        var minutes = currentTime.getMinutes()
        var seconds = currentTime.getSeconds()

        if (minutes < 10) {
            minutes = "0" + minutes
        }
        if (seconds < 10) {
            seconds = "0" + seconds
        }
        str += hours + ":" + minutes + ":" + seconds + " ";
        if(hours > 11){
            str += "PM"
        } else {
            str += "AM"
        }
        return str;
    }

I have call the function in the chart code to change it to for example PH1( 05:30:30 PM) = 11.2 but I don't know where is the problem!

legends.eq(i).text(series.label.replace(/x.*/,  + displayTime(series.data[j][0]) + ") = " + y.toFixed(2)));

Hope to get it solved, Thanks in advance


Solution

  • The threshold plugin splits data series into two parts, one above the threshold and one below. This makes six data series out of your four (two have only values above the threshold). The two relevant changes in the code:

    • skip the series added by the threshold plugin
    • replace i in legends.eq(i) with the labelindex since i runs from 0 to 5 and there are only 4 labels in the legend

    New code:

    for (i = 0; i < dataset.length; i++) {        
        var series = dataset[i];
        if (series.data.length == 0) {
            continue;  // if this is a threshold added series, skip it and continue with the next one
        }
    
        // Find the nearest points, x-wise
        for (j = 0; j < series.data.length; j++) {
            if (series.data[j][0] > pos.x) {
                break;
            }
        }
    
        // Now Interpolate
        var y,
            p1 = series.data[j - 1],
            p2 = series.data[j];
    
        if (p1 === undefined) {
            y = p2[1];
        } else if (p2 === undefined) {
            y = p1[1];
        } else {
            y = p1[1] + (p2[1] - p1[1]) * (pos.x - p1[0]) / (p2[0] - p1[0]);
        }
    
        var labelindex = parseInt(series.label.substr(2, 1));
        legends.eq(labelindex - 1).text(series.label.replace(/x.*/, +series.data[j][0] + ") = " + y.toFixed(2)));
    }
    

    See this fiddle with the working code.