linear.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /**
  2. * @fileOverview The measurement of linear data scale function
  3. * @author dxq613@gmail.com
  4. */
  5. const isNil = require('@antv/util/lib/type/is-nil');
  6. const each = require('@antv/util/lib/each');
  7. const Base = require('./base');
  8. const numberAuto = require('./auto/number');
  9. /**
  10. * 线性度量
  11. * @class Scale.Linear
  12. */
  13. class Linear extends Base {
  14. _initDefaultCfg() {
  15. super._initDefaultCfg();
  16. const self = this;
  17. self.type = 'linear';
  18. self.isLinear = true;
  19. /**
  20. * 是否为了用户习惯,优化min,max和ticks,如果进行优化,则会根据生成的ticks调整min,max,否则舍弃(min,max)范围之外的ticks
  21. * @type {Boolean}
  22. * @default false
  23. */
  24. self.nice = false;
  25. /**
  26. * min value of the scale
  27. * @type {Number}
  28. * @default null
  29. */
  30. self.min = null;
  31. /**
  32. * min value limitted of the scale
  33. * @type {Number}
  34. * @default null
  35. */
  36. self.minLimit = null;
  37. /**
  38. * max value of the scale
  39. * @type {Number}
  40. * @default null
  41. */
  42. self.max = null;
  43. /**
  44. * max value limitted of the scale
  45. * @type {Number}
  46. * @default null
  47. */
  48. self.maxLimit = null;
  49. /**
  50. * 自动生成标记时的个数
  51. * @type {Number}
  52. * @default null
  53. */
  54. self.tickCount = null;
  55. /**
  56. * 坐标轴点之间的间距,指的是真实数据的差值
  57. * @type {Number}
  58. * @default null
  59. */
  60. self.tickInterval = null;
  61. /**
  62. * 坐标轴点之间的最小间距,指的是真实数据的差值
  63. * @type {Number}
  64. * @default null
  65. */
  66. self.minTickInterval = null;
  67. /**
  68. * 用于计算坐标点时逼近的数组
  69. * @type {Array}
  70. */
  71. self.snapArray = null;
  72. }
  73. /**
  74. * @protected
  75. * @override
  76. */
  77. init() {
  78. const self = this;
  79. if (!self.ticks) {
  80. self.min = self.translate(self.min);
  81. self.max = self.translate(self.max);
  82. self.initTicks();
  83. } else {
  84. const ticks = self.ticks;
  85. const firstValue = self.translate(ticks[0]);
  86. const lastValue = self.translate(ticks[ticks.length - 1]);
  87. if (isNil(self.min) || self.min > firstValue) {
  88. self.min = firstValue;
  89. }
  90. if (isNil(self.max) || self.max < lastValue) {
  91. self.max = lastValue;
  92. }
  93. }
  94. }
  95. /**
  96. * 计算坐标点
  97. * @protected
  98. * @return {Array} 计算完成的坐标点
  99. */
  100. calculateTicks() {
  101. const { min, max, minLimit, maxLimit, tickCount, tickInterval, minTickInterval, snapArray } = this;
  102. if (tickCount === 1) {
  103. throw new Error('linear scale\'tickCount should not be 1');
  104. }
  105. if (max < min) {
  106. throw new Error(`max: ${max} should not be less than min: ${min}`);
  107. }
  108. const tmp = numberAuto({
  109. min,
  110. max,
  111. minLimit,
  112. maxLimit,
  113. minCount: tickCount,
  114. maxCount: tickCount,
  115. interval: tickInterval,
  116. minTickInterval,
  117. snapArray
  118. });
  119. return tmp.ticks;
  120. }
  121. // 初始化ticks
  122. initTicks() {
  123. const self = this;
  124. const calTicks = self.calculateTicks();
  125. if (self.nice) { // 如果需要优化显示的tick
  126. self.ticks = calTicks;
  127. self.min = calTicks[0];
  128. self.max = calTicks[calTicks.length - 1];
  129. } else {
  130. const ticks = [];
  131. each(calTicks, tick => {
  132. if (tick >= self.min && tick <= self.max) {
  133. ticks.push(tick);
  134. }
  135. });
  136. // 如果 ticks 为空,直接输入最小值、最大值
  137. if (!ticks.length) {
  138. ticks.push(self.min);
  139. ticks.push(self.max);
  140. }
  141. self.ticks = ticks;
  142. }
  143. }
  144. /**
  145. * @override
  146. */
  147. scale(value) {
  148. if (isNil(value)) {
  149. return NaN;
  150. }
  151. const max = this.max;
  152. const min = this.min;
  153. if (max === min) {
  154. return 0;
  155. }
  156. const percent = (value - min) / (max - min);
  157. const rangeMin = this.rangeMin();
  158. const rangeMax = this.rangeMax();
  159. return rangeMin + percent * (rangeMax - rangeMin);
  160. }
  161. /**
  162. * @override
  163. */
  164. invert(value) {
  165. const percent = (value - this.rangeMin()) / (this.rangeMax() - this.rangeMin());
  166. return this.min + percent * (this.max - this.min);
  167. }
  168. }
  169. Base.Linear = Linear;
  170. module.exports = Linear;