riemann-dash 0.2.4 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/lib/riemann/dash/public/clock.js +12 -8
  2. data/lib/riemann/dash/public/strings.js +8 -2
  3. data/lib/riemann/dash/public/subs.js +8 -4
  4. data/lib/riemann/dash/public/util.js +19 -5
  5. data/lib/riemann/dash/public/vendor/flot/jquery.colorhelpers.js +179 -0
  6. data/lib/riemann/dash/public/vendor/flot/jquery.colorhelpers.min.js +21 -0
  7. data/lib/riemann/dash/public/vendor/flot/jquery.flot.canvas.js +345 -0
  8. data/lib/riemann/dash/public/vendor/flot/jquery.flot.canvas.min.js +28 -0
  9. data/lib/riemann/dash/public/vendor/flot/jquery.flot.categories.js +190 -0
  10. data/lib/riemann/dash/public/vendor/flot/jquery.flot.categories.min.js +44 -0
  11. data/lib/riemann/dash/public/vendor/flot/jquery.flot.crosshair.js +176 -0
  12. data/lib/riemann/dash/public/vendor/flot/jquery.flot.crosshair.min.js +59 -0
  13. data/lib/riemann/dash/public/vendor/flot/jquery.flot.errorbars.js +353 -0
  14. data/lib/riemann/dash/public/vendor/flot/jquery.flot.errorbars.min.js +63 -0
  15. data/lib/riemann/dash/public/vendor/flot/jquery.flot.fillbetween.js +226 -0
  16. data/lib/riemann/dash/public/vendor/flot/jquery.flot.fillbetween.min.js +30 -0
  17. data/lib/riemann/dash/public/vendor/flot/jquery.flot.image.js +241 -0
  18. data/lib/riemann/dash/public/vendor/flot/jquery.flot.image.min.js +53 -0
  19. data/lib/riemann/dash/public/vendor/flot/jquery.flot.js +3061 -0
  20. data/lib/riemann/dash/public/vendor/flot/jquery.flot.min.js +29 -0
  21. data/lib/riemann/dash/public/vendor/flot/jquery.flot.navigate.js +346 -0
  22. data/lib/riemann/dash/public/vendor/flot/jquery.flot.navigate.min.js +86 -0
  23. data/lib/riemann/dash/public/vendor/flot/jquery.flot.pie.js +817 -0
  24. data/lib/riemann/dash/public/vendor/flot/jquery.flot.pie.min.js +56 -0
  25. data/lib/riemann/dash/public/vendor/flot/jquery.flot.resize.js +60 -0
  26. data/lib/riemann/dash/public/vendor/flot/jquery.flot.resize.min.js +19 -0
  27. data/lib/riemann/dash/public/vendor/flot/jquery.flot.selection.js +360 -0
  28. data/lib/riemann/dash/public/vendor/flot/jquery.flot.selection.min.js +79 -0
  29. data/lib/riemann/dash/public/vendor/flot/jquery.flot.stack.js +188 -0
  30. data/lib/riemann/dash/public/vendor/flot/jquery.flot.stack.min.js +36 -0
  31. data/lib/riemann/dash/public/vendor/flot/jquery.flot.symbol.js +71 -0
  32. data/lib/riemann/dash/public/vendor/flot/jquery.flot.symbol.min.js +14 -0
  33. data/lib/riemann/dash/public/vendor/flot/jquery.flot.threshold.js +142 -0
  34. data/lib/riemann/dash/public/vendor/flot/jquery.flot.threshold.min.js +43 -0
  35. data/lib/riemann/dash/public/vendor/flot/jquery.flot.time.js +431 -0
  36. data/lib/riemann/dash/public/vendor/flot/jquery.flot.time.min.js +9 -0
  37. data/lib/riemann/dash/public/view.js +11 -7
  38. data/lib/riemann/dash/public/views/flot.js +248 -0
  39. data/lib/riemann/dash/public/views/grid.js +1 -5
  40. data/lib/riemann/dash/version.rb +1 -1
  41. data/lib/riemann/dash/views/css.scss +24 -0
  42. data/lib/riemann/dash/views/index.erubis +6 -0
  43. metadata +35 -2
@@ -0,0 +1,353 @@
1
+ /* Flot plugin for plotting error bars.
2
+
3
+ Copyright (c) 2007-2013 IOLA and Ole Laursen.
4
+ Licensed under the MIT license.
5
+
6
+ Error bars are used to show standard deviation and other statistical
7
+ properties in a plot.
8
+
9
+ * Created by Rui Pereira - rui (dot) pereira (at) gmail (dot) com
10
+
11
+ This plugin allows you to plot error-bars over points. Set "errorbars" inside
12
+ the points series to the axis name over which there will be error values in
13
+ your data array (*even* if you do not intend to plot them later, by setting
14
+ "show: null" on xerr/yerr).
15
+
16
+ The plugin supports these options:
17
+
18
+ series: {
19
+ points: {
20
+ errorbars: "x" or "y" or "xy",
21
+ xerr: {
22
+ show: null/false or true,
23
+ asymmetric: null/false or true,
24
+ upperCap: null or "-" or function,
25
+ lowerCap: null or "-" or function,
26
+ color: null or color,
27
+ radius: null or number
28
+ },
29
+ yerr: { same options as xerr }
30
+ }
31
+ }
32
+
33
+ Each data point array is expected to be of the type:
34
+
35
+ "x" [ x, y, xerr ]
36
+ "y" [ x, y, yerr ]
37
+ "xy" [ x, y, xerr, yerr ]
38
+
39
+ Where xerr becomes xerr_lower,xerr_upper for the asymmetric error case, and
40
+ equivalently for yerr. Eg., a datapoint for the "xy" case with symmetric
41
+ error-bars on X and asymmetric on Y would be:
42
+
43
+ [ x, y, xerr, yerr_lower, yerr_upper ]
44
+
45
+ By default no end caps are drawn. Setting upperCap and/or lowerCap to "-" will
46
+ draw a small cap perpendicular to the error bar. They can also be set to a
47
+ user-defined drawing function, with (ctx, x, y, radius) as parameters, as eg.
48
+
49
+ function drawSemiCircle( ctx, x, y, radius ) {
50
+ ctx.beginPath();
51
+ ctx.arc( x, y, radius, 0, Math.PI, false );
52
+ ctx.moveTo( x - radius, y );
53
+ ctx.lineTo( x + radius, y );
54
+ ctx.stroke();
55
+ }
56
+
57
+ Color and radius both default to the same ones of the points series if not
58
+ set. The independent radius parameter on xerr/yerr is useful for the case when
59
+ we may want to add error-bars to a line, without showing the interconnecting
60
+ points (with radius: 0), and still showing end caps on the error-bars.
61
+ shadowSize and lineWidth are derived as well from the points series.
62
+
63
+ */
64
+
65
+ (function ($) {
66
+ var options = {
67
+ series: {
68
+ points: {
69
+ errorbars: null, //should be 'x', 'y' or 'xy'
70
+ xerr: { err: 'x', show: null, asymmetric: null, upperCap: null, lowerCap: null, color: null, radius: null},
71
+ yerr: { err: 'y', show: null, asymmetric: null, upperCap: null, lowerCap: null, color: null, radius: null}
72
+ }
73
+ }
74
+ };
75
+
76
+ function processRawData(plot, series, data, datapoints){
77
+ if (!series.points.errorbars)
78
+ return;
79
+
80
+ // x,y values
81
+ var format = [
82
+ { x: true, number: true, required: true },
83
+ { y: true, number: true, required: true }
84
+ ];
85
+
86
+ var errors = series.points.errorbars;
87
+ // error bars - first X then Y
88
+ if (errors == 'x' || errors == 'xy') {
89
+ // lower / upper error
90
+ if (series.points.xerr.asymmetric) {
91
+ format.push({ x: true, number: true, required: true });
92
+ format.push({ x: true, number: true, required: true });
93
+ } else
94
+ format.push({ x: true, number: true, required: true });
95
+ }
96
+ if (errors == 'y' || errors == 'xy') {
97
+ // lower / upper error
98
+ if (series.points.yerr.asymmetric) {
99
+ format.push({ y: true, number: true, required: true });
100
+ format.push({ y: true, number: true, required: true });
101
+ } else
102
+ format.push({ y: true, number: true, required: true });
103
+ }
104
+ datapoints.format = format;
105
+ }
106
+
107
+ function parseErrors(series, i){
108
+
109
+ var points = series.datapoints.points;
110
+
111
+ // read errors from points array
112
+ var exl = null,
113
+ exu = null,
114
+ eyl = null,
115
+ eyu = null;
116
+ var xerr = series.points.xerr,
117
+ yerr = series.points.yerr;
118
+
119
+ var eb = series.points.errorbars;
120
+ // error bars - first X
121
+ if (eb == 'x' || eb == 'xy') {
122
+ if (xerr.asymmetric) {
123
+ exl = points[i + 2];
124
+ exu = points[i + 3];
125
+ if (eb == 'xy')
126
+ if (yerr.asymmetric){
127
+ eyl = points[i + 4];
128
+ eyu = points[i + 5];
129
+ } else eyl = points[i + 4];
130
+ } else {
131
+ exl = points[i + 2];
132
+ if (eb == 'xy')
133
+ if (yerr.asymmetric) {
134
+ eyl = points[i + 3];
135
+ eyu = points[i + 4];
136
+ } else eyl = points[i + 3];
137
+ }
138
+ // only Y
139
+ } else if (eb == 'y')
140
+ if (yerr.asymmetric) {
141
+ eyl = points[i + 2];
142
+ eyu = points[i + 3];
143
+ } else eyl = points[i + 2];
144
+
145
+ // symmetric errors?
146
+ if (exu == null) exu = exl;
147
+ if (eyu == null) eyu = eyl;
148
+
149
+ var errRanges = [exl, exu, eyl, eyu];
150
+ // nullify if not showing
151
+ if (!xerr.show){
152
+ errRanges[0] = null;
153
+ errRanges[1] = null;
154
+ }
155
+ if (!yerr.show){
156
+ errRanges[2] = null;
157
+ errRanges[3] = null;
158
+ }
159
+ return errRanges;
160
+ }
161
+
162
+ function drawSeriesErrors(plot, ctx, s){
163
+
164
+ var points = s.datapoints.points,
165
+ ps = s.datapoints.pointsize,
166
+ ax = [s.xaxis, s.yaxis],
167
+ radius = s.points.radius,
168
+ err = [s.points.xerr, s.points.yerr];
169
+
170
+ //sanity check, in case some inverted axis hack is applied to flot
171
+ var invertX = false;
172
+ if (ax[0].p2c(ax[0].max) < ax[0].p2c(ax[0].min)) {
173
+ invertX = true;
174
+ var tmp = err[0].lowerCap;
175
+ err[0].lowerCap = err[0].upperCap;
176
+ err[0].upperCap = tmp;
177
+ }
178
+
179
+ var invertY = false;
180
+ if (ax[1].p2c(ax[1].min) < ax[1].p2c(ax[1].max)) {
181
+ invertY = true;
182
+ var tmp = err[1].lowerCap;
183
+ err[1].lowerCap = err[1].upperCap;
184
+ err[1].upperCap = tmp;
185
+ }
186
+
187
+ for (var i = 0; i < s.datapoints.points.length; i += ps) {
188
+
189
+ //parse
190
+ var errRanges = parseErrors(s, i);
191
+
192
+ //cycle xerr & yerr
193
+ for (var e = 0; e < err.length; e++){
194
+
195
+ var minmax = [ax[e].min, ax[e].max];
196
+
197
+ //draw this error?
198
+ if (errRanges[e * err.length]){
199
+
200
+ //data coordinates
201
+ var x = points[i],
202
+ y = points[i + 1];
203
+
204
+ //errorbar ranges
205
+ var upper = [x, y][e] + errRanges[e * err.length + 1],
206
+ lower = [x, y][e] - errRanges[e * err.length];
207
+
208
+ //points outside of the canvas
209
+ if (err[e].err == 'x')
210
+ if (y > ax[1].max || y < ax[1].min || upper < ax[0].min || lower > ax[0].max)
211
+ continue;
212
+ if (err[e].err == 'y')
213
+ if (x > ax[0].max || x < ax[0].min || upper < ax[1].min || lower > ax[1].max)
214
+ continue;
215
+
216
+ // prevent errorbars getting out of the canvas
217
+ var drawUpper = true,
218
+ drawLower = true;
219
+
220
+ if (upper > minmax[1]) {
221
+ drawUpper = false;
222
+ upper = minmax[1];
223
+ }
224
+ if (lower < minmax[0]) {
225
+ drawLower = false;
226
+ lower = minmax[0];
227
+ }
228
+
229
+ //sanity check, in case some inverted axis hack is applied to flot
230
+ if ((err[e].err == 'x' && invertX) || (err[e].err == 'y' && invertY)) {
231
+ //swap coordinates
232
+ var tmp = lower;
233
+ lower = upper;
234
+ upper = tmp;
235
+ tmp = drawLower;
236
+ drawLower = drawUpper;
237
+ drawUpper = tmp;
238
+ tmp = minmax[0];
239
+ minmax[0] = minmax[1];
240
+ minmax[1] = tmp;
241
+ }
242
+
243
+ // convert to pixels
244
+ x = ax[0].p2c(x),
245
+ y = ax[1].p2c(y),
246
+ upper = ax[e].p2c(upper);
247
+ lower = ax[e].p2c(lower);
248
+ minmax[0] = ax[e].p2c(minmax[0]);
249
+ minmax[1] = ax[e].p2c(minmax[1]);
250
+
251
+ //same style as points by default
252
+ var lw = err[e].lineWidth ? err[e].lineWidth : s.points.lineWidth,
253
+ sw = s.points.shadowSize != null ? s.points.shadowSize : s.shadowSize;
254
+
255
+ //shadow as for points
256
+ if (lw > 0 && sw > 0) {
257
+ var w = sw / 2;
258
+ ctx.lineWidth = w;
259
+ ctx.strokeStyle = "rgba(0,0,0,0.1)";
260
+ drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, w + w/2, minmax);
261
+
262
+ ctx.strokeStyle = "rgba(0,0,0,0.2)";
263
+ drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, w/2, minmax);
264
+ }
265
+
266
+ ctx.strokeStyle = err[e].color? err[e].color: s.color;
267
+ ctx.lineWidth = lw;
268
+ //draw it
269
+ drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, 0, minmax);
270
+ }
271
+ }
272
+ }
273
+ }
274
+
275
+ function drawError(ctx,err,x,y,upper,lower,drawUpper,drawLower,radius,offset,minmax){
276
+
277
+ //shadow offset
278
+ y += offset;
279
+ upper += offset;
280
+ lower += offset;
281
+
282
+ // error bar - avoid plotting over circles
283
+ if (err.err == 'x'){
284
+ if (upper > x + radius) drawPath(ctx, [[upper,y],[Math.max(x + radius,minmax[0]),y]]);
285
+ else drawUpper = false;
286
+ if (lower < x - radius) drawPath(ctx, [[Math.min(x - radius,minmax[1]),y],[lower,y]] );
287
+ else drawLower = false;
288
+ }
289
+ else {
290
+ if (upper < y - radius) drawPath(ctx, [[x,upper],[x,Math.min(y - radius,minmax[0])]] );
291
+ else drawUpper = false;
292
+ if (lower > y + radius) drawPath(ctx, [[x,Math.max(y + radius,minmax[1])],[x,lower]] );
293
+ else drawLower = false;
294
+ }
295
+
296
+ //internal radius value in errorbar, allows to plot radius 0 points and still keep proper sized caps
297
+ //this is a way to get errorbars on lines without visible connecting dots
298
+ radius = err.radius != null? err.radius: radius;
299
+
300
+ // upper cap
301
+ if (drawUpper) {
302
+ if (err.upperCap == '-'){
303
+ if (err.err=='x') drawPath(ctx, [[upper,y - radius],[upper,y + radius]] );
304
+ else drawPath(ctx, [[x - radius,upper],[x + radius,upper]] );
305
+ } else if ($.isFunction(err.upperCap)){
306
+ if (err.err=='x') err.upperCap(ctx, upper, y, radius);
307
+ else err.upperCap(ctx, x, upper, radius);
308
+ }
309
+ }
310
+ // lower cap
311
+ if (drawLower) {
312
+ if (err.lowerCap == '-'){
313
+ if (err.err=='x') drawPath(ctx, [[lower,y - radius],[lower,y + radius]] );
314
+ else drawPath(ctx, [[x - radius,lower],[x + radius,lower]] );
315
+ } else if ($.isFunction(err.lowerCap)){
316
+ if (err.err=='x') err.lowerCap(ctx, lower, y, radius);
317
+ else err.lowerCap(ctx, x, lower, radius);
318
+ }
319
+ }
320
+ }
321
+
322
+ function drawPath(ctx, pts){
323
+ ctx.beginPath();
324
+ ctx.moveTo(pts[0][0], pts[0][1]);
325
+ for (var p=1; p < pts.length; p++)
326
+ ctx.lineTo(pts[p][0], pts[p][1]);
327
+ ctx.stroke();
328
+ }
329
+
330
+ function draw(plot, ctx){
331
+ var plotOffset = plot.getPlotOffset();
332
+
333
+ ctx.save();
334
+ ctx.translate(plotOffset.left, plotOffset.top);
335
+ $.each(plot.getData(), function (i, s) {
336
+ if (s.points.errorbars && (s.points.xerr.show || s.points.yerr.show))
337
+ drawSeriesErrors(plot, ctx, s);
338
+ });
339
+ ctx.restore();
340
+ }
341
+
342
+ function init(plot) {
343
+ plot.hooks.processRawData.push(processRawData);
344
+ plot.hooks.draw.push(draw);
345
+ }
346
+
347
+ $.plot.plugins.push({
348
+ init: init,
349
+ options: options,
350
+ name: 'errorbars',
351
+ version: '1.0'
352
+ });
353
+ })(jQuery);
@@ -0,0 +1,63 @@
1
+ /* Flot plugin for plotting error bars.
2
+
3
+ Copyright (c) 2007-2013 IOLA and Ole Laursen.
4
+ Licensed under the MIT license.
5
+
6
+ Error bars are used to show standard deviation and other statistical
7
+ properties in a plot.
8
+
9
+ * Created by Rui Pereira - rui (dot) pereira (at) gmail (dot) com
10
+
11
+ This plugin allows you to plot error-bars over points. Set "errorbars" inside
12
+ the points series to the axis name over which there will be error values in
13
+ your data array (*even* if you do not intend to plot them later, by setting
14
+ "show: null" on xerr/yerr).
15
+
16
+ The plugin supports these options:
17
+
18
+ series: {
19
+ points: {
20
+ errorbars: "x" or "y" or "xy",
21
+ xerr: {
22
+ show: null/false or true,
23
+ asymmetric: null/false or true,
24
+ upperCap: null or "-" or function,
25
+ lowerCap: null or "-" or function,
26
+ color: null or color,
27
+ radius: null or number
28
+ },
29
+ yerr: { same options as xerr }
30
+ }
31
+ }
32
+
33
+ Each data point array is expected to be of the type:
34
+
35
+ "x" [ x, y, xerr ]
36
+ "y" [ x, y, yerr ]
37
+ "xy" [ x, y, xerr, yerr ]
38
+
39
+ Where xerr becomes xerr_lower,xerr_upper for the asymmetric error case, and
40
+ equivalently for yerr. Eg., a datapoint for the "xy" case with symmetric
41
+ error-bars on X and asymmetric on Y would be:
42
+
43
+ [ x, y, xerr, yerr_lower, yerr_upper ]
44
+
45
+ By default no end caps are drawn. Setting upperCap and/or lowerCap to "-" will
46
+ draw a small cap perpendicular to the error bar. They can also be set to a
47
+ user-defined drawing function, with (ctx, x, y, radius) as parameters, as eg.
48
+
49
+ function drawSemiCircle( ctx, x, y, radius ) {
50
+ ctx.beginPath();
51
+ ctx.arc( x, y, radius, 0, Math.PI, false );
52
+ ctx.moveTo( x - radius, y );
53
+ ctx.lineTo( x + radius, y );
54
+ ctx.stroke();
55
+ }
56
+
57
+ Color and radius both default to the same ones of the points series if not
58
+ set. The independent radius parameter on xerr/yerr is useful for the case when
59
+ we may want to add error-bars to a line, without showing the interconnecting
60
+ points (with radius: 0), and still showing end caps on the error-bars.
61
+ shadowSize and lineWidth are derived as well from the points series.
62
+
63
+ */(function(e){function n(e,t,n,r){if(!t.points.errorbars)return;var i=[{x:!0,number:!0,required:!0},{y:!0,number:!0,required:!0}],s=t.points.errorbars;if(s=="x"||s=="xy")t.points.xerr.asymmetric?(i.push({x:!0,number:!0,required:!0}),i.push({x:!0,number:!0,required:!0})):i.push({x:!0,number:!0,required:!0});if(s=="y"||s=="xy")t.points.yerr.asymmetric?(i.push({y:!0,number:!0,required:!0}),i.push({y:!0,number:!0,required:!0})):i.push({y:!0,number:!0,required:!0});r.format=i}function r(e,t){var n=e.datapoints.points,r=null,i=null,s=null,o=null,u=e.points.xerr,a=e.points.yerr,f=e.points.errorbars;f=="x"||f=="xy"?u.asymmetric?(r=n[t+2],i=n[t+3],f=="xy"&&(a.asymmetric?(s=n[t+4],o=n[t+5]):s=n[t+4])):(r=n[t+2],f=="xy"&&(a.asymmetric?(s=n[t+3],o=n[t+4]):s=n[t+3])):f=="y"&&(a.asymmetric?(s=n[t+2],o=n[t+3]):s=n[t+2]),i==null&&(i=r),o==null&&(o=s);var l=[r,i,s,o];return u.show||(l[0]=null,l[1]=null),a.show||(l[2]=null,l[3]=null),l}function i(e,t,n){var i=n.datapoints.points,o=n.datapoints.pointsize,u=[n.xaxis,n.yaxis],a=n.points.radius,f=[n.points.xerr,n.points.yerr],l=!1;if(u[0].p2c(u[0].max)<u[0].p2c(u[0].min)){l=!0;var c=f[0].lowerCap;f[0].lowerCap=f[0].upperCap,f[0].upperCap=c}var h=!1;if(u[1].p2c(u[1].min)<u[1].p2c(u[1].max)){h=!0;var c=f[1].lowerCap;f[1].lowerCap=f[1].upperCap,f[1].upperCap=c}for(var p=0;p<n.datapoints.points.length;p+=o){var d=r(n,p);for(var v=0;v<f.length;v++){var m=[u[v].min,u[v].max];if(d[v*f.length]){var g=i[p],y=i[p+1],b=[g,y][v]+d[v*f.length+1],w=[g,y][v]-d[v*f.length];if(f[v].err=="x")if(y>u[1].max||y<u[1].min||b<u[0].min||w>u[0].max)continue;if(f[v].err=="y")if(g>u[0].max||g<u[0].min||b<u[1].min||w>u[1].max)continue;var E=!0,S=!0;b>m[1]&&(E=!1,b=m[1]),w<m[0]&&(S=!1,w=m[0]);if(f[v].err=="x"&&l||f[v].err=="y"&&h){var c=w;w=b,b=c,c=S,S=E,E=c,c=m[0],m[0]=m[1],m[1]=c}g=u[0].p2c(g),y=u[1].p2c(y),b=u[v].p2c(b),w=u[v].p2c(w),m[0]=u[v].p2c(m[0]),m[1]=u[v].p2c(m[1]);var x=f[v].lineWidth?f[v].lineWidth:n.points.lineWidth,T=n.points.shadowSize!=null?n.points.shadowSize:n.shadowSize;if(x>0&&T>0){var N=T/2;t.lineWidth=N,t.strokeStyle="rgba(0,0,0,0.1)",s(t,f[v],g,y,b,w,E,S,a,N+N/2,m),t.strokeStyle="rgba(0,0,0,0.2)",s(t,f[v],g,y,b,w,E,S,a,N/2,m)}t.strokeStyle=f[v].color?f[v].color:n.color,t.lineWidth=x,s(t,f[v],g,y,b,w,E,S,a,0,m)}}}}function s(t,n,r,i,s,u,a,f,l,c,h){i+=c,s+=c,u+=c,n.err=="x"?(s>r+l?o(t,[[s,i],[Math.max(r+l,h[0]),i]]):a=!1,u<r-l?o(t,[[Math.min(r-l,h[1]),i],[u,i]]):f=!1):(s<i-l?o(t,[[r,s],[r,Math.min(i-l,h[0])]]):a=!1,u>i+l?o(t,[[r,Math.max(i+l,h[1])],[r,u]]):f=!1),l=n.radius!=null?n.radius:l,a&&(n.upperCap=="-"?n.err=="x"?o(t,[[s,i-l],[s,i+l]]):o(t,[[r-l,s],[r+l,s]]):e.isFunction(n.upperCap)&&(n.err=="x"?n.upperCap(t,s,i,l):n.upperCap(t,r,s,l))),f&&(n.lowerCap=="-"?n.err=="x"?o(t,[[u,i-l],[u,i+l]]):o(t,[[r-l,u],[r+l,u]]):e.isFunction(n.lowerCap)&&(n.err=="x"?n.lowerCap(t,u,i,l):n.lowerCap(t,r,u,l)))}function o(e,t){e.beginPath(),e.moveTo(t[0][0],t[0][1]);for(var n=1;n<t.length;n++)e.lineTo(t[n][0],t[n][1]);e.stroke()}function u(t,n){var r=t.getPlotOffset();n.save(),n.translate(r.left,r.top),e.each(t.getData(),function(e,r){r.points.errorbars&&(r.points.xerr.show||r.points.yerr.show)&&i(t,n,r)}),n.restore()}function a(e){e.hooks.processRawData.push(n),e.hooks.draw.push(u)}var t={series:{points:{errorbars:null,xerr:{err:"x",show:null,asymmetric:null,upperCap:null,lowerCap:null,color:null,radius:null},yerr:{err:"y",show:null,asymmetric:null,upperCap:null,lowerCap:null,color:null,radius:null}}}};e.plot.plugins.push({init:a,options:t,name:"errorbars",version:"1.0"})})(jQuery);
@@ -0,0 +1,226 @@
1
+ /* Flot plugin for computing bottoms for filled line and bar charts.
2
+
3
+ Copyright (c) 2007-2013 IOLA and Ole Laursen.
4
+ Licensed under the MIT license.
5
+
6
+ The case: you've got two series that you want to fill the area between. In Flot
7
+ terms, you need to use one as the fill bottom of the other. You can specify the
8
+ bottom of each data point as the third coordinate manually, or you can use this
9
+ plugin to compute it for you.
10
+
11
+ In order to name the other series, you need to give it an id, like this:
12
+
13
+ var dataset = [
14
+ { data: [ ... ], id: "foo" } , // use default bottom
15
+ { data: [ ... ], fillBetween: "foo" }, // use first dataset as bottom
16
+ ];
17
+
18
+ $.plot($("#placeholder"), dataset, { lines: { show: true, fill: true }});
19
+
20
+ As a convenience, if the id given is a number that doesn't appear as an id in
21
+ the series, it is interpreted as the index in the array instead (so fillBetween:
22
+ 0 can also mean the first series).
23
+
24
+ Internally, the plugin modifies the datapoints in each series. For line series,
25
+ extra data points might be inserted through interpolation. Note that at points
26
+ where the bottom line is not defined (due to a null point or start/end of line),
27
+ the current line will show a gap too. The algorithm comes from the
28
+ jquery.flot.stack.js plugin, possibly some code could be shared.
29
+
30
+ */
31
+
32
+ (function ( $ ) {
33
+
34
+ var options = {
35
+ series: {
36
+ fillBetween: null // or number
37
+ }
38
+ };
39
+
40
+ function init( plot ) {
41
+
42
+ function findBottomSeries( s, allseries ) {
43
+
44
+ var i;
45
+
46
+ for ( i = 0; i < allseries.length; ++i ) {
47
+ if ( allseries[ i ].id === s.fillBetween ) {
48
+ return allseries[ i ];
49
+ }
50
+ }
51
+
52
+ if ( typeof s.fillBetween === "number" ) {
53
+ if ( s.fillBetween < 0 || s.fillBetween >= allseries.length ) {
54
+ return null;
55
+ }
56
+ return allseries[ s.fillBetween ];
57
+ }
58
+
59
+ return null;
60
+ }
61
+
62
+ function computeFillBottoms( plot, s, datapoints ) {
63
+
64
+ if ( s.fillBetween == null ) {
65
+ return;
66
+ }
67
+
68
+ var other = findBottomSeries( s, plot.getData() );
69
+
70
+ if ( !other ) {
71
+ return;
72
+ }
73
+
74
+ var ps = datapoints.pointsize,
75
+ points = datapoints.points,
76
+ otherps = other.datapoints.pointsize,
77
+ otherpoints = other.datapoints.points,
78
+ newpoints = [],
79
+ px, py, intery, qx, qy, bottom,
80
+ withlines = s.lines.show,
81
+ withbottom = ps > 2 && datapoints.format[2].y,
82
+ withsteps = withlines && s.lines.steps,
83
+ fromgap = true,
84
+ i = 0,
85
+ j = 0,
86
+ l, m;
87
+
88
+ while ( true ) {
89
+
90
+ if ( i >= points.length ) {
91
+ break;
92
+ }
93
+
94
+ l = newpoints.length;
95
+
96
+ if ( points[ i ] == null ) {
97
+
98
+ // copy gaps
99
+
100
+ for ( m = 0; m < ps; ++m ) {
101
+ newpoints.push( points[ i + m ] );
102
+ }
103
+
104
+ i += ps;
105
+
106
+ } else if ( j >= otherpoints.length ) {
107
+
108
+ // for lines, we can't use the rest of the points
109
+
110
+ if ( !withlines ) {
111
+ for ( m = 0; m < ps; ++m ) {
112
+ newpoints.push( points[ i + m ] );
113
+ }
114
+ }
115
+
116
+ i += ps;
117
+
118
+ } else if ( otherpoints[ j ] == null ) {
119
+
120
+ // oops, got a gap
121
+
122
+ for ( m = 0; m < ps; ++m ) {
123
+ newpoints.push( null );
124
+ }
125
+
126
+ fromgap = true;
127
+ j += otherps;
128
+
129
+ } else {
130
+
131
+ // cases where we actually got two points
132
+
133
+ px = points[ i ];
134
+ py = points[ i + 1 ];
135
+ qx = otherpoints[ j ];
136
+ qy = otherpoints[ j + 1 ];
137
+ bottom = 0;
138
+
139
+ if ( px === qx ) {
140
+
141
+ for ( m = 0; m < ps; ++m ) {
142
+ newpoints.push( points[ i + m ] );
143
+ }
144
+
145
+ //newpoints[ l + 1 ] += qy;
146
+ bottom = qy;
147
+
148
+ i += ps;
149
+ j += otherps;
150
+
151
+ } else if ( px > qx ) {
152
+
153
+ // we got past point below, might need to
154
+ // insert interpolated extra point
155
+
156
+ if ( withlines && i > 0 && points[ i - ps ] != null ) {
157
+ intery = py + ( points[ i - ps + 1 ] - py ) * ( qx - px ) / ( points[ i - ps ] - px );
158
+ newpoints.push( qx );
159
+ newpoints.push( intery );
160
+ for ( m = 2; m < ps; ++m ) {
161
+ newpoints.push( points[ i + m ] );
162
+ }
163
+ bottom = qy;
164
+ }
165
+
166
+ j += otherps;
167
+
168
+ } else { // px < qx
169
+
170
+ // if we come from a gap, we just skip this point
171
+
172
+ if ( fromgap && withlines ) {
173
+ i += ps;
174
+ continue;
175
+ }
176
+
177
+ for ( m = 0; m < ps; ++m ) {
178
+ newpoints.push( points[ i + m ] );
179
+ }
180
+
181
+ // we might be able to interpolate a point below,
182
+ // this can give us a better y
183
+
184
+ if ( withlines && j > 0 && otherpoints[ j - otherps ] != null ) {
185
+ bottom = qy + ( otherpoints[ j - otherps + 1 ] - qy ) * ( px - qx ) / ( otherpoints[ j - otherps ] - qx );
186
+ }
187
+
188
+ //newpoints[l + 1] += bottom;
189
+
190
+ i += ps;
191
+ }
192
+
193
+ fromgap = false;
194
+
195
+ if ( l !== newpoints.length && withbottom ) {
196
+ newpoints[ l + 2 ] = bottom;
197
+ }
198
+ }
199
+
200
+ // maintain the line steps invariant
201
+
202
+ if ( withsteps && l !== newpoints.length && l > 0 &&
203
+ newpoints[ l ] !== null &&
204
+ newpoints[ l ] !== newpoints[ l - ps ] &&
205
+ newpoints[ l + 1 ] !== newpoints[ l - ps + 1 ] ) {
206
+ for (m = 0; m < ps; ++m) {
207
+ newpoints[ l + ps + m ] = newpoints[ l + m ];
208
+ }
209
+ newpoints[ l + 1 ] = newpoints[ l - ps + 1 ];
210
+ }
211
+ }
212
+
213
+ datapoints.points = newpoints;
214
+ }
215
+
216
+ plot.hooks.processDatapoints.push( computeFillBottoms );
217
+ }
218
+
219
+ $.plot.plugins.push({
220
+ init: init,
221
+ options: options,
222
+ name: "fillbetween",
223
+ version: "1.0"
224
+ });
225
+
226
+ })(jQuery);
@@ -0,0 +1,30 @@
1
+ /* Flot plugin for computing bottoms for filled line and bar charts.
2
+
3
+ Copyright (c) 2007-2013 IOLA and Ole Laursen.
4
+ Licensed under the MIT license.
5
+
6
+ The case: you've got two series that you want to fill the area between. In Flot
7
+ terms, you need to use one as the fill bottom of the other. You can specify the
8
+ bottom of each data point as the third coordinate manually, or you can use this
9
+ plugin to compute it for you.
10
+
11
+ In order to name the other series, you need to give it an id, like this:
12
+
13
+ var dataset = [
14
+ { data: [ ... ], id: "foo" } , // use default bottom
15
+ { data: [ ... ], fillBetween: "foo" }, // use first dataset as bottom
16
+ ];
17
+
18
+ $.plot($("#placeholder"), dataset, { lines: { show: true, fill: true }});
19
+
20
+ As a convenience, if the id given is a number that doesn't appear as an id in
21
+ the series, it is interpreted as the index in the array instead (so fillBetween:
22
+ 0 can also mean the first series).
23
+
24
+ Internally, the plugin modifies the datapoints in each series. For line series,
25
+ extra data points might be inserted through interpolation. Note that at points
26
+ where the bottom line is not defined (due to a null point or start/end of line),
27
+ the current line will show a gap too. The algorithm comes from the
28
+ jquery.flot.stack.js plugin, possibly some code could be shared.
29
+
30
+ */(function(e){function n(e){function t(e,t){var n;for(n=0;n<t.length;++n)if(t[n].id===e.fillBetween)return t[n];return typeof e.fillBetween=="number"?e.fillBetween<0||e.fillBetween>=t.length?null:t[e.fillBetween]:null}function n(e,n,r){if(n.fillBetween==null)return;var i=t(n,e.getData());if(!i)return;var s=r.pointsize,o=r.points,u=i.datapoints.pointsize,a=i.datapoints.points,f=[],l,c,h,p,d,v,m=n.lines.show,g=s>2&&r.format[2].y,y=m&&n.lines.steps,b=!0,w=0,E=0,S,x;for(;;){if(w>=o.length)break;S=f.length;if(o[w]==null){for(x=0;x<s;++x)f.push(o[w+x]);w+=s}else if(E>=a.length){if(!m)for(x=0;x<s;++x)f.push(o[w+x]);w+=s}else if(a[E]==null){for(x=0;x<s;++x)f.push(null);b=!0,E+=u}else{l=o[w],c=o[w+1],p=a[E],d=a[E+1],v=0;if(l===p){for(x=0;x<s;++x)f.push(o[w+x]);v=d,w+=s,E+=u}else if(l>p){if(m&&w>0&&o[w-s]!=null){h=c+(o[w-s+1]-c)*(p-l)/(o[w-s]-l),f.push(p),f.push(h);for(x=2;x<s;++x)f.push(o[w+x]);v=d}E+=u}else{if(b&&m){w+=s;continue}for(x=0;x<s;++x)f.push(o[w+x]);m&&E>0&&a[E-u]!=null&&(v=d+(a[E-u+1]-d)*(l-p)/(a[E-u]-p)),w+=s}b=!1,S!==f.length&&g&&(f[S+2]=v)}if(y&&S!==f.length&&S>0&&f[S]!==null&&f[S]!==f[S-s]&&f[S+1]!==f[S-s+1]){for(x=0;x<s;++x)f[S+s+x]=f[S+x];f[S+1]=f[S-s+1]}}r.points=f}e.hooks.processDatapoints.push(n)}var t={series:{fillBetween:null}};e.plot.plugins.push({init:n,options:t,name:"fillbetween",version:"1.0"})})(jQuery);