UNPKG

2.46 kBPlain TextView Raw
1import { getLogPositiveMin, log } from '../util/math';
2import Continuous from './base';
3/**
4 * Log 度量,处理非均匀分布
5 */
6class Log extends Continuous {
7 public readonly type: string = 'log';
8 public base: number;
9 // 用于解决 min: 0 的场景下的问题
10 private positiveMin: number;
11
12 /**
13 * @override
14 */
15 public invert(value: number) {
16 const base = this.base;
17 const max = log(base, this.max);
18 const rangeMin = this.rangeMin();
19 const range = this.rangeMax() - rangeMin;
20 let min;
21 const positiveMin = this.positiveMin;
22 if (positiveMin) {
23 if (value === 0) {
24 return 0;
25 }
26 min = log(base, positiveMin / base);
27 const appendPercent = (1 / (max - min)) * range; // 0 到 positiveMin的占比
28 if (value < appendPercent) {
29 // 落到 0 - positiveMin 之间
30 return (value / appendPercent) * positiveMin;
31 }
32 } else {
33 min = log(base, this.min);
34 }
35 const percent = (value - rangeMin) / range;
36 const tmp = percent * (max - min) + min;
37 return Math.pow(base, tmp);
38 }
39
40 protected initCfg() {
41 this.tickMethod = 'log';
42 this.base = 10;
43 this.tickCount = 6;
44 this.nice = true;
45 }
46
47 // 设置
48 protected setDomain() {
49 super.setDomain();
50 const min = this.min;
51 if (min < 0) {
52 throw new Error('When you use log scale, the minimum value must be greater than zero!');
53 }
54 if (min === 0) {
55 this.positiveMin = getLogPositiveMin(this.values, this.base, this.max);
56 }
57 }
58
59 // 根据当前值获取占比
60 protected getScalePercent(value: number) {
61 const max = this.max;
62 let min = this.min;
63 if (max === min) {
64 return 0;
65 }
66 // 如果值小于等于0,则按照0处理
67 if (value <= 0) {
68 return 0;
69 }
70 const base = this.base;
71 const positiveMin = this.positiveMin;
72 // 如果min == 0, 则根据比0大的最小值,计算比例关系。这个最小值作为坐标轴上的第二个tick,第一个是0但是不显示
73 if (positiveMin) {
74 min = (positiveMin * 1) / base;
75 }
76 let percent;
77 // 如果数值小于次小值,那么就计算 value / 次小值 占整体的比例
78 if (value < positiveMin) {
79 percent = value / positiveMin / (log(base, max) - log(base, min));
80 } else {
81 percent = (log(base, value) - log(base, min)) / (log(base, max) - log(base, min));
82 }
83 return percent;
84 }
85}
86
87export default Log;