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.
185 lines
4.2 KiB
185 lines
4.2 KiB
jvm.NumericScale = function(scale, normalizeFunction, minValue, maxValue) { |
|
this.scale = []; |
|
|
|
normalizeFunction = normalizeFunction || 'linear'; |
|
|
|
if (scale) this.setScale(scale); |
|
if (normalizeFunction) this.setNormalizeFunction(normalizeFunction); |
|
if (typeof minValue !== 'undefined' ) this.setMin(minValue); |
|
if (typeof maxValue !== 'undefined' ) this.setMax(maxValue); |
|
}; |
|
|
|
jvm.NumericScale.prototype = { |
|
setMin: function(min) { |
|
this.clearMinValue = min; |
|
if (typeof this.normalize === 'function') { |
|
this.minValue = this.normalize(min); |
|
} else { |
|
this.minValue = min; |
|
} |
|
}, |
|
|
|
setMax: function(max) { |
|
this.clearMaxValue = max; |
|
if (typeof this.normalize === 'function') { |
|
this.maxValue = this.normalize(max); |
|
} else { |
|
this.maxValue = max; |
|
} |
|
}, |
|
|
|
setScale: function(scale) { |
|
var i; |
|
|
|
this.scale = []; |
|
for (i = 0; i < scale.length; i++) { |
|
this.scale[i] = [scale[i]]; |
|
} |
|
}, |
|
|
|
setNormalizeFunction: function(f) { |
|
if (f === 'polynomial') { |
|
this.normalize = function(value) { |
|
return Math.pow(value, 0.2); |
|
} |
|
} else if (f === 'linear') { |
|
delete this.normalize; |
|
} else { |
|
this.normalize = f; |
|
} |
|
this.setMin(this.clearMinValue); |
|
this.setMax(this.clearMaxValue); |
|
}, |
|
|
|
getValue: function(value) { |
|
var lengthes = [], |
|
fullLength = 0, |
|
l, |
|
i = 0, |
|
c; |
|
|
|
if (typeof this.normalize === 'function') { |
|
value = this.normalize(value); |
|
} |
|
for (i = 0; i < this.scale.length-1; i++) { |
|
l = this.vectorLength(this.vectorSubtract(this.scale[i+1], this.scale[i])); |
|
lengthes.push(l); |
|
fullLength += l; |
|
} |
|
|
|
c = (this.maxValue - this.minValue) / fullLength; |
|
for (i=0; i<lengthes.length; i++) { |
|
lengthes[i] *= c; |
|
} |
|
|
|
i = 0; |
|
value -= this.minValue; |
|
while (value - lengthes[i] >= 0) { |
|
value -= lengthes[i]; |
|
i++; |
|
} |
|
|
|
if (i == this.scale.length - 1) { |
|
value = this.vectorToNum(this.scale[i]) |
|
} else { |
|
value = ( |
|
this.vectorToNum( |
|
this.vectorAdd(this.scale[i], |
|
this.vectorMult( |
|
this.vectorSubtract(this.scale[i+1], this.scale[i]), |
|
(value) / (lengthes[i]) |
|
) |
|
) |
|
) |
|
); |
|
} |
|
|
|
return value; |
|
}, |
|
|
|
vectorToNum: function(vector) { |
|
var num = 0, |
|
i; |
|
|
|
for (i = 0; i < vector.length; i++) { |
|
num += Math.round(vector[i])*Math.pow(256, vector.length-i-1); |
|
} |
|
return num; |
|
}, |
|
|
|
vectorSubtract: function(vector1, vector2) { |
|
var vector = [], |
|
i; |
|
|
|
for (i = 0; i < vector1.length; i++) { |
|
vector[i] = vector1[i] - vector2[i]; |
|
} |
|
return vector; |
|
}, |
|
|
|
vectorAdd: function(vector1, vector2) { |
|
var vector = [], |
|
i; |
|
|
|
for (i = 0; i < vector1.length; i++) { |
|
vector[i] = vector1[i] + vector2[i]; |
|
} |
|
return vector; |
|
}, |
|
|
|
vectorMult: function(vector, num) { |
|
var result = [], |
|
i; |
|
|
|
for (i = 0; i < vector.length; i++) { |
|
result[i] = vector[i] * num; |
|
} |
|
return result; |
|
}, |
|
|
|
vectorLength: function(vector) { |
|
var result = 0, |
|
i; |
|
for (i = 0; i < vector.length; i++) { |
|
result += vector[i] * vector[i]; |
|
} |
|
return Math.sqrt(result); |
|
}, |
|
|
|
/* Derived from d3 implementation https://github.com/mbostock/d3/blob/master/src/scale/linear.js#L94 */ |
|
getTicks: function(){ |
|
var m = 5, |
|
extent = [this.clearMinValue, this.clearMaxValue], |
|
span = extent[1] - extent[0], |
|
step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)), |
|
err = m / span * step, |
|
ticks = [], |
|
tick, |
|
v; |
|
|
|
if (err <= .15) step *= 10; |
|
else if (err <= .35) step *= 5; |
|
else if (err <= .75) step *= 2; |
|
|
|
extent[0] = Math.floor(extent[0] / step) * step; |
|
extent[1] = Math.ceil(extent[1] / step) * step; |
|
|
|
tick = extent[0]; |
|
while (tick <= extent[1]) { |
|
if (tick == extent[0]) { |
|
v = this.clearMinValue; |
|
} else if (tick == extent[1]) { |
|
v = this.clearMaxValue; |
|
} else { |
|
v = tick; |
|
} |
|
ticks.push({ |
|
label: tick, |
|
value: this.getValue(v) |
|
}); |
|
tick += step; |
|
} |
|
|
|
return ticks; |
|
} |
|
};
|
|
|