143 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			143 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/* Flot plugin for thresholding data.
 | 
						|
 | 
						|
Copyright (c) 2007-2014 IOLA and Ole Laursen.
 | 
						|
Licensed under the MIT license.
 | 
						|
 | 
						|
The plugin supports these options:
 | 
						|
 | 
						|
	series: {
 | 
						|
		threshold: {
 | 
						|
			below: number
 | 
						|
			color: colorspec
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
It can also be applied to a single series, like this:
 | 
						|
 | 
						|
	$.plot( $("#placeholder"), [{
 | 
						|
		data: [ ... ],
 | 
						|
		threshold: { ... }
 | 
						|
	}])
 | 
						|
 | 
						|
An array can be passed for multiple thresholding, like this:
 | 
						|
 | 
						|
	threshold: [{
 | 
						|
		below: number1
 | 
						|
		color: color1
 | 
						|
	},{
 | 
						|
		below: number2
 | 
						|
		color: color2
 | 
						|
	}]
 | 
						|
 | 
						|
These multiple threshold objects can be passed in any order since they are
 | 
						|
sorted by the processing function.
 | 
						|
 | 
						|
The data points below "below" are drawn with the specified color. This makes
 | 
						|
it easy to mark points below 0, e.g. for budget data.
 | 
						|
 | 
						|
Internally, the plugin works by splitting the data into two series, above and
 | 
						|
below the threshold. The extra series below the threshold will have its label
 | 
						|
cleared and the special "originSeries" attribute set to the original series.
 | 
						|
You may need to check for this in hover events.
 | 
						|
 | 
						|
*/
 | 
						|
 | 
						|
(function ($) {
 | 
						|
    var options = {
 | 
						|
        series: { threshold: null } // or { below: number, color: color spec}
 | 
						|
    };
 | 
						|
    
 | 
						|
    function init(plot) {
 | 
						|
        function thresholdData(plot, s, datapoints, below, color) {
 | 
						|
            var ps = datapoints.pointsize, i, x, y, p, prevp,
 | 
						|
                thresholded = $.extend({}, s); // note: shallow copy
 | 
						|
 | 
						|
            thresholded.datapoints = { points: [], pointsize: ps, format: datapoints.format };
 | 
						|
            thresholded.label = null;
 | 
						|
            thresholded.color = color;
 | 
						|
            thresholded.threshold = null;
 | 
						|
            thresholded.originSeries = s;
 | 
						|
            thresholded.data = [];
 | 
						|
 
 | 
						|
            var origpoints = datapoints.points,
 | 
						|
                addCrossingPoints = s.lines.show;
 | 
						|
 | 
						|
            var threspoints = [];
 | 
						|
            var newpoints = [];
 | 
						|
            var m;
 | 
						|
 | 
						|
            for (i = 0; i < origpoints.length; i += ps) {
 | 
						|
                x = origpoints[i];
 | 
						|
                y = origpoints[i + 1];
 | 
						|
 | 
						|
                prevp = p;
 | 
						|
                if (y < below)
 | 
						|
                    p = threspoints;
 | 
						|
                else
 | 
						|
                    p = newpoints;
 | 
						|
 | 
						|
                if (addCrossingPoints && prevp != p && x != null
 | 
						|
                    && i > 0 && origpoints[i - ps] != null) {
 | 
						|
                    var interx = x + (below - y) * (x - origpoints[i - ps]) / (y - origpoints[i - ps + 1]);
 | 
						|
                    prevp.push(interx);
 | 
						|
                    prevp.push(below);
 | 
						|
                    for (m = 2; m < ps; ++m)
 | 
						|
                        prevp.push(origpoints[i + m]);
 | 
						|
                    
 | 
						|
                    p.push(null); // start new segment
 | 
						|
                    p.push(null);
 | 
						|
                    for (m = 2; m < ps; ++m)
 | 
						|
                        p.push(origpoints[i + m]);
 | 
						|
                    p.push(interx);
 | 
						|
                    p.push(below);
 | 
						|
                    for (m = 2; m < ps; ++m)
 | 
						|
                        p.push(origpoints[i + m]);
 | 
						|
                }
 | 
						|
 | 
						|
                p.push(x);
 | 
						|
                p.push(y);
 | 
						|
                for (m = 2; m < ps; ++m)
 | 
						|
                    p.push(origpoints[i + m]);
 | 
						|
            }
 | 
						|
 | 
						|
            datapoints.points = newpoints;
 | 
						|
            thresholded.datapoints.points = threspoints;
 | 
						|
            
 | 
						|
            if (thresholded.datapoints.points.length > 0) {
 | 
						|
                var origIndex = $.inArray(s, plot.getData());
 | 
						|
                // Insert newly-generated series right after original one (to prevent it from becoming top-most)
 | 
						|
                plot.getData().splice(origIndex + 1, 0, thresholded);
 | 
						|
            }
 | 
						|
                
 | 
						|
            // FIXME: there are probably some edge cases left in bars
 | 
						|
        }
 | 
						|
        
 | 
						|
        function processThresholds(plot, s, datapoints) {
 | 
						|
            if (!s.threshold)
 | 
						|
                return;
 | 
						|
            
 | 
						|
            if (s.threshold instanceof Array) {
 | 
						|
                s.threshold.sort(function(a, b) {
 | 
						|
                    return a.below - b.below;
 | 
						|
                });
 | 
						|
                
 | 
						|
                $(s.threshold).each(function(i, th) {
 | 
						|
                    thresholdData(plot, s, datapoints, th.below, th.color);
 | 
						|
                });
 | 
						|
            }
 | 
						|
            else {
 | 
						|
                thresholdData(plot, s, datapoints, s.threshold.below, s.threshold.color);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        
 | 
						|
        plot.hooks.processDatapoints.push(processThresholds);
 | 
						|
    }
 | 
						|
    
 | 
						|
    $.plot.plugins.push({
 | 
						|
        init: init,
 | 
						|
        options: options,
 | 
						|
        name: 'threshold',
 | 
						|
        version: '1.2'
 | 
						|
    });
 | 
						|
})(jQuery);
 |