pandorafms/pandora_console/include/graphs/flot/jquery.flot.threshold.multi...

190 lines
5.2 KiB
JavaScript

/*
Flot plugin for specifying range of thresolds on data.
Controlled through the option "constraints" in a specific series
usage -
$.plot($("#placeholder"), [{ data: [ ... ], constraints: [constraint1, constraint2]},{data:[...],constraints:[...]}])
where constraint1 = {
threshold: 2,
color: "rgb(0,0,0)",
evaluate : function(y,threshold){ return y < threshold; }
}
threshold -> y-limit on the plot.
evaluate -> the function which defines the limit.This function defines wheteher y < threshold or y > threshold.
color -> the color with which to plot portion of the graph which satisfies the limit condition.
Internally, the plugin works by splitting the data into different series, one for each constraint.
*/
(function($){
function init(plot){
function plotWithMultipleThresholds(plot,s,datapoints){
if(s.data && s.data.length > 0 && s.constraints && s.constraints.length>0){
var series = new Graph(s.data,s.constraints).getPlotData();
for(var i=0;i<series.length;i++){
var ss = $.extend({},s);
ss.constraints = [];
ss.data = series[i].data;
ss.color = series[i].color;
plot.getData().push(ss);
}
}
}
function Graph(dataset, constraints) {
this._constraints = _getSortedConstraints(dataset,constraints);
this._dataset = dataset;
this._plotData = [];
this.getPlotData = function() {
if(this._constraints.length == 0)return [];
for ( var i = this._constraints.length - 1; i >= 0 ; i--) {
var constraint = this._constraints[i];
if(null != constraint.threshold){
var set = new Resolve(this._dataset).using(constraint.threshold, constraint.evaluate);
this._plotData.push( {
data : set,
color : constraint.color
});
}
}
return this._plotData;
};
function Resolve(originalPonits) {
this._originalPoints = originalPonits;
this._data = [];
this._getPointOnThreshold = _getPointOnThreshold;
this.using = using ;
function using(threshold, evaluate) {
var count = 0;
for ( var i = 0; i < this._originalPoints.length; i++) {
var currentPoint = this._originalPoints[i];
if (evaluate(currentPoint[1],threshold)) {
if (i > 0
&& (this._data.length == 0 || this._data[count - 1] == null)) {
this._data[count++] = this._getPointOnThreshold(threshold,this._originalPoints[i - 1], currentPoint);
}
this._data[count++] = currentPoint;
} else {
if (this._data.length > 0 && this._data[count - 1] != null) {
this._data[count++] = this._getPointOnThreshold(threshold,this._originalPoints[i - 1], currentPoint);
this._data[count++] = null;
this._data[count++] = null;
}
}
}
return this._data;
}
function _getPointOnThreshold(threshold, prevP, currP) {
var currentX = currP[0];
var currentY = currP[1];
var prevX = prevP[0];
var prevY = prevP[1];
var slope = (threshold - currentY)
/ (prevY - currentY);
var xOnConstraintLine = slope * (prevX - currentX) + currentX;
return [ xOnConstraintLine, threshold ];
}
}
function _getSortedConstraints(originalpoints,constraints){
var dataRange = _findMaxAndMin(originalpoints);
if(undefined == dataRange)return [];
var max = dataRange.max;
var min = dataRange.min;
var thresholdRanges = [];
var sortedConstraints = [];
for(var i = 0; i < constraints.length ; i++){
var constraint = constraints[i];
var range = 0;
if(constraint.evaluate(min,constraint.threshold)){
range = Math.abs(constraint.threshold - min);
}else{
range = Math.abs(max - constraint.threshold);
}
thresholdRanges.push({constraint:constraint,range:range});
}
QuickSort(thresholdRanges,function(obj1,obj2){ return obj1.range < obj2.range;});
for(var i=thresholdRanges.length-1;i>=0;i--){
sortedConstraints[i] = thresholdRanges[i].constraint;
}
return sortedConstraints;
}
function _findMaxAndMin(dataset){
if(undefined == dataset)return undefined;
var arr = [];
for( var i=0;i<dataset.length;i++){
arr[i] = dataset[i][1];
}
QuickSort(arr,function(p1,p2){return p1 < p2;});
return { min:arr[0],max:arr[arr.length-1]};
}
}
function QuickSort(dataset,comparator){
sort(dataset, 0, dataset.length-1, comparator);
function sort(array, left, right,comparator){
if(right > left){
var pivotIndex = Math.floor(( left + right )/2);
var pivotNewIndex = partition(array,left,right,pivotIndex,comparator);
sort(array, left, pivotNewIndex - 1,comparator);
sort(array, pivotNewIndex + 1, right,comparator);
}
}
function partition(array,left,right,pivotIndex,comparator){
var pivot = array[pivotIndex];
swap(array,pivotIndex,right);
var storeIndex = left;
for( var i= left ; i < right ; i++){
if(comparator(array[i] , pivot)){
swap(array,i,storeIndex);
storeIndex = storeIndex + 1;
}
}
swap(array,storeIndex,right);
return storeIndex;
}
function swap(array,index1,index2){
var temp = array[index1];
array[index1] = array[index2];
array[index2] = temp;
}
}
plot.hooks.processRawData.push(plotWithMultipleThresholds);
}
$.plot.plugins.push({
init: init,
name: 'multiple.threshold',
version: '1.0'
});
})(jQuery);