source: Dev/trunk/src/client/dojox/charting/scaler/linear.js @ 483

Last change on this file since 483 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 8.9 KB
Line 
1define(["dojo/_base/lang", "./common"],
2        function(lang, common){
3        var linear = lang.getObject("dojox.charting.scaler.linear", true);
4       
5        var deltaLimit = 3,     // pixels
6                getLabel = common.getNumericLabel;
7
8                function findString(/*String*/ val, /*Array*/ text){
9                        val = val.toLowerCase();
10                        for(var i = text.length - 1; i >= 0; --i){
11                                if(val === text[i]){
12                                        return true;
13                                }
14                        }
15                        return false;
16                }
17       
18        var calcTicks = function(min, max, kwArgs, majorTick, minorTick, microTick, span){
19                kwArgs = lang.delegate(kwArgs);
20                if(!majorTick){
21                        if(kwArgs.fixUpper == "major"){ kwArgs.fixUpper = "minor"; }
22                        if(kwArgs.fixLower == "major"){ kwArgs.fixLower = "minor"; }
23                }
24                if(!minorTick){
25                        if(kwArgs.fixUpper == "minor"){ kwArgs.fixUpper = "micro"; }
26                        if(kwArgs.fixLower == "minor"){ kwArgs.fixLower = "micro"; }
27                }
28                if(!microTick){
29                        if(kwArgs.fixUpper == "micro"){ kwArgs.fixUpper = "none"; }
30                        if(kwArgs.fixLower == "micro"){ kwArgs.fixLower = "none"; }
31                }
32                var lowerBound = findString(kwArgs.fixLower, ["major"]) ?
33                                Math.floor(kwArgs.min / majorTick) * majorTick :
34                                        findString(kwArgs.fixLower, ["minor"]) ?
35                                                Math.floor(kwArgs.min / minorTick) * minorTick :
36                                                        findString(kwArgs.fixLower, ["micro"]) ?
37                                                                Math.floor(kwArgs.min / microTick) * microTick : kwArgs.min,
38                        upperBound = findString(kwArgs.fixUpper, ["major"]) ?
39                                Math.ceil(kwArgs.max / majorTick) * majorTick :
40                                        findString(kwArgs.fixUpper, ["minor"]) ?
41                                                Math.ceil(kwArgs.max / minorTick) * minorTick :
42                                                        findString(kwArgs.fixUpper, ["micro"]) ?
43                                                                Math.ceil(kwArgs.max / microTick) * microTick : kwArgs.max;
44                                                               
45                if(kwArgs.useMin){ min = lowerBound; }
46                if(kwArgs.useMax){ max = upperBound; }
47               
48                var majorStart = (!majorTick || kwArgs.useMin && findString(kwArgs.fixLower, ["major"])) ?
49                                min : Math.ceil(min / majorTick) * majorTick,
50                        minorStart = (!minorTick || kwArgs.useMin && findString(kwArgs.fixLower, ["major", "minor"])) ?
51                                min : Math.ceil(min / minorTick) * minorTick,
52                        microStart = (! microTick || kwArgs.useMin && findString(kwArgs.fixLower, ["major", "minor", "micro"])) ?
53                                min : Math.ceil(min / microTick) * microTick,
54                        majorCount = !majorTick ? 0 : (kwArgs.useMax && findString(kwArgs.fixUpper, ["major"]) ?
55                                Math.round((max - majorStart) / majorTick) :
56                                Math.floor((max - majorStart) / majorTick)) + 1,
57                        minorCount = !minorTick ? 0 : (kwArgs.useMax && findString(kwArgs.fixUpper, ["major", "minor"]) ?
58                                Math.round((max - minorStart) / minorTick) :
59                                Math.floor((max - minorStart) / minorTick)) + 1,
60                        microCount = !microTick ? 0 : (kwArgs.useMax && findString(kwArgs.fixUpper, ["major", "minor", "micro"]) ?
61                                Math.round((max - microStart) / microTick) :
62                                Math.floor((max - microStart) / microTick)) + 1,
63                        minorPerMajor  = minorTick ? Math.round(majorTick / minorTick) : 0,
64                        microPerMinor  = microTick ? Math.round(minorTick / microTick) : 0,
65                        majorPrecision = majorTick ? Math.floor(Math.log(majorTick) / Math.LN10) : 0,
66                        minorPrecision = minorTick ? Math.floor(Math.log(minorTick) / Math.LN10) : 0,
67                        scale = span / (max - min);
68                if(!isFinite(scale)){ scale = 1; }
69               
70                return {
71                        bounds: {
72                                lower:  lowerBound,
73                                upper:  upperBound,
74                                from:   min,
75                                to:             max,
76                                scale:  scale,
77                                span:   span
78                        },
79                        major: {
80                                tick:   majorTick,
81                                start:  majorStart,
82                                count:  majorCount,
83                                prec:   majorPrecision
84                        },
85                        minor: {
86                                tick:   minorTick,
87                                start:  minorStart,
88                                count:  minorCount,
89                                prec:   minorPrecision
90                        },
91                        micro: {
92                                tick:   microTick,
93                                start:  microStart,
94                                count:  microCount,
95                                prec:   0
96                        },
97                        minorPerMajor:  minorPerMajor,
98                        microPerMinor:  microPerMinor,
99                        scaler:                 linear
100                };
101        };
102       
103        return lang.mixin(linear, {
104                buildScaler: function(/*Number*/ min, /*Number*/ max, /*Number*/ span, /*Object*/ kwArgs, /*Number?*/ delta, /*Number?*/ minorDelta){
105                        var h = {fixUpper: "none", fixLower: "none", natural: false};
106                        if(kwArgs){
107                                if("fixUpper" in kwArgs){ h.fixUpper = String(kwArgs.fixUpper); }
108                                if("fixLower" in kwArgs){ h.fixLower = String(kwArgs.fixLower); }
109                                if("natural"  in kwArgs){ h.natural  = Boolean(kwArgs.natural); }
110                        }
111                        minorDelta = !minorDelta || minorDelta < deltaLimit ? deltaLimit : minorDelta;
112                       
113                        // update bounds
114                        if("min" in kwArgs){ min = kwArgs.min; }
115                        if("max" in kwArgs){ max = kwArgs.max; }
116                        if(kwArgs.includeZero){
117                                if(min > 0){ min = 0; }
118                                if(max < 0){ max = 0; }
119                        }
120                        h.min = min;
121                        h.useMin = true;
122                        h.max = max;
123                        h.useMax = true;
124                       
125                        if("from" in kwArgs){
126                                min = kwArgs.from;
127                                h.useMin = false;
128                        }
129                        if("to" in kwArgs){
130                                max = kwArgs.to;
131                                h.useMax = false;
132                        }
133                       
134                        // check for erroneous condition
135                        if(max <= min){
136                                return calcTicks(min, max, h, 0, 0, 0, span);   // Object
137                        }
138                        if(!delta){
139                                delta = max - min;
140                        }
141                        var mag = Math.floor(Math.log(delta) / Math.LN10),
142                                major = kwArgs && ("majorTickStep" in kwArgs) ? kwArgs.majorTickStep : Math.pow(10, mag),
143                                minor = 0, micro = 0, ticks;
144                               
145                        // calculate minor ticks
146                        if(kwArgs && ("minorTickStep" in kwArgs)){
147                                minor = kwArgs.minorTickStep;
148                        }else{
149                                do{
150                                        minor = major / 10;
151                                        if(!h.natural || minor > 0.9){
152                                                ticks = calcTicks(min, max, h, major, minor, 0, span);
153                                                if(ticks.bounds.scale * ticks.minor.tick > minorDelta){ break; }
154                                        }
155                                        minor = major / 5;
156                                        if(!h.natural || minor > 0.9){
157                                                ticks = calcTicks(min, max, h, major, minor, 0, span);
158                                                if(ticks.bounds.scale * ticks.minor.tick > minorDelta){ break; }
159                                        }
160                                        minor = major / 2;
161                                        if(!h.natural || minor > 0.9){
162                                                ticks = calcTicks(min, max, h, major, minor, 0, span);
163                                                if(ticks.bounds.scale * ticks.minor.tick > minorDelta){ break; }
164                                        }
165                                        return calcTicks(min, max, h, major, 0, 0, span);       // Object
166                                }while(false);
167                        }
168       
169                        // calculate micro ticks
170                        if(kwArgs && ("microTickStep" in kwArgs)){
171                                micro = kwArgs.microTickStep;
172                                ticks = calcTicks(min, max, h, major, minor, micro, span);
173                        }else{
174                                do{
175                                        micro = minor / 10;
176                                        if(!h.natural || micro > 0.9){
177                                                ticks = calcTicks(min, max, h, major, minor, micro, span);
178                                                if(ticks.bounds.scale * ticks.micro.tick > deltaLimit){ break; }
179                                        }
180                                        micro = minor / 5;
181                                        if(!h.natural || micro > 0.9){
182                                                ticks = calcTicks(min, max, h, major, minor, micro, span);
183                                                if(ticks.bounds.scale * ticks.micro.tick > deltaLimit){ break; }
184                                        }
185                                        micro = minor / 2;
186                                        if(!h.natural || micro > 0.9){
187                                                ticks = calcTicks(min, max, h, major, minor, micro, span);
188                                                if(ticks.bounds.scale * ticks.micro.tick > deltaLimit){ break; }
189                                        }
190                                        micro = 0;
191                                }while(false);
192                        }
193       
194                        return micro ? ticks : calcTicks(min, max, h, major, minor, 0, span);   // Object
195                },
196                buildTicks: function(/*Object*/ scaler, /*Object*/ kwArgs){
197                        var step, next, tick,
198                                nextMajor = scaler.major.start,
199                                nextMinor = scaler.minor.start,
200                                nextMicro = scaler.micro.start;
201                        if(kwArgs.microTicks && scaler.micro.tick){
202                                step = scaler.micro.tick, next = nextMicro;
203                        }else if(kwArgs.minorTicks && scaler.minor.tick){
204                                step = scaler.minor.tick, next = nextMinor;
205                        }else if(scaler.major.tick){
206                                step = scaler.major.tick, next = nextMajor;
207                        }else{
208                                // no ticks
209                                return null;
210                        }
211                        // make sure that we have finite bounds
212                        var revScale = 1 / scaler.bounds.scale;
213                        if(scaler.bounds.to <= scaler.bounds.from || isNaN(revScale) || !isFinite(revScale) ||
214                                        step <= 0 || isNaN(step) || !isFinite(step)){
215                                // no ticks
216                                return null;
217                        }
218                        // loop over all ticks
219                        var majorTicks = [], minorTicks = [], microTicks = [];
220                        while(next <= scaler.bounds.to + revScale){
221                                if(Math.abs(nextMajor - next) < step / 2){
222                                        // major tick
223                                        tick = {value: nextMajor};
224                                        if(kwArgs.majorLabels){
225                                                tick.label = getLabel(nextMajor, scaler.major.prec, kwArgs);
226                                        }
227                                        majorTicks.push(tick);
228                                        nextMajor += scaler.major.tick;
229                                        nextMinor += scaler.minor.tick;
230                                        nextMicro += scaler.micro.tick;
231                                }else if(Math.abs(nextMinor - next) < step / 2){
232                                        // minor tick
233                                        if(kwArgs.minorTicks){
234                                                tick = {value: nextMinor};
235                                                if(kwArgs.minorLabels && (scaler.minMinorStep <= scaler.minor.tick * scaler.bounds.scale)){
236                                                        tick.label = getLabel(nextMinor, scaler.minor.prec, kwArgs);
237                                                }
238                                                minorTicks.push(tick);
239                                        }
240                                        nextMinor += scaler.minor.tick;
241                                        nextMicro += scaler.micro.tick;
242                                }else{
243                                        // micro tick
244                                        if(kwArgs.microTicks){
245                                                microTicks.push({value: nextMicro});
246                                        }
247                                        nextMicro += scaler.micro.tick;
248                                }
249                                next += step;
250                        }
251                        return {major: majorTicks, minor: minorTicks, micro: microTicks};       // Object
252                },
253                getTransformerFromModel: function(/*Object*/ scaler){
254                        var offset = scaler.bounds.from, scale = scaler.bounds.scale;
255                        return function(x){ return (x - offset) * scale; };     // Function
256                },
257                getTransformerFromPlot: function(/*Object*/ scaler){
258                        var offset = scaler.bounds.from, scale = scaler.bounds.scale;
259                        return function(x){ return x / scale + offset; };       // Function
260                }
261        });
262});
Note: See TracBrowser for help on using the repository browser.