Kareem Mohamed Kareem Mohamed - 27 days ago 5
Javascript Question

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

Answer

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.