pow.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /**
  2. * @fileOverview 使用pow进行度量计算
  3. * @author dxq613@gmail.com
  4. */
  5. const Base = require('./base');
  6. const Linear = require('./linear');
  7. // 求以a为次幂,结果为b的基数,如 x^^a = b;求x
  8. function calBase(a, b) {
  9. const e = Math.E;
  10. const value = Math.pow(e, Math.log(b) / a); // 使用换底公式求底
  11. return value;
  12. }
  13. /**
  14. * 度量的Pow计算
  15. * @class Scale.Log
  16. */
  17. class Pow extends Linear {
  18. _initDefaultCfg() {
  19. super._initDefaultCfg();
  20. this.type = 'pow';
  21. /**
  22. * @override
  23. * pow 的坐标点的个数控制在10个以下
  24. * @type {Number}
  25. */
  26. this.tickCount = 10;
  27. /**
  28. * 进行pow计算的基数
  29. * @type {Number}
  30. */
  31. this.exponent = 2;
  32. }
  33. /**
  34. * @override
  35. */
  36. calculateTicks() {
  37. const self = this;
  38. const exponent = self.exponent;
  39. let min;
  40. let max = Math.ceil(calBase(exponent, self.max));
  41. if (self.min >= 0) {
  42. min = Math.floor(calBase(exponent, self.min));
  43. } else {
  44. min = 0;
  45. }
  46. if (min > max) {
  47. const tmp = max;
  48. max = min;
  49. min = tmp;
  50. }
  51. const count = max - min;
  52. const tickCount = self.tickCount;
  53. const avg = Math.ceil(count / tickCount);
  54. const ticks = [];
  55. for (let i = min; i < max + avg; i = i + avg) {
  56. ticks.push(Math.pow(i, exponent));
  57. }
  58. return ticks;
  59. }
  60. // 获取度量计算时,value占的定义域百分比
  61. _getScalePercent(value) {
  62. const max = this.max;
  63. const min = this.min;
  64. if (max === min) {
  65. return 0;
  66. }
  67. const exponent = this.exponent;
  68. const percent = (calBase(exponent, value) - calBase(exponent, min)) / (calBase(exponent, max) - calBase(exponent, min));
  69. return percent;
  70. }
  71. /**
  72. * @override
  73. */
  74. scale(value) {
  75. const percent = this._getScalePercent(value);
  76. const rangeMin = this.rangeMin();
  77. const rangeMax = this.rangeMax();
  78. return rangeMin + percent * (rangeMax - rangeMin);
  79. }
  80. /**
  81. * @override
  82. */
  83. invert(value) {
  84. const percent = (value - this.rangeMin()) / (this.rangeMax() - this.rangeMin());
  85. const exponent = this.exponent;
  86. const max = calBase(exponent, this.max);
  87. const min = calBase(exponent, this.min);
  88. const tmp = percent * (max - min) + min;
  89. return Math.pow(tmp, exponent);
  90. }
  91. }
  92. Base.Pow = Pow;
  93. module.exports = Pow;