123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 |
- /*
- Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
- Available via Academic Free License >= 2.1 OR the modified BSD license.
- see: http://dojotoolkit.org/license for details
- */
- if(!dojo._hasResource["dojox.charting.scaler.linear"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
- dojo._hasResource["dojox.charting.scaler.linear"] = true;
- dojo.provide("dojox.charting.scaler.linear");
- dojo.require("dojox.charting.scaler.common");
- (function(){
- var deltaLimit = 3, // pixels
- dc = dojox.charting, dcs = dc.scaler, dcsc = dcs.common,
- findString = dcsc.findString,
- getLabel = dcsc.getNumericLabel;
-
- var calcTicks = function(min, max, kwArgs, majorTick, minorTick, microTick, span){
- kwArgs = dojo.delegate(kwArgs);
- if(!majorTick){
- if(kwArgs.fixUpper == "major"){ kwArgs.fixUpper = "minor"; }
- if(kwArgs.fixLower == "major"){ kwArgs.fixLower = "minor"; }
- }
- if(!minorTick){
- if(kwArgs.fixUpper == "minor"){ kwArgs.fixUpper = "micro"; }
- if(kwArgs.fixLower == "minor"){ kwArgs.fixLower = "micro"; }
- }
- if(!microTick){
- if(kwArgs.fixUpper == "micro"){ kwArgs.fixUpper = "none"; }
- if(kwArgs.fixLower == "micro"){ kwArgs.fixLower = "none"; }
- }
- var lowerBound = findString(kwArgs.fixLower, ["major"]) ?
- Math.floor(kwArgs.min / majorTick) * majorTick :
- findString(kwArgs.fixLower, ["minor"]) ?
- Math.floor(kwArgs.min / minorTick) * minorTick :
- findString(kwArgs.fixLower, ["micro"]) ?
- Math.floor(kwArgs.min / microTick) * microTick : kwArgs.min,
- upperBound = findString(kwArgs.fixUpper, ["major"]) ?
- Math.ceil(kwArgs.max / majorTick) * majorTick :
- findString(kwArgs.fixUpper, ["minor"]) ?
- Math.ceil(kwArgs.max / minorTick) * minorTick :
- findString(kwArgs.fixUpper, ["micro"]) ?
- Math.ceil(kwArgs.max / microTick) * microTick : kwArgs.max;
-
- if(kwArgs.useMin){ min = lowerBound; }
- if(kwArgs.useMax){ max = upperBound; }
-
- var majorStart = (!majorTick || kwArgs.useMin && findString(kwArgs.fixLower, ["major"])) ?
- min : Math.ceil(min / majorTick) * majorTick,
- minorStart = (!minorTick || kwArgs.useMin && findString(kwArgs.fixLower, ["major", "minor"])) ?
- min : Math.ceil(min / minorTick) * minorTick,
- microStart = (! microTick || kwArgs.useMin && findString(kwArgs.fixLower, ["major", "minor", "micro"])) ?
- min : Math.ceil(min / microTick) * microTick,
- majorCount = !majorTick ? 0 : (kwArgs.useMax && findString(kwArgs.fixUpper, ["major"]) ?
- Math.round((max - majorStart) / majorTick) :
- Math.floor((max - majorStart) / majorTick)) + 1,
- minorCount = !minorTick ? 0 : (kwArgs.useMax && findString(kwArgs.fixUpper, ["major", "minor"]) ?
- Math.round((max - minorStart) / minorTick) :
- Math.floor((max - minorStart) / minorTick)) + 1,
- microCount = !microTick ? 0 : (kwArgs.useMax && findString(kwArgs.fixUpper, ["major", "minor", "micro"]) ?
- Math.round((max - microStart) / microTick) :
- Math.floor((max - microStart) / microTick)) + 1,
- minorPerMajor = minorTick ? Math.round(majorTick / minorTick) : 0,
- microPerMinor = microTick ? Math.round(minorTick / microTick) : 0,
- majorPrecision = majorTick ? Math.floor(Math.log(majorTick) / Math.LN10) : 0,
- minorPrecision = minorTick ? Math.floor(Math.log(minorTick) / Math.LN10) : 0,
- scale = span / (max - min);
- if(!isFinite(scale)){ scale = 1; }
-
- return {
- bounds: {
- lower: lowerBound,
- upper: upperBound,
- from: min,
- to: max,
- scale: scale,
- span: span
- },
- major: {
- tick: majorTick,
- start: majorStart,
- count: majorCount,
- prec: majorPrecision
- },
- minor: {
- tick: minorTick,
- start: minorStart,
- count: minorCount,
- prec: minorPrecision
- },
- micro: {
- tick: microTick,
- start: microStart,
- count: microCount,
- prec: 0
- },
- minorPerMajor: minorPerMajor,
- microPerMinor: microPerMinor,
- scaler: dcs.linear
- };
- };
-
- dojo.mixin(dojox.charting.scaler.linear, {
- buildScaler: function(/*Number*/ min, /*Number*/ max, /*Number*/ span, /*Object*/ kwArgs){
- var h = {fixUpper: "none", fixLower: "none", natural: false};
- if(kwArgs){
- if("fixUpper" in kwArgs){ h.fixUpper = String(kwArgs.fixUpper); }
- if("fixLower" in kwArgs){ h.fixLower = String(kwArgs.fixLower); }
- if("natural" in kwArgs){ h.natural = Boolean(kwArgs.natural); }
- }
-
- // update bounds
- if("min" in kwArgs){ min = kwArgs.min; }
- if("max" in kwArgs){ max = kwArgs.max; }
- if(kwArgs.includeZero){
- if(min > 0){ min = 0; }
- if(max < 0){ max = 0; }
- }
- h.min = min;
- h.useMin = true;
- h.max = max;
- h.useMax = true;
-
- if("from" in kwArgs){
- min = kwArgs.from;
- h.useMin = false;
- }
- if("to" in kwArgs){
- max = kwArgs.to;
- h.useMax = false;
- }
-
- // check for erroneous condition
- if(max <= min){
- return calcTicks(min, max, h, 0, 0, 0, span); // Object
- }
-
- var mag = Math.floor(Math.log(max - min) / Math.LN10),
- major = kwArgs && ("majorTickStep" in kwArgs) ? kwArgs.majorTickStep : Math.pow(10, mag),
- minor = 0, micro = 0, ticks;
-
- // calculate minor ticks
- if(kwArgs && ("minorTickStep" in kwArgs)){
- minor = kwArgs.minorTickStep;
- }else{
- do{
- minor = major / 10;
- if(!h.natural || minor > 0.9){
- ticks = calcTicks(min, max, h, major, minor, 0, span);
- if(ticks.bounds.scale * ticks.minor.tick > deltaLimit){ break; }
- }
- minor = major / 5;
- if(!h.natural || minor > 0.9){
- ticks = calcTicks(min, max, h, major, minor, 0, span);
- if(ticks.bounds.scale * ticks.minor.tick > deltaLimit){ break; }
- }
- minor = major / 2;
- if(!h.natural || minor > 0.9){
- ticks = calcTicks(min, max, h, major, minor, 0, span);
- if(ticks.bounds.scale * ticks.minor.tick > deltaLimit){ break; }
- }
- return calcTicks(min, max, h, major, 0, 0, span); // Object
- }while(false);
- }
-
- // calculate micro ticks
- if(kwArgs && ("microTickStep" in kwArgs)){
- micro = kwArgs.microTickStep;
- ticks = calcTicks(min, max, h, major, minor, micro, span);
- }else{
- do{
- micro = minor / 10;
- if(!h.natural || micro > 0.9){
- ticks = calcTicks(min, max, h, major, minor, micro, span);
- if(ticks.bounds.scale * ticks.micro.tick > deltaLimit){ break; }
- }
- micro = minor / 5;
- if(!h.natural || micro > 0.9){
- ticks = calcTicks(min, max, h, major, minor, micro, span);
- if(ticks.bounds.scale * ticks.micro.tick > deltaLimit){ break; }
- }
- micro = minor / 2;
- if(!h.natural || micro > 0.9){
- ticks = calcTicks(min, max, h, major, minor, micro, span);
- if(ticks.bounds.scale * ticks.micro.tick > deltaLimit){ break; }
- }
- micro = 0;
- }while(false);
- }
-
- return micro ? ticks : calcTicks(min, max, h, major, minor, 0, span); // Object
- },
- buildTicks: function(/*Object*/ scaler, /*Object*/ kwArgs){
- var step, next, tick,
- nextMajor = scaler.major.start,
- nextMinor = scaler.minor.start,
- nextMicro = scaler.micro.start;
- if(kwArgs.microTicks && scaler.micro.tick){
- step = scaler.micro.tick, next = nextMicro;
- }else if(kwArgs.minorTicks && scaler.minor.tick){
- step = scaler.minor.tick, next = nextMinor;
- }else if(scaler.major.tick){
- step = scaler.major.tick, next = nextMajor;
- }else{
- // no ticks
- return null;
- }
- // make sure that we have finite bounds
- var revScale = 1 / scaler.bounds.scale;
- if(scaler.bounds.to <= scaler.bounds.from || isNaN(revScale) || !isFinite(revScale) ||
- step <= 0 || isNaN(step) || !isFinite(step)){
- // no ticks
- return null;
- }
- // loop over all ticks
- var majorTicks = [], minorTicks = [], microTicks = [];
- while(next <= scaler.bounds.to + revScale){
- if(Math.abs(nextMajor - next) < step / 2){
- // major tick
- tick = {value: nextMajor};
- if(kwArgs.majorLabels){
- tick.label = getLabel(nextMajor, scaler.major.prec, kwArgs);
- }
- majorTicks.push(tick);
- nextMajor += scaler.major.tick;
- nextMinor += scaler.minor.tick;
- nextMicro += scaler.micro.tick;
- }else if(Math.abs(nextMinor - next) < step / 2){
- // minor tick
- if(kwArgs.minorTicks){
- tick = {value: nextMinor};
- if(kwArgs.minorLabels && (scaler.minMinorStep <= scaler.minor.tick * scaler.bounds.scale)){
- tick.label = getLabel(nextMinor, scaler.minor.prec, kwArgs);
- }
- minorTicks.push(tick);
- }
- nextMinor += scaler.minor.tick;
- nextMicro += scaler.micro.tick;
- }else{
- // micro tick
- if(kwArgs.microTicks){
- microTicks.push({value: nextMicro});
- }
- nextMicro += scaler.micro.tick;
- }
- next += step;
- }
- return {major: majorTicks, minor: minorTicks, micro: microTicks}; // Object
- },
- getTransformerFromModel: function(/*Object*/ scaler){
- var offset = scaler.bounds.from, scale = scaler.bounds.scale;
- return function(x){ return (x - offset) * scale; }; // Function
- },
- getTransformerFromPlot: function(/*Object*/ scaler){
- var offset = scaler.bounds.from, scale = scaler.bounds.scale;
- return function(x){ return x / scale + offset; }; // Function
- }
- });
- })();
- }
|