Free cookie consent management tool by TermsFeed Policy Generator

source: branches/1888_OaaS/HeuristicLab.Services.Optimization.Web/Content/jqplot/src/jqplot.linearAxisRenderer.js @ 16115

Last change on this file since 16115 was 9062, checked in by fschoepp, 12 years ago

#1888:
Backend changes:

  • Simplified job state detection (only one hive call will be made to detect all states now, instead of one additional call per job)
  • Reorganized classes (moved model classes into Model folder)

Website changes:

  • Website now heavily uses JavaScript to achieve better user experience
  • JavaScript degrades gracefully, except for plots
  • Tables: Added jquery-datatable-plugin to extend tables (pagination + search functionality)
  • OaaS-Website now uses the design of the HL websites (found in WebApplication branch)
  • Added jqplot to render zoomable line plots for HL-Datatables
  • Styling.js: Plots will be generated by using an ajax call; additional jquery-styling occurs within this file.
  • Added jquery-ui-1.9.2 which is capable of handling/rendering tabs, accordions and resizers.
File size: 40.6 KB
Line 
1/**
2 * jqPlot
3 * Pure JavaScript plotting plugin using jQuery
4 *
5 * Version: @VERSION
6 *
7 * Copyright (c) 2009-2011 Chris Leonello
8 * jqPlot is currently available for use in all personal or commercial projects
9 * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
10 * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
11 * choose the license that best suits your project and use it accordingly.
12 *
13 * Although not required, the author would appreciate an email letting him
14 * know of any substantial use of jqPlot.  You can reach the author at:
15 * chris at jqplot dot com or see http://www.jqplot.com/info.php .
16 *
17 * If you are feeling kind and generous, consider supporting the project by
18 * making a donation at: http://www.jqplot.com/donate.php .
19 *
20 * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
21 *
22 *     version 2007.04.27
23 *     author Ash Searle
24 *     http://hexmen.com/blog/2007/03/printf-sprintf/
25 *     http://hexmen.com/js/sprintf.js
26 *     The author (Ash Searle) has placed this code in the public domain:
27 *     "This code is unrestricted: you are free to use it however you like."
28 *
29 */
30(function($) {
31    // class: $.jqplot.LinearAxisRenderer
32    // The default jqPlot axis renderer, creating a numeric axis.
33    // The renderer has no additional options beyond the <Axis> object.
34    $.jqplot.LinearAxisRenderer = function() {
35    };
36   
37    // called with scope of axis object.
38    $.jqplot.LinearAxisRenderer.prototype.init = function(options){
39        // prop: breakPoints
40        // EXPERIMENTAL!! Use at your own risk!
41        // Works only with linear axes and the default tick renderer.
42        // Array of [start, stop] points to create a broken axis.
43        // Broken axes have a "jump" in them, which is an immediate
44        // transition from a smaller value to a larger value.
45        // Currently, axis ticks MUST be manually assigned if using breakPoints
46        // by using the axis ticks array option.
47        this.breakPoints = null;
48        // prop: breakTickLabel
49        // Label to use at the axis break if breakPoints are specified.
50        this.breakTickLabel = "&asymp;";
51        // prop: forceTickAt0
52        // This will ensure that there is always a tick mark at 0.
53        // If data range is strictly positive or negative,
54        // this will force 0 to be inside the axis bounds unless
55        // the appropriate axis pad (pad, padMin or padMax) is set
56        // to 0, then this will force an axis min or max value at 0.
57        // This has know effect when any of the following options
58        // are set:  autoscale, min, max, numberTicks or tickInterval.
59        this.forceTickAt0 = false;
60        // prop: forceTickAt100
61        // This will ensure that there is always a tick mark at 100.
62        // If data range is strictly above or below 100,
63        // this will force 100 to be inside the axis bounds unless
64        // the appropriate axis pad (pad, padMin or padMax) is set
65        // to 0, then this will force an axis min or max value at 100.
66        // This has know effect when any of the following options
67        // are set:  autoscale, min, max, numberTicks or tickInterval.
68        this.forceTickAt100 = false;
69        this._autoFormatString = '';
70        this._overrideFormatString = false;
71        $.extend(true, this, options);
72        if (this.breakPoints) {
73            if (!$.isArray(this.breakPoints)) {
74                this.breakPoints = null;
75            }
76            else if (this.breakPoints.length < 2 || this.breakPoints[1] <= this.breakPoints[0]) {
77                this.breakPoints = null;
78            }
79        }
80        this.resetDataBounds();
81    };
82   
83    // called with scope of axis
84    $.jqplot.LinearAxisRenderer.prototype.draw = function(ctx, plot) {
85        if (this.show) {
86            // populate the axis label and value properties.
87            // createTicks is a method on the renderer, but
88            // call it within the scope of the axis.
89            this.renderer.createTicks.call(this);
90            // fill a div with axes labels in the right direction.
91            // Need to pregenerate each axis to get it's bounds and
92            // position it and the labels correctly on the plot.
93            var dim=0;
94            var temp;
95            // Added for theming.
96            if (this._elem) {
97                // Memory Leaks patch
98                //this._elem.empty();
99                this._elem.emptyForce();
100                this._elem = null;
101            }
102           
103            this._elem = $(document.createElement('div'));
104            this._elem.addClass('jqplot-axis jqplot-'+this.name);
105            this._elem.css('posiiton', 'absolute');
106
107           
108            if (this.name == 'xaxis' || this.name == 'x2axis') {
109                this._elem.width(this._plotDimensions.width);
110            }
111            else {
112                this._elem.height(this._plotDimensions.height);
113            }
114           
115            // create a _label object.
116            this.labelOptions.axis = this.name;
117            this._label = new this.labelRenderer(this.labelOptions);
118            if (this._label.show) {
119                var elem = this._label.draw(ctx, plot);
120                elem.appendTo(this._elem);
121                elem = null;
122            }
123   
124            var t = this._ticks;
125            var tick;
126            for (var i=0; i<t.length; i++) {
127                tick = t[i];
128                if (tick.show && tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) {
129                    this._elem.append(tick.draw(ctx, plot));
130                }
131            }
132            tick = null;
133            t = null;
134        }
135        return this._elem;
136    };
137   
138    // called with scope of an axis
139    $.jqplot.LinearAxisRenderer.prototype.reset = function() {
140        this.min = this._min;
141        this.max = this._max;
142        this.tickInterval = this._tickInterval;
143        this.numberTicks = this._numberTicks;
144        this._autoFormatString = '';
145        if (this._overrideFormatString && this.tickOptions && this.tickOptions.formatString) {
146            this.tickOptions.formatString = '';
147        }
148
149        // this._ticks = this.__ticks;
150    };
151   
152    // called with scope of axis
153    $.jqplot.LinearAxisRenderer.prototype.set = function() {
154        var dim = 0;
155        var temp;
156        var w = 0;
157        var h = 0;
158        var lshow = (this._label == null) ? false : this._label.show;
159        if (this.show) {
160            var t = this._ticks;
161            var tick;
162            for (var i=0; i<t.length; i++) {
163                tick = t[i];
164                if (!tick._breakTick && tick.show && tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) {
165                    if (this.name == 'xaxis' || this.name == 'x2axis') {
166                        temp = tick._elem.outerHeight(true);
167                    }
168                    else {
169                        temp = tick._elem.outerWidth(true);
170                    }
171                    if (temp > dim) {
172                        dim = temp;
173                    }
174                }
175            }
176            tick = null;
177            t = null;
178           
179            if (lshow) {
180                w = this._label._elem.outerWidth(true);
181                h = this._label._elem.outerHeight(true);
182            }
183            if (this.name == 'xaxis') {
184                dim = dim + h;
185                this._elem.css({'height':dim+'px', left:'0px', bottom:'0px'});
186            }
187            else if (this.name == 'x2axis') {
188                dim = dim + h;
189                this._elem.css({'height':dim+'px', left:'0px', top:'0px'});
190            }
191            else if (this.name == 'yaxis') {
192                dim = dim + w;
193                this._elem.css({'width':dim+'px', left:'0px', top:'0px'});
194                if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) {
195                    this._label._elem.css('width', w+'px');
196                }
197            }
198            else {
199                dim = dim + w;
200                this._elem.css({'width':dim+'px', right:'0px', top:'0px'});
201                if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) {
202                    this._label._elem.css('width', w+'px');
203                }
204            }
205        } 
206    };   
207   
208    // called with scope of axis
209    $.jqplot.LinearAxisRenderer.prototype.createTicks = function() {
210        // we're are operating on an axis here
211        var ticks = this._ticks;
212        var userTicks = this.ticks;
213        var name = this.name;
214        // databounds were set on axis initialization.
215        var db = this._dataBounds;
216        var dim, interval;
217        var min, max;
218        var pos1, pos2;
219        var tt, i;
220        // get a copy of user's settings for min/max.
221        var userMin = this.min;
222        var userMax = this.max;
223        var userNT = this.numberTicks;
224        var userTI = this.tickInterval;
225       
226        // if we already have ticks, use them.
227        // ticks must be in order of increasing value.
228       
229        if (userTicks.length) {
230            // ticks could be 1D or 2D array of [val, val, ,,,] or [[val, label], [val, label], ...] or mixed
231            for (i=0; i<userTicks.length; i++){
232                var ut = userTicks[i];
233                var t = new this.tickRenderer(this.tickOptions);
234                if (ut.constructor == Array) {
235                    t.value = ut[0];
236                    if (this.breakPoints) {
237                        if (ut[0] == this.breakPoints[0]) {
238                            t.label = this.breakTickLabel;
239                            t._breakTick = true;
240                            t.showGridline = false;
241                            t.showMark = false;
242                        }
243                        else if (ut[0] > this.breakPoints[0] && ut[0] <= this.breakPoints[1]) {
244                            t.show = false;
245                            t.showGridline = false;
246                            t.label = ut[1];
247                        }
248                        else {
249                            t.label = ut[1];
250                        }
251                    }
252                    else {
253                        t.label = ut[1];
254                    }
255                    t.setTick(ut[0], this.name);
256                    this._ticks.push(t);
257                }
258               
259                else {
260                    t.value = ut;
261                    if (this.breakPoints) {
262                        if (ut == this.breakPoints[0]) {
263                            t.label = this.breakTickLabel;
264                            t._breakTick = true;
265                            t.showGridline = false;
266                            t.showMark = false;
267                        }
268                        else if (ut > this.breakPoints[0] && ut <= this.breakPoints[1]) {
269                            t.show = false;
270                            t.showGridline = false;
271                        }
272                    }
273                    t.setTick(ut, this.name);
274                    this._ticks.push(t);
275                }
276            }
277            this.numberTicks = userTicks.length;
278            this.min = this._ticks[0].value;
279            this.max = this._ticks[this.numberTicks-1].value;
280            this.tickInterval = (this.max - this.min) / (this.numberTicks - 1);
281        }
282       
283        // we don't have any ticks yet, let's make some!
284        else {
285            if (name == 'xaxis' || name == 'x2axis') {
286                dim = this._plotDimensions.width;
287            }
288            else {
289                dim = this._plotDimensions.height;
290            }
291           
292            // // if min, max and number of ticks specified, user can't specify interval.
293            // if (!this.autoscale && this.min != null && this.max != null && this.numberTicks != null) {
294            //     console.log('doing this');
295            //     this.tickInterval = null;
296            // }
297           
298            // if max, min, and interval specified and interval won't fit, ignore interval.
299            // if (this.min != null && this.max != null && this.tickInterval != null) {
300            //     if (parseInt((this.max-this.min)/this.tickInterval, 10) != (this.max-this.min)/this.tickInterval) {
301            //         this.tickInterval = null;
302            //     }
303            // }
304       
305            min = ((this.min != null) ? this.min : db.min);
306            max = ((this.max != null) ? this.max : db.max);
307
308            var range = max - min;
309            var rmin, rmax;
310            var temp;
311
312            // Doing complete autoscaling
313            if (this.min == null && this.max == null && this.numberTicks == null && this.tickInterval == null && !this.autoscale) {
314                // check to see if we can override tick format string with autocalculated one
315                if (this.tickOptions == null || !this.tickOptions.formatString) {
316                    this._overrideFormatString = true;
317                }
318
319
320                // Check if user must have tick at 0 or 100 and ensure they are in range.
321                // The autoscaling algorithm will always place ticks at 0 and 100 if they are in range.
322                if (this.forceTickAt0) {
323                    if (min > 0) {
324                        min = 0;
325                    }
326                    if (max < 0) {
327                        max = 0;
328                    }
329                }
330
331                if (this.forceTickAt100) {
332                    if (min > 100) {
333                        min = 100;
334                    }
335                    if (max < 100) {
336                        max = 100;
337                    }
338                }
339
340                // console.log(this.name);
341                var threshold = 30;
342                var tdim = Math.max(dim, threshold+1);
343                var scalefact =  (tdim-threshold)/300.0;
344                // scalefact = 1;
345                var ret = $.jqplot.LinearTickGenerator(min, max, scalefact);
346                // calculate a padded max and min, points should be less than these
347                // so that they aren't too close to the edges of the plot.
348                // User can adjust how much padding is allowed with pad, padMin and PadMax options.
349                var tumin = min + range*(this.padMin - 1);
350                var tumax = max - range*(this.padMax - 1);
351
352                if (min <=tumin || max >= tumax) {
353                    tumin = min - range*(this.padMin - 1);
354                    tumax = max + range*(this.padMax - 1);
355                    ret = $.jqplot.LinearTickGenerator(tumin, tumax, scalefact);
356                }
357
358
359                // if (ret[2] > max_number_ticks) {
360                //     ret[4] = Math.ceil(r[2]/max_number_ticks) * ret[4];
361                   
362                // }
363
364                this.min = ret[0];
365                this.max = ret[1];
366                this.numberTicks = ret[2];
367                this._autoFormatString = ret[3];
368                //this.tickInterval = Math.abs(this.max - this.min)/(this.numberTicks - 1);
369                this.tickInterval = ret[4];
370                // console.log('numberticks: %s, interval: %s', ret[2], ret[4]);
371            }
372
373            // User has specified some axis scale related option, can use auto algorithm
374            else {
375               
376                // if min and max are same, space them out a bit
377                if (min == max) {
378                    var adj = 0.05;
379                    if (min > 0) {
380                        adj = Math.max(Math.log(min)/Math.LN10, 0.05);
381                    }
382                    min -= adj;
383                    max += adj;
384                }
385               
386                // autoscale.  Can't autoscale if min or max is supplied.
387                // Will use numberTicks and tickInterval if supplied.  Ticks
388                // across multiple axes may not line up depending on how
389                // bars are to be plotted.
390                if (this.autoscale && this.min == null && this.max == null) {
391                    var rrange, ti, margin;
392                    var forceMinZero = false;
393                    var forceZeroLine = false;
394                    var intervals = {min:null, max:null, average:null, stddev:null};
395                    // if any series are bars, or if any are fill to zero, and if this
396                    // is the axis to fill toward, check to see if we can start axis at zero.
397                    for (var i=0; i<this._series.length; i++) {
398                        var s = this._series[i];
399                        var faname = (s.fillAxis == 'x') ? s._xaxis.name : s._yaxis.name;
400                        // check to see if this is the fill axis
401                        if (this.name == faname) {
402                            var vals = s._plotValues[s.fillAxis];
403                            var vmin = vals[0];
404                            var vmax = vals[0];
405                            for (var j=1; j<vals.length; j++) {
406                                if (vals[j] < vmin) {
407                                    vmin = vals[j];
408                                }
409                                else if (vals[j] > vmax) {
410                                    vmax = vals[j];
411                                }
412                            }
413                            var dp = (vmax - vmin) / vmax;
414                            // is this sries a bar?
415                            if (s.renderer.constructor == $.jqplot.BarRenderer) {
416                                // if no negative values and could also check range.
417                                if (vmin >= 0 && (s.fillToZero || dp > 0.1)) {
418                                    forceMinZero = true;
419                                }
420                                else {
421                                    forceMinZero = false;
422                                    if (s.fill && s.fillToZero && vmin < 0 && vmax > 0) {
423                                        forceZeroLine = true;
424                                    }
425                                    else {
426                                        forceZeroLine = false;
427                                    }
428                                }
429                            }
430                           
431                            // if not a bar and filling, use appropriate method.
432                            else if (s.fill) {
433                                if (vmin >= 0 && (s.fillToZero || dp > 0.1)) {
434                                    forceMinZero = true;
435                                }
436                                else if (vmin < 0 && vmax > 0 && s.fillToZero) {
437                                    forceMinZero = false;
438                                    forceZeroLine = true;
439                                }
440                                else {
441                                    forceMinZero = false;
442                                    forceZeroLine = false;
443                                }
444                            }
445                           
446                            // if not a bar and not filling, only change existing state
447                            // if it doesn't make sense
448                            else if (vmin < 0) {
449                                forceMinZero = false;
450                            }
451                        }
452                    }
453                   
454                    // check if we need make axis min at 0.
455                    if (forceMinZero) {
456                        // compute number of ticks
457                        this.numberTicks = 2 + Math.ceil((dim-(this.tickSpacing-1))/this.tickSpacing);
458                        this.min = 0;
459                        userMin = 0;
460                        // what order is this range?
461                        // what tick interval does that give us?
462                        ti = max/(this.numberTicks-1);
463                        temp = Math.pow(10, Math.abs(Math.floor(Math.log(ti)/Math.LN10)));
464                        if (ti/temp == parseInt(ti/temp, 10)) {
465                            ti += temp;
466                        }
467                        this.tickInterval = Math.ceil(ti/temp) * temp;
468                        this.max = this.tickInterval * (this.numberTicks - 1);
469                    }
470                   
471                    // check if we need to make sure there is a tick at 0.
472                    else if (forceZeroLine) {
473                        // compute number of ticks
474                        this.numberTicks = 2 + Math.ceil((dim-(this.tickSpacing-1))/this.tickSpacing);
475                        var ntmin = Math.ceil(Math.abs(min)/range*(this.numberTicks-1));
476                        var ntmax = this.numberTicks - 1  - ntmin;
477                        ti = Math.max(Math.abs(min/ntmin), Math.abs(max/ntmax));
478                        temp = Math.pow(10, Math.abs(Math.floor(Math.log(ti)/Math.LN10)));
479                        this.tickInterval = Math.ceil(ti/temp) * temp;
480                        this.max = this.tickInterval * ntmax;
481                        this.min = -this.tickInterval * ntmin;
482                    }
483                   
484                    // if nothing else, do autoscaling which will try to line up ticks across axes.
485                    else { 
486                        if (this.numberTicks == null){
487                            if (this.tickInterval) {
488                                this.numberTicks = 3 + Math.ceil(range / this.tickInterval);
489                            }
490                            else {
491                                this.numberTicks = 2 + Math.ceil((dim-(this.tickSpacing-1))/this.tickSpacing);
492                            }
493                        }
494               
495                        if (this.tickInterval == null) {
496                            // get a tick interval
497                            ti = range/(this.numberTicks - 1);
498
499                            if (ti < 1) {
500                                temp = Math.pow(10, Math.abs(Math.floor(Math.log(ti)/Math.LN10)));
501                            }
502                            else {
503                                temp = 1;
504                            }
505                            this.tickInterval = Math.ceil(ti*temp*this.pad)/temp;
506                        }
507                        else {
508                            temp = 1 / this.tickInterval;
509                        }
510                       
511                        // try to compute a nicer, more even tick interval
512                        // temp = Math.pow(10, Math.floor(Math.log(ti)/Math.LN10));
513                        // this.tickInterval = Math.ceil(ti/temp) * temp;
514                        rrange = this.tickInterval * (this.numberTicks - 1);
515                        margin = (rrange - range)/2;
516           
517                        if (this.min == null) {
518                            this.min = Math.floor(temp*(min-margin))/temp;
519                        }
520                        if (this.max == null) {
521                            this.max = this.min + rrange;
522                        }
523                    }
524                }
525               
526                // Use the default algorithm which pads each axis to make the chart
527                // centered nicely on the grid.
528                else {
529                    rmin = (this.min != null) ? this.min : min - range*(this.padMin - 1);
530                    rmax = (this.max != null) ? this.max : max + range*(this.padMax - 1);
531                    this.min = rmin;
532                    this.max = rmax;
533                    range = this.max - this.min;
534       
535                    if (this.numberTicks == null){
536                        // if tickInterval is specified by user, we will ignore computed maximum.
537                        // max will be equal or greater to fit even # of ticks.
538                        if (this.tickInterval != null) {
539                            this.numberTicks = Math.ceil((this.max - this.min)/this.tickInterval)+1;
540                            this.max = this.min + this.tickInterval*(this.numberTicks-1);
541                        }
542                        else if (dim > 100) {
543                            this.numberTicks = parseInt(3+(dim-100)/75, 10);
544                        }
545                        else {
546                            this.numberTicks = 2;
547                        }
548                    }
549               
550                    if (this.tickInterval == null) {
551                        this.tickInterval = range / (this.numberTicks-1);
552                    }
553                }
554               
555                if (this.renderer.constructor == $.jqplot.LinearAxisRenderer && this._autoFormatString == '') {
556                    // fix for misleading tick display with small range and low precision.
557                    range = this.max - this.min;
558                    // figure out precision
559                    var temptick = new this.tickRenderer(this.tickOptions);
560                    // use the tick formatString or, the default.
561                    var fs = temptick.formatString || $.jqplot.config.defaultTickFormatString;
562                    var fs = fs.match($.jqplot.sprintf.regex)[0];
563                    var precision = 0;
564                    if (fs) {
565                        if (fs.search(/[fFeEgGpP]/) > -1) {
566                            var m = fs.match(/\%\.(\d{0,})?[eEfFgGpP]/);
567                            if (m) {
568                                precision = parseInt(m[1], 10);
569                            }
570                            else {
571                                precision = 6;
572                            }
573                        }
574                        else if (fs.search(/[di]/) > -1) {
575                            precision = 0;
576                        }
577                        // fact will be <= 1;
578                        var fact = Math.pow(10, -precision);
579                        if (this.tickInterval < fact) {
580                            // need to correct underrange
581                            if (userNT == null && userTI == null) {
582                                this.tickInterval = fact;
583                                if (userMax == null && userMin == null) {
584                                    // this.min = Math.floor((this._dataBounds.min - this.tickInterval)/fact) * fact;
585                                    this.min = Math.floor(this._dataBounds.min/fact) * fact;
586                                    if (this.min == this._dataBounds.min) {
587                                        this.min = this._dataBounds.min - this.tickInterval;
588                                    }
589                                    // this.max = Math.ceil((this._dataBounds.max + this.tickInterval)/fact) * fact;
590                                    this.max = Math.ceil(this._dataBounds.max/fact) * fact;
591                                    if (this.max == this._dataBounds.max) {
592                                        this.max = this._dataBounds.max + this.tickInterval;
593                                    }
594                                    var n = (this.max - this.min)/this.tickInterval;
595                                    n = n.toFixed(11);
596                                    n = Math.ceil(n);
597                                    this.numberTicks = n + 1;
598                                }
599                                else if (userMax == null) {
600                                    // add one tick for top of range.
601                                    var n = (this._dataBounds.max - this.min) / this.tickInterval;
602                                    n = n.toFixed(11);
603                                    this.numberTicks = Math.ceil(n) + 2;
604                                    this.max = this.min + this.tickInterval * (this.numberTicks-1);
605                                }
606                                else if (userMin == null) {
607                                    // add one tick for bottom of range.
608                                    var n = (this.max - this._dataBounds.min) / this.tickInterval;
609                                    n = n.toFixed(11);
610                                    this.numberTicks = Math.ceil(n) + 2;
611                                    this.min = this.max - this.tickInterval * (this.numberTicks-1);
612                                }
613                                else {
614                                    // calculate a number of ticks so max is within axis scale
615                                    this.numberTicks = Math.ceil((userMax - userMin)/this.tickInterval) + 1;
616                                    // if user's min and max don't fit evenly in ticks, adjust.
617                                    // This takes care of cases such as user min set to 0, max set to 3.5 but tick
618                                    // format string set to %d (integer ticks)
619                                    this.min =  Math.floor(userMin*Math.pow(10, precision))/Math.pow(10, precision);
620                                    this.max =  Math.ceil(userMax*Math.pow(10, precision))/Math.pow(10, precision);
621                                    // this.max = this.min + this.tickInterval*(this.numberTicks-1);
622                                    this.numberTicks = Math.ceil((this.max - this.min)/this.tickInterval) + 1;
623                                }
624                            }
625                        }
626                    }
627                }
628               
629            }
630           
631            if (this._overrideFormatString && this._autoFormatString != '') {
632                this.tickOptions = this.tickOptions || {};
633                this.tickOptions.formatString = this._autoFormatString;
634            }
635
636            for (var i=0; i<this.numberTicks; i++){
637                tt = this.min + i * this.tickInterval;
638                var t = new this.tickRenderer(this.tickOptions);
639                // var t = new $.jqplot.AxisTickRenderer(this.tickOptions);
640
641                t.setTick(tt, this.name);
642                this._ticks.push(t);
643                t = null;
644            }
645        }
646        ticks = null;
647    };
648   
649    // Used to reset just the values of the ticks and then repack, which will
650    // recalculate the positioning functions.  It is assuemd that the
651    // number of ticks is the same and the values of the new array are at the
652    // proper interval.
653    // This method needs to be called with the scope of an axis object, like:
654    //
655    // > plot.axes.yaxis.renderer.resetTickValues.call(plot.axes.yaxis, yarr);
656    //
657    $.jqplot.LinearAxisRenderer.prototype.resetTickValues = function(opts) {
658        if ($.isArray(opts) && opts.length == this._ticks.length) {
659            var t;
660            for (var i=0; i<opts.length; i++) {
661                t = this._ticks[i];
662                t.value = opts[i];
663                t.label = t.formatter(t.formatString, opts[i]);
664                t.label = t.prefix + t.label;
665                t._elem.html(t.label);
666            }
667            t = null;
668            this.min = $.jqplot.arrayMin(opts);
669            this.max = $.jqplot.arrayMax(opts);
670            this.pack();
671        }
672        // Not implemented yet.
673        // else if ($.isPlainObject(opts)) {
674        //
675        // }
676    };
677   
678    // called with scope of axis
679    $.jqplot.LinearAxisRenderer.prototype.pack = function(pos, offsets) {
680        // Add defaults for repacking from resetTickValues function.
681        pos = pos || {};
682        offsets = offsets || this._offsets;
683       
684        var ticks = this._ticks;
685        var max = this.max;
686        var min = this.min;
687        var offmax = offsets.max;
688        var offmin = offsets.min;
689        var lshow = (this._label == null) ? false : this._label.show;
690       
691        for (var p in pos) {
692            this._elem.css(p, pos[p]);
693        }
694       
695        this._offsets = offsets;
696        // pixellength will be + for x axes and - for y axes becasue pixels always measured from top left.
697        var pixellength = offmax - offmin;
698        var unitlength = max - min;
699       
700        // point to unit and unit to point conversions references to Plot DOM element top left corner.
701        if (this.breakPoints) {
702            unitlength = unitlength - this.breakPoints[1] + this.breakPoints[0];
703           
704            this.p2u = function(p){
705                return (p - offmin) * unitlength / pixellength + min;
706            };
707       
708            this.u2p = function(u){
709                if (u > this.breakPoints[0] && u < this.breakPoints[1]){
710                    u = this.breakPoints[0];
711                }
712                if (u <= this.breakPoints[0]) {
713                    return (u - min) * pixellength / unitlength + offmin;
714                }
715                else {
716                    return (u - this.breakPoints[1] + this.breakPoints[0] - min) * pixellength / unitlength + offmin;
717                }
718            };
719               
720            if (this.name.charAt(0) == 'x'){
721                this.series_u2p = function(u){
722                    if (u > this.breakPoints[0] && u < this.breakPoints[1]){
723                        u = this.breakPoints[0];
724                    }
725                    if (u <= this.breakPoints[0]) {
726                        return (u - min) * pixellength / unitlength;
727                    }
728                    else {
729                        return (u - this.breakPoints[1] + this.breakPoints[0] - min) * pixellength / unitlength;
730                    }
731                };
732                this.series_p2u = function(p){
733                    return p * unitlength / pixellength + min;
734                };
735            }
736       
737            else {
738                this.series_u2p = function(u){
739                    if (u > this.breakPoints[0] && u < this.breakPoints[1]){
740                        u = this.breakPoints[0];
741                    }
742                    if (u >= this.breakPoints[1]) {
743                        return (u - max) * pixellength / unitlength;
744                    }
745                    else {
746                        return (u + this.breakPoints[1] - this.breakPoints[0] - max) * pixellength / unitlength;
747                    }
748                };
749                this.series_p2u = function(p){
750                    return p * unitlength / pixellength + max;
751                };
752            }
753        }
754        else {
755            this.p2u = function(p){
756                return (p - offmin) * unitlength / pixellength + min;
757            };
758       
759            this.u2p = function(u){
760                return (u - min) * pixellength / unitlength + offmin;
761            };
762               
763            if (this.name == 'xaxis' || this.name == 'x2axis'){
764                this.series_u2p = function(u){
765                    return (u - min) * pixellength / unitlength;
766                };
767                this.series_p2u = function(p){
768                    return p * unitlength / pixellength + min;
769                };
770            }
771       
772            else {
773                this.series_u2p = function(u){
774                    return (u - max) * pixellength / unitlength;
775                };
776                this.series_p2u = function(p){
777                    return p * unitlength / pixellength + max;
778                };
779            }
780        }
781       
782        if (this.show) {
783            if (this.name == 'xaxis' || this.name == 'x2axis') {
784                for (var i=0; i<ticks.length; i++) {
785                    var t = ticks[i];
786                    if (t.show && t.showLabel) {
787                        var shim;
788                       
789                        if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) {
790                            // will need to adjust auto positioning based on which axis this is.
791                            var temp = (this.name == 'xaxis') ? 1 : -1;
792                            switch (t.labelPosition) {
793                                case 'auto':
794                                    // position at end
795                                    if (temp * t.angle < 0) {
796                                        shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
797                                    }
798                                    // position at start
799                                    else {
800                                        shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2;
801                                    }
802                                    break;
803                                case 'end':
804                                    shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
805                                    break;
806                                case 'start':
807                                    shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2;
808                                    break;
809                                case 'middle':
810                                    shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
811                                    break;
812                                default:
813                                    shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
814                                    break;
815                            }
816                        }
817                        else {
818                            shim = -t.getWidth()/2;
819                        }
820                        var val = this.u2p(t.value) + shim + 'px';
821                        t._elem.css('left', val);
822                        t.pack();
823                    }
824                }
825                if (lshow) {
826                    var w = this._label._elem.outerWidth(true);
827                    this._label._elem.css('left', offmin + pixellength/2 - w/2 + 'px');
828                    if (this.name == 'xaxis') {
829                        this._label._elem.css('bottom', '0px');
830                    }
831                    else {
832                        this._label._elem.css('top', '0px');
833                    }
834                    this._label.pack();
835                }
836            }
837            else {
838                for (var i=0; i<ticks.length; i++) {
839                    var t = ticks[i];
840                    if (t.show && t.showLabel) {                       
841                        var shim;
842                        if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) {
843                            // will need to adjust auto positioning based on which axis this is.
844                            var temp = (this.name == 'yaxis') ? 1 : -1;
845                            switch (t.labelPosition) {
846                                case 'auto':
847                                    // position at end
848                                case 'end':
849                                    if (temp * t.angle < 0) {
850                                        shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2;
851                                    }
852                                    else {
853                                        shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2;
854                                    }
855                                    break;
856                                case 'start':
857                                    if (t.angle > 0) {
858                                        shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2;
859                                    }
860                                    else {
861                                        shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2;
862                                    }
863                                    break;
864                                case 'middle':
865                                    // if (t.angle > 0) {
866                                    //     shim = -t.getHeight()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
867                                    // }
868                                    // else {
869                                    //     shim = -t.getHeight()/2 - t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2;
870                                    // }
871                                    shim = -t.getHeight()/2;
872                                    break;
873                                default:
874                                    shim = -t.getHeight()/2;
875                                    break;
876                            }
877                        }
878                        else {
879                            shim = -t.getHeight()/2;
880                        }
881                       
882                        var val = this.u2p(t.value) + shim + 'px';
883                        t._elem.css('top', val);
884                        t.pack();
885                    }
886                }
887                if (lshow) {
888                    var h = this._label._elem.outerHeight(true);
889                    this._label._elem.css('top', offmax - pixellength/2 - h/2 + 'px');
890                    if (this.name == 'yaxis') {
891                        this._label._elem.css('left', '0px');
892                    }
893                    else {
894                        this._label._elem.css('right', '0px');
895                    }   
896                    this._label.pack();
897                }
898            }
899        }
900
901        ticks = null;
902    };
903})(jQuery);
Note: See TracBrowser for help on using the repository browser.