You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
149 lines
4.5 KiB
149 lines
4.5 KiB
define(["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; |
|
} |
|
} |
|
} |
|
}); |
|
});
|
|
|