outfielding-jqplot-rails 1.0.8 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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);