UNPKG

5.07 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.Continuous = void 0;
4const util_1 = require("@antv/util");
5const base_1 = require("./base");
6const utils_1 = require("../utils");
7/** 当 domain 和 range 只有一段的时候的 map 的 工厂函数 */
8const createBiMap = (domain, range, createInterpolate) => {
9 const [d0, d1] = domain;
10 const [r0, r1] = range;
11 let normalize;
12 let interpolate;
13 if (d0 < d1) {
14 normalize = (0, utils_1.createNormalize)(d0, d1);
15 interpolate = createInterpolate(r0, r1);
16 }
17 else {
18 normalize = (0, utils_1.createNormalize)(d1, d0);
19 interpolate = createInterpolate(r1, r0);
20 }
21 return (0, utils_1.compose)(interpolate, normalize);
22};
23/** 当 domain 和 range 有多段时候的 map 的 工厂函数 */
24const createPolyMap = (domain, range, createInterpolate) => {
25 const len = Math.min(domain.length, range.length) - 1;
26 const normalizeList = new Array(len);
27 const interpolateList = new Array(len);
28 const reverse = domain[0] > domain[len];
29 const ascendingDomain = reverse ? [...domain].reverse() : domain;
30 const ascendingRange = reverse ? [...range].reverse() : range;
31 // 每一段都生成 normalize 和 interpolate
32 for (let i = 0; i < len; i += 1) {
33 normalizeList[i] = (0, utils_1.createNormalize)(ascendingDomain[i], ascendingDomain[i + 1]);
34 interpolateList[i] = createInterpolate(ascendingRange[i], ascendingRange[i + 1]);
35 }
36 // 二分最右查找到相应的 normalize 和 interpolate
37 return (x) => {
38 const i = (0, utils_1.bisect)(domain, x, 1, len) - 1;
39 const normalize = normalizeList[i];
40 const interpolate = interpolateList[i];
41 return (0, utils_1.compose)(interpolate, normalize)(x);
42 };
43};
44/** 选择一个分段映射的函数 */
45const choosePiecewise = (domain, range, interpolate, shouldRound) => {
46 const n = Math.min(domain.length, range.length);
47 const createPiecewise = n > 2 ? createPolyMap : createBiMap;
48 const createInterpolate = shouldRound ? utils_1.createInterpolateRound : interpolate;
49 return createPiecewise(domain, range, createInterpolate);
50};
51/**
52 * Continuous 比例尺 的输入 x 和输出 y 满足:y = a * f(x) + b
53 * 通过函数柯里化和复合函数可以在映射过程中去掉分支,提高性能。
54 * 参考:https://github.com/d3/d3-scale/blob/master/src/continuous.js
55 */
56class Continuous extends base_1.Base {
57 getDefaultOptions() {
58 return {
59 domain: [0, 1],
60 range: [0, 1],
61 nice: false,
62 clamp: false,
63 round: false,
64 interpolate: utils_1.createInterpolateNumber,
65 tickCount: 5,
66 };
67 }
68 /**
69 * y = interpolate(normalize(clamp(transform(x))))
70 */
71 map(x) {
72 if (!(0, utils_1.isValid)(x))
73 return this.options.unknown;
74 return this.output(x);
75 }
76 /**
77 * x = transform(clamp(interpolate(normalize(y))))
78 */
79 invert(x) {
80 if (!(0, utils_1.isValid)(x))
81 return this.options.unknown;
82 return this.input(x);
83 }
84 nice() {
85 if (!this.options.nice)
86 return;
87 const [min, max, tickCount, ...rest] = this.getTickMethodOptions();
88 this.options.domain = this.chooseNice()(min, max, tickCount, ...rest);
89 }
90 getTicks() {
91 const { tickMethod } = this.options;
92 const [min, max, tickCount, ...rest] = this.getTickMethodOptions();
93 return tickMethod(min, max, tickCount, ...rest);
94 }
95 getTickMethodOptions() {
96 const { domain, tickCount } = this.options;
97 const min = domain[0];
98 const max = domain[domain.length - 1];
99 return [min, max, tickCount];
100 }
101 chooseNice() {
102 return utils_1.d3LinearNice;
103 }
104 rescale() {
105 this.nice();
106 const [transform, untransform] = this.chooseTransforms();
107 this.composeOutput(transform, this.chooseClamp(transform));
108 this.composeInput(transform, untransform, this.chooseClamp(untransform));
109 }
110 chooseClamp(transform) {
111 const { clamp: shouldClamp, range } = this.options;
112 const domain = this.options.domain.map(transform);
113 const n = Math.min(domain.length, range.length);
114 return shouldClamp ? (0, utils_1.createClamp)(domain[0], domain[n - 1]) : util_1.identity;
115 }
116 composeOutput(transform, clamp) {
117 const { domain, range, round, interpolate } = this.options;
118 const piecewise = choosePiecewise(domain.map(transform), range, interpolate, round);
119 this.output = (0, utils_1.compose)(piecewise, clamp, transform);
120 }
121 composeInput(transform, untransform, clamp) {
122 const { domain, range } = this.options;
123 const piecewise = choosePiecewise(range, domain.map(transform), utils_1.createInterpolateNumber);
124 this.input = (0, utils_1.compose)(untransform, clamp, piecewise);
125 }
126}
127exports.Continuous = Continuous;
128//# sourceMappingURL=continuous.js.map
\No newline at end of file