1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.Band = void 0;
|
4 | const utils_1 = require("../utils");
|
5 | const ordinal_1 = require("./ordinal");
|
6 | function normalize(array) {
|
7 | const min = Math.min(...array);
|
8 | return array.map((d) => d / min);
|
9 | }
|
10 | function splice(array, n) {
|
11 | const sn = array.length;
|
12 | const diff = n - sn;
|
13 | return diff > 0 ? [...array, ...new Array(diff).fill(1)] : diff < 0 ? array.slice(0, n) : array;
|
14 | }
|
15 | function pretty(n) {
|
16 | return Math.round(n * 1e12) / 1e12;
|
17 | }
|
18 |
|
19 |
|
20 |
|
21 | function computeFlexBandState(options) {
|
22 |
|
23 |
|
24 | const { domain, range, paddingOuter, paddingInner, flex: F, round, align } = options;
|
25 | const n = domain.length;
|
26 | const flex = splice(F, n);
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 | const [start, end] = range;
|
34 | const width = end - start;
|
35 | const ratio = (2 / n) * paddingOuter + 1 - (1 / n) * paddingInner;
|
36 | const stepSum = width / ratio;
|
37 |
|
38 |
|
39 | const PI = (stepSum * paddingInner) / n;
|
40 | const bandWidthSum = stepSum - n * PI;
|
41 |
|
42 | const normalizedFlex = normalize(flex);
|
43 | const flexSum = normalizedFlex.reduce((sum, value) => sum + value);
|
44 | const minBandWidth = bandWidthSum / flexSum;
|
45 |
|
46 | const valueBandWidth = new utils_1.InternMap(domain.map((d, i) => {
|
47 | const bandWidth = normalizedFlex[i] * minBandWidth;
|
48 | return [d, round ? Math.floor(bandWidth) : bandWidth];
|
49 | }));
|
50 | const valueStep = new utils_1.InternMap(domain.map((d, i) => {
|
51 | const bandWidth = normalizedFlex[i] * minBandWidth;
|
52 | const step = bandWidth + PI;
|
53 | return [d, round ? Math.floor(step) : step];
|
54 | }));
|
55 |
|
56 |
|
57 | const finalStepSum = Array.from(valueStep.values()).reduce((sum, value) => sum + value);
|
58 | const outerPaddingSum = width - (finalStepSum - (finalStepSum / n) * paddingInner);
|
59 | const offset = outerPaddingSum * align;
|
60 |
|
61 | const bandStart = start + offset;
|
62 | let prev = round ? Math.round(bandStart) : bandStart;
|
63 | const adjustedRange = new Array(n);
|
64 | for (let i = 0; i < n; i += 1) {
|
65 |
|
66 | adjustedRange[i] = pretty(prev);
|
67 | const value = domain[i];
|
68 | prev += valueStep.get(value);
|
69 | }
|
70 | return {
|
71 | valueBandWidth,
|
72 | valueStep,
|
73 | adjustedRange,
|
74 | };
|
75 | }
|
76 |
|
77 |
|
78 |
|
79 | function computeBandState(options) {
|
80 | var _a;
|
81 | const { domain } = options;
|
82 | const n = domain.length;
|
83 | if (n === 0) {
|
84 | return {
|
85 | valueBandWidth: undefined,
|
86 | valueStep: undefined,
|
87 | adjustedRange: [],
|
88 | };
|
89 | }
|
90 | const hasFlex = !!((_a = options.flex) === null || _a === void 0 ? void 0 : _a.length);
|
91 | if (hasFlex) {
|
92 | return computeFlexBandState(options);
|
93 | }
|
94 | const { range, paddingOuter, paddingInner, round, align } = options;
|
95 | let step;
|
96 | let bandWidth;
|
97 | let rangeStart = range[0];
|
98 | const rangeEnd = range[1];
|
99 |
|
100 |
|
101 |
|
102 |
|
103 |
|
104 | const deltaRange = rangeEnd - rangeStart;
|
105 | const outerTotal = paddingOuter * 2;
|
106 | const innerTotal = n - paddingInner;
|
107 | step = deltaRange / Math.max(1, outerTotal + innerTotal);
|
108 |
|
109 | if (round) {
|
110 | step = Math.floor(step);
|
111 | }
|
112 |
|
113 | rangeStart += (deltaRange - step * (n - paddingInner)) * align;
|
114 |
|
115 |
|
116 |
|
117 | bandWidth = step * (1 - paddingInner);
|
118 | if (round) {
|
119 | rangeStart = Math.round(rangeStart);
|
120 | bandWidth = Math.round(bandWidth);
|
121 | }
|
122 |
|
123 | const adjustedRange = new Array(n).fill(0).map((_, i) => rangeStart + i * step);
|
124 | return {
|
125 | valueStep: step,
|
126 | valueBandWidth: bandWidth,
|
127 | adjustedRange,
|
128 | };
|
129 | }
|
130 |
|
131 |
|
132 |
|
133 |
|
134 |
|
135 |
|
136 |
|
137 |
|
138 |
|
139 |
|
140 |
|
141 |
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 |
|
150 |
|
151 |
|
152 |
|
153 |
|
154 |
|
155 |
|
156 |
|
157 |
|
158 | class Band extends ordinal_1.Ordinal {
|
159 |
|
160 | getDefaultOptions() {
|
161 | return {
|
162 | domain: [],
|
163 | range: [0, 1],
|
164 | align: 0.5,
|
165 | round: false,
|
166 | paddingInner: 0,
|
167 | paddingOuter: 0,
|
168 | padding: 0,
|
169 | unknown: ordinal_1.defaultUnknown,
|
170 | flex: [],
|
171 | };
|
172 | }
|
173 |
|
174 | constructor(options) {
|
175 | super(options);
|
176 | }
|
177 | clone() {
|
178 | return new Band(this.options);
|
179 | }
|
180 | getStep(x) {
|
181 | if (this.valueStep === undefined)
|
182 | return 1;
|
183 |
|
184 | if (typeof this.valueStep === 'number') {
|
185 | return this.valueStep;
|
186 | }
|
187 |
|
188 |
|
189 | if (x === undefined)
|
190 | return Array.from(this.valueStep.values())[0];
|
191 | return this.valueStep.get(x);
|
192 | }
|
193 | getBandWidth(x) {
|
194 | if (this.valueBandWidth === undefined)
|
195 | return 1;
|
196 |
|
197 | if (typeof this.valueBandWidth === 'number') {
|
198 | return this.valueBandWidth;
|
199 | }
|
200 |
|
201 |
|
202 | if (x === undefined)
|
203 | return Array.from(this.valueBandWidth.values())[0];
|
204 | return this.valueBandWidth.get(x);
|
205 | }
|
206 | getRange() {
|
207 | return this.adjustedRange;
|
208 | }
|
209 | getPaddingInner() {
|
210 | const { padding, paddingInner } = this.options;
|
211 | return padding > 0 ? padding : paddingInner;
|
212 | }
|
213 | getPaddingOuter() {
|
214 | const { padding, paddingOuter } = this.options;
|
215 | return padding > 0 ? padding : paddingOuter;
|
216 | }
|
217 | rescale() {
|
218 | super.rescale();
|
219 |
|
220 |
|
221 | const { align, domain, range, round, flex } = this.options;
|
222 | const { adjustedRange, valueBandWidth, valueStep } = computeBandState({
|
223 | align,
|
224 | range,
|
225 | round,
|
226 | flex,
|
227 | paddingInner: this.getPaddingInner(),
|
228 | paddingOuter: this.getPaddingOuter(),
|
229 | domain,
|
230 | });
|
231 |
|
232 | this.valueStep = valueStep;
|
233 | this.valueBandWidth = valueBandWidth;
|
234 | this.adjustedRange = adjustedRange;
|
235 | }
|
236 | }
|
237 | exports.Band = Band;
|
238 |
|
\ | No newline at end of file |