outfielding-jqplot-rails 1.0.8 → 1.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/CHANGELOG.md +8 -4
  4. data/changes-jqplot.txt +48 -37
  5. data/copyright-jqplot.txt +17 -17
  6. data/lib/outfielding-jqplot-rails/version.rb +1 -1
  7. data/vendor/assets/javascripts/excanvas.js +1438 -1438
  8. data/vendor/assets/javascripts/jqplot-plugins/jqplot.BezierCurveRenderer.js +313 -313
  9. data/vendor/assets/javascripts/jqplot-plugins/jqplot.barRenderer.js +801 -801
  10. data/vendor/assets/javascripts/jqplot-plugins/jqplot.blockRenderer.js +234 -234
  11. data/vendor/assets/javascripts/jqplot-plugins/jqplot.bubbleRenderer.js +758 -758
  12. data/vendor/assets/javascripts/jqplot-plugins/jqplot.canvasAxisLabelRenderer.js +202 -202
  13. data/vendor/assets/javascripts/jqplot-plugins/jqplot.canvasAxisTickRenderer.js +252 -252
  14. data/vendor/assets/javascripts/jqplot-plugins/jqplot.canvasOverlay.js +1020 -1020
  15. data/vendor/assets/javascripts/jqplot-plugins/jqplot.canvasTextRenderer.js +448 -448
  16. data/vendor/assets/javascripts/jqplot-plugins/jqplot.categoryAxisRenderer.js +679 -679
  17. data/vendor/assets/javascripts/jqplot-plugins/jqplot.ciParser.js +115 -115
  18. data/vendor/assets/javascripts/jqplot-plugins/jqplot.cursor.js +1108 -1108
  19. data/vendor/assets/javascripts/jqplot-plugins/jqplot.dateAxisRenderer.js +741 -741
  20. data/vendor/assets/javascripts/jqplot-plugins/jqplot.donutRenderer.js +816 -805
  21. data/vendor/assets/javascripts/jqplot-plugins/jqplot.dragable.js +224 -224
  22. data/vendor/assets/javascripts/jqplot-plugins/jqplot.enhancedLegendRenderer.js +305 -305
  23. data/vendor/assets/javascripts/jqplot-plugins/jqplot.enhancedPieLegendRenderer.js +261 -0
  24. data/vendor/assets/javascripts/jqplot-plugins/jqplot.funnelRenderer.js +942 -942
  25. data/vendor/assets/javascripts/jqplot-plugins/jqplot.highlighter.js +464 -464
  26. data/vendor/assets/javascripts/jqplot-plugins/jqplot.json2.js +475 -475
  27. data/vendor/assets/javascripts/jqplot-plugins/jqplot.logAxisRenderer.js +533 -533
  28. data/vendor/assets/javascripts/jqplot-plugins/jqplot.mekkoAxisRenderer.js +611 -611
  29. data/vendor/assets/javascripts/jqplot-plugins/jqplot.mekkoRenderer.js +437 -437
  30. data/vendor/assets/javascripts/jqplot-plugins/jqplot.meterGaugeRenderer.js +1029 -1029
  31. data/vendor/assets/javascripts/jqplot-plugins/jqplot.mobile.js +2 -2
  32. data/vendor/assets/javascripts/jqplot-plugins/jqplot.ohlcRenderer.js +373 -373
  33. data/vendor/assets/javascripts/jqplot-plugins/jqplot.pieRenderer.js +945 -903
  34. data/vendor/assets/javascripts/jqplot-plugins/jqplot.pointLabels.js +379 -377
  35. data/vendor/assets/javascripts/jqplot-plugins/jqplot.pyramidAxisRenderer.js +728 -728
  36. data/vendor/assets/javascripts/jqplot-plugins/jqplot.pyramidGridRenderer.js +428 -428
  37. data/vendor/assets/javascripts/jqplot-plugins/jqplot.pyramidRenderer.js +513 -513
  38. data/vendor/assets/javascripts/jqplot-plugins/jqplot.trendline.js +222 -222
  39. data/vendor/assets/javascripts/jquery.jqplot.js +11477 -11411
  40. data/vendor/assets/stylesheets/jquery.jqplot.css +259 -259
  41. metadata +9 -10
@@ -1,534 +1,534 @@
1
- /**
2
- * jqPlot
3
- * Pure JavaScript plotting plugin using jQuery
4
- *
5
- * Version: 1.0.8
6
- * Revision: 1250
7
- *
8
- * Copyright (c) 2009-2013 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
- /**
33
- * class: $.jqplot.LogAxisRenderer
34
- * A plugin for a jqPlot to render a logarithmic axis.
35
- *
36
- * To use this renderer, include the plugin in your source
37
- * > <script type="text/javascript" language="javascript" src="plugins/jqplot.logAxisRenderer.js"></script>
38
- *
39
- * and supply the appropriate options to your plot
40
- *
41
- * > {axes:{xaxis:{renderer:$.jqplot.LogAxisRenderer}}}
42
- **/
43
- $.jqplot.LogAxisRenderer = function() {
44
- $.jqplot.LinearAxisRenderer.call(this);
45
- // prop: axisDefaults
46
- // Default properties which will be applied directly to the series.
47
- //
48
- // Group: Properties
49
- //
50
- // Properties
51
- //
52
- // base - the logarithmic base, commonly 2, 10 or Math.E
53
- // tickDistribution - Deprecated. "power" distribution of ticks
54
- // always used. Option has no effect.
55
- this.axisDefaults = {
56
- base : 10,
57
- tickDistribution :'power'
58
- };
59
- };
60
-
61
- $.jqplot.LogAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer();
62
- $.jqplot.LogAxisRenderer.prototype.constructor = $.jqplot.LogAxisRenderer;
63
-
64
- $.jqplot.LogAxisRenderer.prototype.init = function(options) {
65
- // prop: drawBaseline
66
- // True to draw the axis baseline.
67
- this.drawBaseline = true;
68
- // prop: minorTicks
69
- // Number of ticks to add between "major" ticks.
70
- // Major ticks are ticks supplied by user or auto computed.
71
- // Minor ticks cannot be created by user.
72
- this.minorTicks = 'auto';
73
- this._scalefact = 1.0;
74
-
75
- $.extend(true, this, options);
76
-
77
- this._autoFormatString = '%d';
78
- this._overrideFormatString = false;
79
-
80
- for (var d in this.renderer.axisDefaults) {
81
- if (this[d] == null) {
82
- this[d] = this.renderer.axisDefaults[d];
83
- }
84
- }
85
-
86
- this.resetDataBounds();
87
- };
88
-
89
- $.jqplot.LogAxisRenderer.prototype.createTicks = function(plot) {
90
- // we're are operating on an axis here
91
- var ticks = this._ticks;
92
- var userTicks = this.ticks;
93
- var name = this.name;
94
- var db = this._dataBounds;
95
- var dim = (this.name.charAt(0) === 'x') ? this._plotDimensions.width : this._plotDimensions.height;
96
- var interval;
97
- var min, max;
98
- var pos1, pos2;
99
- var tt, i;
100
-
101
- var threshold = 30;
102
- // For some reason scalefactor is screwing up ticks.
103
- this._scalefact = (Math.max(dim, threshold+1) - threshold)/300;
104
-
105
- // if we already have ticks, use them.
106
- // ticks must be in order of increasing value.
107
- if (userTicks.length) {
108
- // ticks could be 1D or 2D array of [val, val, ,,,] or [[val, label], [val, label], ...] or mixed
109
- for (i=0; i<userTicks.length; i++){
110
- var ut = userTicks[i];
111
- var t = new this.tickRenderer(this.tickOptions);
112
- if (ut.constructor == Array) {
113
- t.value = ut[0];
114
- t.label = ut[1];
115
- if (!this.showTicks) {
116
- t.showLabel = false;
117
- t.showMark = false;
118
- }
119
- else if (!this.showTickMarks) {
120
- t.showMark = false;
121
- }
122
- t.setTick(ut[0], this.name);
123
- this._ticks.push(t);
124
- }
125
-
126
- else if ($.isPlainObject(ut)) {
127
- $.extend(true, t, ut);
128
- t.axis = this.name;
129
- this._ticks.push(t);
130
- }
131
-
132
- else {
133
- t.value = ut;
134
- if (!this.showTicks) {
135
- t.showLabel = false;
136
- t.showMark = false;
137
- }
138
- else if (!this.showTickMarks) {
139
- t.showMark = false;
140
- }
141
- t.setTick(ut, this.name);
142
- this._ticks.push(t);
143
- }
144
- }
145
- this.numberTicks = userTicks.length;
146
- this.min = this._ticks[0].value;
147
- this.max = this._ticks[this.numberTicks-1].value;
148
- }
149
-
150
- // we don't have any ticks yet, let's make some!
151
- else if (this.min == null && this.max == null) {
152
- min = db.min * (2 - this.padMin);
153
- max = db.max * this.padMax;
154
-
155
- // if min and max are same, space them out a bit
156
- if (min == max) {
157
- var adj = 0.05;
158
- min = min*(1-adj);
159
- max = max*(1+adj);
160
- }
161
-
162
- // perform some checks
163
- if (this.min != null && this.min <= 0) {
164
- throw new Error("Log axis minimum must be greater than 0");
165
- }
166
- if (this.max != null && this.max <= 0) {
167
- throw new Error("Log axis maximum must be greater than 0");
168
- }
169
-
170
- function findCeil (val) {
171
- var order = Math.pow(10, Math.floor(Math.log(val)/Math.LN10));
172
- return Math.ceil(val/order) * order;
173
- }
174
-
175
- function findFloor(val) {
176
- var order = Math.pow(10, Math.floor(Math.log(val)/Math.LN10));
177
- return Math.floor(val/order) * order;
178
- }
179
-
180
- // var range = max - min;
181
- var rmin, rmax;
182
-
183
- // for power distribution, open up range to get a nice power of axis.renderer.base.
184
- // power distribution won't respect the user's min/max settings.
185
- rmin = Math.pow(this.base, Math.floor(Math.log(min)/Math.log(this.base)));
186
- rmax = Math.pow(this.base, Math.ceil(Math.log(max)/Math.log(this.base)));
187
-
188
- // // if min and max are same, space them out a bit
189
- // if (rmin === rmax) {
190
- // var adj = 0.05;
191
- // rmin = rmin*(1-adj);
192
- // rmax = rmax*(1+adj);
193
- // }
194
-
195
- // Handle case where a data value was zero
196
- if (rmin === 0) {
197
- rmin = 1;
198
- }
199
-
200
- var order = Math.round(Math.log(rmin)/Math.LN10);
201
-
202
- if (this.tickOptions == null || !this.tickOptions.formatString) {
203
- this._overrideFormatString = true;
204
- }
205
-
206
- this.min = rmin;
207
- this.max = rmax;
208
- var range = this.max - this.min;
209
-
210
- var minorTicks = (this.minorTicks === 'auto') ? 0 : this.minorTicks;
211
- var numberTicks;
212
- if (this.numberTicks == null){
213
- if (dim > 140) {
214
- numberTicks = Math.round(Math.log(this.max/this.min)/Math.log(this.base) + 1);
215
- if (numberTicks < 2) {
216
- numberTicks = 2;
217
- }
218
- if (minorTicks === 0) {
219
- var temp = dim/(numberTicks - 1);
220
- if (temp < 100) {
221
- minorTicks = 0;
222
- }
223
- else if (temp < 190) {
224
- minorTicks = 1;
225
- }
226
- else if (temp < 250) {
227
- minorTicks = 3;
228
- }
229
- else if (temp < 600) {
230
- minorTicks = 4;
231
- }
232
- else {
233
- minorTicks = 9;
234
- }
235
- }
236
- }
237
- else {
238
- numberTicks = 2;
239
- if (minorTicks === 0) {
240
- minorTicks = 1;
241
- }
242
- minorTicks = 0;
243
- }
244
- }
245
- else {
246
- numberTicks = this.numberTicks;
247
- }
248
-
249
- if (order >= 0 && minorTicks !== 3) {
250
- this._autoFormatString = '%d';
251
- }
252
- // Adjust format string for case with 3 ticks where we'll have like 1, 2.5, 5, 7.5, 10
253
- else if (order <= 0 && minorTicks === 3) {
254
- var temp = -(order - 1);
255
- this._autoFormatString = '%.'+ Math.abs(order-1) + 'f';
256
- }
257
-
258
- // Adjust format string for values less than 1.
259
- else if (order < 0) {
260
- var temp = -order;
261
- this._autoFormatString = '%.'+ Math.abs(order) + 'f';
262
- }
263
-
264
- else {
265
- this._autoFormatString = '%d';
266
- }
267
-
268
- var to, t, val, tt1, spread, interval;
269
- for (var i=0; i<numberTicks; i++){
270
- tt = Math.pow(this.base, i - numberTicks + 1) * this.max;
271
-
272
- t = new this.tickRenderer(this.tickOptions);
273
-
274
- if (this._overrideFormatString) {
275
- t.formatString = this._autoFormatString;
276
- }
277
-
278
- if (!this.showTicks) {
279
- t.showLabel = false;
280
- t.showMark = false;
281
- }
282
- else if (!this.showTickMarks) {
283
- t.showMark = false;
284
- }
285
- t.setTick(tt, this.name);
286
- this._ticks.push(t);
287
-
288
- if (minorTicks && i<numberTicks-1) {
289
- tt1 = Math.pow(this.base, i - numberTicks + 2) * this.max;
290
- spread = tt1 - tt;
291
- interval = tt1 / (minorTicks+1);
292
- for (var j=minorTicks-1; j>=0; j--) {
293
- val = tt1-interval*(j+1);
294
- t = new this.tickRenderer(this.tickOptions);
295
-
296
- if (this._overrideFormatString && this._autoFormatString != '') {
297
- t.formatString = this._autoFormatString;
298
- }
299
- if (!this.showTicks) {
300
- t.showLabel = false;
301
- t.showMark = false;
302
- }
303
- else if (!this.showTickMarks) {
304
- t.showMark = false;
305
- }
306
- t.setTick(val, this.name);
307
- this._ticks.push(t);
308
- }
309
- }
310
- }
311
- }
312
-
313
- // min and max are set as would be the case with zooming
314
- else if (this.min != null && this.max != null) {
315
- var opts = $.extend(true, {}, this.tickOptions, {name: this.name, value: null});
316
- var nt, ti;
317
- // don't have an interval yet, pick one that gives the most
318
- // "round" ticks we can get.
319
- if (this.numberTicks == null && this.tickInterval == null) {
320
- // var threshold = 30;
321
- var tdim = Math.max(dim, threshold+1);
322
- var nttarget = Math.ceil((tdim-threshold)/35 + 1);
323
-
324
- var ret = $.jqplot.LinearTickGenerator.bestConstrainedInterval(this.min, this.max, nttarget);
325
-
326
- this._autoFormatString = ret[3];
327
- nt = ret[2];
328
- ti = ret[4];
329
-
330
- for (var i=0; i<nt; i++) {
331
- opts.value = this.min + i * ti;
332
- t = new this.tickRenderer(opts);
333
-
334
- if (this._overrideFormatString && this._autoFormatString != '') {
335
- t.formatString = this._autoFormatString;
336
- }
337
- if (!this.showTicks) {
338
- t.showLabel = false;
339
- t.showMark = false;
340
- }
341
- else if (!this.showTickMarks) {
342
- t.showMark = false;
343
- }
344
- this._ticks.push(t);
345
- }
346
- }
347
-
348
- // for loose zoom, number ticks and interval are also set.
349
- else if (this.numberTicks != null && this.tickInterval != null) {
350
- nt = this.numberTicks;
351
- for (var i=0; i<nt; i++) {
352
- opts.value = this.min + i * this.tickInterval;
353
- t = new this.tickRenderer(opts);
354
-
355
- if (this._overrideFormatString && this._autoFormatString != '') {
356
- t.formatString = this._autoFormatString;
357
- }
358
- if (!this.showTicks) {
359
- t.showLabel = false;
360
- t.showMark = false;
361
- }
362
- else if (!this.showTickMarks) {
363
- t.showMark = false;
364
- }
365
- this._ticks.push(t);
366
- }
367
- }
368
- }
369
- };
370
-
371
- $.jqplot.LogAxisRenderer.prototype.pack = function(pos, offsets) {
372
- var lb = parseInt(this.base, 10);
373
- var ticks = this._ticks;
374
- var trans = function (v) { return Math.log(v)/Math.log(lb); };
375
- var invtrans = function (v) { return Math.pow(Math.E, (Math.log(lb)*v)); };
376
- var max = trans(this.max);
377
- var min = trans(this.min);
378
- var offmax = offsets.max;
379
- var offmin = offsets.min;
380
- var lshow = (this._label == null) ? false : this._label.show;
381
-
382
- for (var p in pos) {
383
- this._elem.css(p, pos[p]);
384
- }
385
-
386
- this._offsets = offsets;
387
- // pixellength will be + for x axes and - for y axes becasue pixels always measured from top left.
388
- var pixellength = offmax - offmin;
389
- var unitlength = max - min;
390
-
391
- // point to unit and unit to point conversions references to Plot DOM element top left corner.
392
- this.p2u = function(p){
393
- return invtrans((p - offmin) * unitlength / pixellength + min);
394
- };
395
-
396
- this.u2p = function(u){
397
- return (trans(u) - min) * pixellength / unitlength + offmin;
398
- };
399
-
400
- if (this.name == 'xaxis' || this.name == 'x2axis'){
401
- this.series_u2p = function(u){
402
- return (trans(u) - min) * pixellength / unitlength;
403
- };
404
- this.series_p2u = function(p){
405
- return invtrans(p * unitlength / pixellength + min);
406
- };
407
- }
408
- // yaxis is max at top of canvas.
409
- else {
410
- this.series_u2p = function(u){
411
- return (trans(u) - max) * pixellength / unitlength;
412
- };
413
- this.series_p2u = function(p){
414
- return invtrans(p * unitlength / pixellength + max);
415
- };
416
- }
417
-
418
- if (this.show) {
419
- if (this.name == 'xaxis' || this.name == 'x2axis') {
420
- for (var i=0; i<ticks.length; i++) {
421
- var t = ticks[i];
422
- if (t.show && t.showLabel) {
423
- var shim;
424
-
425
- if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) {
426
- switch (t.labelPosition) {
427
- case 'auto':
428
- // position at end
429
- if (t.angle < 0) {
430
- shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
431
- }
432
- // position at start
433
- else {
434
- shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2;
435
- }
436
- break;
437
- case 'end':
438
- shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
439
- break;
440
- case 'start':
441
- shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2;
442
- break;
443
- case 'middle':
444
- shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
445
- break;
446
- default:
447
- shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
448
- break;
449
- }
450
- }
451
- else {
452
- shim = -t.getWidth()/2;
453
- }
454
- // var shim = t.getWidth()/2;
455
- var val = this.u2p(t.value) + shim + 'px';
456
- t._elem.css('left', val);
457
- t.pack();
458
- }
459
- }
460
- if (lshow) {
461
- var w = this._label._elem.outerWidth(true);
462
- this._label._elem.css('left', offmin + pixellength/2 - w/2 + 'px');
463
- if (this.name == 'xaxis') {
464
- this._label._elem.css('bottom', '0px');
465
- }
466
- else {
467
- this._label._elem.css('top', '0px');
468
- }
469
- this._label.pack();
470
- }
471
- }
472
- else {
473
- for (var i=0; i<ticks.length; i++) {
474
- var t = ticks[i];
475
- if (t.show && t.showLabel) {
476
- var shim;
477
- if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) {
478
- switch (t.labelPosition) {
479
- case 'auto':
480
- // position at end
481
- case 'end':
482
- if (t.angle < 0) {
483
- shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2;
484
- }
485
- else {
486
- shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2;
487
- }
488
- break;
489
- case 'start':
490
- if (t.angle > 0) {
491
- shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2;
492
- }
493
- else {
494
- shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2;
495
- }
496
- break;
497
- case 'middle':
498
- // if (t.angle > 0) {
499
- // shim = -t.getHeight()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
500
- // }
501
- // else {
502
- // shim = -t.getHeight()/2 - t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2;
503
- // }
504
- shim = -t.getHeight()/2;
505
- break;
506
- default:
507
- shim = -t.getHeight()/2;
508
- break;
509
- }
510
- }
511
- else {
512
- shim = -t.getHeight()/2;
513
- }
514
-
515
- var val = this.u2p(t.value) + shim + 'px';
516
- t._elem.css('top', val);
517
- t.pack();
518
- }
519
- }
520
- if (lshow) {
521
- var h = this._label._elem.outerHeight(true);
522
- this._label._elem.css('top', offmax - pixellength/2 - h/2 + 'px');
523
- if (this.name == 'yaxis') {
524
- this._label._elem.css('left', '0px');
525
- }
526
- else {
527
- this._label._elem.css('right', '0px');
528
- }
529
- this._label.pack();
530
- }
531
- }
532
- }
533
- };
1
+ /**
2
+ * jqPlot
3
+ * Pure JavaScript plotting plugin using jQuery
4
+ *
5
+ * Version: 1.0.9
6
+ * Revision: d96a669
7
+ *
8
+ * Copyright (c) 2009-2016 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
+ /**
33
+ * class: $.jqplot.LogAxisRenderer
34
+ * A plugin for a jqPlot to render a logarithmic axis.
35
+ *
36
+ * To use this renderer, include the plugin in your source
37
+ * > <script type="text/javascript" language="javascript" src="plugins/jqplot.logAxisRenderer.js"></script>
38
+ *
39
+ * and supply the appropriate options to your plot
40
+ *
41
+ * > {axes:{xaxis:{renderer:$.jqplot.LogAxisRenderer}}}
42
+ **/
43
+ $.jqplot.LogAxisRenderer = function() {
44
+ $.jqplot.LinearAxisRenderer.call(this);
45
+ // prop: axisDefaults
46
+ // Default properties which will be applied directly to the series.
47
+ //
48
+ // Group: Properties
49
+ //
50
+ // Properties
51
+ //
52
+ // base - the logarithmic base, commonly 2, 10 or Math.E
53
+ // tickDistribution - Deprecated. "power" distribution of ticks
54
+ // always used. Option has no effect.
55
+ this.axisDefaults = {
56
+ base : 10,
57
+ tickDistribution :'power'
58
+ };
59
+ };
60
+
61
+ $.jqplot.LogAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer();
62
+ $.jqplot.LogAxisRenderer.prototype.constructor = $.jqplot.LogAxisRenderer;
63
+
64
+ $.jqplot.LogAxisRenderer.prototype.init = function(options) {
65
+ // prop: drawBaseline
66
+ // True to draw the axis baseline.
67
+ this.drawBaseline = true;
68
+ // prop: minorTicks
69
+ // Number of ticks to add between "major" ticks.
70
+ // Major ticks are ticks supplied by user or auto computed.
71
+ // Minor ticks cannot be created by user.
72
+ this.minorTicks = 'auto';
73
+ this._scalefact = 1.0;
74
+
75
+ $.extend(true, this, options);
76
+
77
+ this._autoFormatString = '%d';
78
+ this._overrideFormatString = false;
79
+
80
+ for (var d in this.renderer.axisDefaults) {
81
+ if (this[d] == null) {
82
+ this[d] = this.renderer.axisDefaults[d];
83
+ }
84
+ }
85
+
86
+ this.resetDataBounds();
87
+ };
88
+
89
+ $.jqplot.LogAxisRenderer.prototype.createTicks = function(plot) {
90
+ // we're are operating on an axis here
91
+ var ticks = this._ticks;
92
+ var userTicks = this.ticks;
93
+ var name = this.name;
94
+ var db = this._dataBounds;
95
+ var dim = (this.name.charAt(0) === 'x') ? this._plotDimensions.width : this._plotDimensions.height;
96
+ var interval;
97
+ var min, max;
98
+ var pos1, pos2;
99
+ var tt, i;
100
+
101
+ var threshold = 30;
102
+ // For some reason scalefactor is screwing up ticks.
103
+ this._scalefact = (Math.max(dim, threshold+1) - threshold)/300;
104
+
105
+ // if we already have ticks, use them.
106
+ // ticks must be in order of increasing value.
107
+ if (userTicks.length) {
108
+ // ticks could be 1D or 2D array of [val, val, ,,,] or [[val, label], [val, label], ...] or mixed
109
+ for (i=0; i<userTicks.length; i++){
110
+ var ut = userTicks[i];
111
+ var t = new this.tickRenderer(this.tickOptions);
112
+ if (ut.constructor == Array) {
113
+ t.value = ut[0];
114
+ t.label = ut[1];
115
+ if (!this.showTicks) {
116
+ t.showLabel = false;
117
+ t.showMark = false;
118
+ }
119
+ else if (!this.showTickMarks) {
120
+ t.showMark = false;
121
+ }
122
+ t.setTick(ut[0], this.name);
123
+ this._ticks.push(t);
124
+ }
125
+
126
+ else if ($.isPlainObject(ut)) {
127
+ $.extend(true, t, ut);
128
+ t.axis = this.name;
129
+ this._ticks.push(t);
130
+ }
131
+
132
+ else {
133
+ t.value = ut;
134
+ if (!this.showTicks) {
135
+ t.showLabel = false;
136
+ t.showMark = false;
137
+ }
138
+ else if (!this.showTickMarks) {
139
+ t.showMark = false;
140
+ }
141
+ t.setTick(ut, this.name);
142
+ this._ticks.push(t);
143
+ }
144
+ }
145
+ this.numberTicks = userTicks.length;
146
+ this.min = this._ticks[0].value;
147
+ this.max = this._ticks[this.numberTicks-1].value;
148
+ }
149
+
150
+ // we don't have any ticks yet, let's make some!
151
+ else if (this.min == null && this.max == null) {
152
+ min = db.min * (2 - this.padMin);
153
+ max = db.max * this.padMax;
154
+
155
+ // if min and max are same, space them out a bit
156
+ if (min == max) {
157
+ var adj = 0.05;
158
+ min = min*(1-adj);
159
+ max = max*(1+adj);
160
+ }
161
+
162
+ // perform some checks
163
+ if (this.min != null && this.min <= 0) {
164
+ throw new Error("Log axis minimum must be greater than 0");
165
+ }
166
+ if (this.max != null && this.max <= 0) {
167
+ throw new Error("Log axis maximum must be greater than 0");
168
+ }
169
+
170
+ function findCeil (val) {
171
+ var order = Math.pow(10, Math.floor(Math.log(val)/Math.LN10));
172
+ return Math.ceil(val/order) * order;
173
+ }
174
+
175
+ function findFloor(val) {
176
+ var order = Math.pow(10, Math.floor(Math.log(val)/Math.LN10));
177
+ return Math.floor(val/order) * order;
178
+ }
179
+
180
+ // var range = max - min;
181
+ var rmin, rmax;
182
+
183
+ // for power distribution, open up range to get a nice power of axis.renderer.base.
184
+ // power distribution won't respect the user's min/max settings.
185
+ rmin = Math.pow(this.base, Math.floor(Math.log(min)/Math.log(this.base)));
186
+ rmax = Math.pow(this.base, Math.ceil(Math.log(max)/Math.log(this.base)));
187
+
188
+ // // if min and max are same, space them out a bit
189
+ // if (rmin === rmax) {
190
+ // var adj = 0.05;
191
+ // rmin = rmin*(1-adj);
192
+ // rmax = rmax*(1+adj);
193
+ // }
194
+
195
+ // Handle case where a data value was zero
196
+ if (rmin === 0) {
197
+ rmin = 1;
198
+ }
199
+
200
+ var order = Math.round(Math.log(rmin)/Math.LN10);
201
+
202
+ if (this.tickOptions == null || !this.tickOptions.formatString) {
203
+ this._overrideFormatString = true;
204
+ }
205
+
206
+ this.min = rmin;
207
+ this.max = rmax;
208
+ var range = this.max - this.min;
209
+
210
+ var minorTicks = (this.minorTicks === 'auto') ? 0 : this.minorTicks;
211
+ var numberTicks;
212
+ if (this.numberTicks == null){
213
+ if (dim > 140) {
214
+ numberTicks = Math.round(Math.log(this.max/this.min)/Math.log(this.base) + 1);
215
+ if (numberTicks < 2) {
216
+ numberTicks = 2;
217
+ }
218
+ if (minorTicks === 0) {
219
+ var temp = dim/(numberTicks - 1);
220
+ if (temp < 100) {
221
+ minorTicks = 0;
222
+ }
223
+ else if (temp < 190) {
224
+ minorTicks = 1;
225
+ }
226
+ else if (temp < 250) {
227
+ minorTicks = 3;
228
+ }
229
+ else if (temp < 600) {
230
+ minorTicks = 4;
231
+ }
232
+ else {
233
+ minorTicks = 9;
234
+ }
235
+ }
236
+ }
237
+ else {
238
+ numberTicks = 2;
239
+ if (minorTicks === 0) {
240
+ minorTicks = 1;
241
+ }
242
+ minorTicks = 0;
243
+ }
244
+ }
245
+ else {
246
+ numberTicks = this.numberTicks;
247
+ }
248
+
249
+ if (order >= 0 && minorTicks !== 3) {
250
+ this._autoFormatString = '%d';
251
+ }
252
+ // Adjust format string for case with 3 ticks where we'll have like 1, 2.5, 5, 7.5, 10
253
+ else if (order <= 0 && minorTicks === 3) {
254
+ var temp = -(order - 1);
255
+ this._autoFormatString = '%.'+ Math.abs(order-1) + 'f';
256
+ }
257
+
258
+ // Adjust format string for values less than 1.
259
+ else if (order < 0) {
260
+ var temp = -order;
261
+ this._autoFormatString = '%.'+ Math.abs(order) + 'f';
262
+ }
263
+
264
+ else {
265
+ this._autoFormatString = '%d';
266
+ }
267
+
268
+ var to, t, val, tt1, spread, interval;
269
+ for (var i=0; i<numberTicks; i++){
270
+ tt = Math.pow(this.base, i - numberTicks + 1) * this.max;
271
+
272
+ t = new this.tickRenderer(this.tickOptions);
273
+
274
+ if (this._overrideFormatString) {
275
+ t.formatString = this._autoFormatString;
276
+ }
277
+
278
+ if (!this.showTicks) {
279
+ t.showLabel = false;
280
+ t.showMark = false;
281
+ }
282
+ else if (!this.showTickMarks) {
283
+ t.showMark = false;
284
+ }
285
+ t.setTick(tt, this.name);
286
+ this._ticks.push(t);
287
+
288
+ if (minorTicks && i<numberTicks-1) {
289
+ tt1 = Math.pow(this.base, i - numberTicks + 2) * this.max;
290
+ spread = tt1 - tt;
291
+ interval = tt1 / (minorTicks+1);
292
+ for (var j=minorTicks-1; j>=0; j--) {
293
+ val = tt1-interval*(j+1);
294
+ t = new this.tickRenderer(this.tickOptions);
295
+
296
+ if (this._overrideFormatString && this._autoFormatString != '') {
297
+ t.formatString = this._autoFormatString;
298
+ }
299
+ if (!this.showTicks) {
300
+ t.showLabel = false;
301
+ t.showMark = false;
302
+ }
303
+ else if (!this.showTickMarks) {
304
+ t.showMark = false;
305
+ }
306
+ t.setTick(val, this.name);
307
+ this._ticks.push(t);
308
+ }
309
+ }
310
+ }
311
+ }
312
+
313
+ // min and max are set as would be the case with zooming
314
+ else if (this.min != null && this.max != null) {
315
+ var opts = $.extend(true, {}, this.tickOptions, {name: this.name, value: null});
316
+ var nt, ti;
317
+ // don't have an interval yet, pick one that gives the most
318
+ // "round" ticks we can get.
319
+ if (this.numberTicks == null && this.tickInterval == null) {
320
+ // var threshold = 30;
321
+ var tdim = Math.max(dim, threshold+1);
322
+ var nttarget = Math.ceil((tdim-threshold)/35 + 1);
323
+
324
+ var ret = $.jqplot.LinearTickGenerator.bestConstrainedInterval(this.min, this.max, nttarget);
325
+
326
+ this._autoFormatString = ret[3];
327
+ nt = ret[2];
328
+ ti = ret[4];
329
+
330
+ for (var i=0; i<nt; i++) {
331
+ opts.value = this.min + i * ti;
332
+ t = new this.tickRenderer(opts);
333
+
334
+ if (this._overrideFormatString && this._autoFormatString != '') {
335
+ t.formatString = this._autoFormatString;
336
+ }
337
+ if (!this.showTicks) {
338
+ t.showLabel = false;
339
+ t.showMark = false;
340
+ }
341
+ else if (!this.showTickMarks) {
342
+ t.showMark = false;
343
+ }
344
+ this._ticks.push(t);
345
+ }
346
+ }
347
+
348
+ // for loose zoom, number ticks and interval are also set.
349
+ else if (this.numberTicks != null && this.tickInterval != null) {
350
+ nt = this.numberTicks;
351
+ for (var i=0; i<nt; i++) {
352
+ opts.value = this.min + i * this.tickInterval;
353
+ t = new this.tickRenderer(opts);
354
+
355
+ if (this._overrideFormatString && this._autoFormatString != '') {
356
+ t.formatString = this._autoFormatString;
357
+ }
358
+ if (!this.showTicks) {
359
+ t.showLabel = false;
360
+ t.showMark = false;
361
+ }
362
+ else if (!this.showTickMarks) {
363
+ t.showMark = false;
364
+ }
365
+ this._ticks.push(t);
366
+ }
367
+ }
368
+ }
369
+ };
370
+
371
+ $.jqplot.LogAxisRenderer.prototype.pack = function(pos, offsets) {
372
+ var lb = parseInt(this.base, 10);
373
+ var ticks = this._ticks;
374
+ var trans = function (v) { return Math.log(v)/Math.log(lb); };
375
+ var invtrans = function (v) { return Math.pow(Math.E, (Math.log(lb)*v)); };
376
+ var max = trans(this.max);
377
+ var min = trans(this.min);
378
+ var offmax = offsets.max;
379
+ var offmin = offsets.min;
380
+ var lshow = (this._label == null) ? false : this._label.show;
381
+
382
+ for (var p in pos) {
383
+ this._elem.css(p, pos[p]);
384
+ }
385
+
386
+ this._offsets = offsets;
387
+ // pixellength will be + for x axes and - for y axes becasue pixels always measured from top left.
388
+ var pixellength = offmax - offmin;
389
+ var unitlength = max - min;
390
+
391
+ // point to unit and unit to point conversions references to Plot DOM element top left corner.
392
+ this.p2u = function(p){
393
+ return invtrans((p - offmin) * unitlength / pixellength + min);
394
+ };
395
+
396
+ this.u2p = function(u){
397
+ return (trans(u) - min) * pixellength / unitlength + offmin;
398
+ };
399
+
400
+ if (this.name == 'xaxis' || this.name == 'x2axis'){
401
+ this.series_u2p = function(u){
402
+ return (trans(u) - min) * pixellength / unitlength;
403
+ };
404
+ this.series_p2u = function(p){
405
+ return invtrans(p * unitlength / pixellength + min);
406
+ };
407
+ }
408
+ // yaxis is max at top of canvas.
409
+ else {
410
+ this.series_u2p = function(u){
411
+ return (trans(u) - max) * pixellength / unitlength;
412
+ };
413
+ this.series_p2u = function(p){
414
+ return invtrans(p * unitlength / pixellength + max);
415
+ };
416
+ }
417
+
418
+ if (this.show) {
419
+ if (this.name == 'xaxis' || this.name == 'x2axis') {
420
+ for (var i=0; i<ticks.length; i++) {
421
+ var t = ticks[i];
422
+ if (t.show && t.showLabel) {
423
+ var shim;
424
+
425
+ if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) {
426
+ switch (t.labelPosition) {
427
+ case 'auto':
428
+ // position at end
429
+ if (t.angle < 0) {
430
+ shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
431
+ }
432
+ // position at start
433
+ else {
434
+ shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2;
435
+ }
436
+ break;
437
+ case 'end':
438
+ shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
439
+ break;
440
+ case 'start':
441
+ shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2;
442
+ break;
443
+ case 'middle':
444
+ shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
445
+ break;
446
+ default:
447
+ shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
448
+ break;
449
+ }
450
+ }
451
+ else {
452
+ shim = -t.getWidth()/2;
453
+ }
454
+ // var shim = t.getWidth()/2;
455
+ var val = this.u2p(t.value) + shim + 'px';
456
+ t._elem.css('left', val);
457
+ t.pack();
458
+ }
459
+ }
460
+ if (lshow) {
461
+ var w = this._label._elem.outerWidth(true);
462
+ this._label._elem.css('left', offmin + pixellength/2 - w/2 + 'px');
463
+ if (this.name == 'xaxis') {
464
+ this._label._elem.css('bottom', '0px');
465
+ }
466
+ else {
467
+ this._label._elem.css('top', '0px');
468
+ }
469
+ this._label.pack();
470
+ }
471
+ }
472
+ else {
473
+ for (var i=0; i<ticks.length; i++) {
474
+ var t = ticks[i];
475
+ if (t.show && t.showLabel) {
476
+ var shim;
477
+ if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) {
478
+ switch (t.labelPosition) {
479
+ case 'auto':
480
+ // position at end
481
+ case 'end':
482
+ if (t.angle < 0) {
483
+ shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2;
484
+ }
485
+ else {
486
+ shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2;
487
+ }
488
+ break;
489
+ case 'start':
490
+ if (t.angle > 0) {
491
+ shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2;
492
+ }
493
+ else {
494
+ shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2;
495
+ }
496
+ break;
497
+ case 'middle':
498
+ // if (t.angle > 0) {
499
+ // shim = -t.getHeight()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
500
+ // }
501
+ // else {
502
+ // shim = -t.getHeight()/2 - t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2;
503
+ // }
504
+ shim = -t.getHeight()/2;
505
+ break;
506
+ default:
507
+ shim = -t.getHeight()/2;
508
+ break;
509
+ }
510
+ }
511
+ else {
512
+ shim = -t.getHeight()/2;
513
+ }
514
+
515
+ var val = this.u2p(t.value) + shim + 'px';
516
+ t._elem.css('top', val);
517
+ t.pack();
518
+ }
519
+ }
520
+ if (lshow) {
521
+ var h = this._label._elem.outerHeight(true);
522
+ this._label._elem.css('top', offmax - pixellength/2 - h/2 + 'px');
523
+ if (this.name == 'yaxis') {
524
+ this._label._elem.css('left', '0px');
525
+ }
526
+ else {
527
+ this._label._elem.css('right', '0px');
528
+ }
529
+ this._label.pack();
530
+ }
531
+ }
532
+ }
533
+ };
534
534
  })(jQuery);