| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 | 
							- /* Flot plugin for computing bottoms for filled line and bar charts.
 
- Copyright (c) 2007-2014 IOLA and Ole Laursen.
 
- Licensed under the MIT license.
 
- The case: you've got two series that you want to fill the area between. In Flot
 
- terms, you need to use one as the fill bottom of the other. You can specify the
 
- bottom of each data point as the third coordinate manually, or you can use this
 
- plugin to compute it for you.
 
- In order to name the other series, you need to give it an id, like this:
 
- 	var dataset = [
 
- 		{ data: [ ... ], id: "foo" } ,         // use default bottom
 
- 		{ data: [ ... ], fillBetween: "foo" }, // use first dataset as bottom
 
- 	];
 
- 	$.plot($("#placeholder"), dataset, { lines: { show: true, fill: true }});
 
- As a convenience, if the id given is a number that doesn't appear as an id in
 
- the series, it is interpreted as the index in the array instead (so fillBetween:
 
- 0 can also mean the first series).
 
- Internally, the plugin modifies the datapoints in each series. For line series,
 
- extra data points might be inserted through interpolation. Note that at points
 
- where the bottom line is not defined (due to a null point or start/end of line),
 
- the current line will show a gap too. The algorithm comes from the
 
- jquery.flot.stack.js plugin, possibly some code could be shared.
 
- */
 
- (function ( $ ) {
 
- 	var options = {
 
- 		series: {
 
- 			fillBetween: null	// or number
 
- 		}
 
- 	};
 
- 	function init( plot ) {
 
- 		function findBottomSeries( s, allseries ) {
 
- 			var i;
 
- 			for ( i = 0; i < allseries.length; ++i ) {
 
- 				if ( allseries[ i ].id === s.fillBetween ) {
 
- 					return allseries[ i ];
 
- 				}
 
- 			}
 
- 			if ( typeof s.fillBetween === "number" ) {
 
- 				if ( s.fillBetween < 0 || s.fillBetween >= allseries.length ) {
 
- 					return null;
 
- 				}
 
- 				return allseries[ s.fillBetween ];
 
- 			}
 
- 			return null;
 
- 		}
 
- 		function computeFillBottoms( plot, s, datapoints ) {
 
- 			if ( s.fillBetween == null ) {
 
- 				return;
 
- 			}
 
- 			var other = findBottomSeries( s, plot.getData() );
 
- 			if ( !other ) {
 
- 				return;
 
- 			}
 
- 			var ps = datapoints.pointsize,
 
- 				points = datapoints.points,
 
- 				otherps = other.datapoints.pointsize,
 
- 				otherpoints = other.datapoints.points,
 
- 				newpoints = [],
 
- 				px, py, intery, qx, qy, bottom,
 
- 				withlines = s.lines.show,
 
- 				withbottom = ps > 2 && datapoints.format[2].y,
 
- 				withsteps = withlines && s.lines.steps,
 
- 				fromgap = true,
 
- 				i = 0,
 
- 				j = 0,
 
- 				l, m;
 
- 			while ( true ) {
 
- 				if ( i >= points.length ) {
 
- 					break;
 
- 				}
 
- 				l = newpoints.length;
 
- 				if ( points[ i ] == null ) {
 
- 					// copy gaps
 
- 					for ( m = 0; m < ps; ++m ) {
 
- 						newpoints.push( points[ i + m ] );
 
- 					}
 
- 					i += ps;
 
- 				} else if ( j >= otherpoints.length ) {
 
- 					// for lines, we can't use the rest of the points
 
- 					if ( !withlines ) {
 
- 						for ( m = 0; m < ps; ++m ) {
 
- 							newpoints.push( points[ i + m ] );
 
- 						}
 
- 					}
 
- 					i += ps;
 
- 				} else if ( otherpoints[ j ] == null ) {
 
- 					// oops, got a gap
 
- 					for ( m = 0; m < ps; ++m ) {
 
- 						newpoints.push( null );
 
- 					}
 
- 					fromgap = true;
 
- 					j += otherps;
 
- 				} else {
 
- 					// cases where we actually got two points
 
- 					px = points[ i ];
 
- 					py = points[ i + 1 ];
 
- 					qx = otherpoints[ j ];
 
- 					qy = otherpoints[ j + 1 ];
 
- 					bottom = 0;
 
- 					if ( px === qx ) {
 
- 						for ( m = 0; m < ps; ++m ) {
 
- 							newpoints.push( points[ i + m ] );
 
- 						}
 
- 						//newpoints[ l + 1 ] += qy;
 
- 						bottom = qy;
 
- 						i += ps;
 
- 						j += otherps;
 
- 					} else if ( px > qx ) {
 
- 						// we got past point below, might need to
 
- 						// insert interpolated extra point
 
- 						if ( withlines && i > 0 && points[ i - ps ] != null ) {
 
- 							intery = py + ( points[ i - ps + 1 ] - py ) * ( qx - px ) / ( points[ i - ps ] - px );
 
- 							newpoints.push( qx );
 
- 							newpoints.push( intery );
 
- 							for ( m = 2; m < ps; ++m ) {
 
- 								newpoints.push( points[ i + m ] );
 
- 							}
 
- 							bottom = qy;
 
- 						}
 
- 						j += otherps;
 
- 					} else { // px < qx
 
- 						// if we come from a gap, we just skip this point
 
- 						if ( fromgap && withlines ) {
 
- 							i += ps;
 
- 							continue;
 
- 						}
 
- 						for ( m = 0; m < ps; ++m ) {
 
- 							newpoints.push( points[ i + m ] );
 
- 						}
 
- 						// we might be able to interpolate a point below,
 
- 						// this can give us a better y
 
- 						if ( withlines && j > 0 && otherpoints[ j - otherps ] != null ) {
 
- 							bottom = qy + ( otherpoints[ j - otherps + 1 ] - qy ) * ( px - qx ) / ( otherpoints[ j - otherps ] - qx );
 
- 						}
 
- 						//newpoints[l + 1] += bottom;
 
- 						i += ps;
 
- 					}
 
- 					fromgap = false;
 
- 					if ( l !== newpoints.length && withbottom ) {
 
- 						newpoints[ l + 2 ] = bottom;
 
- 					}
 
- 				}
 
- 				// maintain the line steps invariant
 
- 				if ( withsteps && l !== newpoints.length && l > 0 &&
 
- 					newpoints[ l ] !== null &&
 
- 					newpoints[ l ] !== newpoints[ l - ps ] &&
 
- 					newpoints[ l + 1 ] !== newpoints[ l - ps + 1 ] ) {
 
- 					for (m = 0; m < ps; ++m) {
 
- 						newpoints[ l + ps + m ] = newpoints[ l + m ];
 
- 					}
 
- 					newpoints[ l + 1 ] = newpoints[ l - ps + 1 ];
 
- 				}
 
- 			}
 
- 			datapoints.points = newpoints;
 
- 		}
 
- 		plot.hooks.processDatapoints.push( computeFillBottoms );
 
- 	}
 
- 	$.plot.plugins.push({
 
- 		init: init,
 
- 		options: options,
 
- 		name: "fillbetween",
 
- 		version: "1.0"
 
- 	});
 
- })(jQuery);
 
 
  |