123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- /* 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);
|