outfielding-jqplot-rails 1.0.4.1121

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/.gitignore +17 -0
  2. data/CHANGELOG.md +3 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +27 -0
  5. data/README-jqplot.txt +77 -0
  6. data/README.md +48 -0
  7. data/Rakefile +1 -0
  8. data/lib/outfielding-jqplot-rails/version.rb +7 -0
  9. data/lib/outfielding-jqplot-rails.rb +10 -0
  10. data/outfielding-jqplot-rails.gemspec +19 -0
  11. data/vendor/assets/javascripts/excanvas.js +1438 -0
  12. data/vendor/assets/javascripts/jqplot-plugins/jqplot.BezierCurveRenderer.js +313 -0
  13. data/vendor/assets/javascripts/jqplot-plugins/jqplot.barRenderer.js +797 -0
  14. data/vendor/assets/javascripts/jqplot-plugins/jqplot.blockRenderer.js +235 -0
  15. data/vendor/assets/javascripts/jqplot-plugins/jqplot.bubbleRenderer.js +759 -0
  16. data/vendor/assets/javascripts/jqplot-plugins/jqplot.canvasAxisLabelRenderer.js +203 -0
  17. data/vendor/assets/javascripts/jqplot-plugins/jqplot.canvasAxisTickRenderer.js +243 -0
  18. data/vendor/assets/javascripts/jqplot-plugins/jqplot.canvasOverlay.js +865 -0
  19. data/vendor/assets/javascripts/jqplot-plugins/jqplot.canvasTextRenderer.js +449 -0
  20. data/vendor/assets/javascripts/jqplot-plugins/jqplot.categoryAxisRenderer.js +673 -0
  21. data/vendor/assets/javascripts/jqplot-plugins/jqplot.ciParser.js +116 -0
  22. data/vendor/assets/javascripts/jqplot-plugins/jqplot.cursor.js +1108 -0
  23. data/vendor/assets/javascripts/jqplot-plugins/jqplot.dateAxisRenderer.js +737 -0
  24. data/vendor/assets/javascripts/jqplot-plugins/jqplot.donutRenderer.js +805 -0
  25. data/vendor/assets/javascripts/jqplot-plugins/jqplot.dragable.js +225 -0
  26. data/vendor/assets/javascripts/jqplot-plugins/jqplot.enhancedLegendRenderer.js +305 -0
  27. data/vendor/assets/javascripts/jqplot-plugins/jqplot.funnelRenderer.js +943 -0
  28. data/vendor/assets/javascripts/jqplot-plugins/jqplot.highlighter.js +465 -0
  29. data/vendor/assets/javascripts/jqplot-plugins/jqplot.json2.js +475 -0
  30. data/vendor/assets/javascripts/jqplot-plugins/jqplot.logAxisRenderer.js +529 -0
  31. data/vendor/assets/javascripts/jqplot-plugins/jqplot.mekkoAxisRenderer.js +611 -0
  32. data/vendor/assets/javascripts/jqplot-plugins/jqplot.mekkoRenderer.js +437 -0
  33. data/vendor/assets/javascripts/jqplot-plugins/jqplot.meterGaugeRenderer.js +1030 -0
  34. data/vendor/assets/javascripts/jqplot-plugins/jqplot.mobile.js +45 -0
  35. data/vendor/assets/javascripts/jqplot-plugins/jqplot.ohlcRenderer.js +373 -0
  36. data/vendor/assets/javascripts/jqplot-plugins/jqplot.pieRenderer.js +904 -0
  37. data/vendor/assets/javascripts/jqplot-plugins/jqplot.pointLabels.js +379 -0
  38. data/vendor/assets/javascripts/jqplot-plugins/jqplot.pyramidAxisRenderer.js +728 -0
  39. data/vendor/assets/javascripts/jqplot-plugins/jqplot.pyramidGridRenderer.js +429 -0
  40. data/vendor/assets/javascripts/jqplot-plugins/jqplot.pyramidRenderer.js +514 -0
  41. data/vendor/assets/javascripts/jqplot-plugins/jqplot.trendline.js +223 -0
  42. data/vendor/assets/javascripts/jquery.jqplot.js +11381 -0
  43. data/vendor/assets/stylesheets/jquery.jqplot.css +259 -0
  44. metadata +88 -0
@@ -0,0 +1,865 @@
1
+ /**
2
+ * jqPlot
3
+ * Pure JavaScript plotting plugin using jQuery
4
+ *
5
+ * Version: 1.0.4
6
+ * Revision: 1121
7
+ *
8
+ * Copyright (c) 2009-2012 Chris Leonello
9
+ * jqPlot is currently available for use in all personal or commercial projects
10
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
11
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
12
+ * choose the license that best suits your project and use it accordingly.
13
+ *
14
+ * Although not required, the author would appreciate an email letting him
15
+ * know of any substantial use of jqPlot. You can reach the author at:
16
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
17
+ *
18
+ * If you are feeling kind and generous, consider supporting the project by
19
+ * making a donation at: http://www.jqplot.com/donate.php .
20
+ *
21
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
22
+ *
23
+ * version 2007.04.27
24
+ * author Ash Searle
25
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
26
+ * http://hexmen.com/js/sprintf.js
27
+ * The author (Ash Searle) has placed this code in the public domain:
28
+ * "This code is unrestricted: you are free to use it however you like."
29
+ *
30
+ */
31
+ (function($) {
32
+ var objCounter = 0;
33
+ // class: $.jqplot.CanvasOverlay
34
+ $.jqplot.CanvasOverlay = function(opts){
35
+ var options = opts || {};
36
+ this.options = {
37
+ show: $.jqplot.config.enablePlugins,
38
+ deferDraw: false
39
+ };
40
+ // prop: objects
41
+ this.objects = [];
42
+ this.objectNames = [];
43
+ this.canvas = null;
44
+ this.markerRenderer = new $.jqplot.MarkerRenderer({style:'line'});
45
+ this.markerRenderer.init();
46
+ this.highlightObjectIndex = null;
47
+ if (options.objects) {
48
+ var objs = options.objects,
49
+ obj;
50
+ for (var i=0; i<objs.length; i++) {
51
+ obj = objs[i];
52
+ for (var n in obj) {
53
+ switch (n) {
54
+ case 'line':
55
+ this.addLine(obj[n]);
56
+ break;
57
+ case 'horizontalLine':
58
+ this.addHorizontalLine(obj[n]);
59
+ break;
60
+ case 'dashedHorizontalLine':
61
+ this.addDashedHorizontalLine(obj[n]);
62
+ break;
63
+ case 'verticalLine':
64
+ this.addVerticalLine(obj[n]);
65
+ break;
66
+ case 'dashedVerticalLine':
67
+ this.addDashedVerticalLine(obj[n]);
68
+ break;
69
+ default:
70
+ break;
71
+ }
72
+ }
73
+ }
74
+ }
75
+ $.extend(true, this.options, options);
76
+ };
77
+
78
+ // called with scope of a plot object
79
+ $.jqplot.CanvasOverlay.postPlotInit = function (target, data, opts) {
80
+ var options = opts || {};
81
+ // add a canvasOverlay attribute to the plot
82
+ this.plugins.canvasOverlay = new $.jqplot.CanvasOverlay(options.canvasOverlay);
83
+ };
84
+
85
+
86
+ function LineBase() {
87
+ this.uid = null;
88
+ this.type = null;
89
+ this.gridStart = null;
90
+ this.gridStop = null;
91
+ this.tooltipWidthFactor = 0;
92
+ this.options = {
93
+ // prop: name
94
+ // Optional name for the overlay object.
95
+ // Can be later used to retrieve the object by name.
96
+ name: null,
97
+ // prop: show
98
+ // true to show (draw), false to not draw.
99
+ show: true,
100
+ // prop: lineWidth
101
+ // Width of the line.
102
+ lineWidth: 2,
103
+ // prop: lineCap
104
+ // Type of ending placed on the line ['round', 'butt', 'square']
105
+ lineCap: 'round',
106
+ // prop: color
107
+ // color of the line
108
+ color: '#666666',
109
+ // prop: shadow
110
+ // wether or not to draw a shadow on the line
111
+ shadow: true,
112
+ // prop: shadowAngle
113
+ // Shadow angle in degrees
114
+ shadowAngle: 45,
115
+ // prop: shadowOffset
116
+ // Shadow offset from line in pixels
117
+ shadowOffset: 1,
118
+ // prop: shadowDepth
119
+ // Number of times shadow is stroked, each stroke offset shadowOffset from the last.
120
+ shadowDepth: 3,
121
+ // prop: shadowAlpha
122
+ // Alpha channel transparency of shadow. 0 = transparent.
123
+ shadowAlpha: '0.07',
124
+ // prop: xaxis
125
+ // X axis to use for positioning/scaling the line.
126
+ xaxis: 'xaxis',
127
+ // prop: yaxis
128
+ // Y axis to use for positioning/scaling the line.
129
+ yaxis: 'yaxis',
130
+ // prop: showTooltip
131
+ // Show a tooltip with data point values.
132
+ showTooltip: false,
133
+ // prop: showTooltipPrecision
134
+ // Controls how close to line cursor must be to show tooltip.
135
+ // Higher number = closer to line, lower number = farther from line.
136
+ // 1.0 = cursor must be over line.
137
+ showTooltipPrecision: 0.6,
138
+ // prop: tooltipLocation
139
+ // Where to position tooltip, 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw'
140
+ tooltipLocation: 'nw',
141
+ // prop: fadeTooltip
142
+ // true = fade in/out tooltip, flase = show/hide tooltip
143
+ fadeTooltip: true,
144
+ // prop: tooltipFadeSpeed
145
+ // 'slow', 'def', 'fast', or number of milliseconds.
146
+ tooltipFadeSpeed: "fast",
147
+ // prop: tooltipOffset
148
+ // Pixel offset of tooltip from the highlight.
149
+ tooltipOffset: 4,
150
+ // prop: tooltipFormatString
151
+ // Format string passed the x and y values of the cursor on the line.
152
+ // e.g., 'Dogs: %.2f, Cats: %d'.
153
+ tooltipFormatString: '%d, %d'
154
+ };
155
+ }
156
+
157
+ /**
158
+ * Class: Line
159
+ * A straight line.
160
+ */
161
+ function Line(options) {
162
+ LineBase.call(this);
163
+ this.type = 'line';
164
+ var opts = {
165
+ // prop: start
166
+ // [x, y] coordinates for the start of the line.
167
+ start: [],
168
+ // prop: stop
169
+ // [x, y] coordinates for the end of the line.
170
+ stop: []
171
+ };
172
+ $.extend(true, this.options, opts, options);
173
+
174
+ if (this.options.showTooltipPrecision < 0.01) {
175
+ this.options.showTooltipPrecision = 0.01;
176
+ }
177
+ }
178
+
179
+ Line.prototype = new LineBase();
180
+ Line.prototype.constructor = Line;
181
+
182
+
183
+ /**
184
+ * Class: HorizontalLine
185
+ * A straight horizontal line.
186
+ */
187
+ function HorizontalLine(options) {
188
+ LineBase.call(this);
189
+ this.type = 'horizontalLine';
190
+ var opts = {
191
+ // prop: y
192
+ // y value to position the line
193
+ y: null,
194
+ // prop: xmin
195
+ // x value for the start of the line, null to scale to axis min.
196
+ xmin: null,
197
+ // prop: xmax
198
+ // x value for the end of the line, null to scale to axis max.
199
+ xmax: null,
200
+ // prop xOffset
201
+ // offset ends of the line inside the grid. Number
202
+ xOffset: '6px', // number or string. Number interpreted as units, string as pixels.
203
+ xminOffset: null,
204
+ xmaxOffset: null
205
+ };
206
+ $.extend(true, this.options, opts, options);
207
+
208
+ if (this.options.showTooltipPrecision < 0.01) {
209
+ this.options.showTooltipPrecision = 0.01;
210
+ }
211
+ }
212
+
213
+ HorizontalLine.prototype = new LineBase();
214
+ HorizontalLine.prototype.constructor = HorizontalLine;
215
+
216
+
217
+ /**
218
+ * Class: DashedHorizontalLine
219
+ * A straight dashed horizontal line.
220
+ */
221
+ function DashedHorizontalLine(options) {
222
+ LineBase.call(this);
223
+ this.type = 'dashedHorizontalLine';
224
+ var opts = {
225
+ y: null,
226
+ xmin: null,
227
+ xmax: null,
228
+ xOffset: '6px', // number or string. Number interpreted as units, string as pixels.
229
+ xminOffset: null,
230
+ xmaxOffset: null,
231
+ // prop: dashPattern
232
+ // Array of line, space settings in pixels.
233
+ // Default is 8 pixel of line, 8 pixel of space.
234
+ // Note, limit to a 2 element array b/c of bug with higher order arrays.
235
+ dashPattern: [8,8]
236
+ };
237
+ $.extend(true, this.options, opts, options);
238
+
239
+ if (this.options.showTooltipPrecision < 0.01) {
240
+ this.options.showTooltipPrecision = 0.01;
241
+ }
242
+ }
243
+
244
+ DashedHorizontalLine.prototype = new LineBase();
245
+ DashedHorizontalLine.prototype.constructor = DashedHorizontalLine;
246
+
247
+
248
+ /**
249
+ * Class: VerticalLine
250
+ * A straight vertical line.
251
+ */
252
+ function VerticalLine(options) {
253
+ LineBase.call(this);
254
+ this.type = 'verticalLine';
255
+ var opts = {
256
+ x: null,
257
+ ymin: null,
258
+ ymax: null,
259
+ yOffset: '6px', // number or string. Number interpreted as units, string as pixels.
260
+ yminOffset: null,
261
+ ymaxOffset: null
262
+ };
263
+ $.extend(true, this.options, opts, options);
264
+
265
+ if (this.options.showTooltipPrecision < 0.01) {
266
+ this.options.showTooltipPrecision = 0.01;
267
+ }
268
+ }
269
+
270
+ VerticalLine.prototype = new LineBase();
271
+ VerticalLine.prototype.constructor = VerticalLine;
272
+
273
+
274
+ /**
275
+ * Class: DashedVerticalLine
276
+ * A straight dashed vertical line.
277
+ */
278
+ function DashedVerticalLine(options) {
279
+ LineBase.call(this);
280
+ this.type = 'dashedVerticalLine';
281
+ this.start = null;
282
+ this.stop = null;
283
+ var opts = {
284
+ x: null,
285
+ ymin: null,
286
+ ymax: null,
287
+ yOffset: '6px', // number or string. Number interpreted as units, string as pixels.
288
+ yminOffset: null,
289
+ ymaxOffset: null,
290
+ // prop: dashPattern
291
+ // Array of line, space settings in pixels.
292
+ // Default is 8 pixel of line, 8 pixel of space.
293
+ // Note, limit to a 2 element array b/c of bug with higher order arrays.
294
+ dashPattern: [8,8]
295
+ };
296
+ $.extend(true, this.options, opts, options);
297
+
298
+ if (this.options.showTooltipPrecision < 0.01) {
299
+ this.options.showTooltipPrecision = 0.01;
300
+ }
301
+ }
302
+
303
+ DashedVerticalLine.prototype = new LineBase();
304
+ DashedVerticalLine.prototype.constructor = DashedVerticalLine;
305
+
306
+ $.jqplot.CanvasOverlay.prototype.addLine = function(opts) {
307
+ var line = new Line(opts);
308
+ line.uid = objCounter++;
309
+ this.objects.push(line);
310
+ this.objectNames.push(line.options.name);
311
+ };
312
+
313
+ $.jqplot.CanvasOverlay.prototype.addHorizontalLine = function(opts) {
314
+ var line = new HorizontalLine(opts);
315
+ line.uid = objCounter++;
316
+ this.objects.push(line);
317
+ this.objectNames.push(line.options.name);
318
+ };
319
+
320
+ $.jqplot.CanvasOverlay.prototype.addDashedHorizontalLine = function(opts) {
321
+ var line = new DashedHorizontalLine(opts);
322
+ line.uid = objCounter++;
323
+ this.objects.push(line);
324
+ this.objectNames.push(line.options.name);
325
+ };
326
+
327
+ $.jqplot.CanvasOverlay.prototype.addVerticalLine = function(opts) {
328
+ var line = new VerticalLine(opts);
329
+ line.uid = objCounter++;
330
+ this.objects.push(line);
331
+ this.objectNames.push(line.options.name);
332
+ };
333
+
334
+ $.jqplot.CanvasOverlay.prototype.addDashedVerticalLine = function(opts) {
335
+ var line = new DashedVerticalLine(opts);
336
+ line.uid = objCounter++;
337
+ this.objects.push(line);
338
+ this.objectNames.push(line.options.name);
339
+ };
340
+
341
+ $.jqplot.CanvasOverlay.prototype.removeObject = function(idx) {
342
+ // check if integer, remove by index
343
+ if ($.type(idx) == 'number') {
344
+ this.objects.splice(idx, 1);
345
+ this.objectNames.splice(idx, 1);
346
+ }
347
+ // if string, remove by name
348
+ else {
349
+ var id = $.inArray(idx, this.objectNames);
350
+ if (id != -1) {
351
+ this.objects.splice(id, 1);
352
+ this.objectNames.splice(id, 1);
353
+ }
354
+ }
355
+ };
356
+
357
+ $.jqplot.CanvasOverlay.prototype.getObject = function(idx) {
358
+ // check if integer, remove by index
359
+ if ($.type(idx) == 'number') {
360
+ return this.objects[idx];
361
+ }
362
+ // if string, remove by name
363
+ else {
364
+ var id = $.inArray(idx, this.objectNames);
365
+ if (id != -1) {
366
+ return this.objects[id];
367
+ }
368
+ }
369
+ };
370
+
371
+ // Set get as alias for getObject.
372
+ $.jqplot.CanvasOverlay.prototype.get = $.jqplot.CanvasOverlay.prototype.getObject;
373
+
374
+ $.jqplot.CanvasOverlay.prototype.clear = function(plot) {
375
+ this.canvas._ctx.clearRect(0,0,this.canvas.getWidth(), this.canvas.getHeight());
376
+ };
377
+
378
+ $.jqplot.CanvasOverlay.prototype.draw = function(plot) {
379
+ var obj,
380
+ objs = this.objects,
381
+ mr = this.markerRenderer,
382
+ start,
383
+ stop;
384
+ if (this.options.show) {
385
+ this.canvas._ctx.clearRect(0,0,this.canvas.getWidth(), this.canvas.getHeight());
386
+ for (var k=0; k<objs.length; k++) {
387
+ obj = objs[k];
388
+ var opts = $.extend(true, {}, obj.options);
389
+ if (obj.options.show) {
390
+ // style and shadow properties should be set before
391
+ // every draw of marker renderer.
392
+ mr.shadow = obj.options.shadow;
393
+ obj.tooltipWidthFactor = obj.options.lineWidth / obj.options.showTooltipPrecision;
394
+ switch (obj.type) {
395
+ case 'line':
396
+ // style and shadow properties should be set before
397
+ // every draw of marker renderer.
398
+ mr.style = 'line';
399
+ opts.closePath = false;
400
+ start = [plot.axes[obj.options.xaxis].series_u2p(obj.options.start[0]), plot.axes[obj.options.yaxis].series_u2p(obj.options.start[1])];
401
+ stop = [plot.axes[obj.options.xaxis].series_u2p(obj.options.stop[0]), plot.axes[obj.options.yaxis].series_u2p(obj.options.stop[1])];
402
+ obj.gridStart = start;
403
+ obj.gridStop = stop;
404
+ mr.draw(start, stop, this.canvas._ctx, opts);
405
+ break;
406
+ case 'horizontalLine':
407
+
408
+ // style and shadow properties should be set before
409
+ // every draw of marker renderer.
410
+ if (obj.options.y != null) {
411
+ mr.style = 'line';
412
+ opts.closePath = false;
413
+ var xaxis = plot.axes[obj.options.xaxis],
414
+ xstart,
415
+ xstop,
416
+ y = plot.axes[obj.options.yaxis].series_u2p(obj.options.y),
417
+ xminoff = obj.options.xminOffset || obj.options.xOffset,
418
+ xmaxoff = obj.options.xmaxOffset || obj.options.xOffset;
419
+ if (obj.options.xmin != null) {
420
+ xstart = xaxis.series_u2p(obj.options.xmin);
421
+ }
422
+ else if (xminoff != null) {
423
+ if ($.type(xminoff) == "number") {
424
+ xstart = xaxis.series_u2p(xaxis.min + xminoff);
425
+ }
426
+ else if ($.type(xminoff) == "string") {
427
+ xstart = xaxis.series_u2p(xaxis.min) + parseFloat(xminoff);
428
+ }
429
+ }
430
+ if (obj.options.xmax != null) {
431
+ xstop = xaxis.series_u2p(obj.options.xmax);
432
+ }
433
+ else if (xmaxoff != null) {
434
+ if ($.type(xmaxoff) == "number") {
435
+ xstop = xaxis.series_u2p(xaxis.max - xmaxoff);
436
+ }
437
+ else if ($.type(xmaxoff) == "string") {
438
+ xstop = xaxis.series_u2p(xaxis.max) - parseFloat(xmaxoff);
439
+ }
440
+ }
441
+ if (xstop != null && xstart != null) {
442
+ obj.gridStart = [xstart, y];
443
+ obj.gridStop = [xstop, y];
444
+ mr.draw([xstart, y], [xstop, y], this.canvas._ctx, opts);
445
+ }
446
+ }
447
+ break;
448
+
449
+ case 'dashedHorizontalLine':
450
+
451
+ var dashPat = obj.options.dashPattern;
452
+ var dashPatLen = 0;
453
+ for (var i=0; i<dashPat.length; i++) {
454
+ dashPatLen += dashPat[i];
455
+ }
456
+
457
+ // style and shadow properties should be set before
458
+ // every draw of marker renderer.
459
+ if (obj.options.y != null) {
460
+ mr.style = 'line';
461
+ opts.closePath = false;
462
+ var xaxis = plot.axes[obj.options.xaxis],
463
+ xstart,
464
+ xstop,
465
+ y = plot.axes[obj.options.yaxis].series_u2p(obj.options.y),
466
+ xminoff = obj.options.xminOffset || obj.options.xOffset,
467
+ xmaxoff = obj.options.xmaxOffset || obj.options.xOffset;
468
+ if (obj.options.xmin != null) {
469
+ xstart = xaxis.series_u2p(obj.options.xmin);
470
+ }
471
+ else if (xminoff != null) {
472
+ if ($.type(xminoff) == "number") {
473
+ xstart = xaxis.series_u2p(xaxis.min + xminoff);
474
+ }
475
+ else if ($.type(xminoff) == "string") {
476
+ xstart = xaxis.series_u2p(xaxis.min) + parseFloat(xminoff);
477
+ }
478
+ }
479
+ if (obj.options.xmax != null) {
480
+ xstop = xaxis.series_u2p(obj.options.xmax);
481
+ }
482
+ else if (xmaxoff != null) {
483
+ if ($.type(xmaxoff) == "number") {
484
+ xstop = xaxis.series_u2p(xaxis.max - xmaxoff);
485
+ }
486
+ else if ($.type(xmaxoff) == "string") {
487
+ xstop = xaxis.series_u2p(xaxis.max) - parseFloat(xmaxoff);
488
+ }
489
+ }
490
+ if (xstop != null && xstart != null) {
491
+ obj.gridStart = [xstart, y];
492
+ obj.gridStop = [xstop, y];
493
+ var numDash = Math.ceil((xstop - xstart)/dashPatLen);
494
+ var b=xstart, e;
495
+ for (var i=0; i<numDash; i++) {
496
+ for (var j=0; j<dashPat.length; j+=2) {
497
+ e = b+dashPat[j];
498
+ mr.draw([b, y], [e, y], this.canvas._ctx, opts);
499
+ b += dashPat[j];
500
+ if (j < dashPat.length-1) {
501
+ b += dashPat[j+1];
502
+ }
503
+ }
504
+ }
505
+ }
506
+ }
507
+ break;
508
+
509
+ case 'verticalLine':
510
+
511
+ // style and shadow properties should be set before
512
+ // every draw of marker renderer.
513
+ if (obj.options.x != null) {
514
+ mr.style = 'line';
515
+ opts.closePath = false;
516
+ var yaxis = plot.axes[obj.options.yaxis],
517
+ ystart,
518
+ ystop,
519
+ x = plot.axes[obj.options.xaxis].series_u2p(obj.options.x),
520
+ yminoff = obj.options.yminOffset || obj.options.yOffset,
521
+ ymaxoff = obj.options.ymaxOffset || obj.options.yOffset;
522
+ if (obj.options.ymin != null) {
523
+ ystart = yaxis.series_u2p(obj.options.ymin);
524
+ }
525
+ else if (yminoff != null) {
526
+ if ($.type(yminoff) == "number") {
527
+ ystart = yaxis.series_u2p(yaxis.min - yminoff);
528
+ }
529
+ else if ($.type(yminoff) == "string") {
530
+ ystart = yaxis.series_u2p(yaxis.min) - parseFloat(yminoff);
531
+ }
532
+ }
533
+ if (obj.options.ymax != null) {
534
+ ystop = yaxis.series_u2p(obj.options.ymax);
535
+ }
536
+ else if (ymaxoff != null) {
537
+ if ($.type(ymaxoff) == "number") {
538
+ ystop = yaxis.series_u2p(yaxis.max + ymaxoff);
539
+ }
540
+ else if ($.type(ymaxoff) == "string") {
541
+ ystop = yaxis.series_u2p(yaxis.max) + parseFloat(ymaxoff);
542
+ }
543
+ }
544
+ if (ystop != null && ystart != null) {
545
+ obj.gridStart = [x, ystart];
546
+ obj.gridStop = [x, ystop];
547
+ mr.draw([x, ystart], [x, ystop], this.canvas._ctx, opts);
548
+ }
549
+ }
550
+ break;
551
+
552
+ case 'dashedVerticalLine':
553
+
554
+ var dashPat = obj.options.dashPattern;
555
+ var dashPatLen = 0;
556
+ for (var i=0; i<dashPat.length; i++) {
557
+ dashPatLen += dashPat[i];
558
+ }
559
+
560
+ // style and shadow properties should be set before
561
+ // every draw of marker renderer.
562
+ if (obj.options.x != null) {
563
+ mr.style = 'line';
564
+ opts.closePath = false;
565
+ var yaxis = plot.axes[obj.options.yaxis],
566
+ ystart,
567
+ ystop,
568
+ x = plot.axes[obj.options.xaxis].series_u2p(obj.options.x),
569
+ yminoff = obj.options.yminOffset || obj.options.yOffset,
570
+ ymaxoff = obj.options.ymaxOffset || obj.options.yOffset;
571
+ if (obj.options.ymin != null) {
572
+ ystart = yaxis.series_u2p(obj.options.ymin);
573
+ }
574
+ else if (yminoff != null) {
575
+ if ($.type(yminoff) == "number") {
576
+ ystart = yaxis.series_u2p(yaxis.min - yminoff);
577
+ }
578
+ else if ($.type(yminoff) == "string") {
579
+ ystart = yaxis.series_u2p(yaxis.min) - parseFloat(yminoff);
580
+ }
581
+ }
582
+ if (obj.options.ymax != null) {
583
+ ystop = yaxis.series_u2p(obj.options.ymax);
584
+ }
585
+ else if (ymaxoff != null) {
586
+ if ($.type(ymaxoff) == "number") {
587
+ ystop = yaxis.series_u2p(yaxis.max + ymaxoff);
588
+ }
589
+ else if ($.type(ymaxoff) == "string") {
590
+ ystop = yaxis.series_u2p(yaxis.max) + parseFloat(ymaxoff);
591
+ }
592
+ }
593
+
594
+
595
+ if (ystop != null && ystart != null) {
596
+ obj.gridStart = [x, ystart];
597
+ obj.gridStop = [x, ystop];
598
+ var numDash = Math.ceil((ystart - ystop)/dashPatLen);
599
+ var firstDashAdjust = ((numDash * dashPatLen) - (ystart - ystop))/2.0;
600
+ var b=ystart, e, bs, es;
601
+ for (var i=0; i<numDash; i++) {
602
+ for (var j=0; j<dashPat.length; j+=2) {
603
+ e = b - dashPat[j];
604
+ if (e < ystop) {
605
+ e = ystop;
606
+ }
607
+ if (b < ystop) {
608
+ b = ystop;
609
+ }
610
+ // es = e;
611
+ // if (i == 0) {
612
+ // es += firstDashAdjust;
613
+ // }
614
+ mr.draw([x, b], [x, e], this.canvas._ctx, opts);
615
+ b -= dashPat[j];
616
+ if (j < dashPat.length-1) {
617
+ b -= dashPat[j+1];
618
+ }
619
+ }
620
+ }
621
+ }
622
+ }
623
+ break;
624
+
625
+ default:
626
+ break;
627
+ }
628
+ }
629
+ }
630
+ }
631
+ };
632
+
633
+ // called within context of plot
634
+ // create a canvas which we can draw on.
635
+ // insert it before the eventCanvas, so eventCanvas will still capture events.
636
+ $.jqplot.CanvasOverlay.postPlotDraw = function() {
637
+ var co = this.plugins.canvasOverlay;
638
+ // Memory Leaks patch
639
+ if (co && co.highlightCanvas) {
640
+ co.highlightCanvas.resetCanvas();
641
+ co.highlightCanvas = null;
642
+ }
643
+ co.canvas = new $.jqplot.GenericCanvas();
644
+
645
+ this.eventCanvas._elem.before(co.canvas.createElement(this._gridPadding, 'jqplot-overlayCanvas-canvas', this._plotDimensions, this));
646
+ co.canvas.setContext();
647
+ if (!co.deferDraw) {
648
+ co.draw(this);
649
+ }
650
+
651
+ var elem = document.createElement('div');
652
+ co._tooltipElem = $(elem);
653
+ elem = null;
654
+ co._tooltipElem.addClass('jqplot-canvasOverlay-tooltip');
655
+ co._tooltipElem.css({position:'absolute', display:'none'});
656
+
657
+ this.eventCanvas._elem.before(co._tooltipElem);
658
+ this.eventCanvas._elem.bind('mouseleave', { elem: co._tooltipElem }, function (ev) { ev.data.elem.hide(); });
659
+
660
+ var co = null;
661
+ };
662
+
663
+
664
+ function showTooltip(plot, obj, gridpos, datapos) {
665
+ var co = plot.plugins.canvasOverlay;
666
+ var elem = co._tooltipElem;
667
+
668
+ var opts = obj.options, x, y;
669
+
670
+ elem.html($.jqplot.sprintf(opts.tooltipFormatString, datapos[0], datapos[1]));
671
+
672
+ switch (opts.tooltipLocation) {
673
+ case 'nw':
674
+ x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset;
675
+ y = gridpos[1] + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true);
676
+ break;
677
+ case 'n':
678
+ x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true)/2;
679
+ y = gridpos[1] + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true);
680
+ break;
681
+ case 'ne':
682
+ x = gridpos[0] + plot._gridPadding.left + opts.tooltipOffset;
683
+ y = gridpos[1] + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true);
684
+ break;
685
+ case 'e':
686
+ x = gridpos[0] + plot._gridPadding.left + opts.tooltipOffset;
687
+ y = gridpos[1] + plot._gridPadding.top - elem.outerHeight(true)/2;
688
+ break;
689
+ case 'se':
690
+ x = gridpos[0] + plot._gridPadding.left + opts.tooltipOffset;
691
+ y = gridpos[1] + plot._gridPadding.top + opts.tooltipOffset;
692
+ break;
693
+ case 's':
694
+ x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true)/2;
695
+ y = gridpos[1] + plot._gridPadding.top + opts.tooltipOffset;
696
+ break;
697
+ case 'sw':
698
+ x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset;
699
+ y = gridpos[1] + plot._gridPadding.top + opts.tooltipOffset;
700
+ break;
701
+ case 'w':
702
+ x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset;
703
+ y = gridpos[1] + plot._gridPadding.top - elem.outerHeight(true)/2;
704
+ break;
705
+ default: // same as 'nw'
706
+ x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset;
707
+ y = gridpos[1] + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true);
708
+ break;
709
+ }
710
+
711
+ elem.css('left', x);
712
+ elem.css('top', y);
713
+ if (opts.fadeTooltip) {
714
+ // Fix for stacked up animations. Thnanks Trevor!
715
+ elem.stop(true,true).fadeIn(opts.tooltipFadeSpeed);
716
+ }
717
+ else {
718
+ elem.show();
719
+ }
720
+ elem = null;
721
+ }
722
+
723
+
724
+ function isNearLine(point, lstart, lstop, width) {
725
+ // r is point to test, p and q are end points.
726
+ var rx = point[0];
727
+ var ry = point[1];
728
+ var px = Math.round(lstop[0]);
729
+ var py = Math.round(lstop[1]);
730
+ var qx = Math.round(lstart[0]);
731
+ var qy = Math.round(lstart[1]);
732
+
733
+ var l = Math.sqrt(Math.pow(px-qx, 2) + Math.pow(py-qy, 2));
734
+
735
+ // scale error term by length of line.
736
+ var eps = width*l;
737
+ var res = Math.abs((qx-px) * (ry-py) - (qy-py) * (rx-px));
738
+ var ret = (res < eps) ? true : false;
739
+ return ret;
740
+ }
741
+
742
+
743
+ function handleMove(ev, gridpos, datapos, neighbor, plot) {
744
+ var co = plot.plugins.canvasOverlay;
745
+ var objs = co.objects;
746
+ var l = objs.length;
747
+ var obj, haveHighlight=false;
748
+ var elem;
749
+ for (var i=0; i<l; i++) {
750
+ obj = objs[i];
751
+ if (obj.options.showTooltip) {
752
+ var n = isNearLine([gridpos.x, gridpos.y], obj.gridStart, obj.gridStop, obj.tooltipWidthFactor);
753
+ datapos = [plot.axes[obj.options.xaxis].series_p2u(gridpos.x), plot.axes[obj.options.yaxis].series_p2u(gridpos.y)];
754
+
755
+ // cases:
756
+ // near line, no highlighting
757
+ // near line, highliting on this line
758
+ // near line, highlighting another line
759
+ // not near any line, highlighting
760
+ // not near any line, no highlighting
761
+
762
+ // near line, not currently highlighting
763
+ if (n && co.highlightObjectIndex == null) {
764
+ switch (obj.type) {
765
+ case 'line':
766
+ showTooltip(plot, obj, [gridpos.x, gridpos.y], datapos);
767
+ break;
768
+
769
+ case 'horizontalLine':
770
+ case 'dashedHorizontalLine':
771
+ showTooltip(plot, obj, [gridpos.x, obj.gridStart[1]], [datapos[0], obj.options.y]);
772
+ break;
773
+
774
+ case 'verticalLine':
775
+ case 'dashedVerticalLine':
776
+ showTooltip(plot, obj, [obj.gridStart[0], gridpos.y], [obj.options.x, datapos[1]]);
777
+ break;
778
+ default:
779
+ break;
780
+ }
781
+ co.highlightObjectIndex = i;
782
+ haveHighlight = true;
783
+ break;
784
+ }
785
+
786
+ // near line, highlighting another line.
787
+ else if (n && co.highlightObjectIndex !== i) {
788
+ // turn off tooltip.
789
+ elem = co._tooltipElem;
790
+ if (obj.fadeTooltip) {
791
+ elem.fadeOut(obj.tooltipFadeSpeed);
792
+ }
793
+ else {
794
+ elem.hide();
795
+ }
796
+
797
+ // turn on right tooltip.
798
+ switch (obj.type) {
799
+ case 'line':
800
+ showTooltip(plot, obj, [gridpos.x, gridpos.y], datapos);
801
+ break;
802
+
803
+ case 'horizontalLine':
804
+ case 'dashedHorizontalLine':
805
+ showTooltip(plot, obj, [gridpos.x, obj.gridStart[1]], [datapos[0], obj.options.y]);
806
+ break;
807
+
808
+ case 'verticalLine':
809
+ case 'dashedVerticalLine':
810
+ showTooltip(plot, obj, [obj.gridStart[0], gridpos.y], [obj.options.x, datapos[1]]);
811
+ break;
812
+ default:
813
+ break;
814
+ }
815
+
816
+ co.highlightObjectIndex = i;
817
+ haveHighlight = true;
818
+ break;
819
+ }
820
+
821
+ // near line, already highlighting this line, update
822
+ else if (n) {
823
+ switch (obj.type) {
824
+ case 'line':
825
+ showTooltip(plot, obj, [gridpos.x, gridpos.y], datapos);
826
+ break;
827
+
828
+ case 'horizontalLine':
829
+ case 'dashedHorizontalLine':
830
+ showTooltip(plot, obj, [gridpos.x, obj.gridStart[1]], [datapos[0], obj.options.y]);
831
+ break;
832
+
833
+ case 'verticalLine':
834
+ case 'dashedVerticalLine':
835
+ showTooltip(plot, obj, [obj.gridStart[0], gridpos.y], [obj.options.x, datapos[1]]);
836
+ break;
837
+ default:
838
+ break;
839
+ }
840
+
841
+ haveHighlight = true;
842
+ break;
843
+ }
844
+ }
845
+ }
846
+
847
+ // check if we are highlighting and not near a line, turn it off.
848
+ if (!haveHighlight && co.highlightObjectIndex !== null) {
849
+ elem = co._tooltipElem;
850
+ obj = co.getObject(co.highlightObjectIndex);
851
+ if (obj.fadeTooltip) {
852
+ elem.fadeOut(obj.tooltipFadeSpeed);
853
+ }
854
+ else {
855
+ elem.hide();
856
+ }
857
+ co.highlightObjectIndex = null;
858
+ }
859
+ }
860
+
861
+ $.jqplot.postInitHooks.push($.jqplot.CanvasOverlay.postPlotInit);
862
+ $.jqplot.postDrawHooks.push($.jqplot.CanvasOverlay.postPlotDraw);
863
+ $.jqplot.eventListenerHooks.push(['jqplotMouseMove', handleMove]);
864
+
865
+ })(jQuery);