105 lines
2.3 KiB
Java
105 lines
2.3 KiB
Java
|
|
/**
|
|||
|
|
* @fileOverview 使用pow进行度量计算
|
|||
|
|
* @author dxq613@gmail.com
|
|||
|
|
*/
|
|||
|
|
const Base = require('./base');
|
|||
|
|
const Linear = require('./linear');
|
|||
|
|
|
|||
|
|
// 求以a为次幂,结果为b的基数,如 x^^a = b;求x
|
|||
|
|
function calBase(a, b) {
|
|||
|
|
const e = Math.E;
|
|||
|
|
const value = Math.pow(e, Math.log(b) / a); // 使用换底公式求底
|
|||
|
|
return value;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 度量的Pow计算
|
|||
|
|
* @class Scale.Log
|
|||
|
|
*/
|
|||
|
|
class Pow extends Linear {
|
|||
|
|
|
|||
|
|
_initDefaultCfg() {
|
|||
|
|
super._initDefaultCfg();
|
|||
|
|
|
|||
|
|
this.type = 'pow';
|
|||
|
|
/**
|
|||
|
|
* @override
|
|||
|
|
* pow 的坐标点的个数控制在10个以下
|
|||
|
|
* @type {Number}
|
|||
|
|
*/
|
|||
|
|
this.tickCount = 10;
|
|||
|
|
/**
|
|||
|
|
* 进行pow计算的基数
|
|||
|
|
* @type {Number}
|
|||
|
|
*/
|
|||
|
|
this.exponent = 2;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @override
|
|||
|
|
*/
|
|||
|
|
calculateTicks() {
|
|||
|
|
const self = this;
|
|||
|
|
const exponent = self.exponent;
|
|||
|
|
let min;
|
|||
|
|
let max = Math.ceil(calBase(exponent, self.max));
|
|||
|
|
|
|||
|
|
if (self.min >= 0) {
|
|||
|
|
min = Math.floor(calBase(exponent, self.min));
|
|||
|
|
} else {
|
|||
|
|
min = 0;
|
|||
|
|
}
|
|||
|
|
if (min > max) {
|
|||
|
|
const tmp = max;
|
|||
|
|
max = min;
|
|||
|
|
min = tmp;
|
|||
|
|
}
|
|||
|
|
const count = max - min;
|
|||
|
|
const tickCount = self.tickCount;
|
|||
|
|
const avg = Math.ceil(count / tickCount);
|
|||
|
|
const ticks = [];
|
|||
|
|
|
|||
|
|
for (let i = min; i < max + avg; i = i + avg) {
|
|||
|
|
ticks.push(Math.pow(i, exponent));
|
|||
|
|
}
|
|||
|
|
return ticks;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 获取度量计算时,value占的定义域百分比
|
|||
|
|
_getScalePercent(value) {
|
|||
|
|
const max = this.max;
|
|||
|
|
const min = this.min;
|
|||
|
|
if (max === min) {
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
const exponent = this.exponent;
|
|||
|
|
const percent = (calBase(exponent, value) - calBase(exponent, min)) / (calBase(exponent, max) - calBase(exponent, min));
|
|||
|
|
return percent;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @override
|
|||
|
|
*/
|
|||
|
|
scale(value) {
|
|||
|
|
const percent = this._getScalePercent(value);
|
|||
|
|
const rangeMin = this.rangeMin();
|
|||
|
|
const rangeMax = this.rangeMax();
|
|||
|
|
return rangeMin + percent * (rangeMax - rangeMin);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @override
|
|||
|
|
*/
|
|||
|
|
invert(value) {
|
|||
|
|
const percent = (value - this.rangeMin()) / (this.rangeMax() - this.rangeMin());
|
|||
|
|
const exponent = this.exponent;
|
|||
|
|
const max = calBase(exponent, this.max);
|
|||
|
|
const min = calBase(exponent, this.min);
|
|||
|
|
const tmp = percent * (max - min) + min;
|
|||
|
|
return Math.pow(tmp, exponent);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Base.Pow = Pow;
|
|||
|
|
module.exports = Pow;
|