polardbxengine/storage/ndb/mcc/frontend/dojo/dojox/dgauges/MultiLinearScaler.js.uncomp...

150 lines
4.6 KiB
JavaScript

define("dojox/dgauges/MultiLinearScaler", ["dojo/_base/declare", "dojo/Stateful"], function(declare, Stateful){
return declare("dojox.dgauges.MultiLinearScaler", Stateful, {
// summary:
// The multi-linear scaler. This scaler maps numeric values according
// to the majorTickValues content.
// This allows display of very large value intervals that are difficult to render
// with a linear scale. For example, if majorTickValues contains [0, 10, 50, 500, 2000],
// the scale will show five major ticks with these values.
// Note that this is not a logarithmic scale, the interpolation is linear between
// two contiguous major ticks.
// Scalers are responsible for tick generation and various data-transform operations.
// majorTickValues: Array
// An array of Number for creating major ticks.
// This array must be sorted in ascendant order.
majorTickValues: null,
// minorTickCount: Array
// The number of minor ticks between two contiguous major ticks.
// The default value is 4.
minorTickCount: 4,
// majorTicks:
// The array of generated major ticks. You should not set this
// property when using the scaler.
majorTicks: null,
// minorTicks:
// The array of generated minor ticks. You should not set this
// property when using the scaler.
minorTicks: null,
_snapIntervalPrecision: null,
_snapCount: 4,
_snapIntervalPrecision: 6,
constructor: function(){
this.watchedProperties = ["majorTickValues", "snapCount", "minorTickCount"];
},
computeTicks: function(){
// summary:
// Creates or re-creates the ticks for this scaler.
// returns: Array
// An array containing all ticks (major then minor ticks).
this.majorTicks = [];
this.minorTicks = [];
var ti;
var step = 1 / (this.majorTickValues.length - 1);
var minorStep = step / (this.minorTickCount + 1);
var currentIndex = 0;
var minorInterval;
var currentMajorValue;
var v;
for(var i = 0; i < this.majorTickValues.length; i++){
v = this.majorTickValues[i];
ti = {scaler: this};
ti.position = currentIndex * step;
ti.value = v;
ti.isMinor = false;
this.majorTicks.push(ti);
if(currentIndex < this.majorTickValues.length - 1){
currentMajorValue = Number(v);
minorInterval = (Number(this.majorTickValues[i + 1]) - currentMajorValue) / (this.minorTickCount + 1);
for(var j = 1; j <= this.minorTickCount; j++){
ti = {scaler: this};
ti.isMinor = true;
ti.position = currentIndex * step + j * minorStep;
ti.value = currentMajorValue + minorInterval * j;
this.minorTicks.push(ti);
}
}
currentIndex++;
}
return this.majorTicks.concat(this.minorTicks);
},
positionForValue: function(value){
// summary:
// Transforms a value into a relative position between 0 and 1.
// value: Number
// A value to transform.
// returns: Number
// The position between 0 and 1.
if(!this.majorTickValues){
return 0;
}
if(!this.majorTicks){
this.computeTicks();
}
var minmax = this._getMinMax(value);
var position = (value - minmax[0].value) / (minmax[1].value - minmax[0].value);
return minmax[0].position + position * (minmax[1].position - minmax[0].position);
},
valueForPosition: function(position){
// summary:
// Transforms a relative position (between 0 and 1) into a value.
// position: Number
// A relative position to transform.
// returns: Number
// The transformed value.
if(this.majorTicks == null){
return 0;
}
var minmax = this._getMinMax(position, "position");
var value = (position - minmax[0].position) / (minmax[1].position - minmax[0].position);
return minmax[0].value + value * (minmax[1].value - minmax[0].value);
},
_getMinMax: function(v, property){
// summary:
// Internal method.
// tags:
// private
if(!property){
property = "value";
}
var res = [];
var pre;
var post;
var left = 0;
var right = this.majorTicks.length - 1;
var center;
if(v <= this.majorTicks[0][property] || v >= this.majorTicks[right][property]){
res[0] = this.majorTicks[0];
res[1] = this.majorTicks[right];
return res;
}
while (true){
center = Math.floor((left + right) / 2);
if(this.majorTicks[center][property] <= v){
if(this.majorTicks[center + 1][property] >= v){
res[0] = this.majorTicks[center];
res[1] = this.majorTicks[center + 1];
return res;
}else{
left = center + 1;
continue;
}
}else{
right = center;
continue;
}
}
}
});
});