@ggterm/core 0.2.5 → 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/canvas/canvas.d.ts.map +1 -1
- package/dist/cli-plot.d.ts +1 -1
- package/dist/cli-plot.js +11594 -0
- package/dist/cli.js +1468 -887
- package/dist/demo.d.ts +6 -0
- package/dist/demo.d.ts.map +1 -0
- package/dist/export/vega-lite.d.ts.map +1 -1
- package/dist/geoms/bin2d.d.ts +47 -0
- package/dist/geoms/bin2d.d.ts.map +1 -0
- package/dist/geoms/index.d.ts +1 -0
- package/dist/geoms/index.d.ts.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2443 -1436
- package/dist/init.d.ts +8 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/pipeline/pipeline.d.ts.map +1 -1
- package/dist/pipeline/render-geoms.d.ts.map +1 -1
- package/dist/pipeline/scales.d.ts.map +1 -1
- package/dist/stats/bin2d.d.ts +34 -0
- package/dist/stats/bin2d.d.ts.map +1 -0
- package/dist/stats/density2d.d.ts +36 -0
- package/dist/stats/density2d.d.ts.map +1 -0
- package/dist/stats/index.d.ts +4 -0
- package/dist/stats/index.d.ts.map +1 -1
- package/package.json +5 -4
- package/dist/canvas/canvas.d.ts +0 -71
- package/dist/canvas/index.d.ts +0 -5
- package/dist/geoms/area.d.ts +0 -18
- package/dist/geoms/boxplot.d.ts +0 -25
- package/dist/geoms/line.d.ts +0 -31
- package/dist/geoms/segment.d.ts +0 -33
- package/dist/pipeline/pipeline.d.ts +0 -45
- package/dist/stats/bin.d.ts +0 -33
- package/dist/stats/boxplot.d.ts +0 -28
- package/dist/stats/smooth.d.ts +0 -33
- package/dist/stats/summary.d.ts +0 -32
- package/dist/themes/default.d.ts +0 -25
package/dist/index.js
CHANGED
|
@@ -29,423 +29,102 @@ var __export = (target, all) => {
|
|
|
29
29
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
30
30
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
31
31
|
|
|
32
|
-
// src/
|
|
33
|
-
|
|
34
|
-
__export(exports_scales, {
|
|
35
|
-
niceDomain: () => niceDomain,
|
|
36
|
-
inferDiscreteDomain: () => inferDiscreteDomain,
|
|
37
|
-
inferContinuousDomain: () => inferContinuousDomain,
|
|
38
|
-
getTransformFunctions: () => getTransformFunctions,
|
|
39
|
-
expandDomain: () => expandDomain,
|
|
40
|
-
createResolvedSizeScale: () => createResolvedSizeScale,
|
|
41
|
-
createResolvedDiscreteScale: () => createResolvedDiscreteScale,
|
|
42
|
-
createResolvedDiscreteColorScale: () => createResolvedDiscreteColorScale,
|
|
43
|
-
createResolvedContinuousScale: () => createResolvedContinuousScale,
|
|
44
|
-
createResolvedContinuousColorScale: () => createResolvedContinuousColorScale,
|
|
45
|
-
buildScaleContext: () => buildScaleContext,
|
|
46
|
-
DEFAULT_POINT_COLOR: () => DEFAULT_POINT_COLOR
|
|
47
|
-
});
|
|
48
|
-
function inferContinuousDomain(data, field) {
|
|
49
|
-
let min = Infinity;
|
|
50
|
-
let max = -Infinity;
|
|
51
|
-
for (const row of data) {
|
|
52
|
-
const value = row[field];
|
|
53
|
-
if (typeof value === "number" && !isNaN(value)) {
|
|
54
|
-
if (value < min)
|
|
55
|
-
min = value;
|
|
56
|
-
if (value > max)
|
|
57
|
-
max = value;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
if (min === Infinity)
|
|
61
|
-
min = 0;
|
|
62
|
-
if (max === -Infinity)
|
|
63
|
-
max = 1;
|
|
64
|
-
if (min === max) {
|
|
65
|
-
min = min - 1;
|
|
66
|
-
max = max + 1;
|
|
67
|
-
}
|
|
68
|
-
return [min, max];
|
|
69
|
-
}
|
|
70
|
-
function inferDiscreteDomain(data, field, options = {}) {
|
|
71
|
-
const { limits, order = "alphabetical", reverse = false, exclude, drop = true } = options;
|
|
72
|
-
const seen = new Map;
|
|
73
|
-
let index = 0;
|
|
74
|
-
for (const row of data) {
|
|
75
|
-
const value = row[field];
|
|
76
|
-
if (value !== null && value !== undefined) {
|
|
77
|
-
const key = String(value);
|
|
78
|
-
if (!seen.has(key)) {
|
|
79
|
-
seen.set(key, { firstIndex: index, count: 1 });
|
|
80
|
-
} else {
|
|
81
|
-
seen.get(key).count++;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
index++;
|
|
85
|
-
}
|
|
86
|
-
let result;
|
|
87
|
-
if (limits) {
|
|
88
|
-
if (drop) {
|
|
89
|
-
result = limits.filter((v) => seen.has(v));
|
|
90
|
-
} else {
|
|
91
|
-
result = [...limits];
|
|
92
|
-
}
|
|
93
|
-
} else {
|
|
94
|
-
const values = Array.from(seen.keys());
|
|
95
|
-
switch (order) {
|
|
96
|
-
case "data":
|
|
97
|
-
result = values.sort((a, b) => seen.get(a).firstIndex - seen.get(b).firstIndex);
|
|
98
|
-
break;
|
|
99
|
-
case "frequency":
|
|
100
|
-
result = values.sort((a, b) => seen.get(b).count - seen.get(a).count);
|
|
101
|
-
break;
|
|
102
|
-
case "reverse":
|
|
103
|
-
result = values.sort().reverse();
|
|
104
|
-
break;
|
|
105
|
-
case "alphabetical":
|
|
106
|
-
default:
|
|
107
|
-
result = values.sort();
|
|
108
|
-
break;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
if (exclude && exclude.length > 0) {
|
|
112
|
-
const excludeSet = new Set(exclude);
|
|
113
|
-
result = result.filter((v) => !excludeSet.has(v));
|
|
114
|
-
}
|
|
115
|
-
if (reverse) {
|
|
116
|
-
result = result.reverse();
|
|
117
|
-
}
|
|
118
|
-
return result;
|
|
119
|
-
}
|
|
120
|
-
function expandDomain(domain, expand = 0.05) {
|
|
121
|
-
const range = domain[1] - domain[0];
|
|
122
|
-
const padding = range * expand;
|
|
123
|
-
return [domain[0] - padding, domain[1] + padding];
|
|
124
|
-
}
|
|
125
|
-
function niceStep(range, targetTicks = 5) {
|
|
126
|
-
const rawStep = range / Math.max(1, targetTicks - 1);
|
|
127
|
-
const magnitude = Math.pow(10, Math.floor(Math.log10(rawStep)));
|
|
128
|
-
const normalized = rawStep / magnitude;
|
|
129
|
-
let nice;
|
|
130
|
-
if (normalized <= 1.5)
|
|
131
|
-
nice = 1;
|
|
132
|
-
else if (normalized <= 3)
|
|
133
|
-
nice = 2;
|
|
134
|
-
else if (normalized <= 7)
|
|
135
|
-
nice = 5;
|
|
136
|
-
else
|
|
137
|
-
nice = 10;
|
|
138
|
-
return nice * magnitude;
|
|
139
|
-
}
|
|
140
|
-
function niceDomain(domain, targetTicks = 5) {
|
|
141
|
-
const [min, max] = domain;
|
|
142
|
-
const range = max - min;
|
|
143
|
-
if (range === 0) {
|
|
144
|
-
if (min === 0)
|
|
145
|
-
return [-1, 1];
|
|
146
|
-
const magnitude = Math.pow(10, Math.floor(Math.log10(Math.abs(min))));
|
|
147
|
-
return [min - magnitude, min + magnitude];
|
|
148
|
-
}
|
|
149
|
-
const step = niceStep(range, targetTicks);
|
|
150
|
-
const niceMin = Math.floor(min / step) * step;
|
|
151
|
-
const niceMax = Math.ceil(max / step) * step;
|
|
152
|
-
return [niceMin, niceMax];
|
|
153
|
-
}
|
|
154
|
-
function getTransformFunctions(trans = "identity") {
|
|
155
|
-
switch (trans) {
|
|
156
|
-
case "log10":
|
|
157
|
-
return {
|
|
158
|
-
type: "log10",
|
|
159
|
-
transform: (v) => v > 0 ? Math.log10(v) : -Infinity,
|
|
160
|
-
invert: (v) => Math.pow(10, v)
|
|
161
|
-
};
|
|
162
|
-
case "sqrt":
|
|
163
|
-
return {
|
|
164
|
-
type: "sqrt",
|
|
165
|
-
transform: (v) => v >= 0 ? Math.sqrt(v) : 0,
|
|
166
|
-
invert: (v) => v * v
|
|
167
|
-
};
|
|
168
|
-
case "reverse":
|
|
169
|
-
return {
|
|
170
|
-
type: "reverse",
|
|
171
|
-
transform: (v) => -v,
|
|
172
|
-
invert: (v) => -v
|
|
173
|
-
};
|
|
174
|
-
default:
|
|
175
|
-
return {
|
|
176
|
-
type: "identity",
|
|
177
|
-
transform: (v) => v,
|
|
178
|
-
invert: (v) => v
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
function createResolvedContinuousScale(aesthetic, domain, range, trans = "identity") {
|
|
183
|
-
const [domainMin, domainMax] = domain;
|
|
184
|
-
const [rangeMin, rangeMax] = range;
|
|
185
|
-
const rangeSpan = rangeMax - rangeMin;
|
|
186
|
-
const { transform, invert } = getTransformFunctions(trans);
|
|
32
|
+
// src/themes/default.ts
|
|
33
|
+
function defaultTheme() {
|
|
187
34
|
return {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
trans,
|
|
193
|
-
transform,
|
|
194
|
-
invert,
|
|
195
|
-
normalize(value) {
|
|
196
|
-
const num = Number(value);
|
|
197
|
-
if (isNaN(num))
|
|
198
|
-
return 0;
|
|
199
|
-
const transformed = transform(num);
|
|
200
|
-
const transformedMin = transform(domainMin);
|
|
201
|
-
const transformedMax = transform(domainMax);
|
|
202
|
-
if (transformedMax === transformedMin)
|
|
203
|
-
return 0.5;
|
|
204
|
-
return (transformed - transformedMin) / (transformedMax - transformedMin);
|
|
35
|
+
panel: {
|
|
36
|
+
background: "",
|
|
37
|
+
border: "single",
|
|
38
|
+
grid: { major: "·", minor: null }
|
|
205
39
|
},
|
|
206
|
-
|
|
207
|
-
|
|
40
|
+
axis: {
|
|
41
|
+
text: { color: "" },
|
|
42
|
+
ticks: { char: "┼", length: 1 },
|
|
43
|
+
title: { color: "", bold: false }
|
|
208
44
|
},
|
|
209
|
-
|
|
210
|
-
|
|
45
|
+
legend: {
|
|
46
|
+
position: "right",
|
|
47
|
+
title: { bold: true }
|
|
48
|
+
},
|
|
49
|
+
title: {
|
|
50
|
+
align: "center",
|
|
51
|
+
bold: true
|
|
52
|
+
},
|
|
53
|
+
facet: {
|
|
54
|
+
strip: {
|
|
55
|
+
text: "#c8c8c8",
|
|
56
|
+
background: ""
|
|
57
|
+
}
|
|
211
58
|
}
|
|
212
59
|
};
|
|
213
60
|
}
|
|
214
|
-
function
|
|
215
|
-
const [rangeMin, rangeMax] = range;
|
|
216
|
-
const rangeSpan = rangeMax - rangeMin;
|
|
61
|
+
function themeMinimal() {
|
|
217
62
|
return {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
normalize(value) {
|
|
223
|
-
const str = String(value);
|
|
224
|
-
const index = domain.indexOf(str);
|
|
225
|
-
if (index < 0)
|
|
226
|
-
return 0;
|
|
227
|
-
return domain.length > 1 ? index / (domain.length - 1) : 0.5;
|
|
63
|
+
panel: {
|
|
64
|
+
background: "",
|
|
65
|
+
border: "none",
|
|
66
|
+
grid: { major: null, minor: null }
|
|
228
67
|
},
|
|
229
|
-
|
|
230
|
-
|
|
68
|
+
axis: {
|
|
69
|
+
text: { color: "" },
|
|
70
|
+
ticks: { char: "│", length: 1 },
|
|
71
|
+
title: { color: "", bold: false }
|
|
231
72
|
},
|
|
232
|
-
|
|
233
|
-
|
|
73
|
+
legend: {
|
|
74
|
+
position: "right",
|
|
75
|
+
title: { bold: false }
|
|
76
|
+
},
|
|
77
|
+
title: {
|
|
78
|
+
align: "left",
|
|
79
|
+
bold: false
|
|
80
|
+
},
|
|
81
|
+
facet: {
|
|
82
|
+
strip: {
|
|
83
|
+
text: "#999999",
|
|
84
|
+
background: ""
|
|
85
|
+
}
|
|
234
86
|
}
|
|
235
87
|
};
|
|
236
88
|
}
|
|
237
|
-
function
|
|
238
|
-
return {
|
|
239
|
-
r: Math.round(color1.r + (color2.r - color1.r) * t),
|
|
240
|
-
g: Math.round(color1.g + (color2.g - color1.g) * t),
|
|
241
|
-
b: Math.round(color1.b + (color2.b - color1.b) * t),
|
|
242
|
-
a: color1.a + (color2.a - color1.a) * t
|
|
243
|
-
};
|
|
244
|
-
}
|
|
245
|
-
function createResolvedDiscreteColorScale(domain, palette = CATEGORY_COLORS) {
|
|
89
|
+
function themeDark() {
|
|
246
90
|
return {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
return lowColor;
|
|
270
|
-
const t = Math.max(0, Math.min(1, (num - min) / span));
|
|
271
|
-
return interpolateColor(lowColor, highColor, t);
|
|
272
|
-
}
|
|
273
|
-
};
|
|
274
|
-
}
|
|
275
|
-
function isCategoricalField(data, field) {
|
|
276
|
-
for (const row of data) {
|
|
277
|
-
const value = row[field];
|
|
278
|
-
if (value !== null && value !== undefined) {
|
|
279
|
-
if (typeof value === "string" && isNaN(Number(value))) {
|
|
280
|
-
return true;
|
|
91
|
+
panel: {
|
|
92
|
+
background: "#1e1e1e",
|
|
93
|
+
border: "rounded",
|
|
94
|
+
grid: { major: "·", minor: null }
|
|
95
|
+
},
|
|
96
|
+
axis: {
|
|
97
|
+
text: { color: "#ccc" },
|
|
98
|
+
ticks: { char: "┼", length: 1 },
|
|
99
|
+
title: { color: "#fff", bold: true }
|
|
100
|
+
},
|
|
101
|
+
legend: {
|
|
102
|
+
position: "right",
|
|
103
|
+
title: { bold: true }
|
|
104
|
+
},
|
|
105
|
+
title: {
|
|
106
|
+
align: "center",
|
|
107
|
+
bold: true
|
|
108
|
+
},
|
|
109
|
+
facet: {
|
|
110
|
+
strip: {
|
|
111
|
+
text: "#ffffff",
|
|
112
|
+
background: "#333333"
|
|
281
113
|
}
|
|
282
114
|
}
|
|
283
|
-
}
|
|
284
|
-
return false;
|
|
285
|
-
}
|
|
286
|
-
function createResolvedSizeScale(domain) {
|
|
287
|
-
const [min, max] = domain;
|
|
288
|
-
const span = max - min;
|
|
289
|
-
return {
|
|
290
|
-
aesthetic: "size",
|
|
291
|
-
type: "continuous",
|
|
292
|
-
domain,
|
|
293
|
-
map(value) {
|
|
294
|
-
const num = Number(value);
|
|
295
|
-
if (isNaN(num))
|
|
296
|
-
return 1;
|
|
297
|
-
const t = Math.max(0, Math.min(1, (num - min) / span));
|
|
298
|
-
return Math.floor(t * 3.99);
|
|
299
|
-
}
|
|
300
115
|
};
|
|
301
116
|
}
|
|
302
|
-
function
|
|
303
|
-
const rawDomain = inferContinuousDomain(data, field);
|
|
304
|
-
if (trans === "log10") {
|
|
305
|
-
const [min, max] = rawDomain;
|
|
306
|
-
const safeMin = min > 0 ? min : 0.001;
|
|
307
|
-
const safeMax = max > 0 ? max : 1;
|
|
308
|
-
const minPow = Math.floor(Math.log10(safeMin));
|
|
309
|
-
const maxPow = Math.ceil(Math.log10(safeMax));
|
|
310
|
-
return [Math.pow(10, minPow), Math.pow(10, maxPow)];
|
|
311
|
-
}
|
|
312
|
-
return niceDomain(rawDomain);
|
|
313
|
-
}
|
|
314
|
-
function buildScaleContext(data, aes, plotArea, userScales = [], coordLimits) {
|
|
315
|
-
const userXScale = userScales.find((s) => s.aesthetic === "x");
|
|
316
|
-
const userYScale = userScales.find((s) => s.aesthetic === "y");
|
|
317
|
-
const userColorScale = userScales.find((s) => s.aesthetic === "color" || s.aesthetic === "fill");
|
|
318
|
-
const xIsCategorical = isCategoricalField(data, aes.x);
|
|
319
|
-
let x;
|
|
320
|
-
if (xIsCategorical) {
|
|
321
|
-
const xOrderOptions = {};
|
|
322
|
-
if (userXScale) {
|
|
323
|
-
if (userXScale.domain && Array.isArray(userXScale.domain)) {
|
|
324
|
-
xOrderOptions.limits = userXScale.domain;
|
|
325
|
-
}
|
|
326
|
-
const orderOpts = userXScale.orderOptions;
|
|
327
|
-
if (orderOpts) {
|
|
328
|
-
if (orderOpts.order)
|
|
329
|
-
xOrderOptions.order = orderOpts.order;
|
|
330
|
-
if (orderOpts.reverse)
|
|
331
|
-
xOrderOptions.reverse = orderOpts.reverse;
|
|
332
|
-
if (orderOpts.exclude)
|
|
333
|
-
xOrderOptions.exclude = orderOpts.exclude;
|
|
334
|
-
if (orderOpts.drop !== undefined)
|
|
335
|
-
xOrderOptions.drop = orderOpts.drop;
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
const xDomain = inferDiscreteDomain(data, aes.x, xOrderOptions);
|
|
339
|
-
x = createResolvedDiscreteScale("x", xDomain, [plotArea.x, plotArea.x + plotArea.width - 1]);
|
|
340
|
-
if (userXScale?.labels) {
|
|
341
|
-
x.labels = userXScale.labels;
|
|
342
|
-
}
|
|
343
|
-
} else {
|
|
344
|
-
const xTrans = userXScale?.trans ?? "identity";
|
|
345
|
-
const xDomain = coordLimits?.xlim ?? userXScale?.domain ?? computeDomain(data, aes.x, xTrans);
|
|
346
|
-
x = createResolvedContinuousScale("x", xDomain, [plotArea.x, plotArea.x + plotArea.width - 1], xTrans);
|
|
347
|
-
if (userXScale?.breaks) {
|
|
348
|
-
x.breaks = userXScale.breaks;
|
|
349
|
-
}
|
|
350
|
-
if (userXScale?.labels) {
|
|
351
|
-
x.labels = userXScale.labels;
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
const yTrans = userYScale?.trans ?? "identity";
|
|
355
|
-
const yDomain = coordLimits?.ylim ?? userYScale?.domain ?? computeDomain(data, aes.y, yTrans);
|
|
356
|
-
const y = createResolvedContinuousScale("y", yDomain, [plotArea.y + plotArea.height - 1, plotArea.y], yTrans);
|
|
357
|
-
if (userYScale?.breaks) {
|
|
358
|
-
y.breaks = userYScale.breaks;
|
|
359
|
-
}
|
|
360
|
-
if (userYScale?.labels) {
|
|
361
|
-
y.labels = userYScale.labels;
|
|
362
|
-
}
|
|
363
|
-
const context = { x, y };
|
|
364
|
-
if (aes.y2) {
|
|
365
|
-
const userY2Scale = userScales.find((s) => s.aesthetic === "y2");
|
|
366
|
-
const y2Trans = userY2Scale?.trans ?? "identity";
|
|
367
|
-
const y2Domain = userY2Scale?.domain ?? computeDomain(data, aes.y2, y2Trans);
|
|
368
|
-
const y2 = createResolvedContinuousScale("y2", y2Domain, [plotArea.y + plotArea.height - 1, plotArea.y], y2Trans);
|
|
369
|
-
if (userY2Scale?.breaks) {
|
|
370
|
-
y2.breaks = userY2Scale.breaks;
|
|
371
|
-
}
|
|
372
|
-
if (userY2Scale?.labels) {
|
|
373
|
-
y2.labels = userY2Scale.labels;
|
|
374
|
-
}
|
|
375
|
-
context.y2 = y2;
|
|
376
|
-
}
|
|
377
|
-
const colorAesField = aes.color || aes.fill;
|
|
378
|
-
if (colorAesField) {
|
|
379
|
-
const colorOrderOptions = {};
|
|
380
|
-
if (userColorScale) {
|
|
381
|
-
if (userColorScale.domain && Array.isArray(userColorScale.domain)) {
|
|
382
|
-
colorOrderOptions.limits = userColorScale.domain;
|
|
383
|
-
}
|
|
384
|
-
const orderOpts = userColorScale.orderOptions;
|
|
385
|
-
if (orderOpts) {
|
|
386
|
-
if (orderOpts.order)
|
|
387
|
-
colorOrderOptions.order = orderOpts.order;
|
|
388
|
-
if (orderOpts.reverse)
|
|
389
|
-
colorOrderOptions.reverse = orderOpts.reverse;
|
|
390
|
-
if (orderOpts.exclude)
|
|
391
|
-
colorOrderOptions.exclude = orderOpts.exclude;
|
|
392
|
-
if (orderOpts.drop !== undefined)
|
|
393
|
-
colorOrderOptions.drop = orderOpts.drop;
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
const colorDomain = inferDiscreteDomain(data, colorAesField, colorOrderOptions);
|
|
397
|
-
if (userColorScale && userColorScale.map) {
|
|
398
|
-
context.color = {
|
|
399
|
-
aesthetic: userColorScale.aesthetic || "color",
|
|
400
|
-
type: userColorScale.type === "continuous" ? "continuous" : "discrete",
|
|
401
|
-
domain: userColorScale.type === "continuous" ? userColorScale.domain ?? inferContinuousDomain(data, colorAesField) : colorDomain,
|
|
402
|
-
map: (value) => {
|
|
403
|
-
const result = userColorScale.map(value);
|
|
404
|
-
if (typeof result === "object" && "r" in result) {
|
|
405
|
-
return result;
|
|
406
|
-
}
|
|
407
|
-
return { r: 128, g: 128, b: 128, a: 1 };
|
|
408
|
-
}
|
|
409
|
-
};
|
|
410
|
-
} else {
|
|
411
|
-
context.color = createResolvedDiscreteColorScale(colorDomain);
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
if (aes.size) {
|
|
415
|
-
const sizeDomain = inferContinuousDomain(data, aes.size);
|
|
416
|
-
context.size = createResolvedSizeScale(sizeDomain);
|
|
417
|
-
}
|
|
418
|
-
return context;
|
|
419
|
-
}
|
|
420
|
-
var CATEGORY_COLORS, DEFAULT_POINT_COLOR;
|
|
421
|
-
var init_scales = __esm(() => {
|
|
422
|
-
CATEGORY_COLORS = [
|
|
423
|
-
{ r: 31, g: 119, b: 180, a: 1 },
|
|
424
|
-
{ r: 255, g: 127, b: 14, a: 1 },
|
|
425
|
-
{ r: 44, g: 160, b: 44, a: 1 },
|
|
426
|
-
{ r: 214, g: 39, b: 40, a: 1 },
|
|
427
|
-
{ r: 148, g: 103, b: 189, a: 1 },
|
|
428
|
-
{ r: 140, g: 86, b: 75, a: 1 },
|
|
429
|
-
{ r: 227, g: 119, b: 194, a: 1 },
|
|
430
|
-
{ r: 127, g: 127, b: 127, a: 1 },
|
|
431
|
-
{ r: 188, g: 189, b: 34, a: 1 },
|
|
432
|
-
{ r: 23, g: 190, b: 207, a: 1 }
|
|
433
|
-
];
|
|
434
|
-
DEFAULT_POINT_COLOR = { r: 79, g: 169, b: 238, a: 1 };
|
|
435
|
-
});
|
|
436
|
-
|
|
437
|
-
// src/themes/default.ts
|
|
438
|
-
function defaultTheme() {
|
|
117
|
+
function themeClassic() {
|
|
439
118
|
return {
|
|
440
119
|
panel: {
|
|
441
120
|
background: "",
|
|
442
121
|
border: "single",
|
|
443
|
-
grid: { major:
|
|
122
|
+
grid: { major: null, minor: null }
|
|
444
123
|
},
|
|
445
124
|
axis: {
|
|
446
125
|
text: { color: "" },
|
|
447
|
-
ticks: { char: "
|
|
448
|
-
title: { color: "", bold:
|
|
126
|
+
ticks: { char: "─", length: 1 },
|
|
127
|
+
title: { color: "", bold: true }
|
|
449
128
|
},
|
|
450
129
|
legend: {
|
|
451
130
|
position: "right",
|
|
@@ -463,7 +142,7 @@ function defaultTheme() {
|
|
|
463
142
|
}
|
|
464
143
|
};
|
|
465
144
|
}
|
|
466
|
-
function
|
|
145
|
+
function themeVoid() {
|
|
467
146
|
return {
|
|
468
147
|
panel: {
|
|
469
148
|
background: "",
|
|
@@ -472,11 +151,11 @@ function themeMinimal() {
|
|
|
472
151
|
},
|
|
473
152
|
axis: {
|
|
474
153
|
text: { color: "" },
|
|
475
|
-
ticks: { char: "
|
|
154
|
+
ticks: { char: "", length: 0 },
|
|
476
155
|
title: { color: "", bold: false }
|
|
477
156
|
},
|
|
478
157
|
legend: {
|
|
479
|
-
position: "
|
|
158
|
+
position: "none",
|
|
480
159
|
title: { bold: false }
|
|
481
160
|
},
|
|
482
161
|
title: {
|
|
@@ -485,332 +164,677 @@ function themeMinimal() {
|
|
|
485
164
|
},
|
|
486
165
|
facet: {
|
|
487
166
|
strip: {
|
|
488
|
-
text: "#
|
|
167
|
+
text: "#888888",
|
|
489
168
|
background: ""
|
|
490
169
|
}
|
|
491
170
|
}
|
|
492
171
|
};
|
|
493
172
|
}
|
|
494
|
-
|
|
173
|
+
|
|
174
|
+
// src/coords/cartesian.ts
|
|
175
|
+
function coordCartesian(options = {}) {
|
|
495
176
|
return {
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
title: {
|
|
511
|
-
align: "center",
|
|
512
|
-
bold: true
|
|
513
|
-
},
|
|
514
|
-
facet: {
|
|
515
|
-
strip: {
|
|
516
|
-
text: "#ffffff",
|
|
517
|
-
background: "#333333"
|
|
518
|
-
}
|
|
177
|
+
type: "cartesian",
|
|
178
|
+
xlim: options.xlim,
|
|
179
|
+
ylim: options.ylim,
|
|
180
|
+
clip: options.clip ?? true,
|
|
181
|
+
transform(x, y) {
|
|
182
|
+
return { x, y };
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
function coordFlip() {
|
|
187
|
+
return {
|
|
188
|
+
type: "flip",
|
|
189
|
+
transform(x, y) {
|
|
190
|
+
return { x: y, y: x };
|
|
519
191
|
}
|
|
520
192
|
};
|
|
521
193
|
}
|
|
522
|
-
function
|
|
194
|
+
function coordPolar(options = {}) {
|
|
195
|
+
const theta = options.theta ?? "x";
|
|
196
|
+
return {
|
|
197
|
+
type: "polar",
|
|
198
|
+
transform(x, y) {
|
|
199
|
+
const angle = theta === "x" ? x : y;
|
|
200
|
+
const radius = theta === "x" ? y : x;
|
|
201
|
+
return {
|
|
202
|
+
x: radius * Math.cos(angle),
|
|
203
|
+
y: radius * Math.sin(angle)
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
function coordFixed(options = {}) {
|
|
209
|
+
const ratio = options.ratio ?? 1;
|
|
210
|
+
return {
|
|
211
|
+
type: "fixed",
|
|
212
|
+
xlim: options.xlim,
|
|
213
|
+
ylim: options.ylim,
|
|
214
|
+
clip: options.clip ?? true,
|
|
215
|
+
ratio,
|
|
216
|
+
transform(x, y) {
|
|
217
|
+
return { x, y };
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
function coordEqual(options = {}) {
|
|
222
|
+
return coordFixed({ ...options, ratio: 1 });
|
|
223
|
+
}
|
|
224
|
+
function getTransform(type) {
|
|
225
|
+
switch (type) {
|
|
226
|
+
case "log10":
|
|
227
|
+
return (v) => v > 0 ? Math.log10(v) : -Infinity;
|
|
228
|
+
case "sqrt":
|
|
229
|
+
return (v) => v >= 0 ? Math.sqrt(v) : 0;
|
|
230
|
+
case "reverse":
|
|
231
|
+
return (v) => -v;
|
|
232
|
+
default:
|
|
233
|
+
return (v) => v;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
function coordTrans(options = {}) {
|
|
237
|
+
const xTrans = getTransform(options.x ?? "identity");
|
|
238
|
+
const yTrans = getTransform(options.y ?? "identity");
|
|
239
|
+
return {
|
|
240
|
+
type: "trans",
|
|
241
|
+
xlim: options.xlim,
|
|
242
|
+
ylim: options.ylim,
|
|
243
|
+
clip: options.clip ?? true,
|
|
244
|
+
xTransType: options.x ?? "identity",
|
|
245
|
+
yTransType: options.y ?? "identity",
|
|
246
|
+
transform(x, y) {
|
|
247
|
+
return {
|
|
248
|
+
x: xTrans(x),
|
|
249
|
+
y: yTrans(y)
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
function coordFlipWithLimits(options = {}) {
|
|
255
|
+
return {
|
|
256
|
+
type: "flip",
|
|
257
|
+
xlim: options.xlim,
|
|
258
|
+
ylim: options.ylim,
|
|
259
|
+
clip: options.clip ?? true,
|
|
260
|
+
transform(x, y) {
|
|
261
|
+
return { x: y, y: x };
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// src/canvas/canvas.ts
|
|
267
|
+
function createEmptyCell() {
|
|
268
|
+
return {
|
|
269
|
+
char: " ",
|
|
270
|
+
fg: { ...DEFAULT_FG },
|
|
271
|
+
bg: { ...DEFAULT_BG }
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
class TerminalCanvas {
|
|
276
|
+
width;
|
|
277
|
+
height;
|
|
278
|
+
cells;
|
|
279
|
+
constructor(width, height) {
|
|
280
|
+
this.width = width;
|
|
281
|
+
this.height = height;
|
|
282
|
+
this.cells = [];
|
|
283
|
+
this.clear();
|
|
284
|
+
}
|
|
285
|
+
setCell(x, y, cell) {
|
|
286
|
+
if (!Number.isFinite(x) || !Number.isFinite(y) || x < 0 || x >= this.width || y < 0 || y >= this.height) {
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
const ix = Math.floor(x);
|
|
290
|
+
const iy = Math.floor(y);
|
|
291
|
+
const existing = this.cells[iy][ix];
|
|
292
|
+
this.cells[iy][ix] = {
|
|
293
|
+
char: cell.char ?? existing.char,
|
|
294
|
+
fg: cell.fg ?? existing.fg,
|
|
295
|
+
bg: cell.bg ?? existing.bg,
|
|
296
|
+
bold: cell.bold ?? existing.bold,
|
|
297
|
+
italic: cell.italic ?? existing.italic,
|
|
298
|
+
underline: cell.underline ?? existing.underline
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
getCell(x, y) {
|
|
302
|
+
if (!Number.isFinite(x) || !Number.isFinite(y) || x < 0 || x >= this.width || y < 0 || y >= this.height) {
|
|
303
|
+
return createEmptyCell();
|
|
304
|
+
}
|
|
305
|
+
return this.cells[Math.floor(y)][Math.floor(x)];
|
|
306
|
+
}
|
|
307
|
+
clear() {
|
|
308
|
+
this.cells = [];
|
|
309
|
+
for (let y = 0;y < this.height; y++) {
|
|
310
|
+
const row = [];
|
|
311
|
+
for (let x = 0;x < this.width; x++) {
|
|
312
|
+
row.push(createEmptyCell());
|
|
313
|
+
}
|
|
314
|
+
this.cells.push(row);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
drawChar(x, y, char, fg) {
|
|
318
|
+
this.setCell(x, y, { char, fg });
|
|
319
|
+
}
|
|
320
|
+
drawString(x, y, str, fg) {
|
|
321
|
+
for (let i = 0;i < str.length; i++) {
|
|
322
|
+
this.drawChar(x + i, y, str[i], fg);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
drawHLine(x, y, length, char = "─", fg) {
|
|
326
|
+
for (let i = 0;i < length; i++) {
|
|
327
|
+
this.drawChar(x + i, y, char, fg);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
drawVLine(x, y, length, char = "│", fg) {
|
|
331
|
+
for (let i = 0;i < length; i++) {
|
|
332
|
+
this.drawChar(x, y + i, char, fg);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
drawPoint(x, y, fg, shape = "●") {
|
|
336
|
+
this.drawChar(x, y, shape, fg);
|
|
337
|
+
}
|
|
338
|
+
fillRect(x, y, width, height, char = " ", fg, bg) {
|
|
339
|
+
for (let dy = 0;dy < height; dy++) {
|
|
340
|
+
for (let dx = 0;dx < width; dx++) {
|
|
341
|
+
this.setCell(x + dx, y + dy, { char, fg, bg });
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
drawBox(x, y, width, height, style = "single", fg) {
|
|
346
|
+
const chars = style === "double" ? { tl: "╔", tr: "╗", bl: "╚", br: "╝", h: "═", v: "║" } : style === "rounded" ? { tl: "╭", tr: "╮", bl: "╰", br: "╯", h: "─", v: "│" } : { tl: "┌", tr: "┐", bl: "└", br: "┘", h: "─", v: "│" };
|
|
347
|
+
this.drawChar(x, y, chars.tl, fg);
|
|
348
|
+
this.drawChar(x + width - 1, y, chars.tr, fg);
|
|
349
|
+
this.drawChar(x, y + height - 1, chars.bl, fg);
|
|
350
|
+
this.drawChar(x + width - 1, y + height - 1, chars.br, fg);
|
|
351
|
+
this.drawHLine(x + 1, y, width - 2, chars.h, fg);
|
|
352
|
+
this.drawHLine(x + 1, y + height - 1, width - 2, chars.h, fg);
|
|
353
|
+
this.drawVLine(x, y + 1, height - 2, chars.v, fg);
|
|
354
|
+
this.drawVLine(x + width - 1, y + 1, height - 2, chars.v, fg);
|
|
355
|
+
}
|
|
356
|
+
toString() {
|
|
357
|
+
return this.cells.map((row) => row.map((cell) => cell.char).join("")).join(`
|
|
358
|
+
`);
|
|
359
|
+
}
|
|
360
|
+
toAnsiString() {
|
|
361
|
+
const lines = [];
|
|
362
|
+
for (const row of this.cells) {
|
|
363
|
+
let line = "";
|
|
364
|
+
let currentFg = null;
|
|
365
|
+
let currentBg = null;
|
|
366
|
+
for (const cell of row) {
|
|
367
|
+
const fgChanged = !currentFg || currentFg.r !== cell.fg.r || currentFg.g !== cell.fg.g || currentFg.b !== cell.fg.b;
|
|
368
|
+
const bgChanged = cell.bg.a > 0 && (!currentBg || currentBg.r !== cell.bg.r || currentBg.g !== cell.bg.g || currentBg.b !== cell.bg.b);
|
|
369
|
+
if (fgChanged) {
|
|
370
|
+
line += `\x1B[38;2;${cell.fg.r};${cell.fg.g};${cell.fg.b}m`;
|
|
371
|
+
currentFg = cell.fg;
|
|
372
|
+
}
|
|
373
|
+
if (bgChanged) {
|
|
374
|
+
line += `\x1B[48;2;${cell.bg.r};${cell.bg.g};${cell.bg.b}m`;
|
|
375
|
+
currentBg = cell.bg;
|
|
376
|
+
}
|
|
377
|
+
if (cell.bold)
|
|
378
|
+
line += "\x1B[1m";
|
|
379
|
+
if (cell.italic)
|
|
380
|
+
line += "\x1B[3m";
|
|
381
|
+
if (cell.underline)
|
|
382
|
+
line += "\x1B[4m";
|
|
383
|
+
line += cell.char;
|
|
384
|
+
if (cell.bold || cell.italic || cell.underline) {
|
|
385
|
+
line += "\x1B[22;23;24m";
|
|
386
|
+
if (currentFg) {
|
|
387
|
+
line += `\x1B[38;2;${currentFg.r};${currentFg.g};${currentFg.b}m`;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
line += "\x1B[0m";
|
|
392
|
+
lines.push(line);
|
|
393
|
+
}
|
|
394
|
+
return lines.join(`
|
|
395
|
+
`);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
function createCanvas(width, height) {
|
|
399
|
+
return new TerminalCanvas(width, height);
|
|
400
|
+
}
|
|
401
|
+
var DEFAULT_FG, DEFAULT_BG;
|
|
402
|
+
var init_canvas = __esm(() => {
|
|
403
|
+
DEFAULT_FG = { r: 255, g: 255, b: 255, a: 1 };
|
|
404
|
+
DEFAULT_BG = { r: 0, g: 0, b: 0, a: 0 };
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
// src/pipeline/scales.ts
|
|
408
|
+
var exports_scales = {};
|
|
409
|
+
__export(exports_scales, {
|
|
410
|
+
niceDomain: () => niceDomain,
|
|
411
|
+
inferDiscreteDomain: () => inferDiscreteDomain,
|
|
412
|
+
inferContinuousDomain: () => inferContinuousDomain,
|
|
413
|
+
getTransformFunctions: () => getTransformFunctions,
|
|
414
|
+
expandDomain: () => expandDomain,
|
|
415
|
+
createResolvedSizeScale: () => createResolvedSizeScale,
|
|
416
|
+
createResolvedDiscreteScale: () => createResolvedDiscreteScale,
|
|
417
|
+
createResolvedDiscreteColorScale: () => createResolvedDiscreteColorScale,
|
|
418
|
+
createResolvedContinuousScale: () => createResolvedContinuousScale,
|
|
419
|
+
createResolvedContinuousColorScale: () => createResolvedContinuousColorScale,
|
|
420
|
+
buildScaleContext: () => buildScaleContext,
|
|
421
|
+
DEFAULT_POINT_COLOR: () => DEFAULT_POINT_COLOR
|
|
422
|
+
});
|
|
423
|
+
function inferContinuousDomain(data, field) {
|
|
424
|
+
let min = Infinity;
|
|
425
|
+
let max = -Infinity;
|
|
426
|
+
for (const row of data) {
|
|
427
|
+
const value = row[field];
|
|
428
|
+
if (typeof value === "number" && !isNaN(value)) {
|
|
429
|
+
if (value < min)
|
|
430
|
+
min = value;
|
|
431
|
+
if (value > max)
|
|
432
|
+
max = value;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
if (min === Infinity)
|
|
436
|
+
min = 0;
|
|
437
|
+
if (max === -Infinity)
|
|
438
|
+
max = 1;
|
|
439
|
+
if (min === max) {
|
|
440
|
+
min = min - 1;
|
|
441
|
+
max = max + 1;
|
|
442
|
+
}
|
|
443
|
+
return [min, max];
|
|
444
|
+
}
|
|
445
|
+
function inferDiscreteDomain(data, field, options = {}) {
|
|
446
|
+
const { limits, order = "alphabetical", reverse = false, exclude, drop = true } = options;
|
|
447
|
+
const seen = new Map;
|
|
448
|
+
let index = 0;
|
|
449
|
+
for (const row of data) {
|
|
450
|
+
const value = row[field];
|
|
451
|
+
if (value !== null && value !== undefined) {
|
|
452
|
+
const key = String(value);
|
|
453
|
+
if (!seen.has(key)) {
|
|
454
|
+
seen.set(key, { firstIndex: index, count: 1 });
|
|
455
|
+
} else {
|
|
456
|
+
seen.get(key).count++;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
index++;
|
|
460
|
+
}
|
|
461
|
+
let result;
|
|
462
|
+
if (limits) {
|
|
463
|
+
if (drop) {
|
|
464
|
+
result = limits.filter((v) => seen.has(v));
|
|
465
|
+
} else {
|
|
466
|
+
result = [...limits];
|
|
467
|
+
}
|
|
468
|
+
} else {
|
|
469
|
+
const values = Array.from(seen.keys());
|
|
470
|
+
switch (order) {
|
|
471
|
+
case "data":
|
|
472
|
+
result = values.sort((a, b) => seen.get(a).firstIndex - seen.get(b).firstIndex);
|
|
473
|
+
break;
|
|
474
|
+
case "frequency":
|
|
475
|
+
result = values.sort((a, b) => seen.get(b).count - seen.get(a).count);
|
|
476
|
+
break;
|
|
477
|
+
case "reverse":
|
|
478
|
+
result = values.sort().reverse();
|
|
479
|
+
break;
|
|
480
|
+
case "alphabetical":
|
|
481
|
+
default:
|
|
482
|
+
result = values.sort();
|
|
483
|
+
break;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
if (exclude && exclude.length > 0) {
|
|
487
|
+
const excludeSet = new Set(exclude);
|
|
488
|
+
result = result.filter((v) => !excludeSet.has(v));
|
|
489
|
+
}
|
|
490
|
+
if (reverse) {
|
|
491
|
+
result = result.reverse();
|
|
492
|
+
}
|
|
493
|
+
return result;
|
|
494
|
+
}
|
|
495
|
+
function expandDomain(domain, expand = 0.05) {
|
|
496
|
+
const range = domain[1] - domain[0];
|
|
497
|
+
const padding = range * expand;
|
|
498
|
+
return [domain[0] - padding, domain[1] + padding];
|
|
499
|
+
}
|
|
500
|
+
function niceStep(range, targetTicks = 5) {
|
|
501
|
+
const rawStep = range / Math.max(1, targetTicks - 1);
|
|
502
|
+
const magnitude = Math.pow(10, Math.floor(Math.log10(rawStep)));
|
|
503
|
+
const normalized = rawStep / magnitude;
|
|
504
|
+
let nice;
|
|
505
|
+
if (normalized <= 1.5)
|
|
506
|
+
nice = 1;
|
|
507
|
+
else if (normalized <= 3)
|
|
508
|
+
nice = 2;
|
|
509
|
+
else if (normalized <= 7)
|
|
510
|
+
nice = 5;
|
|
511
|
+
else
|
|
512
|
+
nice = 10;
|
|
513
|
+
return nice * magnitude;
|
|
514
|
+
}
|
|
515
|
+
function niceDomain(domain, targetTicks = 5) {
|
|
516
|
+
const [min, max] = domain;
|
|
517
|
+
const range = max - min;
|
|
518
|
+
if (range === 0) {
|
|
519
|
+
if (min === 0)
|
|
520
|
+
return [-1, 1];
|
|
521
|
+
const magnitude = Math.pow(10, Math.floor(Math.log10(Math.abs(min))));
|
|
522
|
+
return [min - magnitude, min + magnitude];
|
|
523
|
+
}
|
|
524
|
+
const step = niceStep(range, targetTicks);
|
|
525
|
+
const niceMin = Math.floor(min / step) * step;
|
|
526
|
+
const niceMax = Math.ceil(max / step) * step;
|
|
527
|
+
return [niceMin, niceMax];
|
|
528
|
+
}
|
|
529
|
+
function getTransformFunctions(trans = "identity") {
|
|
530
|
+
switch (trans) {
|
|
531
|
+
case "log10":
|
|
532
|
+
return {
|
|
533
|
+
type: "log10",
|
|
534
|
+
transform: (v) => v > 0 ? Math.log10(v) : -Infinity,
|
|
535
|
+
invert: (v) => Math.pow(10, v)
|
|
536
|
+
};
|
|
537
|
+
case "sqrt":
|
|
538
|
+
return {
|
|
539
|
+
type: "sqrt",
|
|
540
|
+
transform: (v) => v >= 0 ? Math.sqrt(v) : 0,
|
|
541
|
+
invert: (v) => v * v
|
|
542
|
+
};
|
|
543
|
+
case "reverse":
|
|
544
|
+
return {
|
|
545
|
+
type: "reverse",
|
|
546
|
+
transform: (v) => -v,
|
|
547
|
+
invert: (v) => -v
|
|
548
|
+
};
|
|
549
|
+
default:
|
|
550
|
+
return {
|
|
551
|
+
type: "identity",
|
|
552
|
+
transform: (v) => v,
|
|
553
|
+
invert: (v) => v
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
function createResolvedContinuousScale(aesthetic, domain, range, trans = "identity") {
|
|
558
|
+
const [domainMin, domainMax] = domain;
|
|
559
|
+
const [rangeMin, rangeMax] = range;
|
|
560
|
+
const rangeSpan = rangeMax - rangeMin;
|
|
561
|
+
const { transform, invert } = getTransformFunctions(trans);
|
|
523
562
|
return {
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
563
|
+
aesthetic,
|
|
564
|
+
type: "continuous",
|
|
565
|
+
domain,
|
|
566
|
+
range,
|
|
567
|
+
trans,
|
|
568
|
+
transform,
|
|
569
|
+
invert,
|
|
570
|
+
normalize(value) {
|
|
571
|
+
const num = Number(value);
|
|
572
|
+
if (isNaN(num))
|
|
573
|
+
return 0;
|
|
574
|
+
const transformed = transform(num);
|
|
575
|
+
const transformedMin = transform(domainMin);
|
|
576
|
+
const transformedMax = transform(domainMax);
|
|
577
|
+
if (transformedMax === transformedMin)
|
|
578
|
+
return 0.5;
|
|
579
|
+
return (transformed - transformedMin) / (transformedMax - transformedMin);
|
|
537
580
|
},
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
bold: true
|
|
581
|
+
toCanvas(normalized) {
|
|
582
|
+
return rangeMin + normalized * rangeSpan;
|
|
541
583
|
},
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
text: "#c8c8c8",
|
|
545
|
-
background: ""
|
|
546
|
-
}
|
|
584
|
+
map(value) {
|
|
585
|
+
return this.toCanvas(this.normalize(value));
|
|
547
586
|
}
|
|
548
587
|
};
|
|
549
588
|
}
|
|
550
|
-
function
|
|
589
|
+
function createResolvedDiscreteScale(aesthetic, domain, range) {
|
|
590
|
+
const [rangeMin, rangeMax] = range;
|
|
591
|
+
const rangeSpan = rangeMax - rangeMin;
|
|
551
592
|
return {
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
legend: {
|
|
563
|
-
position: "none",
|
|
564
|
-
title: { bold: false }
|
|
593
|
+
aesthetic,
|
|
594
|
+
type: "discrete",
|
|
595
|
+
domain,
|
|
596
|
+
range,
|
|
597
|
+
normalize(value) {
|
|
598
|
+
const str = String(value);
|
|
599
|
+
const index = domain.indexOf(str);
|
|
600
|
+
if (index < 0)
|
|
601
|
+
return 0;
|
|
602
|
+
return domain.length > 1 ? index / (domain.length - 1) : 0.5;
|
|
565
603
|
},
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
bold: false
|
|
604
|
+
toCanvas(normalized) {
|
|
605
|
+
return rangeMin + normalized * rangeSpan;
|
|
569
606
|
},
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
text: "#888888",
|
|
573
|
-
background: ""
|
|
574
|
-
}
|
|
607
|
+
map(value) {
|
|
608
|
+
return this.toCanvas(this.normalize(value));
|
|
575
609
|
}
|
|
576
610
|
};
|
|
577
611
|
}
|
|
578
|
-
|
|
579
|
-
// src/coords/cartesian.ts
|
|
580
|
-
function coordCartesian(options = {}) {
|
|
612
|
+
function interpolateColor(color1, color2, t) {
|
|
581
613
|
return {
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
transform(x, y) {
|
|
587
|
-
return { x, y };
|
|
588
|
-
}
|
|
614
|
+
r: Math.round(color1.r + (color2.r - color1.r) * t),
|
|
615
|
+
g: Math.round(color1.g + (color2.g - color1.g) * t),
|
|
616
|
+
b: Math.round(color1.b + (color2.b - color1.b) * t),
|
|
617
|
+
a: color1.a + (color2.a - color1.a) * t
|
|
589
618
|
};
|
|
590
619
|
}
|
|
591
|
-
function
|
|
620
|
+
function createResolvedDiscreteColorScale(domain, palette = CATEGORY_COLORS) {
|
|
592
621
|
return {
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
622
|
+
aesthetic: "color",
|
|
623
|
+
type: "discrete",
|
|
624
|
+
domain,
|
|
625
|
+
map(value) {
|
|
626
|
+
const str = String(value);
|
|
627
|
+
const index = domain.indexOf(str);
|
|
628
|
+
if (index < 0)
|
|
629
|
+
return palette[0];
|
|
630
|
+
return palette[index % palette.length];
|
|
596
631
|
}
|
|
597
632
|
};
|
|
598
633
|
}
|
|
599
|
-
function
|
|
600
|
-
const
|
|
634
|
+
function createResolvedContinuousColorScale(domain, lowColor = { r: 68, g: 1, b: 84, a: 1 }, highColor = { r: 253, g: 231, b: 37, a: 1 }) {
|
|
635
|
+
const [min, max] = domain;
|
|
636
|
+
const span = max - min;
|
|
601
637
|
return {
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
638
|
+
aesthetic: "color",
|
|
639
|
+
type: "continuous",
|
|
640
|
+
domain,
|
|
641
|
+
map(value) {
|
|
642
|
+
const num = Number(value);
|
|
643
|
+
if (isNaN(num))
|
|
644
|
+
return lowColor;
|
|
645
|
+
const t = Math.max(0, Math.min(1, (num - min) / span));
|
|
646
|
+
return interpolateColor(lowColor, highColor, t);
|
|
610
647
|
}
|
|
611
648
|
};
|
|
612
649
|
}
|
|
613
|
-
function
|
|
614
|
-
const
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
ratio,
|
|
621
|
-
transform(x, y) {
|
|
622
|
-
return { x, y };
|
|
650
|
+
function isCategoricalField(data, field) {
|
|
651
|
+
for (const row of data) {
|
|
652
|
+
const value = row[field];
|
|
653
|
+
if (value !== null && value !== undefined) {
|
|
654
|
+
if (typeof value === "string") {
|
|
655
|
+
return true;
|
|
656
|
+
}
|
|
623
657
|
}
|
|
624
|
-
};
|
|
625
|
-
}
|
|
626
|
-
function coordEqual(options = {}) {
|
|
627
|
-
return coordFixed({ ...options, ratio: 1 });
|
|
628
|
-
}
|
|
629
|
-
function getTransform(type) {
|
|
630
|
-
switch (type) {
|
|
631
|
-
case "log10":
|
|
632
|
-
return (v) => v > 0 ? Math.log10(v) : -Infinity;
|
|
633
|
-
case "sqrt":
|
|
634
|
-
return (v) => v >= 0 ? Math.sqrt(v) : 0;
|
|
635
|
-
case "reverse":
|
|
636
|
-
return (v) => -v;
|
|
637
|
-
default:
|
|
638
|
-
return (v) => v;
|
|
639
658
|
}
|
|
659
|
+
return false;
|
|
640
660
|
}
|
|
641
|
-
function
|
|
642
|
-
const
|
|
643
|
-
const
|
|
644
|
-
return {
|
|
645
|
-
type: "trans",
|
|
646
|
-
xlim: options.xlim,
|
|
647
|
-
ylim: options.ylim,
|
|
648
|
-
clip: options.clip ?? true,
|
|
649
|
-
xTransType: options.x ?? "identity",
|
|
650
|
-
yTransType: options.y ?? "identity",
|
|
651
|
-
transform(x, y) {
|
|
652
|
-
return {
|
|
653
|
-
x: xTrans(x),
|
|
654
|
-
y: yTrans(y)
|
|
655
|
-
};
|
|
656
|
-
}
|
|
657
|
-
};
|
|
658
|
-
}
|
|
659
|
-
function coordFlipWithLimits(options = {}) {
|
|
660
|
-
return {
|
|
661
|
-
type: "flip",
|
|
662
|
-
xlim: options.xlim,
|
|
663
|
-
ylim: options.ylim,
|
|
664
|
-
clip: options.clip ?? true,
|
|
665
|
-
transform(x, y) {
|
|
666
|
-
return { x: y, y: x };
|
|
667
|
-
}
|
|
668
|
-
};
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
// src/canvas/canvas.ts
|
|
672
|
-
var DEFAULT_FG = { r: 255, g: 255, b: 255, a: 1 };
|
|
673
|
-
var DEFAULT_BG = { r: 0, g: 0, b: 0, a: 0 };
|
|
674
|
-
function createEmptyCell() {
|
|
661
|
+
function createResolvedSizeScale(domain) {
|
|
662
|
+
const [min, max] = domain;
|
|
663
|
+
const span = max - min;
|
|
675
664
|
return {
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
665
|
+
aesthetic: "size",
|
|
666
|
+
type: "continuous",
|
|
667
|
+
domain,
|
|
668
|
+
map(value) {
|
|
669
|
+
const num = Number(value);
|
|
670
|
+
if (isNaN(num))
|
|
671
|
+
return 1;
|
|
672
|
+
const t = Math.max(0, Math.min(1, (num - min) / span));
|
|
673
|
+
return Math.floor(t * 3.99);
|
|
674
|
+
}
|
|
679
675
|
};
|
|
680
676
|
}
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
this.clear();
|
|
677
|
+
function computeDomain(data, field, trans = "identity") {
|
|
678
|
+
const rawDomain = inferContinuousDomain(data, field);
|
|
679
|
+
if (trans === "log10") {
|
|
680
|
+
const [min, max] = rawDomain;
|
|
681
|
+
const safeMin = min > 0 ? min : 0.001;
|
|
682
|
+
const safeMax = max > 0 ? max : 1;
|
|
683
|
+
const minPow = Math.floor(Math.log10(safeMin));
|
|
684
|
+
const maxPow = Math.ceil(Math.log10(safeMax));
|
|
685
|
+
return [Math.pow(10, minPow), Math.pow(10, maxPow)];
|
|
691
686
|
}
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
687
|
+
return niceDomain(rawDomain);
|
|
688
|
+
}
|
|
689
|
+
function buildScaleContext(data, aes, plotArea, userScales = [], coordLimits) {
|
|
690
|
+
const userXScale = userScales.find((s) => s.aesthetic === "x");
|
|
691
|
+
const userYScale = userScales.find((s) => s.aesthetic === "y");
|
|
692
|
+
const userColorScale = userScales.find((s) => s.aesthetic === "color" || s.aesthetic === "fill");
|
|
693
|
+
const xIsCategorical = isCategoricalField(data, aes.x);
|
|
694
|
+
let x;
|
|
695
|
+
if (xIsCategorical) {
|
|
696
|
+
const xOrderOptions = {};
|
|
697
|
+
if (userXScale) {
|
|
698
|
+
if (userXScale.domain && Array.isArray(userXScale.domain)) {
|
|
699
|
+
xOrderOptions.limits = userXScale.domain;
|
|
700
|
+
}
|
|
701
|
+
const orderOpts = userXScale.orderOptions;
|
|
702
|
+
if (orderOpts) {
|
|
703
|
+
if (orderOpts.order)
|
|
704
|
+
xOrderOptions.order = orderOpts.order;
|
|
705
|
+
if (orderOpts.reverse)
|
|
706
|
+
xOrderOptions.reverse = orderOpts.reverse;
|
|
707
|
+
if (orderOpts.exclude)
|
|
708
|
+
xOrderOptions.exclude = orderOpts.exclude;
|
|
709
|
+
if (orderOpts.drop !== undefined)
|
|
710
|
+
xOrderOptions.drop = orderOpts.drop;
|
|
711
|
+
}
|
|
695
712
|
}
|
|
696
|
-
const
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
return createEmptyCell();
|
|
713
|
+
const xDomain = inferDiscreteDomain(data, aes.x, xOrderOptions);
|
|
714
|
+
x = createResolvedDiscreteScale("x", xDomain, [plotArea.x, plotArea.x + plotArea.width - 1]);
|
|
715
|
+
if (userXScale?.labels) {
|
|
716
|
+
x.labels = userXScale.labels;
|
|
717
|
+
}
|
|
718
|
+
} else {
|
|
719
|
+
const xTrans = userXScale?.trans ?? "identity";
|
|
720
|
+
const xDomain = coordLimits?.xlim ?? userXScale?.domain ?? computeDomain(data, aes.x, xTrans);
|
|
721
|
+
x = createResolvedContinuousScale("x", xDomain, [plotArea.x, plotArea.x + plotArea.width - 1], xTrans);
|
|
722
|
+
if (userXScale?.breaks) {
|
|
723
|
+
x.breaks = userXScale.breaks;
|
|
724
|
+
}
|
|
725
|
+
if (userXScale?.labels) {
|
|
726
|
+
x.labels = userXScale.labels;
|
|
711
727
|
}
|
|
712
|
-
return this.cells[Math.floor(y)][Math.floor(x)];
|
|
713
728
|
}
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
729
|
+
const yIsCategorical = isCategoricalField(data, aes.y);
|
|
730
|
+
let y;
|
|
731
|
+
if (yIsCategorical) {
|
|
732
|
+
const yOrderOptions = {};
|
|
733
|
+
if (userYScale) {
|
|
734
|
+
if (userYScale.domain && Array.isArray(userYScale.domain)) {
|
|
735
|
+
yOrderOptions.limits = userYScale.domain;
|
|
736
|
+
}
|
|
737
|
+
const orderOpts = userYScale.orderOptions;
|
|
738
|
+
if (orderOpts) {
|
|
739
|
+
if (orderOpts.order)
|
|
740
|
+
yOrderOptions.order = orderOpts.order;
|
|
741
|
+
if (orderOpts.reverse)
|
|
742
|
+
yOrderOptions.reverse = orderOpts.reverse;
|
|
743
|
+
if (orderOpts.exclude)
|
|
744
|
+
yOrderOptions.exclude = orderOpts.exclude;
|
|
745
|
+
if (orderOpts.drop !== undefined)
|
|
746
|
+
yOrderOptions.drop = orderOpts.drop;
|
|
720
747
|
}
|
|
721
|
-
this.cells.push(row);
|
|
722
748
|
}
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
drawString(x, y, str, fg) {
|
|
728
|
-
for (let i = 0;i < str.length; i++) {
|
|
729
|
-
this.drawChar(x + i, y, str[i], fg);
|
|
749
|
+
const yDomain = inferDiscreteDomain(data, aes.y, yOrderOptions);
|
|
750
|
+
y = createResolvedDiscreteScale("y", yDomain, [plotArea.y + plotArea.height - 1, plotArea.y]);
|
|
751
|
+
if (userYScale?.labels) {
|
|
752
|
+
y.labels = userYScale.labels;
|
|
730
753
|
}
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
754
|
+
} else {
|
|
755
|
+
const yTrans = userYScale?.trans ?? "identity";
|
|
756
|
+
const yDomain = coordLimits?.ylim ?? userYScale?.domain ?? computeDomain(data, aes.y, yTrans);
|
|
757
|
+
y = createResolvedContinuousScale("y", yDomain, [plotArea.y + plotArea.height - 1, plotArea.y], yTrans);
|
|
758
|
+
if (userYScale?.breaks) {
|
|
759
|
+
y.breaks = userYScale.breaks;
|
|
735
760
|
}
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
for (let i = 0;i < length; i++) {
|
|
739
|
-
this.drawChar(x, y + i, char, fg);
|
|
761
|
+
if (userYScale?.labels) {
|
|
762
|
+
y.labels = userYScale.labels;
|
|
740
763
|
}
|
|
741
764
|
}
|
|
742
|
-
|
|
743
|
-
|
|
765
|
+
const context = { x, y };
|
|
766
|
+
if (aes.y2) {
|
|
767
|
+
const userY2Scale = userScales.find((s) => s.aesthetic === "y2");
|
|
768
|
+
const y2Trans = userY2Scale?.trans ?? "identity";
|
|
769
|
+
const y2Domain = userY2Scale?.domain ?? computeDomain(data, aes.y2, y2Trans);
|
|
770
|
+
const y2 = createResolvedContinuousScale("y2", y2Domain, [plotArea.y + plotArea.height - 1, plotArea.y], y2Trans);
|
|
771
|
+
if (userY2Scale?.breaks) {
|
|
772
|
+
y2.breaks = userY2Scale.breaks;
|
|
773
|
+
}
|
|
774
|
+
if (userY2Scale?.labels) {
|
|
775
|
+
y2.labels = userY2Scale.labels;
|
|
776
|
+
}
|
|
777
|
+
context.y2 = y2;
|
|
744
778
|
}
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
779
|
+
const colorAesField = aes.color || aes.fill;
|
|
780
|
+
if (colorAesField) {
|
|
781
|
+
const colorOrderOptions = {};
|
|
782
|
+
if (userColorScale) {
|
|
783
|
+
if (userColorScale.domain && Array.isArray(userColorScale.domain)) {
|
|
784
|
+
colorOrderOptions.limits = userColorScale.domain;
|
|
785
|
+
}
|
|
786
|
+
const orderOpts = userColorScale.orderOptions;
|
|
787
|
+
if (orderOpts) {
|
|
788
|
+
if (orderOpts.order)
|
|
789
|
+
colorOrderOptions.order = orderOpts.order;
|
|
790
|
+
if (orderOpts.reverse)
|
|
791
|
+
colorOrderOptions.reverse = orderOpts.reverse;
|
|
792
|
+
if (orderOpts.exclude)
|
|
793
|
+
colorOrderOptions.exclude = orderOpts.exclude;
|
|
794
|
+
if (orderOpts.drop !== undefined)
|
|
795
|
+
colorOrderOptions.drop = orderOpts.drop;
|
|
749
796
|
}
|
|
750
797
|
}
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
this.drawVLine(x + width - 1, y + 1, height - 2, chars.v, fg);
|
|
762
|
-
}
|
|
763
|
-
toString() {
|
|
764
|
-
return this.cells.map((row) => row.map((cell) => cell.char).join("")).join(`
|
|
765
|
-
`);
|
|
766
|
-
}
|
|
767
|
-
toAnsiString() {
|
|
768
|
-
const lines = [];
|
|
769
|
-
for (const row of this.cells) {
|
|
770
|
-
let line = "";
|
|
771
|
-
let currentFg = null;
|
|
772
|
-
let currentBg = null;
|
|
773
|
-
for (const cell of row) {
|
|
774
|
-
const fgChanged = !currentFg || currentFg.r !== cell.fg.r || currentFg.g !== cell.fg.g || currentFg.b !== cell.fg.b;
|
|
775
|
-
const bgChanged = cell.bg.a > 0 && (!currentBg || currentBg.r !== cell.bg.r || currentBg.g !== cell.bg.g || currentBg.b !== cell.bg.b);
|
|
776
|
-
if (fgChanged) {
|
|
777
|
-
line += `\x1B[38;2;${cell.fg.r};${cell.fg.g};${cell.fg.b}m`;
|
|
778
|
-
currentFg = cell.fg;
|
|
779
|
-
}
|
|
780
|
-
if (bgChanged) {
|
|
781
|
-
line += `\x1B[48;2;${cell.bg.r};${cell.bg.g};${cell.bg.b}m`;
|
|
782
|
-
currentBg = cell.bg;
|
|
783
|
-
}
|
|
784
|
-
if (cell.bold)
|
|
785
|
-
line += "\x1B[1m";
|
|
786
|
-
if (cell.italic)
|
|
787
|
-
line += "\x1B[3m";
|
|
788
|
-
if (cell.underline)
|
|
789
|
-
line += "\x1B[4m";
|
|
790
|
-
line += cell.char;
|
|
791
|
-
if (cell.bold || cell.italic || cell.underline) {
|
|
792
|
-
line += "\x1B[22;23;24m";
|
|
793
|
-
if (currentFg) {
|
|
794
|
-
line += `\x1B[38;2;${currentFg.r};${currentFg.g};${currentFg.b}m`;
|
|
798
|
+
const colorDomain = inferDiscreteDomain(data, colorAesField, colorOrderOptions);
|
|
799
|
+
if (userColorScale && userColorScale.map) {
|
|
800
|
+
context.color = {
|
|
801
|
+
aesthetic: userColorScale.aesthetic || "color",
|
|
802
|
+
type: userColorScale.type === "continuous" ? "continuous" : "discrete",
|
|
803
|
+
domain: userColorScale.type === "continuous" ? userColorScale.domain ?? inferContinuousDomain(data, colorAesField) : colorDomain,
|
|
804
|
+
map: (value) => {
|
|
805
|
+
const result = userColorScale.map(value);
|
|
806
|
+
if (typeof result === "object" && "r" in result) {
|
|
807
|
+
return result;
|
|
795
808
|
}
|
|
809
|
+
return { r: 128, g: 128, b: 128, a: 1 };
|
|
796
810
|
}
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
|
|
811
|
+
};
|
|
812
|
+
} else {
|
|
813
|
+
context.color = createResolvedDiscreteColorScale(colorDomain);
|
|
800
814
|
}
|
|
801
|
-
return lines.join(`
|
|
802
|
-
`);
|
|
803
815
|
}
|
|
816
|
+
if (aes.size) {
|
|
817
|
+
const sizeDomain = inferContinuousDomain(data, aes.size);
|
|
818
|
+
context.size = createResolvedSizeScale(sizeDomain);
|
|
819
|
+
}
|
|
820
|
+
return context;
|
|
804
821
|
}
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
822
|
+
var CATEGORY_COLORS, DEFAULT_POINT_COLOR;
|
|
823
|
+
var init_scales = __esm(() => {
|
|
824
|
+
CATEGORY_COLORS = [
|
|
825
|
+
{ r: 31, g: 119, b: 180, a: 1 },
|
|
826
|
+
{ r: 255, g: 127, b: 14, a: 1 },
|
|
827
|
+
{ r: 44, g: 160, b: 44, a: 1 },
|
|
828
|
+
{ r: 214, g: 39, b: 40, a: 1 },
|
|
829
|
+
{ r: 148, g: 103, b: 189, a: 1 },
|
|
830
|
+
{ r: 140, g: 86, b: 75, a: 1 },
|
|
831
|
+
{ r: 227, g: 119, b: 194, a: 1 },
|
|
832
|
+
{ r: 127, g: 127, b: 127, a: 1 },
|
|
833
|
+
{ r: 188, g: 189, b: 34, a: 1 },
|
|
834
|
+
{ r: 23, g: 190, b: 207, a: 1 }
|
|
835
|
+
];
|
|
836
|
+
DEFAULT_POINT_COLOR = { r: 79, g: 169, b: 238, a: 1 };
|
|
837
|
+
});
|
|
814
838
|
|
|
815
839
|
// src/positions/index.ts
|
|
816
840
|
function position_identity() {
|
|
@@ -1012,22 +1036,6 @@ function getPositionType(position) {
|
|
|
1012
1036
|
}
|
|
1013
1037
|
|
|
1014
1038
|
// src/pipeline/render-geoms.ts
|
|
1015
|
-
var POINT_SHAPES = {
|
|
1016
|
-
circle: "●",
|
|
1017
|
-
filled_circle: "●",
|
|
1018
|
-
open_circle: "○",
|
|
1019
|
-
square: "■",
|
|
1020
|
-
open_square: "□",
|
|
1021
|
-
diamond: "◆",
|
|
1022
|
-
open_diamond: "◇",
|
|
1023
|
-
triangle: "▲",
|
|
1024
|
-
open_triangle: "△",
|
|
1025
|
-
cross: "✕",
|
|
1026
|
-
plus: "+",
|
|
1027
|
-
star: "★",
|
|
1028
|
-
dot: "•"
|
|
1029
|
-
};
|
|
1030
|
-
var SIZE_CHARS = ["·", "•", "●", "⬤"];
|
|
1031
1039
|
function getPointShape(shape) {
|
|
1032
1040
|
if (!shape)
|
|
1033
1041
|
return POINT_SHAPES.circle;
|
|
@@ -1038,7 +1046,45 @@ function getPointColor(row, aes, colorScale) {
|
|
|
1038
1046
|
const value = row[aes.color];
|
|
1039
1047
|
return colorScale.map(value);
|
|
1040
1048
|
}
|
|
1041
|
-
return DEFAULT_POINT_COLOR;
|
|
1049
|
+
return DEFAULT_POINT_COLOR;
|
|
1050
|
+
}
|
|
1051
|
+
function parseColorToRgba(color, fallback = { r: 128, g: 128, b: 128, a: 1 }) {
|
|
1052
|
+
if (!color)
|
|
1053
|
+
return fallback;
|
|
1054
|
+
if (typeof color === "object" && color !== null && "r" in color) {
|
|
1055
|
+
return color;
|
|
1056
|
+
}
|
|
1057
|
+
if (typeof color === "string") {
|
|
1058
|
+
if (color.startsWith("#")) {
|
|
1059
|
+
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(color);
|
|
1060
|
+
if (result) {
|
|
1061
|
+
return {
|
|
1062
|
+
r: parseInt(result[1], 16),
|
|
1063
|
+
g: parseInt(result[2], 16),
|
|
1064
|
+
b: parseInt(result[3], 16),
|
|
1065
|
+
a: 1
|
|
1066
|
+
};
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
const namedColors = {
|
|
1070
|
+
red: { r: 255, g: 0, b: 0, a: 1 },
|
|
1071
|
+
blue: { r: 0, g: 0, b: 255, a: 1 },
|
|
1072
|
+
green: { r: 0, g: 128, b: 0, a: 1 },
|
|
1073
|
+
black: { r: 0, g: 0, b: 0, a: 1 },
|
|
1074
|
+
white: { r: 255, g: 255, b: 255, a: 1 },
|
|
1075
|
+
gray: { r: 128, g: 128, b: 128, a: 1 },
|
|
1076
|
+
grey: { r: 128, g: 128, b: 128, a: 1 },
|
|
1077
|
+
yellow: { r: 255, g: 255, b: 0, a: 1 },
|
|
1078
|
+
orange: { r: 255, g: 165, b: 0, a: 1 },
|
|
1079
|
+
purple: { r: 128, g: 0, b: 128, a: 1 },
|
|
1080
|
+
cyan: { r: 0, g: 255, b: 255, a: 1 },
|
|
1081
|
+
magenta: { r: 255, g: 0, b: 255, a: 1 }
|
|
1082
|
+
};
|
|
1083
|
+
const named = namedColors[color.toLowerCase()];
|
|
1084
|
+
if (named)
|
|
1085
|
+
return named;
|
|
1086
|
+
}
|
|
1087
|
+
return fallback;
|
|
1042
1088
|
}
|
|
1043
1089
|
function renderGeomPoint(data, geom, aes, scales, canvas) {
|
|
1044
1090
|
const defaultShape = getPointShape(geom.params.shape);
|
|
@@ -1438,7 +1484,7 @@ function renderGeomHLine(_data, geom, _aes, scales, canvas) {
|
|
|
1438
1484
|
if (yintercept === undefined)
|
|
1439
1485
|
return;
|
|
1440
1486
|
const cy = Math.round(scales.y.map(yintercept));
|
|
1441
|
-
const color = geom.params.color
|
|
1487
|
+
const color = parseColorToRgba(geom.params.color);
|
|
1442
1488
|
const startX = Math.round(scales.x.range[0]);
|
|
1443
1489
|
const endX = Math.round(scales.x.range[1]);
|
|
1444
1490
|
canvas.drawHLine(startX, cy, endX - startX + 1, "─", color);
|
|
@@ -1448,7 +1494,7 @@ function renderGeomVLine(_data, geom, _aes, scales, canvas) {
|
|
|
1448
1494
|
if (xintercept === undefined)
|
|
1449
1495
|
return;
|
|
1450
1496
|
const cx = Math.round(scales.x.map(xintercept));
|
|
1451
|
-
const color = geom.params.color
|
|
1497
|
+
const color = parseColorToRgba(geom.params.color);
|
|
1452
1498
|
const startY = Math.round(Math.min(scales.y.range[0], scales.y.range[1]));
|
|
1453
1499
|
const endY = Math.round(Math.max(scales.y.range[0], scales.y.range[1]));
|
|
1454
1500
|
canvas.drawVLine(cx, startY, endY - startY + 1, "│", color);
|
|
@@ -1765,20 +1811,52 @@ function renderGeomTile(data, geom, aes, scales, canvas) {
|
|
|
1765
1811
|
const plotRight = Math.round(scales.x.range[1]);
|
|
1766
1812
|
const plotTop = Math.round(Math.min(scales.y.range[0], scales.y.range[1]));
|
|
1767
1813
|
const plotBottom = Math.round(Math.max(scales.y.range[0], scales.y.range[1]));
|
|
1768
|
-
let
|
|
1769
|
-
let
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1814
|
+
let halfW;
|
|
1815
|
+
let halfH;
|
|
1816
|
+
const xIsDiscrete = scales.x.type === "discrete";
|
|
1817
|
+
const yIsDiscrete = scales.y.type === "discrete";
|
|
1818
|
+
if (xIsDiscrete) {
|
|
1819
|
+
const xDomain = scales.x.domain;
|
|
1820
|
+
const canvasWidth = Math.abs(scales.x.range[1] - scales.x.range[0]);
|
|
1821
|
+
halfW = Math.max(1, Math.floor(canvasWidth / (xDomain.length * 2)));
|
|
1822
|
+
} else {
|
|
1823
|
+
let tileWidth = data[0]?.width ?? geom.params.width;
|
|
1824
|
+
if (!tileWidth) {
|
|
1825
|
+
const xVals = [...new Set(data.map((r) => Number(r[aes.x])).filter((v) => !isNaN(v)))].sort((a, b) => a - b);
|
|
1826
|
+
if (xVals.length > 1) {
|
|
1827
|
+
tileWidth = xVals[1] - xVals[0];
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
tileWidth = tileWidth ?? 1;
|
|
1831
|
+
const sampleX = data.find((r) => r[aes.x] !== null && r[aes.x] !== undefined)?.[aes.x];
|
|
1832
|
+
if (sampleX !== undefined) {
|
|
1833
|
+
const cx = scales.x.map(sampleX);
|
|
1834
|
+
halfW = Math.max(1, Math.floor(Math.abs(scales.x.map(Number(sampleX) + tileWidth / 2) - cx)));
|
|
1835
|
+
} else {
|
|
1836
|
+
halfW = 1;
|
|
1775
1837
|
}
|
|
1776
|
-
|
|
1777
|
-
|
|
1838
|
+
}
|
|
1839
|
+
if (yIsDiscrete) {
|
|
1840
|
+
const yDomain = scales.y.domain;
|
|
1841
|
+
const canvasHeight = Math.abs(scales.y.range[1] - scales.y.range[0]);
|
|
1842
|
+
halfH = Math.max(1, Math.floor(canvasHeight / (yDomain.length * 2)));
|
|
1843
|
+
} else {
|
|
1844
|
+
let tileHeight = data[0]?.height ?? geom.params.height;
|
|
1845
|
+
if (!tileHeight) {
|
|
1846
|
+
const yVals = [...new Set(data.map((r) => Number(r[aes.y])).filter((v) => !isNaN(v)))].sort((a, b) => a - b);
|
|
1847
|
+
if (yVals.length > 1) {
|
|
1848
|
+
tileHeight = yVals[1] - yVals[0];
|
|
1849
|
+
}
|
|
1850
|
+
}
|
|
1851
|
+
tileHeight = tileHeight ?? 1;
|
|
1852
|
+
const sampleY = data.find((r) => r[aes.y] !== null && r[aes.y] !== undefined)?.[aes.y];
|
|
1853
|
+
if (sampleY !== undefined) {
|
|
1854
|
+
const cy = scales.y.map(sampleY);
|
|
1855
|
+
halfH = Math.max(1, Math.floor(Math.abs(scales.y.map(Number(sampleY) + tileHeight / 2) - cy)));
|
|
1856
|
+
} else {
|
|
1857
|
+
halfH = 1;
|
|
1778
1858
|
}
|
|
1779
1859
|
}
|
|
1780
|
-
tileWidth = tileWidth ?? 1;
|
|
1781
|
-
tileHeight = tileHeight ?? 1;
|
|
1782
1860
|
for (const row of data) {
|
|
1783
1861
|
const xVal = row[aes.x];
|
|
1784
1862
|
const yVal = row[aes.y];
|
|
@@ -1788,8 +1866,6 @@ function renderGeomTile(data, geom, aes, scales, canvas) {
|
|
|
1788
1866
|
}
|
|
1789
1867
|
const cx = Math.round(scales.x.map(xVal));
|
|
1790
1868
|
const cy = Math.round(scales.y.map(yVal));
|
|
1791
|
-
const halfW = Math.max(1, Math.floor(Math.abs(scales.x.map(Number(xVal) + tileWidth / 2) - cx)));
|
|
1792
|
-
const halfH = Math.max(1, Math.floor(Math.abs(scales.y.map(Number(yVal) + tileHeight / 2) - cy)));
|
|
1793
1869
|
let color;
|
|
1794
1870
|
if (scales.color && typeof fillVal === "number") {
|
|
1795
1871
|
color = scales.color.map(fillVal);
|
|
@@ -1977,7 +2053,7 @@ function renderGeomAbline(_data, geom, _aes, scales, canvas) {
|
|
|
1977
2053
|
const intercept = geom.params.intercept ?? 0;
|
|
1978
2054
|
const linetype = geom.params.linetype ?? "solid";
|
|
1979
2055
|
const lineChar = linetype === "dotted" ? "·" : linetype === "dashed" ? "╌" : "─";
|
|
1980
|
-
const color = geom.params.color
|
|
2056
|
+
const color = parseColorToRgba(geom.params.color);
|
|
1981
2057
|
const plotLeft = Math.round(scales.x.range[0]);
|
|
1982
2058
|
const plotRight = Math.round(scales.x.range[1]);
|
|
1983
2059
|
const plotTop = Math.round(Math.min(scales.y.range[0], scales.y.range[1]));
|
|
@@ -2169,6 +2245,7 @@ function renderGeom(data, geom, aes, scales, canvas, coordType) {
|
|
|
2169
2245
|
break;
|
|
2170
2246
|
case "tile":
|
|
2171
2247
|
case "raster":
|
|
2248
|
+
case "bin2d":
|
|
2172
2249
|
renderGeomTile(data, geom, aes, scales, canvas);
|
|
2173
2250
|
break;
|
|
2174
2251
|
case "contour":
|
|
@@ -2198,6 +2275,26 @@ function renderGeom(data, geom, aes, scales, canvas, coordType) {
|
|
|
2198
2275
|
break;
|
|
2199
2276
|
}
|
|
2200
2277
|
}
|
|
2278
|
+
var POINT_SHAPES, SIZE_CHARS;
|
|
2279
|
+
var init_render_geoms = __esm(() => {
|
|
2280
|
+
init_scales();
|
|
2281
|
+
POINT_SHAPES = {
|
|
2282
|
+
circle: "●",
|
|
2283
|
+
filled_circle: "●",
|
|
2284
|
+
open_circle: "○",
|
|
2285
|
+
square: "■",
|
|
2286
|
+
open_square: "□",
|
|
2287
|
+
diamond: "◆",
|
|
2288
|
+
open_diamond: "◇",
|
|
2289
|
+
triangle: "▲",
|
|
2290
|
+
open_triangle: "△",
|
|
2291
|
+
cross: "✕",
|
|
2292
|
+
plus: "+",
|
|
2293
|
+
star: "★",
|
|
2294
|
+
dot: "•"
|
|
2295
|
+
};
|
|
2296
|
+
SIZE_CHARS = ["·", "•", "●", "⬤"];
|
|
2297
|
+
});
|
|
2201
2298
|
|
|
2202
2299
|
// src/pipeline/render-axes.ts
|
|
2203
2300
|
function calculateTicks(domain, targetTicks = 5, transform, invert) {
|
|
@@ -2505,7 +2602,6 @@ function renderTitle(canvas, title, width, theme) {
|
|
|
2505
2602
|
}
|
|
2506
2603
|
canvas.drawString(x, 0, title, titleColor);
|
|
2507
2604
|
}
|
|
2508
|
-
var SIZE_SYMBOLS = ["·", "•", "●", "⬤"];
|
|
2509
2605
|
function renderMultiLegend(canvas, entries, x, y, theme, width) {
|
|
2510
2606
|
if (theme.legend.position === "none" || entries.length === 0)
|
|
2511
2607
|
return;
|
|
@@ -2633,6 +2729,10 @@ function formatContinuousLegendValue(value) {
|
|
|
2633
2729
|
}
|
|
2634
2730
|
return value.toFixed(1);
|
|
2635
2731
|
}
|
|
2732
|
+
var SIZE_SYMBOLS;
|
|
2733
|
+
var init_render_axes = __esm(() => {
|
|
2734
|
+
SIZE_SYMBOLS = ["·", "•", "●", "⬤"];
|
|
2735
|
+
});
|
|
2636
2736
|
|
|
2637
2737
|
// src/stats/bin.ts
|
|
2638
2738
|
function computeBins(data, field, params = {}) {
|
|
@@ -2678,71 +2778,313 @@ function computeBins(data, field, params = {}) {
|
|
|
2678
2778
|
} else {
|
|
2679
2779
|
binStart = min;
|
|
2680
2780
|
}
|
|
2681
|
-
const binCounts = new Map;
|
|
2682
|
-
for (const val of values) {
|
|
2683
|
-
const binIndex = Math.floor((val - binStart) / binWidth);
|
|
2684
|
-
binCounts.set(binIndex, (binCounts.get(binIndex) ?? 0) + 1);
|
|
2781
|
+
const binCounts = new Map;
|
|
2782
|
+
for (const val of values) {
|
|
2783
|
+
const binIndex = Math.floor((val - binStart) / binWidth);
|
|
2784
|
+
binCounts.set(binIndex, (binCounts.get(binIndex) ?? 0) + 1);
|
|
2785
|
+
}
|
|
2786
|
+
const bins = [];
|
|
2787
|
+
const maxBinIndex = Math.ceil((max - binStart) / binWidth);
|
|
2788
|
+
for (let i = 0;i <= maxBinIndex; i++) {
|
|
2789
|
+
const count = binCounts.get(i) ?? 0;
|
|
2790
|
+
const xmin = binStart + i * binWidth;
|
|
2791
|
+
const xmax = xmin + binWidth;
|
|
2792
|
+
const x = (xmin + xmax) / 2;
|
|
2793
|
+
bins.push({
|
|
2794
|
+
x,
|
|
2795
|
+
xmin,
|
|
2796
|
+
xmax,
|
|
2797
|
+
count,
|
|
2798
|
+
density: count / (values.length * binWidth)
|
|
2799
|
+
});
|
|
2800
|
+
}
|
|
2801
|
+
return { bins, binWidth };
|
|
2802
|
+
}
|
|
2803
|
+
function stat_bin(params = {}) {
|
|
2804
|
+
return {
|
|
2805
|
+
type: "bin",
|
|
2806
|
+
compute(data, aes) {
|
|
2807
|
+
const groupField = aes.color || aes.fill || aes.group;
|
|
2808
|
+
if (groupField) {
|
|
2809
|
+
const groups = new Map;
|
|
2810
|
+
for (const row of data) {
|
|
2811
|
+
const groupVal = String(row[groupField] ?? "default");
|
|
2812
|
+
if (!groups.has(groupVal)) {
|
|
2813
|
+
groups.set(groupVal, []);
|
|
2814
|
+
}
|
|
2815
|
+
groups.get(groupVal).push(row);
|
|
2816
|
+
}
|
|
2817
|
+
const results = [];
|
|
2818
|
+
for (const [groupVal, groupData] of groups) {
|
|
2819
|
+
const { bins: bins2 } = computeBins(groupData, aes.x, params);
|
|
2820
|
+
for (const bin of bins2) {
|
|
2821
|
+
results.push({
|
|
2822
|
+
x: bin.x,
|
|
2823
|
+
xmin: bin.xmin,
|
|
2824
|
+
xmax: bin.xmax,
|
|
2825
|
+
y: bin.count,
|
|
2826
|
+
count: bin.count,
|
|
2827
|
+
density: bin.density,
|
|
2828
|
+
[groupField]: groupVal
|
|
2829
|
+
});
|
|
2830
|
+
}
|
|
2831
|
+
}
|
|
2832
|
+
return results;
|
|
2833
|
+
}
|
|
2834
|
+
const { bins } = computeBins(data, aes.x, params);
|
|
2835
|
+
return bins.map((bin) => ({
|
|
2836
|
+
x: bin.x,
|
|
2837
|
+
xmin: bin.xmin,
|
|
2838
|
+
xmax: bin.xmax,
|
|
2839
|
+
y: bin.count,
|
|
2840
|
+
count: bin.count,
|
|
2841
|
+
density: bin.density
|
|
2842
|
+
}));
|
|
2843
|
+
}
|
|
2844
|
+
};
|
|
2845
|
+
}
|
|
2846
|
+
|
|
2847
|
+
// src/performance/binning.ts
|
|
2848
|
+
function computeDomain2(data, field) {
|
|
2849
|
+
let min = Infinity;
|
|
2850
|
+
let max = -Infinity;
|
|
2851
|
+
for (const d of data) {
|
|
2852
|
+
const v = d[field];
|
|
2853
|
+
if (typeof v === "number" && !isNaN(v)) {
|
|
2854
|
+
if (v < min)
|
|
2855
|
+
min = v;
|
|
2856
|
+
if (v > max)
|
|
2857
|
+
max = v;
|
|
2858
|
+
}
|
|
2859
|
+
}
|
|
2860
|
+
if (min === Infinity)
|
|
2861
|
+
return [0, 1];
|
|
2862
|
+
if (min === max)
|
|
2863
|
+
return [min - 0.5, max + 0.5];
|
|
2864
|
+
return [min, max];
|
|
2865
|
+
}
|
|
2866
|
+
function aggregateValues(values, method) {
|
|
2867
|
+
if (values.length === 0)
|
|
2868
|
+
return 0;
|
|
2869
|
+
switch (method) {
|
|
2870
|
+
case "count":
|
|
2871
|
+
return values.length;
|
|
2872
|
+
case "sum":
|
|
2873
|
+
return values.reduce((a, b) => a + b, 0);
|
|
2874
|
+
case "mean":
|
|
2875
|
+
return values.reduce((a, b) => a + b, 0) / values.length;
|
|
2876
|
+
case "median":
|
|
2877
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
2878
|
+
const mid = Math.floor(sorted.length / 2);
|
|
2879
|
+
return sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
|
|
2880
|
+
case "min":
|
|
2881
|
+
return Math.min(...values);
|
|
2882
|
+
case "max":
|
|
2883
|
+
return Math.max(...values);
|
|
2884
|
+
default:
|
|
2885
|
+
return values.length;
|
|
2886
|
+
}
|
|
2887
|
+
}
|
|
2888
|
+
function rectbin(data, options) {
|
|
2889
|
+
const {
|
|
2890
|
+
xField,
|
|
2891
|
+
yField,
|
|
2892
|
+
xBins = 20,
|
|
2893
|
+
yBins = 20,
|
|
2894
|
+
aggregate = "count",
|
|
2895
|
+
valueField
|
|
2896
|
+
} = options;
|
|
2897
|
+
if (data.length === 0)
|
|
2898
|
+
return [];
|
|
2899
|
+
const xDomain = options.xDomain ?? computeDomain2(data, xField);
|
|
2900
|
+
const yDomain = options.yDomain ?? computeDomain2(data, yField);
|
|
2901
|
+
const xRange = xDomain[1] - xDomain[0];
|
|
2902
|
+
const yRange = yDomain[1] - yDomain[0];
|
|
2903
|
+
const binWidth = xRange / xBins;
|
|
2904
|
+
const binHeight = yRange / yBins;
|
|
2905
|
+
const bins = new Map;
|
|
2906
|
+
for (const point of data) {
|
|
2907
|
+
const x = point[xField];
|
|
2908
|
+
const y = point[yField];
|
|
2909
|
+
if (typeof x !== "number" || typeof y !== "number")
|
|
2910
|
+
continue;
|
|
2911
|
+
const bx = Math.min(xBins - 1, Math.max(0, Math.floor((x - xDomain[0]) / binWidth)));
|
|
2912
|
+
const by = Math.min(yBins - 1, Math.max(0, Math.floor((y - yDomain[0]) / binHeight)));
|
|
2913
|
+
const key = `${bx},${by}`;
|
|
2914
|
+
if (!bins.has(key)) {
|
|
2915
|
+
bins.set(key, { points: [], values: [] });
|
|
2916
|
+
}
|
|
2917
|
+
const bin = bins.get(key);
|
|
2918
|
+
bin.points.push(point);
|
|
2919
|
+
if (valueField && typeof point[valueField] === "number") {
|
|
2920
|
+
bin.values.push(point[valueField]);
|
|
2921
|
+
}
|
|
2922
|
+
}
|
|
2923
|
+
const result = [];
|
|
2924
|
+
for (const [key, bin] of bins) {
|
|
2925
|
+
const [bx, by] = key.split(",").map(Number);
|
|
2926
|
+
const centerX = xDomain[0] + (bx + 0.5) * binWidth;
|
|
2927
|
+
const centerY = yDomain[0] + (by + 0.5) * binHeight;
|
|
2928
|
+
result.push({
|
|
2929
|
+
x: centerX,
|
|
2930
|
+
y: centerY,
|
|
2931
|
+
count: bin.points.length,
|
|
2932
|
+
value: aggregateValues(bin.values.length > 0 ? bin.values : [bin.points.length], aggregate),
|
|
2933
|
+
width: binWidth,
|
|
2934
|
+
height: binHeight,
|
|
2935
|
+
points: bin.points
|
|
2936
|
+
});
|
|
2937
|
+
}
|
|
2938
|
+
return result;
|
|
2939
|
+
}
|
|
2940
|
+
function hexbin(data, options) {
|
|
2941
|
+
const { xField, yField, aggregate = "count", valueField, radius = 10 } = options;
|
|
2942
|
+
if (data.length === 0)
|
|
2943
|
+
return [];
|
|
2944
|
+
const xDomain = options.xDomain ?? computeDomain2(data, xField);
|
|
2945
|
+
const yDomain = options.yDomain ?? computeDomain2(data, yField);
|
|
2946
|
+
const hexWidth = radius * 2;
|
|
2947
|
+
const hexHeight = radius * Math.sqrt(3);
|
|
2948
|
+
const bins = new Map;
|
|
2949
|
+
for (const point of data) {
|
|
2950
|
+
const x = point[xField];
|
|
2951
|
+
const y = point[yField];
|
|
2952
|
+
if (typeof x !== "number" || typeof y !== "number")
|
|
2953
|
+
continue;
|
|
2954
|
+
const col = Math.round((x - xDomain[0]) / (hexWidth * 0.75));
|
|
2955
|
+
const row = Math.round((y - yDomain[0]) / hexHeight - col % 2 * 0.5);
|
|
2956
|
+
const key = `${col},${row}`;
|
|
2957
|
+
if (!bins.has(key)) {
|
|
2958
|
+
bins.set(key, { points: [], values: [], col, row });
|
|
2959
|
+
}
|
|
2960
|
+
const bin = bins.get(key);
|
|
2961
|
+
bin.points.push(point);
|
|
2962
|
+
if (valueField && typeof point[valueField] === "number") {
|
|
2963
|
+
bin.values.push(point[valueField]);
|
|
2964
|
+
}
|
|
2965
|
+
}
|
|
2966
|
+
function hexVertices(cx, cy, r) {
|
|
2967
|
+
const vertices = [];
|
|
2968
|
+
for (let i = 0;i < 6; i++) {
|
|
2969
|
+
const angle = Math.PI / 3 * i + Math.PI / 6;
|
|
2970
|
+
vertices.push({
|
|
2971
|
+
x: cx + r * Math.cos(angle),
|
|
2972
|
+
y: cy + r * Math.sin(angle)
|
|
2973
|
+
});
|
|
2974
|
+
}
|
|
2975
|
+
return vertices;
|
|
2976
|
+
}
|
|
2977
|
+
const result = [];
|
|
2978
|
+
for (const [, bin] of bins) {
|
|
2979
|
+
const centerX = xDomain[0] + bin.col * hexWidth * 0.75;
|
|
2980
|
+
const centerY = yDomain[0] + (bin.row + bin.col % 2 * 0.5) * hexHeight;
|
|
2981
|
+
result.push({
|
|
2982
|
+
x: centerX,
|
|
2983
|
+
y: centerY,
|
|
2984
|
+
count: bin.points.length,
|
|
2985
|
+
value: aggregateValues(bin.values.length > 0 ? bin.values : [bin.points.length], aggregate),
|
|
2986
|
+
width: hexWidth,
|
|
2987
|
+
height: hexHeight,
|
|
2988
|
+
points: bin.points,
|
|
2989
|
+
vertices: hexVertices(centerX, centerY, radius),
|
|
2990
|
+
col: bin.col,
|
|
2991
|
+
row: bin.row
|
|
2992
|
+
});
|
|
2993
|
+
}
|
|
2994
|
+
return result;
|
|
2995
|
+
}
|
|
2996
|
+
|
|
2997
|
+
class Binner {
|
|
2998
|
+
options;
|
|
2999
|
+
type;
|
|
3000
|
+
hexRadius;
|
|
3001
|
+
constructor(options) {
|
|
3002
|
+
this.options = options;
|
|
3003
|
+
this.type = options.type ?? "rect";
|
|
3004
|
+
this.hexRadius = options.hexRadius ?? 10;
|
|
3005
|
+
}
|
|
3006
|
+
bin(data) {
|
|
3007
|
+
if (this.type === "hex") {
|
|
3008
|
+
return hexbin(data, { ...this.options, radius: this.hexRadius });
|
|
3009
|
+
}
|
|
3010
|
+
return rectbin(data, this.options);
|
|
3011
|
+
}
|
|
3012
|
+
toPlotData(data) {
|
|
3013
|
+
const bins = this.bin(data);
|
|
3014
|
+
const maxCount = Math.max(...bins.map((b) => b.count));
|
|
3015
|
+
const minSize = 1;
|
|
3016
|
+
const maxSize = 5;
|
|
3017
|
+
return bins.map((bin) => ({
|
|
3018
|
+
x: bin.x,
|
|
3019
|
+
y: bin.y,
|
|
3020
|
+
count: bin.count,
|
|
3021
|
+
value: bin.value,
|
|
3022
|
+
size: minSize + bin.count / maxCount * (maxSize - minSize)
|
|
3023
|
+
}));
|
|
3024
|
+
}
|
|
3025
|
+
getDensityColors(bins, colorScale) {
|
|
3026
|
+
const maxCount = Math.max(...bins.map((b) => b.count));
|
|
3027
|
+
const colors = new Map;
|
|
3028
|
+
for (const bin of bins) {
|
|
3029
|
+
const t = bin.count / maxCount;
|
|
3030
|
+
colors.set(bin, colorScale(t));
|
|
3031
|
+
}
|
|
3032
|
+
return colors;
|
|
2685
3033
|
}
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
3034
|
+
}
|
|
3035
|
+
function createBinner(options) {
|
|
3036
|
+
return new Binner(options);
|
|
3037
|
+
}
|
|
3038
|
+
|
|
3039
|
+
// src/stats/bin2d.ts
|
|
3040
|
+
function computeBins2d(data, xField, yField, params = {}) {
|
|
3041
|
+
const {
|
|
3042
|
+
bins = 30,
|
|
3043
|
+
binsx,
|
|
3044
|
+
binsy,
|
|
3045
|
+
drop = true
|
|
3046
|
+
} = params;
|
|
3047
|
+
const xBins = binsx ?? bins;
|
|
3048
|
+
const yBins = binsy ?? bins;
|
|
3049
|
+
const binned = rectbin(data, {
|
|
3050
|
+
xField,
|
|
3051
|
+
yField,
|
|
3052
|
+
xBins,
|
|
3053
|
+
yBins,
|
|
3054
|
+
aggregate: "count"
|
|
3055
|
+
});
|
|
3056
|
+
const total = data.length;
|
|
3057
|
+
const results = binned.map((bin) => ({
|
|
3058
|
+
x: bin.x,
|
|
3059
|
+
y: bin.y,
|
|
3060
|
+
count: bin.count,
|
|
3061
|
+
density: total > 0 ? bin.count / total : 0,
|
|
3062
|
+
width: bin.width,
|
|
3063
|
+
height: bin.height
|
|
3064
|
+
}));
|
|
3065
|
+
if (drop) {
|
|
3066
|
+
return results.filter((r) => r.count > 0);
|
|
2700
3067
|
}
|
|
2701
|
-
return
|
|
3068
|
+
return results;
|
|
2702
3069
|
}
|
|
2703
|
-
function
|
|
3070
|
+
function stat_bin2d(params = {}) {
|
|
2704
3071
|
return {
|
|
2705
|
-
type: "
|
|
3072
|
+
type: "bin2d",
|
|
2706
3073
|
compute(data, aes) {
|
|
2707
|
-
const
|
|
2708
|
-
if (groupField) {
|
|
2709
|
-
const groups = new Map;
|
|
2710
|
-
for (const row of data) {
|
|
2711
|
-
const groupVal = String(row[groupField] ?? "default");
|
|
2712
|
-
if (!groups.has(groupVal)) {
|
|
2713
|
-
groups.set(groupVal, []);
|
|
2714
|
-
}
|
|
2715
|
-
groups.get(groupVal).push(row);
|
|
2716
|
-
}
|
|
2717
|
-
const results = [];
|
|
2718
|
-
for (const [groupVal, groupData] of groups) {
|
|
2719
|
-
const { bins: bins2 } = computeBins(groupData, aes.x, params);
|
|
2720
|
-
for (const bin of bins2) {
|
|
2721
|
-
results.push({
|
|
2722
|
-
x: bin.x,
|
|
2723
|
-
xmin: bin.xmin,
|
|
2724
|
-
xmax: bin.xmax,
|
|
2725
|
-
y: bin.count,
|
|
2726
|
-
count: bin.count,
|
|
2727
|
-
density: bin.density,
|
|
2728
|
-
[groupField]: groupVal
|
|
2729
|
-
});
|
|
2730
|
-
}
|
|
2731
|
-
}
|
|
2732
|
-
return results;
|
|
2733
|
-
}
|
|
2734
|
-
const { bins } = computeBins(data, aes.x, params);
|
|
3074
|
+
const bins = computeBins2d(data, aes.x, aes.y, params);
|
|
2735
3075
|
return bins.map((bin) => ({
|
|
2736
3076
|
x: bin.x,
|
|
2737
|
-
|
|
2738
|
-
xmax: bin.xmax,
|
|
2739
|
-
y: bin.count,
|
|
3077
|
+
y: bin.y,
|
|
2740
3078
|
count: bin.count,
|
|
2741
|
-
density: bin.density
|
|
3079
|
+
density: bin.density,
|
|
3080
|
+
fill: bin.count,
|
|
3081
|
+
width: bin.width,
|
|
3082
|
+
height: bin.height
|
|
2742
3083
|
}));
|
|
2743
3084
|
}
|
|
2744
3085
|
};
|
|
2745
3086
|
}
|
|
3087
|
+
var init_bin2d = () => {};
|
|
2746
3088
|
|
|
2747
3089
|
// src/stats/boxplot.ts
|
|
2748
3090
|
function quantile(sorted, p) {
|
|
@@ -3159,17 +3501,6 @@ function stat_smooth(params = {}) {
|
|
|
3159
3501
|
}
|
|
3160
3502
|
|
|
3161
3503
|
// src/stats/summary.ts
|
|
3162
|
-
var summaryFunctions = {
|
|
3163
|
-
mean: (values) => values.reduce((a, b) => a + b, 0) / values.length,
|
|
3164
|
-
median: (values) => {
|
|
3165
|
-
const sorted = [...values].sort((a, b) => a - b);
|
|
3166
|
-
const mid = Math.floor(sorted.length / 2);
|
|
3167
|
-
return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;
|
|
3168
|
-
},
|
|
3169
|
-
min: (values) => Math.min(...values),
|
|
3170
|
-
max: (values) => Math.max(...values),
|
|
3171
|
-
sum: (values) => values.reduce((a, b) => a + b, 0)
|
|
3172
|
-
};
|
|
3173
3504
|
function sd(values) {
|
|
3174
3505
|
const n = values.length;
|
|
3175
3506
|
if (n < 2)
|
|
@@ -3301,6 +3632,20 @@ function stat_summary(params = {}) {
|
|
|
3301
3632
|
}
|
|
3302
3633
|
};
|
|
3303
3634
|
}
|
|
3635
|
+
var summaryFunctions;
|
|
3636
|
+
var init_summary = __esm(() => {
|
|
3637
|
+
summaryFunctions = {
|
|
3638
|
+
mean: (values) => values.reduce((a, b) => a + b, 0) / values.length,
|
|
3639
|
+
median: (values) => {
|
|
3640
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
3641
|
+
const mid = Math.floor(sorted.length / 2);
|
|
3642
|
+
return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;
|
|
3643
|
+
},
|
|
3644
|
+
min: (values) => Math.min(...values),
|
|
3645
|
+
max: (values) => Math.max(...values),
|
|
3646
|
+
sum: (values) => values.reduce((a, b) => a + b, 0)
|
|
3647
|
+
};
|
|
3648
|
+
});
|
|
3304
3649
|
|
|
3305
3650
|
// src/stats/qq.ts
|
|
3306
3651
|
function qnorm(p, mean = 0, sd2 = 1) {
|
|
@@ -3483,15 +3828,125 @@ function stat_qq_line(params = {}) {
|
|
|
3483
3828
|
};
|
|
3484
3829
|
}
|
|
3485
3830
|
|
|
3831
|
+
// src/stats/density2d.ts
|
|
3832
|
+
function gaussian2d(dx, dy, hx, hy) {
|
|
3833
|
+
const ux = dx / hx;
|
|
3834
|
+
const uy = dy / hy;
|
|
3835
|
+
return Math.exp(-0.5 * (ux * ux + uy * uy)) / (2 * Math.PI * hx * hy);
|
|
3836
|
+
}
|
|
3837
|
+
function scottBandwidth2d(values) {
|
|
3838
|
+
const n = values.length;
|
|
3839
|
+
if (n < 2)
|
|
3840
|
+
return 1;
|
|
3841
|
+
const mean = values.reduce((a, b) => a + b, 0) / n;
|
|
3842
|
+
const variance = values.reduce((sum, v) => sum + (v - mean) ** 2, 0) / (n - 1);
|
|
3843
|
+
const std = Math.sqrt(variance);
|
|
3844
|
+
return std * Math.pow(n, -1 / 6);
|
|
3845
|
+
}
|
|
3846
|
+
function computeDensity2d(data, xField, yField, params = {}) {
|
|
3847
|
+
const points = [];
|
|
3848
|
+
const xValues = [];
|
|
3849
|
+
const yValues = [];
|
|
3850
|
+
for (const row of data) {
|
|
3851
|
+
const xVal = row[xField];
|
|
3852
|
+
const yVal = row[yField];
|
|
3853
|
+
if (xVal === null || xVal === undefined || yVal === null || yVal === undefined)
|
|
3854
|
+
continue;
|
|
3855
|
+
const x = Number(xVal);
|
|
3856
|
+
const y = Number(yVal);
|
|
3857
|
+
if (isNaN(x) || isNaN(y))
|
|
3858
|
+
continue;
|
|
3859
|
+
points.push({ x, y });
|
|
3860
|
+
xValues.push(x);
|
|
3861
|
+
yValues.push(y);
|
|
3862
|
+
}
|
|
3863
|
+
if (points.length < 3) {
|
|
3864
|
+
return [];
|
|
3865
|
+
}
|
|
3866
|
+
const n = params.n ?? 50;
|
|
3867
|
+
const nx = params.nx ?? n;
|
|
3868
|
+
const ny = params.ny ?? n;
|
|
3869
|
+
const adjust = params.adjust ?? 1;
|
|
3870
|
+
let hx, hy;
|
|
3871
|
+
if (Array.isArray(params.h)) {
|
|
3872
|
+
hx = params.h[0] * adjust;
|
|
3873
|
+
hy = params.h[1] * adjust;
|
|
3874
|
+
} else if (params.h !== undefined) {
|
|
3875
|
+
hx = params.h * adjust;
|
|
3876
|
+
hy = params.h * adjust;
|
|
3877
|
+
} else {
|
|
3878
|
+
hx = scottBandwidth2d(xValues) * adjust;
|
|
3879
|
+
hy = scottBandwidth2d(yValues) * adjust;
|
|
3880
|
+
}
|
|
3881
|
+
if (hx <= 0)
|
|
3882
|
+
hx = 1;
|
|
3883
|
+
if (hy <= 0)
|
|
3884
|
+
hy = 1;
|
|
3885
|
+
const xMin = Math.min(...xValues);
|
|
3886
|
+
const xMax = Math.max(...xValues);
|
|
3887
|
+
const yMin = Math.min(...yValues);
|
|
3888
|
+
const yMax = Math.max(...yValues);
|
|
3889
|
+
const xPad = 3 * hx;
|
|
3890
|
+
const yPad = 3 * hy;
|
|
3891
|
+
const gridXMin = xMin - xPad;
|
|
3892
|
+
const gridXMax = xMax + xPad;
|
|
3893
|
+
const gridYMin = yMin - yPad;
|
|
3894
|
+
const gridYMax = yMax + yPad;
|
|
3895
|
+
const xStep = (gridXMax - gridXMin) / (nx - 1);
|
|
3896
|
+
const yStep = (gridYMax - gridYMin) / (ny - 1);
|
|
3897
|
+
const results = [];
|
|
3898
|
+
const nPoints = points.length;
|
|
3899
|
+
for (let i = 0;i < nx; i++) {
|
|
3900
|
+
const gx = gridXMin + i * xStep;
|
|
3901
|
+
for (let j = 0;j < ny; j++) {
|
|
3902
|
+
const gy = gridYMin + j * yStep;
|
|
3903
|
+
let density = 0;
|
|
3904
|
+
for (const pt of points) {
|
|
3905
|
+
density += gaussian2d(gx - pt.x, gy - pt.y, hx, hy);
|
|
3906
|
+
}
|
|
3907
|
+
density /= nPoints;
|
|
3908
|
+
results.push({
|
|
3909
|
+
x: gx,
|
|
3910
|
+
y: gy,
|
|
3911
|
+
z: density,
|
|
3912
|
+
density,
|
|
3913
|
+
level: density
|
|
3914
|
+
});
|
|
3915
|
+
}
|
|
3916
|
+
}
|
|
3917
|
+
return results;
|
|
3918
|
+
}
|
|
3919
|
+
function stat_density_2d(params = {}) {
|
|
3920
|
+
return {
|
|
3921
|
+
type: "density_2d",
|
|
3922
|
+
compute(data, aes) {
|
|
3923
|
+
if (aes.color) {
|
|
3924
|
+
const groups = new Map;
|
|
3925
|
+
for (const row of data) {
|
|
3926
|
+
const group = String(row[aes.color] ?? "default");
|
|
3927
|
+
if (!groups.has(group)) {
|
|
3928
|
+
groups.set(group, []);
|
|
3929
|
+
}
|
|
3930
|
+
groups.get(group).push(row);
|
|
3931
|
+
}
|
|
3932
|
+
const result = [];
|
|
3933
|
+
for (const [group, groupData] of groups) {
|
|
3934
|
+
const density = computeDensity2d(groupData, aes.x, aes.y, params);
|
|
3935
|
+
for (const d of density) {
|
|
3936
|
+
result.push({
|
|
3937
|
+
...d,
|
|
3938
|
+
[aes.color]: group
|
|
3939
|
+
});
|
|
3940
|
+
}
|
|
3941
|
+
}
|
|
3942
|
+
return result;
|
|
3943
|
+
}
|
|
3944
|
+
return computeDensity2d(data, aes.x, aes.y, params);
|
|
3945
|
+
}
|
|
3946
|
+
};
|
|
3947
|
+
}
|
|
3948
|
+
|
|
3486
3949
|
// src/facets/index.ts
|
|
3487
|
-
var label_value = (value) => value;
|
|
3488
|
-
var label_both = (value, variable) => variable ? `${variable}: ${value}` : value;
|
|
3489
|
-
var label_parsed = (value) => value.replace(/_/g, " ");
|
|
3490
|
-
var label_wrap = (width) => (value) => {
|
|
3491
|
-
if (value.length <= width)
|
|
3492
|
-
return value;
|
|
3493
|
-
return value.substring(0, width - 1) + "…";
|
|
3494
|
-
};
|
|
3495
3950
|
function as_labeller(labels) {
|
|
3496
3951
|
return (value) => labels[value] ?? value;
|
|
3497
3952
|
}
|
|
@@ -3684,6 +4139,11 @@ function calculateGridStripLayout(totalWidth, totalHeight, nrow, ncol, hasTitle,
|
|
|
3684
4139
|
rowStripWidth: rowStripWidth - 1
|
|
3685
4140
|
};
|
|
3686
4141
|
}
|
|
4142
|
+
var label_value = (value) => value, label_both = (value, variable) => variable ? `${variable}: ${value}` : value, label_parsed = (value) => value.replace(/_/g, " "), label_wrap = (width) => (value) => {
|
|
4143
|
+
if (value.length <= width)
|
|
4144
|
+
return value;
|
|
4145
|
+
return value.substring(0, width - 1) + "…";
|
|
4146
|
+
};
|
|
3687
4147
|
|
|
3688
4148
|
// src/pipeline/pipeline.ts
|
|
3689
4149
|
function calculateLayout(spec, options) {
|
|
@@ -3796,6 +4256,23 @@ function applyStatTransform(data, geom, aes) {
|
|
|
3796
4256
|
dparams: geom.params.dparams
|
|
3797
4257
|
});
|
|
3798
4258
|
return qqLineStat.compute(data, aes);
|
|
4259
|
+
} else if (geom.stat === "bin2d") {
|
|
4260
|
+
const bin2dStat = stat_bin2d({
|
|
4261
|
+
bins: geom.params.bins,
|
|
4262
|
+
binsx: geom.params.binsx,
|
|
4263
|
+
binsy: geom.params.binsy,
|
|
4264
|
+
drop: geom.params.drop
|
|
4265
|
+
});
|
|
4266
|
+
return bin2dStat.compute(data, aes);
|
|
4267
|
+
} else if (geom.stat === "density_2d") {
|
|
4268
|
+
const density2dStat = stat_density_2d({
|
|
4269
|
+
h: geom.params.bandwidth,
|
|
4270
|
+
n: geom.params.n,
|
|
4271
|
+
nx: geom.params.nx,
|
|
4272
|
+
ny: geom.params.ny,
|
|
4273
|
+
adjust: geom.params.adjust
|
|
4274
|
+
});
|
|
4275
|
+
return density2dStat.compute(data, aes);
|
|
3799
4276
|
}
|
|
3800
4277
|
return data;
|
|
3801
4278
|
}
|
|
@@ -3860,6 +4337,14 @@ function renderToCanvas(spec, options) {
|
|
|
3860
4337
|
scaleAes = { ...spec.aes, x: "x", y: "y" };
|
|
3861
4338
|
}
|
|
3862
4339
|
break;
|
|
4340
|
+
} else if (geom.stat === "bin2d") {
|
|
4341
|
+
scaleData = applyStatTransform(spec.data, geom, spec.aes);
|
|
4342
|
+
scaleAes = { ...spec.aes, x: "x", y: "y", fill: "fill" };
|
|
4343
|
+
break;
|
|
4344
|
+
} else if (geom.stat === "density_2d") {
|
|
4345
|
+
scaleData = applyStatTransform(spec.data, geom, spec.aes);
|
|
4346
|
+
scaleAes = { ...spec.aes, x: "x", y: "y" };
|
|
4347
|
+
break;
|
|
3863
4348
|
}
|
|
3864
4349
|
}
|
|
3865
4350
|
scaleData = applyCoordTransform(scaleData, scaleAes, spec.coord);
|
|
@@ -3894,6 +4379,10 @@ function renderToCanvas(spec, options) {
|
|
|
3894
4379
|
geomAes = { ...spec.aes, x: "x", y: "y" };
|
|
3895
4380
|
} else if (geom.stat === "qq_line") {
|
|
3896
4381
|
geomAes = { ...spec.aes, x: "x", y: "y", xend: "xend", yend: "yend" };
|
|
4382
|
+
} else if (geom.stat === "bin2d") {
|
|
4383
|
+
geomAes = { ...spec.aes, x: "x", y: "y", fill: "fill" };
|
|
4384
|
+
} else if (geom.stat === "density_2d") {
|
|
4385
|
+
geomAes = { ...spec.aes, x: "x", y: "y" };
|
|
3897
4386
|
}
|
|
3898
4387
|
geomData = applyCoordTransform(geomData, geomAes, spec.coord);
|
|
3899
4388
|
}
|
|
@@ -4144,8 +4633,14 @@ function renderPanel(canvas, panel, layout, spec, facet, sharedScales, nrow = 1,
|
|
|
4144
4633
|
renderPanelAxes(canvas, scales, plotArea, panel.row, panel.col, nrow, ncol, spec.theme);
|
|
4145
4634
|
for (const geom of spec.geoms) {
|
|
4146
4635
|
let geomData = applyStatTransform(panel.data, geom, spec.aes);
|
|
4147
|
-
|
|
4148
|
-
|
|
4636
|
+
let geomAes = spec.aes;
|
|
4637
|
+
if (geom.stat === "bin" || geom.stat === "boxplot" || geom.stat === "count" || geom.stat === "qq") {
|
|
4638
|
+
geomAes = { ...spec.aes, x: "x", y: "y" };
|
|
4639
|
+
} else if (geom.stat === "bin2d") {
|
|
4640
|
+
geomAes = { ...spec.aes, x: "x", y: "y", fill: "fill" };
|
|
4641
|
+
}
|
|
4642
|
+
geomData = applyCoordTransform(geomData, geomAes, spec.coord);
|
|
4643
|
+
renderGeom(geomData, geom, geomAes, scales, canvas, spec.coord.type);
|
|
4149
4644
|
}
|
|
4150
4645
|
}
|
|
4151
4646
|
function renderPanelAxes(canvas, scales, plotArea, row, col, nrow, _ncol, _theme) {
|
|
@@ -4193,9 +4688,22 @@ function renderToString(spec, options) {
|
|
|
4193
4688
|
}
|
|
4194
4689
|
return canvas.toAnsiString();
|
|
4195
4690
|
}
|
|
4691
|
+
var init_pipeline = __esm(() => {
|
|
4692
|
+
init_canvas();
|
|
4693
|
+
init_scales();
|
|
4694
|
+
init_render_geoms();
|
|
4695
|
+
init_render_axes();
|
|
4696
|
+
init_bin2d();
|
|
4697
|
+
init_summary();
|
|
4698
|
+
});
|
|
4196
4699
|
|
|
4197
4700
|
// src/pipeline/index.ts
|
|
4198
|
-
|
|
4701
|
+
var init_pipeline2 = __esm(() => {
|
|
4702
|
+
init_pipeline();
|
|
4703
|
+
init_scales();
|
|
4704
|
+
init_render_geoms();
|
|
4705
|
+
init_render_axes();
|
|
4706
|
+
});
|
|
4199
4707
|
|
|
4200
4708
|
// src/grammar.ts
|
|
4201
4709
|
class GGPlot {
|
|
@@ -4286,6 +4794,15 @@ class GGPlot {
|
|
|
4286
4794
|
function gg(data = []) {
|
|
4287
4795
|
return new GGPlot(data);
|
|
4288
4796
|
}
|
|
4797
|
+
var init_grammar = __esm(() => {
|
|
4798
|
+
init_pipeline2();
|
|
4799
|
+
});
|
|
4800
|
+
|
|
4801
|
+
// src/canvas/index.ts
|
|
4802
|
+
var init_canvas2 = __esm(() => {
|
|
4803
|
+
init_canvas();
|
|
4804
|
+
});
|
|
4805
|
+
|
|
4289
4806
|
// src/geoms/point.ts
|
|
4290
4807
|
function geom_point(options = {}) {
|
|
4291
4808
|
return {
|
|
@@ -4300,6 +4817,7 @@ function geom_point(options = {}) {
|
|
|
4300
4817
|
}
|
|
4301
4818
|
};
|
|
4302
4819
|
}
|
|
4820
|
+
|
|
4303
4821
|
// src/geoms/line.ts
|
|
4304
4822
|
function geom_line(options = {}) {
|
|
4305
4823
|
return {
|
|
@@ -4338,6 +4856,7 @@ function geom_vline(options) {
|
|
|
4338
4856
|
}
|
|
4339
4857
|
};
|
|
4340
4858
|
}
|
|
4859
|
+
|
|
4341
4860
|
// src/geoms/path.ts
|
|
4342
4861
|
function geom_path(options = {}) {
|
|
4343
4862
|
return {
|
|
@@ -4354,6 +4873,7 @@ function geom_path(options = {}) {
|
|
|
4354
4873
|
}
|
|
4355
4874
|
};
|
|
4356
4875
|
}
|
|
4876
|
+
|
|
4357
4877
|
// src/geoms/bar.ts
|
|
4358
4878
|
function geom_bar(options = {}) {
|
|
4359
4879
|
return {
|
|
@@ -4371,6 +4891,7 @@ function geom_bar(options = {}) {
|
|
|
4371
4891
|
function geom_col(options = {}) {
|
|
4372
4892
|
return geom_bar({ ...options, stat: "identity" });
|
|
4373
4893
|
}
|
|
4894
|
+
|
|
4374
4895
|
// src/geoms/text.ts
|
|
4375
4896
|
function geom_text(options = {}) {
|
|
4376
4897
|
return {
|
|
@@ -4403,6 +4924,7 @@ function geom_label(options = {}) {
|
|
|
4403
4924
|
}
|
|
4404
4925
|
};
|
|
4405
4926
|
}
|
|
4927
|
+
|
|
4406
4928
|
// src/geoms/area.ts
|
|
4407
4929
|
function geom_area(options = {}) {
|
|
4408
4930
|
return {
|
|
@@ -4428,6 +4950,7 @@ function geom_ribbon(options = {}) {
|
|
|
4428
4950
|
}
|
|
4429
4951
|
};
|
|
4430
4952
|
}
|
|
4953
|
+
|
|
4431
4954
|
// src/geoms/histogram.ts
|
|
4432
4955
|
function geom_histogram(options = {}) {
|
|
4433
4956
|
return {
|
|
@@ -4459,6 +4982,7 @@ function geom_freqpoly(options = {}) {
|
|
|
4459
4982
|
}
|
|
4460
4983
|
};
|
|
4461
4984
|
}
|
|
4985
|
+
|
|
4462
4986
|
// src/geoms/boxplot.ts
|
|
4463
4987
|
function geom_boxplot(options = {}) {
|
|
4464
4988
|
return {
|
|
@@ -4475,6 +4999,7 @@ function geom_boxplot(options = {}) {
|
|
|
4475
4999
|
}
|
|
4476
5000
|
};
|
|
4477
5001
|
}
|
|
5002
|
+
|
|
4478
5003
|
// src/geoms/segment.ts
|
|
4479
5004
|
function geom_segment(options = {}) {
|
|
4480
5005
|
return {
|
|
@@ -4507,6 +5032,7 @@ function geom_curve(options = {}) {
|
|
|
4507
5032
|
}
|
|
4508
5033
|
};
|
|
4509
5034
|
}
|
|
5035
|
+
|
|
4510
5036
|
// src/geoms/smooth.ts
|
|
4511
5037
|
function geom_smooth(options = {}) {
|
|
4512
5038
|
return {
|
|
@@ -4526,6 +5052,7 @@ function geom_smooth(options = {}) {
|
|
|
4526
5052
|
}
|
|
4527
5053
|
};
|
|
4528
5054
|
}
|
|
5055
|
+
|
|
4529
5056
|
// src/geoms/step.ts
|
|
4530
5057
|
function geom_step(options = {}) {
|
|
4531
5058
|
return {
|
|
@@ -4541,6 +5068,7 @@ function geom_step(options = {}) {
|
|
|
4541
5068
|
}
|
|
4542
5069
|
};
|
|
4543
5070
|
}
|
|
5071
|
+
|
|
4544
5072
|
// src/geoms/rug.ts
|
|
4545
5073
|
function geom_rug(options = {}) {
|
|
4546
5074
|
return {
|
|
@@ -4556,6 +5084,7 @@ function geom_rug(options = {}) {
|
|
|
4556
5084
|
}
|
|
4557
5085
|
};
|
|
4558
5086
|
}
|
|
5087
|
+
|
|
4559
5088
|
// src/geoms/violin.ts
|
|
4560
5089
|
function geom_violin(options = {}) {
|
|
4561
5090
|
return {
|
|
@@ -4573,6 +5102,7 @@ function geom_violin(options = {}) {
|
|
|
4573
5102
|
}
|
|
4574
5103
|
};
|
|
4575
5104
|
}
|
|
5105
|
+
|
|
4576
5106
|
// src/geoms/tile.ts
|
|
4577
5107
|
function geom_tile(options = {}) {
|
|
4578
5108
|
return {
|
|
@@ -4591,6 +5121,22 @@ function geom_tile(options = {}) {
|
|
|
4591
5121
|
function geom_raster(options = {}) {
|
|
4592
5122
|
return geom_tile(options);
|
|
4593
5123
|
}
|
|
5124
|
+
|
|
5125
|
+
// src/geoms/bin2d.ts
|
|
5126
|
+
function geom_bin2d(options = {}) {
|
|
5127
|
+
return {
|
|
5128
|
+
type: "bin2d",
|
|
5129
|
+
stat: "bin2d",
|
|
5130
|
+
params: {
|
|
5131
|
+
bins: options.bins ?? 30,
|
|
5132
|
+
binsx: options.binsx,
|
|
5133
|
+
binsy: options.binsy,
|
|
5134
|
+
alpha: options.alpha ?? 1,
|
|
5135
|
+
drop: options.drop ?? true
|
|
5136
|
+
}
|
|
5137
|
+
};
|
|
5138
|
+
}
|
|
5139
|
+
|
|
4594
5140
|
// src/geoms/contour.ts
|
|
4595
5141
|
function geom_contour(options = {}) {
|
|
4596
5142
|
return {
|
|
@@ -4633,6 +5179,7 @@ function geom_density_2d(options = {}) {
|
|
|
4633
5179
|
}
|
|
4634
5180
|
};
|
|
4635
5181
|
}
|
|
5182
|
+
|
|
4636
5183
|
// src/geoms/errorbar.ts
|
|
4637
5184
|
function geom_errorbar(options = {}) {
|
|
4638
5185
|
return {
|
|
@@ -4699,6 +5246,7 @@ function geom_pointrange(options = {}) {
|
|
|
4699
5246
|
}
|
|
4700
5247
|
};
|
|
4701
5248
|
}
|
|
5249
|
+
|
|
4702
5250
|
// src/geoms/rect.ts
|
|
4703
5251
|
function geom_rect(options = {}) {
|
|
4704
5252
|
return {
|
|
@@ -4727,6 +5275,7 @@ function geom_abline(options = {}) {
|
|
|
4727
5275
|
}
|
|
4728
5276
|
};
|
|
4729
5277
|
}
|
|
5278
|
+
|
|
4730
5279
|
// src/geoms/qq.ts
|
|
4731
5280
|
function geom_qq(options = {}) {
|
|
4732
5281
|
return {
|
|
@@ -4755,6 +5304,16 @@ function geom_qq_line(options = {}) {
|
|
|
4755
5304
|
}
|
|
4756
5305
|
};
|
|
4757
5306
|
}
|
|
5307
|
+
|
|
5308
|
+
// src/geoms/index.ts
|
|
5309
|
+
var init_geoms = () => {};
|
|
5310
|
+
|
|
5311
|
+
// src/stats/index.ts
|
|
5312
|
+
var init_stats = __esm(() => {
|
|
5313
|
+
init_bin2d();
|
|
5314
|
+
init_summary();
|
|
5315
|
+
});
|
|
5316
|
+
|
|
4758
5317
|
// src/scales/continuous.ts
|
|
4759
5318
|
function createContinuousScale(aesthetic, options = {}) {
|
|
4760
5319
|
const trans = options.trans ?? "identity";
|
|
@@ -4833,6 +5392,7 @@ function scale_y2_sqrt(options = {}) {
|
|
|
4833
5392
|
function scale_y2_reverse(options = {}) {
|
|
4834
5393
|
return createContinuousScale("y2", { ...options, trans: "reverse" });
|
|
4835
5394
|
}
|
|
5395
|
+
|
|
4836
5396
|
// src/scales/discrete.ts
|
|
4837
5397
|
function createDiscreteScale(aesthetic, options = {}) {
|
|
4838
5398
|
const valueToPosition = new Map;
|
|
@@ -4882,123 +5442,8 @@ function scale_x_discrete(options = {}) {
|
|
|
4882
5442
|
function scale_y_discrete(options = {}) {
|
|
4883
5443
|
return createDiscreteScale("y", options);
|
|
4884
5444
|
}
|
|
5445
|
+
|
|
4885
5446
|
// src/scales/color.ts
|
|
4886
|
-
var PALETTES = {
|
|
4887
|
-
viridis: ["#440154", "#414487", "#2a788e", "#22a884", "#7ad151", "#fde725"],
|
|
4888
|
-
plasma: ["#0d0887", "#6a00a8", "#b12a90", "#e16462", "#fca636", "#f0f921"],
|
|
4889
|
-
inferno: ["#000004", "#420a68", "#932667", "#dd513a", "#fca50a", "#fcffa4"],
|
|
4890
|
-
magma: ["#000004", "#3b0f70", "#8c2981", "#de4968", "#fe9f6d", "#fcfdbf"],
|
|
4891
|
-
cividis: ["#002051", "#1d3f6e", "#52596a", "#7b7b78", "#a89f68", "#d9c84a", "#fdea45"],
|
|
4892
|
-
turbo: ["#30123b", "#4662d7", "#35aaf8", "#1ae4b6", "#72fe5e", "#c8ef34", "#faba39", "#f66b19", "#ca2a04"],
|
|
4893
|
-
Blues: ["#f7fbff", "#deebf7", "#c6dbef", "#9ecae1", "#6baed6", "#4292c6", "#2171b5", "#08519c", "#08306b"],
|
|
4894
|
-
Greens: ["#f7fcf5", "#e5f5e0", "#c7e9c0", "#a1d99b", "#74c476", "#41ab5d", "#238b45", "#006d2c", "#00441b"],
|
|
4895
|
-
Greys: ["#ffffff", "#f0f0f0", "#d9d9d9", "#bdbdbd", "#969696", "#737373", "#525252", "#252525", "#000000"],
|
|
4896
|
-
Oranges: ["#fff5eb", "#fee6ce", "#fdd0a2", "#fdae6b", "#fd8d3c", "#f16913", "#d94801", "#a63603", "#7f2704"],
|
|
4897
|
-
Purples: ["#fcfbfd", "#efedf5", "#dadaeb", "#bcbddc", "#9e9ac8", "#807dba", "#6a51a3", "#54278f", "#3f007d"],
|
|
4898
|
-
Reds: ["#fff5f0", "#fee0d2", "#fcbba1", "#fc9272", "#fb6a4a", "#ef3b2c", "#cb181d", "#a50f15", "#67000d"],
|
|
4899
|
-
BuGn: ["#f7fcfd", "#e5f5f9", "#ccece6", "#99d8c9", "#66c2a4", "#41ae76", "#238b45", "#006d2c", "#00441b"],
|
|
4900
|
-
BuPu: ["#f7fcfd", "#e0ecf4", "#bfd3e6", "#9ebcda", "#8c96c6", "#8c6bb1", "#88419d", "#810f7c", "#4d004b"],
|
|
4901
|
-
GnBu: ["#f7fcf0", "#e0f3db", "#ccebc5", "#a8ddb5", "#7bccc4", "#4eb3d3", "#2b8cbe", "#0868ac", "#084081"],
|
|
4902
|
-
OrRd: ["#fff7ec", "#fee8c8", "#fdd49e", "#fdbb84", "#fc8d59", "#ef6548", "#d7301f", "#b30000", "#7f0000"],
|
|
4903
|
-
PuBu: ["#fff7fb", "#ece7f2", "#d0d1e6", "#a6bddb", "#74a9cf", "#3690c0", "#0570b0", "#045a8d", "#023858"],
|
|
4904
|
-
PuBuGn: ["#fff7fb", "#ece2f0", "#d0d1e6", "#a6bddb", "#67a9cf", "#3690c0", "#02818a", "#016c59", "#014636"],
|
|
4905
|
-
PuRd: ["#f7f4f9", "#e7e1ef", "#d4b9da", "#c994c7", "#df65b0", "#e7298a", "#ce1256", "#980043", "#67001f"],
|
|
4906
|
-
RdPu: ["#fff7f3", "#fde0dd", "#fcc5c0", "#fa9fb5", "#f768a1", "#dd3497", "#ae017e", "#7a0177", "#49006a"],
|
|
4907
|
-
YlGn: ["#ffffe5", "#f7fcb9", "#d9f0a3", "#addd8e", "#78c679", "#41ab5d", "#238b45", "#006837", "#004529"],
|
|
4908
|
-
YlGnBu: ["#ffffd9", "#edf8b1", "#c7e9b4", "#7fcdbb", "#41b6c4", "#1d91c0", "#225ea8", "#253494", "#081d58"],
|
|
4909
|
-
YlOrBr: ["#ffffe5", "#fff7bc", "#fee391", "#fec44f", "#fe9929", "#ec7014", "#cc4c02", "#993404", "#662506"],
|
|
4910
|
-
YlOrRd: ["#ffffcc", "#ffeda0", "#fed976", "#feb24c", "#fd8d3c", "#fc4e2a", "#e31a1c", "#bd0026", "#800026"],
|
|
4911
|
-
BrBG: ["#543005", "#8c510a", "#bf812d", "#dfc27d", "#f6e8c3", "#f5f5f5", "#c7eae5", "#80cdc1", "#35978f", "#01665e", "#003c30"],
|
|
4912
|
-
PiYG: ["#8e0152", "#c51b7d", "#de77ae", "#f1b6da", "#fde0ef", "#f7f7f7", "#e6f5d0", "#b8e186", "#7fbc41", "#4d9221", "#276419"],
|
|
4913
|
-
PRGn: ["#40004b", "#762a83", "#9970ab", "#c2a5cf", "#e7d4e8", "#f7f7f7", "#d9f0d3", "#a6dba0", "#5aae61", "#1b7837", "#00441b"],
|
|
4914
|
-
PuOr: ["#7f3b08", "#b35806", "#e08214", "#fdb863", "#fee0b6", "#f7f7f7", "#d8daeb", "#b2abd2", "#8073ac", "#542788", "#2d004b"],
|
|
4915
|
-
RdBu: ["#67001f", "#b2182b", "#d6604d", "#f4a582", "#fddbc7", "#f7f7f7", "#d1e5f0", "#92c5de", "#4393c3", "#2166ac", "#053061"],
|
|
4916
|
-
RdGy: ["#67001f", "#b2182b", "#d6604d", "#f4a582", "#fddbc7", "#ffffff", "#e0e0e0", "#bababa", "#878787", "#4d4d4d", "#1a1a1a"],
|
|
4917
|
-
RdYlBu: ["#a50026", "#d73027", "#f46d43", "#fdae61", "#fee090", "#ffffbf", "#e0f3f8", "#abd9e9", "#74add1", "#4575b4", "#313695"],
|
|
4918
|
-
RdYlGn: ["#a50026", "#d73027", "#f46d43", "#fdae61", "#fee08b", "#ffffbf", "#d9ef8b", "#a6d96a", "#66bd63", "#1a9850", "#006837"],
|
|
4919
|
-
Spectral: ["#9e0142", "#d53e4f", "#f46d43", "#fdae61", "#fee08b", "#ffffbf", "#e6f598", "#abdda4", "#66c2a5", "#3288bd", "#5e4fa2"],
|
|
4920
|
-
category10: [
|
|
4921
|
-
"#1f77b4",
|
|
4922
|
-
"#ff7f0e",
|
|
4923
|
-
"#2ca02c",
|
|
4924
|
-
"#d62728",
|
|
4925
|
-
"#9467bd",
|
|
4926
|
-
"#8c564b",
|
|
4927
|
-
"#e377c2",
|
|
4928
|
-
"#7f7f7f",
|
|
4929
|
-
"#bcbd22",
|
|
4930
|
-
"#17becf"
|
|
4931
|
-
],
|
|
4932
|
-
category20: [
|
|
4933
|
-
"#1f77b4",
|
|
4934
|
-
"#aec7e8",
|
|
4935
|
-
"#ff7f0e",
|
|
4936
|
-
"#ffbb78",
|
|
4937
|
-
"#2ca02c",
|
|
4938
|
-
"#98df8a",
|
|
4939
|
-
"#d62728",
|
|
4940
|
-
"#ff9896",
|
|
4941
|
-
"#9467bd",
|
|
4942
|
-
"#c5b0d5",
|
|
4943
|
-
"#8c564b",
|
|
4944
|
-
"#c49c94",
|
|
4945
|
-
"#e377c2",
|
|
4946
|
-
"#f7b6d2",
|
|
4947
|
-
"#7f7f7f",
|
|
4948
|
-
"#c7c7c7",
|
|
4949
|
-
"#bcbd22",
|
|
4950
|
-
"#dbdb8d",
|
|
4951
|
-
"#17becf",
|
|
4952
|
-
"#9edae5"
|
|
4953
|
-
],
|
|
4954
|
-
Accent: ["#7fc97f", "#beaed4", "#fdc086", "#ffff99", "#386cb0", "#f0027f", "#bf5b17", "#666666"],
|
|
4955
|
-
Dark2: ["#1b9e77", "#d95f02", "#7570b3", "#e7298a", "#66a61e", "#e6ab02", "#a6761d", "#666666"],
|
|
4956
|
-
Paired: ["#a6cee3", "#1f78b4", "#b2df8a", "#33a02c", "#fb9a99", "#e31a1c", "#fdbf6f", "#ff7f00", "#cab2d6", "#6a3d9a", "#ffff99", "#b15928"],
|
|
4957
|
-
Pastel1: ["#fbb4ae", "#b3cde3", "#ccebc5", "#decbe4", "#fed9a6", "#ffffcc", "#e5d8bd", "#fddaec", "#f2f2f2"],
|
|
4958
|
-
Pastel2: ["#b3e2cd", "#fdcdac", "#cbd5e8", "#f4cae4", "#e6f5c9", "#fff2ae", "#f1e2cc", "#cccccc"],
|
|
4959
|
-
Set1: ["#e41a1c", "#377eb8", "#4daf4a", "#984ea3", "#ff7f00", "#ffff33", "#a65628", "#f781bf", "#999999"],
|
|
4960
|
-
Set2: ["#66c2a5", "#fc8d62", "#8da0cb", "#e78ac3", "#a6d854", "#ffd92f", "#e5c494", "#b3b3b3"],
|
|
4961
|
-
Set3: ["#8dd3c7", "#ffffb3", "#bebada", "#fb8072", "#80b1d3", "#fdb462", "#b3de69", "#fccde5", "#d9d9d9", "#bc80bd", "#ccebc5", "#ffed6f"],
|
|
4962
|
-
Tab10: [
|
|
4963
|
-
"#4e79a7",
|
|
4964
|
-
"#f28e2c",
|
|
4965
|
-
"#e15759",
|
|
4966
|
-
"#76b7b2",
|
|
4967
|
-
"#59a14f",
|
|
4968
|
-
"#edc949",
|
|
4969
|
-
"#af7aa1",
|
|
4970
|
-
"#ff9da7",
|
|
4971
|
-
"#9c755f",
|
|
4972
|
-
"#bab0ab"
|
|
4973
|
-
],
|
|
4974
|
-
Tab20: [
|
|
4975
|
-
"#4e79a7",
|
|
4976
|
-
"#a0cbe8",
|
|
4977
|
-
"#f28e2c",
|
|
4978
|
-
"#ffbe7d",
|
|
4979
|
-
"#59a14f",
|
|
4980
|
-
"#8cd17d",
|
|
4981
|
-
"#b6992d",
|
|
4982
|
-
"#f1ce63",
|
|
4983
|
-
"#499894",
|
|
4984
|
-
"#86bcb6",
|
|
4985
|
-
"#e15759",
|
|
4986
|
-
"#ff9d9a",
|
|
4987
|
-
"#79706e",
|
|
4988
|
-
"#bab0ac",
|
|
4989
|
-
"#d37295",
|
|
4990
|
-
"#fabfd2",
|
|
4991
|
-
"#b07aa1",
|
|
4992
|
-
"#d4a6c8",
|
|
4993
|
-
"#9d7660",
|
|
4994
|
-
"#d7b5a6"
|
|
4995
|
-
],
|
|
4996
|
-
thermal: ["#042333", "#2c3e50", "#0b5345", "#1e8449", "#f39c12", "#e74c3c", "#fadbd8"],
|
|
4997
|
-
haline: ["#2c3e50", "#1a5276", "#2980b9", "#5dade2", "#aed6f1", "#d5f5e3"],
|
|
4998
|
-
terrain: ["#333399", "#0099ff", "#00cc00", "#ffff00", "#ff9900", "#cc6600", "#996633", "#ffffff"],
|
|
4999
|
-
rainbow: ["#ff0000", "#ff8000", "#ffff00", "#80ff00", "#00ff00", "#00ff80", "#00ffff", "#0080ff", "#0000ff", "#8000ff"],
|
|
5000
|
-
cubehelix: ["#000000", "#1a1530", "#30304d", "#4d5366", "#6d826e", "#8ab17d", "#add38a", "#dae8a2", "#ffffff"]
|
|
5001
|
-
};
|
|
5002
5447
|
function hexToRgba(hex) {
|
|
5003
5448
|
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
5004
5449
|
if (!result)
|
|
@@ -5219,6 +5664,126 @@ function getAvailablePalettes() {
|
|
|
5219
5664
|
function getPaletteColors(name) {
|
|
5220
5665
|
return PALETTES[name];
|
|
5221
5666
|
}
|
|
5667
|
+
var PALETTES;
|
|
5668
|
+
var init_color = __esm(() => {
|
|
5669
|
+
PALETTES = {
|
|
5670
|
+
viridis: ["#440154", "#414487", "#2a788e", "#22a884", "#7ad151", "#fde725"],
|
|
5671
|
+
plasma: ["#0d0887", "#6a00a8", "#b12a90", "#e16462", "#fca636", "#f0f921"],
|
|
5672
|
+
inferno: ["#000004", "#420a68", "#932667", "#dd513a", "#fca50a", "#fcffa4"],
|
|
5673
|
+
magma: ["#000004", "#3b0f70", "#8c2981", "#de4968", "#fe9f6d", "#fcfdbf"],
|
|
5674
|
+
cividis: ["#002051", "#1d3f6e", "#52596a", "#7b7b78", "#a89f68", "#d9c84a", "#fdea45"],
|
|
5675
|
+
turbo: ["#30123b", "#4662d7", "#35aaf8", "#1ae4b6", "#72fe5e", "#c8ef34", "#faba39", "#f66b19", "#ca2a04"],
|
|
5676
|
+
Blues: ["#f7fbff", "#deebf7", "#c6dbef", "#9ecae1", "#6baed6", "#4292c6", "#2171b5", "#08519c", "#08306b"],
|
|
5677
|
+
Greens: ["#f7fcf5", "#e5f5e0", "#c7e9c0", "#a1d99b", "#74c476", "#41ab5d", "#238b45", "#006d2c", "#00441b"],
|
|
5678
|
+
Greys: ["#ffffff", "#f0f0f0", "#d9d9d9", "#bdbdbd", "#969696", "#737373", "#525252", "#252525", "#000000"],
|
|
5679
|
+
Oranges: ["#fff5eb", "#fee6ce", "#fdd0a2", "#fdae6b", "#fd8d3c", "#f16913", "#d94801", "#a63603", "#7f2704"],
|
|
5680
|
+
Purples: ["#fcfbfd", "#efedf5", "#dadaeb", "#bcbddc", "#9e9ac8", "#807dba", "#6a51a3", "#54278f", "#3f007d"],
|
|
5681
|
+
Reds: ["#fff5f0", "#fee0d2", "#fcbba1", "#fc9272", "#fb6a4a", "#ef3b2c", "#cb181d", "#a50f15", "#67000d"],
|
|
5682
|
+
BuGn: ["#f7fcfd", "#e5f5f9", "#ccece6", "#99d8c9", "#66c2a4", "#41ae76", "#238b45", "#006d2c", "#00441b"],
|
|
5683
|
+
BuPu: ["#f7fcfd", "#e0ecf4", "#bfd3e6", "#9ebcda", "#8c96c6", "#8c6bb1", "#88419d", "#810f7c", "#4d004b"],
|
|
5684
|
+
GnBu: ["#f7fcf0", "#e0f3db", "#ccebc5", "#a8ddb5", "#7bccc4", "#4eb3d3", "#2b8cbe", "#0868ac", "#084081"],
|
|
5685
|
+
OrRd: ["#fff7ec", "#fee8c8", "#fdd49e", "#fdbb84", "#fc8d59", "#ef6548", "#d7301f", "#b30000", "#7f0000"],
|
|
5686
|
+
PuBu: ["#fff7fb", "#ece7f2", "#d0d1e6", "#a6bddb", "#74a9cf", "#3690c0", "#0570b0", "#045a8d", "#023858"],
|
|
5687
|
+
PuBuGn: ["#fff7fb", "#ece2f0", "#d0d1e6", "#a6bddb", "#67a9cf", "#3690c0", "#02818a", "#016c59", "#014636"],
|
|
5688
|
+
PuRd: ["#f7f4f9", "#e7e1ef", "#d4b9da", "#c994c7", "#df65b0", "#e7298a", "#ce1256", "#980043", "#67001f"],
|
|
5689
|
+
RdPu: ["#fff7f3", "#fde0dd", "#fcc5c0", "#fa9fb5", "#f768a1", "#dd3497", "#ae017e", "#7a0177", "#49006a"],
|
|
5690
|
+
YlGn: ["#ffffe5", "#f7fcb9", "#d9f0a3", "#addd8e", "#78c679", "#41ab5d", "#238b45", "#006837", "#004529"],
|
|
5691
|
+
YlGnBu: ["#ffffd9", "#edf8b1", "#c7e9b4", "#7fcdbb", "#41b6c4", "#1d91c0", "#225ea8", "#253494", "#081d58"],
|
|
5692
|
+
YlOrBr: ["#ffffe5", "#fff7bc", "#fee391", "#fec44f", "#fe9929", "#ec7014", "#cc4c02", "#993404", "#662506"],
|
|
5693
|
+
YlOrRd: ["#ffffcc", "#ffeda0", "#fed976", "#feb24c", "#fd8d3c", "#fc4e2a", "#e31a1c", "#bd0026", "#800026"],
|
|
5694
|
+
BrBG: ["#543005", "#8c510a", "#bf812d", "#dfc27d", "#f6e8c3", "#f5f5f5", "#c7eae5", "#80cdc1", "#35978f", "#01665e", "#003c30"],
|
|
5695
|
+
PiYG: ["#8e0152", "#c51b7d", "#de77ae", "#f1b6da", "#fde0ef", "#f7f7f7", "#e6f5d0", "#b8e186", "#7fbc41", "#4d9221", "#276419"],
|
|
5696
|
+
PRGn: ["#40004b", "#762a83", "#9970ab", "#c2a5cf", "#e7d4e8", "#f7f7f7", "#d9f0d3", "#a6dba0", "#5aae61", "#1b7837", "#00441b"],
|
|
5697
|
+
PuOr: ["#7f3b08", "#b35806", "#e08214", "#fdb863", "#fee0b6", "#f7f7f7", "#d8daeb", "#b2abd2", "#8073ac", "#542788", "#2d004b"],
|
|
5698
|
+
RdBu: ["#67001f", "#b2182b", "#d6604d", "#f4a582", "#fddbc7", "#f7f7f7", "#d1e5f0", "#92c5de", "#4393c3", "#2166ac", "#053061"],
|
|
5699
|
+
RdGy: ["#67001f", "#b2182b", "#d6604d", "#f4a582", "#fddbc7", "#ffffff", "#e0e0e0", "#bababa", "#878787", "#4d4d4d", "#1a1a1a"],
|
|
5700
|
+
RdYlBu: ["#a50026", "#d73027", "#f46d43", "#fdae61", "#fee090", "#ffffbf", "#e0f3f8", "#abd9e9", "#74add1", "#4575b4", "#313695"],
|
|
5701
|
+
RdYlGn: ["#a50026", "#d73027", "#f46d43", "#fdae61", "#fee08b", "#ffffbf", "#d9ef8b", "#a6d96a", "#66bd63", "#1a9850", "#006837"],
|
|
5702
|
+
Spectral: ["#9e0142", "#d53e4f", "#f46d43", "#fdae61", "#fee08b", "#ffffbf", "#e6f598", "#abdda4", "#66c2a5", "#3288bd", "#5e4fa2"],
|
|
5703
|
+
category10: [
|
|
5704
|
+
"#1f77b4",
|
|
5705
|
+
"#ff7f0e",
|
|
5706
|
+
"#2ca02c",
|
|
5707
|
+
"#d62728",
|
|
5708
|
+
"#9467bd",
|
|
5709
|
+
"#8c564b",
|
|
5710
|
+
"#e377c2",
|
|
5711
|
+
"#7f7f7f",
|
|
5712
|
+
"#bcbd22",
|
|
5713
|
+
"#17becf"
|
|
5714
|
+
],
|
|
5715
|
+
category20: [
|
|
5716
|
+
"#1f77b4",
|
|
5717
|
+
"#aec7e8",
|
|
5718
|
+
"#ff7f0e",
|
|
5719
|
+
"#ffbb78",
|
|
5720
|
+
"#2ca02c",
|
|
5721
|
+
"#98df8a",
|
|
5722
|
+
"#d62728",
|
|
5723
|
+
"#ff9896",
|
|
5724
|
+
"#9467bd",
|
|
5725
|
+
"#c5b0d5",
|
|
5726
|
+
"#8c564b",
|
|
5727
|
+
"#c49c94",
|
|
5728
|
+
"#e377c2",
|
|
5729
|
+
"#f7b6d2",
|
|
5730
|
+
"#7f7f7f",
|
|
5731
|
+
"#c7c7c7",
|
|
5732
|
+
"#bcbd22",
|
|
5733
|
+
"#dbdb8d",
|
|
5734
|
+
"#17becf",
|
|
5735
|
+
"#9edae5"
|
|
5736
|
+
],
|
|
5737
|
+
Accent: ["#7fc97f", "#beaed4", "#fdc086", "#ffff99", "#386cb0", "#f0027f", "#bf5b17", "#666666"],
|
|
5738
|
+
Dark2: ["#1b9e77", "#d95f02", "#7570b3", "#e7298a", "#66a61e", "#e6ab02", "#a6761d", "#666666"],
|
|
5739
|
+
Paired: ["#a6cee3", "#1f78b4", "#b2df8a", "#33a02c", "#fb9a99", "#e31a1c", "#fdbf6f", "#ff7f00", "#cab2d6", "#6a3d9a", "#ffff99", "#b15928"],
|
|
5740
|
+
Pastel1: ["#fbb4ae", "#b3cde3", "#ccebc5", "#decbe4", "#fed9a6", "#ffffcc", "#e5d8bd", "#fddaec", "#f2f2f2"],
|
|
5741
|
+
Pastel2: ["#b3e2cd", "#fdcdac", "#cbd5e8", "#f4cae4", "#e6f5c9", "#fff2ae", "#f1e2cc", "#cccccc"],
|
|
5742
|
+
Set1: ["#e41a1c", "#377eb8", "#4daf4a", "#984ea3", "#ff7f00", "#ffff33", "#a65628", "#f781bf", "#999999"],
|
|
5743
|
+
Set2: ["#66c2a5", "#fc8d62", "#8da0cb", "#e78ac3", "#a6d854", "#ffd92f", "#e5c494", "#b3b3b3"],
|
|
5744
|
+
Set3: ["#8dd3c7", "#ffffb3", "#bebada", "#fb8072", "#80b1d3", "#fdb462", "#b3de69", "#fccde5", "#d9d9d9", "#bc80bd", "#ccebc5", "#ffed6f"],
|
|
5745
|
+
Tab10: [
|
|
5746
|
+
"#4e79a7",
|
|
5747
|
+
"#f28e2c",
|
|
5748
|
+
"#e15759",
|
|
5749
|
+
"#76b7b2",
|
|
5750
|
+
"#59a14f",
|
|
5751
|
+
"#edc949",
|
|
5752
|
+
"#af7aa1",
|
|
5753
|
+
"#ff9da7",
|
|
5754
|
+
"#9c755f",
|
|
5755
|
+
"#bab0ab"
|
|
5756
|
+
],
|
|
5757
|
+
Tab20: [
|
|
5758
|
+
"#4e79a7",
|
|
5759
|
+
"#a0cbe8",
|
|
5760
|
+
"#f28e2c",
|
|
5761
|
+
"#ffbe7d",
|
|
5762
|
+
"#59a14f",
|
|
5763
|
+
"#8cd17d",
|
|
5764
|
+
"#b6992d",
|
|
5765
|
+
"#f1ce63",
|
|
5766
|
+
"#499894",
|
|
5767
|
+
"#86bcb6",
|
|
5768
|
+
"#e15759",
|
|
5769
|
+
"#ff9d9a",
|
|
5770
|
+
"#79706e",
|
|
5771
|
+
"#bab0ac",
|
|
5772
|
+
"#d37295",
|
|
5773
|
+
"#fabfd2",
|
|
5774
|
+
"#b07aa1",
|
|
5775
|
+
"#d4a6c8",
|
|
5776
|
+
"#9d7660",
|
|
5777
|
+
"#d7b5a6"
|
|
5778
|
+
],
|
|
5779
|
+
thermal: ["#042333", "#2c3e50", "#0b5345", "#1e8449", "#f39c12", "#e74c3c", "#fadbd8"],
|
|
5780
|
+
haline: ["#2c3e50", "#1a5276", "#2980b9", "#5dade2", "#aed6f1", "#d5f5e3"],
|
|
5781
|
+
terrain: ["#333399", "#0099ff", "#00cc00", "#ffff00", "#ff9900", "#cc6600", "#996633", "#ffffff"],
|
|
5782
|
+
rainbow: ["#ff0000", "#ff8000", "#ffff00", "#80ff00", "#00ff00", "#00ff80", "#00ffff", "#0080ff", "#0000ff", "#8000ff"],
|
|
5783
|
+
cubehelix: ["#000000", "#1a1530", "#30304d", "#4d5366", "#6d826e", "#8ab17d", "#add38a", "#dae8a2", "#ffffff"]
|
|
5784
|
+
};
|
|
5785
|
+
});
|
|
5786
|
+
|
|
5222
5787
|
// src/scales/size.ts
|
|
5223
5788
|
function scale_size_continuous(options = {}) {
|
|
5224
5789
|
const range = options.range ?? [1, 6];
|
|
@@ -5287,45 +5852,8 @@ function scale_size_binned(options = {}) {
|
|
|
5287
5852
|
}
|
|
5288
5853
|
};
|
|
5289
5854
|
}
|
|
5855
|
+
|
|
5290
5856
|
// src/scales/shape.ts
|
|
5291
|
-
var DEFAULT_SHAPES = [
|
|
5292
|
-
"circle",
|
|
5293
|
-
"square",
|
|
5294
|
-
"triangle",
|
|
5295
|
-
"diamond",
|
|
5296
|
-
"cross",
|
|
5297
|
-
"plus",
|
|
5298
|
-
"star",
|
|
5299
|
-
"open_circle",
|
|
5300
|
-
"open_square",
|
|
5301
|
-
"open_triangle",
|
|
5302
|
-
"open_diamond",
|
|
5303
|
-
"dot"
|
|
5304
|
-
];
|
|
5305
|
-
var SHAPE_CHARS = {
|
|
5306
|
-
circle: "●",
|
|
5307
|
-
filled_circle: "●",
|
|
5308
|
-
open_circle: "○",
|
|
5309
|
-
square: "■",
|
|
5310
|
-
filled_square: "■",
|
|
5311
|
-
open_square: "□",
|
|
5312
|
-
triangle: "▲",
|
|
5313
|
-
filled_triangle: "▲",
|
|
5314
|
-
open_triangle: "△",
|
|
5315
|
-
triangle_down: "▼",
|
|
5316
|
-
diamond: "◆",
|
|
5317
|
-
filled_diamond: "◆",
|
|
5318
|
-
open_diamond: "◇",
|
|
5319
|
-
cross: "✕",
|
|
5320
|
-
plus: "+",
|
|
5321
|
-
star: "★",
|
|
5322
|
-
open_star: "☆",
|
|
5323
|
-
dot: "•",
|
|
5324
|
-
bullet: "•",
|
|
5325
|
-
asterisk: "*",
|
|
5326
|
-
hash: "#",
|
|
5327
|
-
at: "@"
|
|
5328
|
-
};
|
|
5329
5857
|
function scale_shape_discrete(options = {}) {
|
|
5330
5858
|
const shapes = options.values ?? DEFAULT_SHAPES;
|
|
5331
5859
|
return {
|
|
@@ -5384,6 +5912,48 @@ function scale_shape_ordinal(options = {}) {
|
|
|
5384
5912
|
}
|
|
5385
5913
|
};
|
|
5386
5914
|
}
|
|
5915
|
+
var DEFAULT_SHAPES, SHAPE_CHARS;
|
|
5916
|
+
var init_shape = __esm(() => {
|
|
5917
|
+
DEFAULT_SHAPES = [
|
|
5918
|
+
"circle",
|
|
5919
|
+
"square",
|
|
5920
|
+
"triangle",
|
|
5921
|
+
"diamond",
|
|
5922
|
+
"cross",
|
|
5923
|
+
"plus",
|
|
5924
|
+
"star",
|
|
5925
|
+
"open_circle",
|
|
5926
|
+
"open_square",
|
|
5927
|
+
"open_triangle",
|
|
5928
|
+
"open_diamond",
|
|
5929
|
+
"dot"
|
|
5930
|
+
];
|
|
5931
|
+
SHAPE_CHARS = {
|
|
5932
|
+
circle: "●",
|
|
5933
|
+
filled_circle: "●",
|
|
5934
|
+
open_circle: "○",
|
|
5935
|
+
square: "■",
|
|
5936
|
+
filled_square: "■",
|
|
5937
|
+
open_square: "□",
|
|
5938
|
+
triangle: "▲",
|
|
5939
|
+
filled_triangle: "▲",
|
|
5940
|
+
open_triangle: "△",
|
|
5941
|
+
triangle_down: "▼",
|
|
5942
|
+
diamond: "◆",
|
|
5943
|
+
filled_diamond: "◆",
|
|
5944
|
+
open_diamond: "◇",
|
|
5945
|
+
cross: "✕",
|
|
5946
|
+
plus: "+",
|
|
5947
|
+
star: "★",
|
|
5948
|
+
open_star: "☆",
|
|
5949
|
+
dot: "•",
|
|
5950
|
+
bullet: "•",
|
|
5951
|
+
asterisk: "*",
|
|
5952
|
+
hash: "#",
|
|
5953
|
+
at: "@"
|
|
5954
|
+
};
|
|
5955
|
+
});
|
|
5956
|
+
|
|
5387
5957
|
// src/scales/alpha.ts
|
|
5388
5958
|
function scale_alpha_continuous(options = {}) {
|
|
5389
5959
|
const range = options.range ?? [0.1, 1];
|
|
@@ -5480,17 +6050,8 @@ function scale_alpha_binned(options = {}) {
|
|
|
5480
6050
|
}
|
|
5481
6051
|
};
|
|
5482
6052
|
}
|
|
6053
|
+
|
|
5483
6054
|
// src/scales/datetime.ts
|
|
5484
|
-
var TIME_INTERVALS = [
|
|
5485
|
-
{ name: "millisecond", ms: 1 },
|
|
5486
|
-
{ name: "second", ms: 1000 },
|
|
5487
|
-
{ name: "minute", ms: 60 * 1000 },
|
|
5488
|
-
{ name: "hour", ms: 60 * 60 * 1000 },
|
|
5489
|
-
{ name: "day", ms: 24 * 60 * 60 * 1000 },
|
|
5490
|
-
{ name: "week", ms: 7 * 24 * 60 * 60 * 1000 },
|
|
5491
|
-
{ name: "month", ms: 30 * 24 * 60 * 60 * 1000 },
|
|
5492
|
-
{ name: "year", ms: 365 * 24 * 60 * 60 * 1000 }
|
|
5493
|
-
];
|
|
5494
6055
|
function parseDateTime(value) {
|
|
5495
6056
|
if (value === null || value === undefined)
|
|
5496
6057
|
return null;
|
|
@@ -5672,6 +6233,27 @@ function scale_y_duration(options = {}) {
|
|
|
5672
6233
|
scale.aesthetic = "y";
|
|
5673
6234
|
return scale;
|
|
5674
6235
|
}
|
|
6236
|
+
var TIME_INTERVALS;
|
|
6237
|
+
var init_datetime = __esm(() => {
|
|
6238
|
+
TIME_INTERVALS = [
|
|
6239
|
+
{ name: "millisecond", ms: 1 },
|
|
6240
|
+
{ name: "second", ms: 1000 },
|
|
6241
|
+
{ name: "minute", ms: 60 * 1000 },
|
|
6242
|
+
{ name: "hour", ms: 60 * 60 * 1000 },
|
|
6243
|
+
{ name: "day", ms: 24 * 60 * 60 * 1000 },
|
|
6244
|
+
{ name: "week", ms: 7 * 24 * 60 * 60 * 1000 },
|
|
6245
|
+
{ name: "month", ms: 30 * 24 * 60 * 60 * 1000 },
|
|
6246
|
+
{ name: "year", ms: 365 * 24 * 60 * 60 * 1000 }
|
|
6247
|
+
];
|
|
6248
|
+
});
|
|
6249
|
+
|
|
6250
|
+
// src/scales/index.ts
|
|
6251
|
+
var init_scales2 = __esm(() => {
|
|
6252
|
+
init_color();
|
|
6253
|
+
init_shape();
|
|
6254
|
+
init_datetime();
|
|
6255
|
+
});
|
|
6256
|
+
|
|
5675
6257
|
// src/annotations.ts
|
|
5676
6258
|
function annotate(geomType, options = {}) {
|
|
5677
6259
|
const parseColor2 = (c) => {
|
|
@@ -5825,6 +6407,7 @@ function annotate_hline(yintercept, options = {}) {
|
|
|
5825
6407
|
function annotate_vline(xintercept, options = {}) {
|
|
5826
6408
|
return annotate("vline", { ...options, x: xintercept });
|
|
5827
6409
|
}
|
|
6410
|
+
|
|
5828
6411
|
// src/terminal/capabilities.ts
|
|
5829
6412
|
function detectColorCapability() {
|
|
5830
6413
|
const colorTerm = process.env.COLORTERM ?? "";
|
|
@@ -5937,7 +6520,6 @@ function getRecommendedRenderer(caps) {
|
|
|
5937
6520
|
return "block";
|
|
5938
6521
|
return "ascii";
|
|
5939
6522
|
}
|
|
5940
|
-
var cachedCapabilities = null;
|
|
5941
6523
|
function getCapabilities() {
|
|
5942
6524
|
if (!cachedCapabilities) {
|
|
5943
6525
|
cachedCapabilities = detectCapabilities();
|
|
@@ -5947,25 +6529,9 @@ function getCapabilities() {
|
|
|
5947
6529
|
function clearCapabilityCache() {
|
|
5948
6530
|
cachedCapabilities = null;
|
|
5949
6531
|
}
|
|
6532
|
+
var cachedCapabilities = null;
|
|
6533
|
+
|
|
5950
6534
|
// src/terminal/colors.ts
|
|
5951
|
-
var ANSI_16_COLORS = [
|
|
5952
|
-
{ r: 0, g: 0, b: 0, a: 255 },
|
|
5953
|
-
{ r: 128, g: 0, b: 0, a: 255 },
|
|
5954
|
-
{ r: 0, g: 128, b: 0, a: 255 },
|
|
5955
|
-
{ r: 128, g: 128, b: 0, a: 255 },
|
|
5956
|
-
{ r: 0, g: 0, b: 128, a: 255 },
|
|
5957
|
-
{ r: 128, g: 0, b: 128, a: 255 },
|
|
5958
|
-
{ r: 0, g: 128, b: 128, a: 255 },
|
|
5959
|
-
{ r: 192, g: 192, b: 192, a: 255 },
|
|
5960
|
-
{ r: 128, g: 128, b: 128, a: 255 },
|
|
5961
|
-
{ r: 255, g: 0, b: 0, a: 255 },
|
|
5962
|
-
{ r: 0, g: 255, b: 0, a: 255 },
|
|
5963
|
-
{ r: 255, g: 255, b: 0, a: 255 },
|
|
5964
|
-
{ r: 0, g: 0, b: 255, a: 255 },
|
|
5965
|
-
{ r: 255, g: 0, b: 255, a: 255 },
|
|
5966
|
-
{ r: 0, g: 255, b: 255, a: 255 },
|
|
5967
|
-
{ r: 255, g: 255, b: 255, a: 255 }
|
|
5968
|
-
];
|
|
5969
6535
|
function generate256Palette() {
|
|
5970
6536
|
const palette = [];
|
|
5971
6537
|
palette.push(...ANSI_16_COLORS);
|
|
@@ -5988,7 +6554,6 @@ function generate256Palette() {
|
|
|
5988
6554
|
}
|
|
5989
6555
|
return palette;
|
|
5990
6556
|
}
|
|
5991
|
-
var _palette256 = null;
|
|
5992
6557
|
function getPalette256() {
|
|
5993
6558
|
if (!_palette256) {
|
|
5994
6559
|
_palette256 = generate256Palette();
|
|
@@ -6225,28 +6790,29 @@ function getColorEscape(color, mode, type) {
|
|
|
6225
6790
|
}
|
|
6226
6791
|
return bgEscape(color, mode);
|
|
6227
6792
|
}
|
|
6228
|
-
var RESET = "\x1B[0m";
|
|
6229
|
-
var
|
|
6230
|
-
|
|
6793
|
+
var ANSI_16_COLORS, _palette256 = null, RESET = "\x1B[0m", RESET_FG = "\x1B[39m", RESET_BG = "\x1B[49m";
|
|
6794
|
+
var init_colors = __esm(() => {
|
|
6795
|
+
ANSI_16_COLORS = [
|
|
6796
|
+
{ r: 0, g: 0, b: 0, a: 255 },
|
|
6797
|
+
{ r: 128, g: 0, b: 0, a: 255 },
|
|
6798
|
+
{ r: 0, g: 128, b: 0, a: 255 },
|
|
6799
|
+
{ r: 128, g: 128, b: 0, a: 255 },
|
|
6800
|
+
{ r: 0, g: 0, b: 128, a: 255 },
|
|
6801
|
+
{ r: 128, g: 0, b: 128, a: 255 },
|
|
6802
|
+
{ r: 0, g: 128, b: 128, a: 255 },
|
|
6803
|
+
{ r: 192, g: 192, b: 192, a: 255 },
|
|
6804
|
+
{ r: 128, g: 128, b: 128, a: 255 },
|
|
6805
|
+
{ r: 255, g: 0, b: 0, a: 255 },
|
|
6806
|
+
{ r: 0, g: 255, b: 0, a: 255 },
|
|
6807
|
+
{ r: 255, g: 255, b: 0, a: 255 },
|
|
6808
|
+
{ r: 0, g: 0, b: 255, a: 255 },
|
|
6809
|
+
{ r: 255, g: 0, b: 255, a: 255 },
|
|
6810
|
+
{ r: 0, g: 255, b: 255, a: 255 },
|
|
6811
|
+
{ r: 255, g: 255, b: 255, a: 255 }
|
|
6812
|
+
];
|
|
6813
|
+
});
|
|
6814
|
+
|
|
6231
6815
|
// src/terminal/renderer-chain.ts
|
|
6232
|
-
var RENDERER_REQUIREMENTS = {
|
|
6233
|
-
kitty: { graphics: "kitty" },
|
|
6234
|
-
iterm2: { graphics: "iterm2" },
|
|
6235
|
-
sixel: { graphics: "sixel" },
|
|
6236
|
-
braille: { unicode: true, braille: true },
|
|
6237
|
-
"block-subpixel": { unicode: true },
|
|
6238
|
-
block: { unicode: true },
|
|
6239
|
-
ascii: {}
|
|
6240
|
-
};
|
|
6241
|
-
var FALLBACK_ORDER = [
|
|
6242
|
-
"kitty",
|
|
6243
|
-
"iterm2",
|
|
6244
|
-
"sixel",
|
|
6245
|
-
"braille",
|
|
6246
|
-
"block-subpixel",
|
|
6247
|
-
"block",
|
|
6248
|
-
"ascii"
|
|
6249
|
-
];
|
|
6250
6816
|
function isRendererAvailable(type, caps) {
|
|
6251
6817
|
const reqs = RENDERER_REQUIREMENTS[type];
|
|
6252
6818
|
if (reqs.graphics) {
|
|
@@ -6395,194 +6961,226 @@ function getTerminalInfo() {
|
|
|
6395
6961
|
isTTY: caps.isTTY
|
|
6396
6962
|
};
|
|
6397
6963
|
}
|
|
6964
|
+
var RENDERER_REQUIREMENTS, FALLBACK_ORDER;
|
|
6965
|
+
var init_renderer_chain = __esm(() => {
|
|
6966
|
+
init_colors();
|
|
6967
|
+
RENDERER_REQUIREMENTS = {
|
|
6968
|
+
kitty: { graphics: "kitty" },
|
|
6969
|
+
iterm2: { graphics: "iterm2" },
|
|
6970
|
+
sixel: { graphics: "sixel" },
|
|
6971
|
+
braille: { unicode: true, braille: true },
|
|
6972
|
+
"block-subpixel": { unicode: true },
|
|
6973
|
+
block: { unicode: true },
|
|
6974
|
+
ascii: {}
|
|
6975
|
+
};
|
|
6976
|
+
FALLBACK_ORDER = [
|
|
6977
|
+
"kitty",
|
|
6978
|
+
"iterm2",
|
|
6979
|
+
"sixel",
|
|
6980
|
+
"braille",
|
|
6981
|
+
"block-subpixel",
|
|
6982
|
+
"block",
|
|
6983
|
+
"ascii"
|
|
6984
|
+
];
|
|
6985
|
+
});
|
|
6986
|
+
|
|
6987
|
+
// src/terminal/index.ts
|
|
6988
|
+
var init_terminal = __esm(() => {
|
|
6989
|
+
init_colors();
|
|
6990
|
+
init_renderer_chain();
|
|
6991
|
+
});
|
|
6992
|
+
|
|
6398
6993
|
// src/streaming/data-buffer.ts
|
|
6399
|
-
|
|
6400
|
-
|
|
6401
|
-
|
|
6402
|
-
|
|
6403
|
-
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
|
|
6407
|
-
|
|
6408
|
-
|
|
6409
|
-
|
|
6410
|
-
|
|
6411
|
-
|
|
6412
|
-
|
|
6413
|
-
|
|
6414
|
-
|
|
6415
|
-
|
|
6416
|
-
|
|
6417
|
-
|
|
6418
|
-
|
|
6994
|
+
function createDataBuffer(options) {
|
|
6995
|
+
return new DataBuffer(options);
|
|
6996
|
+
}
|
|
6997
|
+
var DataBuffer;
|
|
6998
|
+
var init_data_buffer = __esm(() => {
|
|
6999
|
+
DataBuffer = class DataBuffer {
|
|
7000
|
+
buffer;
|
|
7001
|
+
head = 0;
|
|
7002
|
+
tail = 0;
|
|
7003
|
+
_size = 0;
|
|
7004
|
+
options;
|
|
7005
|
+
lastCleanup = 0;
|
|
7006
|
+
cleanupInterval = 1000;
|
|
7007
|
+
constructor(options) {
|
|
7008
|
+
this.options = {
|
|
7009
|
+
maxSize: options.maxSize,
|
|
7010
|
+
overwrite: options.overwrite ?? true,
|
|
7011
|
+
timeField: options.timeField ?? "time",
|
|
7012
|
+
maxAge: options.maxAge ?? 0
|
|
7013
|
+
};
|
|
7014
|
+
this.buffer = new Array(options.maxSize);
|
|
6419
7015
|
}
|
|
6420
|
-
|
|
6421
|
-
if (
|
|
6422
|
-
|
|
7016
|
+
push(record) {
|
|
7017
|
+
if (this.options.maxAge > 0) {
|
|
7018
|
+
this.cleanupOldData();
|
|
6423
7019
|
}
|
|
6424
|
-
|
|
6425
|
-
|
|
6426
|
-
|
|
7020
|
+
if (this._size === this.options.maxSize) {
|
|
7021
|
+
if (!this.options.overwrite) {
|
|
7022
|
+
return false;
|
|
7023
|
+
}
|
|
7024
|
+
this.head = (this.head + 1) % this.options.maxSize;
|
|
7025
|
+
} else {
|
|
7026
|
+
this._size++;
|
|
7027
|
+
}
|
|
7028
|
+
this.buffer[this.tail] = record;
|
|
7029
|
+
this.tail = (this.tail + 1) % this.options.maxSize;
|
|
7030
|
+
return true;
|
|
6427
7031
|
}
|
|
6428
|
-
|
|
6429
|
-
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
|
|
7032
|
+
pushMany(records) {
|
|
7033
|
+
let added = 0;
|
|
7034
|
+
for (const record of records) {
|
|
7035
|
+
if (this.push(record)) {
|
|
7036
|
+
added++;
|
|
7037
|
+
}
|
|
7038
|
+
}
|
|
7039
|
+
return added;
|
|
7040
|
+
}
|
|
7041
|
+
shift() {
|
|
7042
|
+
if (this._size === 0) {
|
|
7043
|
+
return;
|
|
6437
7044
|
}
|
|
7045
|
+
const record = this.buffer[this.head];
|
|
7046
|
+
this.head = (this.head + 1) % this.options.maxSize;
|
|
7047
|
+
this._size--;
|
|
7048
|
+
return record;
|
|
6438
7049
|
}
|
|
6439
|
-
|
|
6440
|
-
|
|
6441
|
-
|
|
6442
|
-
|
|
6443
|
-
|
|
7050
|
+
get(index) {
|
|
7051
|
+
if (index < 0 || index >= this._size) {
|
|
7052
|
+
return;
|
|
7053
|
+
}
|
|
7054
|
+
const actualIndex = (this.head + index) % this.options.maxSize;
|
|
7055
|
+
return this.buffer[actualIndex];
|
|
6444
7056
|
}
|
|
6445
|
-
|
|
6446
|
-
|
|
6447
|
-
|
|
6448
|
-
|
|
6449
|
-
|
|
6450
|
-
|
|
6451
|
-
if (index < 0 || index >= this._size) {
|
|
6452
|
-
return;
|
|
7057
|
+
latest() {
|
|
7058
|
+
if (this._size === 0) {
|
|
7059
|
+
return;
|
|
7060
|
+
}
|
|
7061
|
+
const index = (this.tail - 1 + this.options.maxSize) % this.options.maxSize;
|
|
7062
|
+
return this.buffer[index];
|
|
6453
7063
|
}
|
|
6454
|
-
|
|
6455
|
-
|
|
6456
|
-
|
|
6457
|
-
|
|
6458
|
-
|
|
6459
|
-
return;
|
|
7064
|
+
oldest() {
|
|
7065
|
+
if (this._size === 0) {
|
|
7066
|
+
return;
|
|
7067
|
+
}
|
|
7068
|
+
return this.buffer[this.head];
|
|
6460
7069
|
}
|
|
6461
|
-
|
|
6462
|
-
|
|
6463
|
-
|
|
6464
|
-
|
|
6465
|
-
|
|
6466
|
-
|
|
7070
|
+
toArray() {
|
|
7071
|
+
const result = [];
|
|
7072
|
+
for (let i = 0;i < this._size; i++) {
|
|
7073
|
+
const index = (this.head + i) % this.options.maxSize;
|
|
7074
|
+
result.push(this.buffer[index]);
|
|
7075
|
+
}
|
|
7076
|
+
return result;
|
|
6467
7077
|
}
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6473
|
-
|
|
6474
|
-
|
|
7078
|
+
getTimeRange(startTime, endTime) {
|
|
7079
|
+
const timeField = this.options.timeField;
|
|
7080
|
+
const result = [];
|
|
7081
|
+
for (let i = 0;i < this._size; i++) {
|
|
7082
|
+
const index = (this.head + i) % this.options.maxSize;
|
|
7083
|
+
const record = this.buffer[index];
|
|
7084
|
+
const time = record[timeField];
|
|
7085
|
+
if (time >= startTime && time <= endTime) {
|
|
7086
|
+
result.push(record);
|
|
7087
|
+
}
|
|
7088
|
+
}
|
|
7089
|
+
return result;
|
|
6475
7090
|
}
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6482
|
-
const index = (this.head + i) % this.options.maxSize;
|
|
6483
|
-
const record = this.buffer[index];
|
|
6484
|
-
const time = record[timeField];
|
|
6485
|
-
if (time >= startTime && time <= endTime) {
|
|
6486
|
-
result.push(record);
|
|
7091
|
+
getLast(n) {
|
|
7092
|
+
const count = Math.min(n, this._size);
|
|
7093
|
+
const result = [];
|
|
7094
|
+
for (let i = this._size - count;i < this._size; i++) {
|
|
7095
|
+
const index = (this.head + i) % this.options.maxSize;
|
|
7096
|
+
result.push(this.buffer[index]);
|
|
6487
7097
|
}
|
|
7098
|
+
return result;
|
|
6488
7099
|
}
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
|
|
6492
|
-
|
|
6493
|
-
const result = [];
|
|
6494
|
-
for (let i = this._size - count;i < this._size; i++) {
|
|
6495
|
-
const index = (this.head + i) % this.options.maxSize;
|
|
6496
|
-
result.push(this.buffer[index]);
|
|
7100
|
+
clear() {
|
|
7101
|
+
this.head = 0;
|
|
7102
|
+
this.tail = 0;
|
|
7103
|
+
this._size = 0;
|
|
6497
7104
|
}
|
|
6498
|
-
|
|
6499
|
-
|
|
6500
|
-
clear() {
|
|
6501
|
-
this.head = 0;
|
|
6502
|
-
this.tail = 0;
|
|
6503
|
-
this._size = 0;
|
|
6504
|
-
}
|
|
6505
|
-
get size() {
|
|
6506
|
-
return this._size;
|
|
6507
|
-
}
|
|
6508
|
-
get capacity() {
|
|
6509
|
-
return this.options.maxSize;
|
|
6510
|
-
}
|
|
6511
|
-
get isFull() {
|
|
6512
|
-
return this._size === this.options.maxSize;
|
|
6513
|
-
}
|
|
6514
|
-
get isEmpty() {
|
|
6515
|
-
return this._size === 0;
|
|
6516
|
-
}
|
|
6517
|
-
getTimeExtent() {
|
|
6518
|
-
if (this._size === 0) {
|
|
6519
|
-
return null;
|
|
7105
|
+
get size() {
|
|
7106
|
+
return this._size;
|
|
6520
7107
|
}
|
|
6521
|
-
|
|
6522
|
-
|
|
6523
|
-
let max = -Infinity;
|
|
6524
|
-
for (let i = 0;i < this._size; i++) {
|
|
6525
|
-
const index = (this.head + i) % this.options.maxSize;
|
|
6526
|
-
const time = this.buffer[index][timeField];
|
|
6527
|
-
if (time < min)
|
|
6528
|
-
min = time;
|
|
6529
|
-
if (time > max)
|
|
6530
|
-
max = time;
|
|
7108
|
+
get capacity() {
|
|
7109
|
+
return this.options.maxSize;
|
|
6531
7110
|
}
|
|
6532
|
-
|
|
6533
|
-
|
|
6534
|
-
cleanupOldData() {
|
|
6535
|
-
const now = Date.now();
|
|
6536
|
-
if (now - this.lastCleanup < this.cleanupInterval) {
|
|
6537
|
-
return;
|
|
7111
|
+
get isFull() {
|
|
7112
|
+
return this._size === this.options.maxSize;
|
|
6538
7113
|
}
|
|
6539
|
-
|
|
6540
|
-
|
|
6541
|
-
|
|
6542
|
-
|
|
6543
|
-
|
|
6544
|
-
|
|
6545
|
-
if (time >= cutoff) {
|
|
6546
|
-
break;
|
|
7114
|
+
get isEmpty() {
|
|
7115
|
+
return this._size === 0;
|
|
7116
|
+
}
|
|
7117
|
+
getTimeExtent() {
|
|
7118
|
+
if (this._size === 0) {
|
|
7119
|
+
return null;
|
|
6547
7120
|
}
|
|
6548
|
-
|
|
6549
|
-
|
|
7121
|
+
const timeField = this.options.timeField;
|
|
7122
|
+
let min = Infinity;
|
|
7123
|
+
let max = -Infinity;
|
|
7124
|
+
for (let i = 0;i < this._size; i++) {
|
|
7125
|
+
const index = (this.head + i) % this.options.maxSize;
|
|
7126
|
+
const time = this.buffer[index][timeField];
|
|
7127
|
+
if (time < min)
|
|
7128
|
+
min = time;
|
|
7129
|
+
if (time > max)
|
|
7130
|
+
max = time;
|
|
7131
|
+
}
|
|
7132
|
+
return { min, max };
|
|
6550
7133
|
}
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
|
|
7134
|
+
cleanupOldData() {
|
|
7135
|
+
const now = Date.now();
|
|
7136
|
+
if (now - this.lastCleanup < this.cleanupInterval) {
|
|
7137
|
+
return;
|
|
7138
|
+
}
|
|
7139
|
+
this.lastCleanup = now;
|
|
7140
|
+
const cutoff = now - this.options.maxAge;
|
|
7141
|
+
const timeField = this.options.timeField;
|
|
7142
|
+
while (this._size > 0) {
|
|
7143
|
+
const oldest = this.buffer[this.head];
|
|
7144
|
+
const time = oldest[timeField];
|
|
7145
|
+
if (time >= cutoff) {
|
|
7146
|
+
break;
|
|
7147
|
+
}
|
|
7148
|
+
this.head = (this.head + 1) % this.options.maxSize;
|
|
7149
|
+
this._size--;
|
|
7150
|
+
}
|
|
6556
7151
|
}
|
|
6557
|
-
|
|
6558
|
-
|
|
6559
|
-
|
|
6560
|
-
|
|
6561
|
-
|
|
6562
|
-
result.push(fn(record, i++));
|
|
7152
|
+
*[Symbol.iterator]() {
|
|
7153
|
+
for (let i = 0;i < this._size; i++) {
|
|
7154
|
+
const index = (this.head + i) % this.options.maxSize;
|
|
7155
|
+
yield this.buffer[index];
|
|
7156
|
+
}
|
|
6563
7157
|
}
|
|
6564
|
-
|
|
6565
|
-
|
|
6566
|
-
|
|
6567
|
-
|
|
6568
|
-
|
|
6569
|
-
if (fn(record)) {
|
|
6570
|
-
result.push(record);
|
|
7158
|
+
map(fn) {
|
|
7159
|
+
const result = [];
|
|
7160
|
+
let i = 0;
|
|
7161
|
+
for (const record of this) {
|
|
7162
|
+
result.push(fn(record, i++));
|
|
6571
7163
|
}
|
|
7164
|
+
return result;
|
|
6572
7165
|
}
|
|
6573
|
-
|
|
6574
|
-
|
|
6575
|
-
|
|
6576
|
-
|
|
6577
|
-
|
|
6578
|
-
|
|
7166
|
+
filter(fn) {
|
|
7167
|
+
const result = [];
|
|
7168
|
+
for (const record of this) {
|
|
7169
|
+
if (fn(record)) {
|
|
7170
|
+
result.push(record);
|
|
7171
|
+
}
|
|
7172
|
+
}
|
|
7173
|
+
return result;
|
|
6579
7174
|
}
|
|
6580
|
-
|
|
6581
|
-
|
|
6582
|
-
|
|
6583
|
-
|
|
6584
|
-
|
|
6585
|
-
|
|
7175
|
+
reduce(fn, initial) {
|
|
7176
|
+
let acc = initial;
|
|
7177
|
+
for (const record of this) {
|
|
7178
|
+
acc = fn(acc, record);
|
|
7179
|
+
}
|
|
7180
|
+
return acc;
|
|
7181
|
+
}
|
|
7182
|
+
};
|
|
7183
|
+
});
|
|
6586
7184
|
|
|
6587
7185
|
// src/streaming/data-window.ts
|
|
6588
7186
|
class DataWindow {
|
|
@@ -6757,6 +7355,9 @@ class DataWindow {
|
|
|
6757
7355
|
function createDataWindow(options) {
|
|
6758
7356
|
return new DataWindow(options);
|
|
6759
7357
|
}
|
|
7358
|
+
var init_data_window = __esm(() => {
|
|
7359
|
+
init_data_buffer();
|
|
7360
|
+
});
|
|
6760
7361
|
|
|
6761
7362
|
// src/streaming/rolling-aggregator.ts
|
|
6762
7363
|
class RollingAggregator {
|
|
@@ -7217,6 +7818,19 @@ function createTimeSeriesPlot(options) {
|
|
|
7217
7818
|
labels: { title: options.title ?? "Time Series" }
|
|
7218
7819
|
});
|
|
7219
7820
|
}
|
|
7821
|
+
var init_streaming_plot = __esm(() => {
|
|
7822
|
+
init_grammar();
|
|
7823
|
+
init_data_buffer();
|
|
7824
|
+
init_data_window();
|
|
7825
|
+
});
|
|
7826
|
+
|
|
7827
|
+
// src/streaming/index.ts
|
|
7828
|
+
var init_streaming = __esm(() => {
|
|
7829
|
+
init_streaming_plot();
|
|
7830
|
+
init_data_window();
|
|
7831
|
+
init_data_buffer();
|
|
7832
|
+
});
|
|
7833
|
+
|
|
7220
7834
|
// src/performance/sampling.ts
|
|
7221
7835
|
class SeededRandom {
|
|
7222
7836
|
seed;
|
|
@@ -7382,14 +7996,8 @@ function autoSample(data, targetSize, options = {}) {
|
|
|
7382
7996
|
}
|
|
7383
7997
|
return systematicSample(data, targetSize);
|
|
7384
7998
|
}
|
|
7999
|
+
|
|
7385
8000
|
// src/performance/level-of-detail.ts
|
|
7386
|
-
var DEFAULT_LOD_LEVELS = [
|
|
7387
|
-
{ name: "full", maxPoints: 500, threshold: 0 },
|
|
7388
|
-
{ name: "medium", maxPoints: 1000, threshold: 1000, samplingMethod: "lttb" },
|
|
7389
|
-
{ name: "low", maxPoints: 500, threshold: 5000, samplingMethod: "lttb" },
|
|
7390
|
-
{ name: "veryLow", maxPoints: 200, threshold: 20000, samplingMethod: "systematic" },
|
|
7391
|
-
{ name: "minimal", maxPoints: 100, threshold: 1e5, samplingMethod: "binned", binResolution: 50 }
|
|
7392
|
-
];
|
|
7393
8001
|
function binData(data, resolution, xField, yField) {
|
|
7394
8002
|
if (data.length === 0)
|
|
7395
8003
|
return [];
|
|
@@ -7487,252 +8095,72 @@ class LevelOfDetail {
|
|
|
7487
8095
|
switch (method) {
|
|
7488
8096
|
case "lttb":
|
|
7489
8097
|
return lttbSample(data, level.maxPoints, this.options.xField, this.options.yField);
|
|
7490
|
-
case "binned":
|
|
7491
|
-
return binData(data, level.binResolution || 50, this.options.xField, this.options.yField);
|
|
7492
|
-
case "systematic":
|
|
7493
|
-
default:
|
|
7494
|
-
return systematicSample(data, level.maxPoints);
|
|
7495
|
-
}
|
|
7496
|
-
}
|
|
7497
|
-
updateRenderTime(renderMs) {
|
|
7498
|
-
this.lastRenderMs = renderMs;
|
|
7499
|
-
if (renderMs > this.options.targetRenderMs * 1.5) {
|
|
7500
|
-
this.adaptiveMaxPoints = Math.max(50, Math.floor(this.adaptiveMaxPoints * 0.8));
|
|
7501
|
-
} else if (renderMs < this.options.targetRenderMs * 0.5) {
|
|
7502
|
-
this.adaptiveMaxPoints = Math.min(this.currentLevel.maxPoints * 2, Math.floor(this.adaptiveMaxPoints * 1.2));
|
|
7503
|
-
}
|
|
7504
|
-
}
|
|
7505
|
-
getCurrentLevel() {
|
|
7506
|
-
return this.currentLevel;
|
|
7507
|
-
}
|
|
7508
|
-
getLevels() {
|
|
7509
|
-
return [...this.options.levels];
|
|
7510
|
-
}
|
|
7511
|
-
setLevel(name) {
|
|
7512
|
-
const level = this.options.levels.find((l) => l.name === name);
|
|
7513
|
-
if (level) {
|
|
7514
|
-
this.currentLevel = level;
|
|
7515
|
-
this.adaptiveMaxPoints = level.maxPoints;
|
|
7516
|
-
return true;
|
|
7517
|
-
}
|
|
7518
|
-
return false;
|
|
7519
|
-
}
|
|
7520
|
-
getStats() {
|
|
7521
|
-
return {
|
|
7522
|
-
currentLevel: this.currentLevel.name,
|
|
7523
|
-
maxPoints: this.currentLevel.maxPoints,
|
|
7524
|
-
adaptiveMaxPoints: this.adaptiveMaxPoints,
|
|
7525
|
-
lastRenderMs: this.lastRenderMs,
|
|
7526
|
-
targetRenderMs: this.options.targetRenderMs
|
|
7527
|
-
};
|
|
7528
|
-
}
|
|
7529
|
-
processAdaptive(data) {
|
|
7530
|
-
if (data.length <= this.adaptiveMaxPoints) {
|
|
7531
|
-
return data;
|
|
7532
|
-
}
|
|
7533
|
-
return lttbSample(data, this.adaptiveMaxPoints, this.options.xField, this.options.yField);
|
|
7534
|
-
}
|
|
7535
|
-
}
|
|
7536
|
-
function createLOD(options = {}) {
|
|
7537
|
-
return new LevelOfDetail({
|
|
7538
|
-
levels: options.levels ?? DEFAULT_LOD_LEVELS,
|
|
7539
|
-
xField: options.xField,
|
|
7540
|
-
yField: options.yField,
|
|
7541
|
-
autoSelect: options.autoSelect,
|
|
7542
|
-
targetRenderMs: options.targetRenderMs
|
|
7543
|
-
});
|
|
7544
|
-
}
|
|
7545
|
-
// src/performance/binning.ts
|
|
7546
|
-
function computeDomain2(data, field) {
|
|
7547
|
-
let min = Infinity;
|
|
7548
|
-
let max = -Infinity;
|
|
7549
|
-
for (const d of data) {
|
|
7550
|
-
const v = d[field];
|
|
7551
|
-
if (typeof v === "number" && !isNaN(v)) {
|
|
7552
|
-
if (v < min)
|
|
7553
|
-
min = v;
|
|
7554
|
-
if (v > max)
|
|
7555
|
-
max = v;
|
|
7556
|
-
}
|
|
7557
|
-
}
|
|
7558
|
-
if (min === Infinity)
|
|
7559
|
-
return [0, 1];
|
|
7560
|
-
if (min === max)
|
|
7561
|
-
return [min - 0.5, max + 0.5];
|
|
7562
|
-
return [min, max];
|
|
7563
|
-
}
|
|
7564
|
-
function aggregateValues(values, method) {
|
|
7565
|
-
if (values.length === 0)
|
|
7566
|
-
return 0;
|
|
7567
|
-
switch (method) {
|
|
7568
|
-
case "count":
|
|
7569
|
-
return values.length;
|
|
7570
|
-
case "sum":
|
|
7571
|
-
return values.reduce((a, b) => a + b, 0);
|
|
7572
|
-
case "mean":
|
|
7573
|
-
return values.reduce((a, b) => a + b, 0) / values.length;
|
|
7574
|
-
case "median":
|
|
7575
|
-
const sorted = [...values].sort((a, b) => a - b);
|
|
7576
|
-
const mid = Math.floor(sorted.length / 2);
|
|
7577
|
-
return sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
|
|
7578
|
-
case "min":
|
|
7579
|
-
return Math.min(...values);
|
|
7580
|
-
case "max":
|
|
7581
|
-
return Math.max(...values);
|
|
7582
|
-
default:
|
|
7583
|
-
return values.length;
|
|
7584
|
-
}
|
|
7585
|
-
}
|
|
7586
|
-
function rectbin(data, options) {
|
|
7587
|
-
const {
|
|
7588
|
-
xField,
|
|
7589
|
-
yField,
|
|
7590
|
-
xBins = 20,
|
|
7591
|
-
yBins = 20,
|
|
7592
|
-
aggregate = "count",
|
|
7593
|
-
valueField
|
|
7594
|
-
} = options;
|
|
7595
|
-
if (data.length === 0)
|
|
7596
|
-
return [];
|
|
7597
|
-
const xDomain = options.xDomain ?? computeDomain2(data, xField);
|
|
7598
|
-
const yDomain = options.yDomain ?? computeDomain2(data, yField);
|
|
7599
|
-
const xRange = xDomain[1] - xDomain[0];
|
|
7600
|
-
const yRange = yDomain[1] - yDomain[0];
|
|
7601
|
-
const binWidth = xRange / xBins;
|
|
7602
|
-
const binHeight = yRange / yBins;
|
|
7603
|
-
const bins = new Map;
|
|
7604
|
-
for (const point of data) {
|
|
7605
|
-
const x = point[xField];
|
|
7606
|
-
const y = point[yField];
|
|
7607
|
-
if (typeof x !== "number" || typeof y !== "number")
|
|
7608
|
-
continue;
|
|
7609
|
-
const bx = Math.min(xBins - 1, Math.max(0, Math.floor((x - xDomain[0]) / binWidth)));
|
|
7610
|
-
const by = Math.min(yBins - 1, Math.max(0, Math.floor((y - yDomain[0]) / binHeight)));
|
|
7611
|
-
const key = `${bx},${by}`;
|
|
7612
|
-
if (!bins.has(key)) {
|
|
7613
|
-
bins.set(key, { points: [], values: [] });
|
|
7614
|
-
}
|
|
7615
|
-
const bin = bins.get(key);
|
|
7616
|
-
bin.points.push(point);
|
|
7617
|
-
if (valueField && typeof point[valueField] === "number") {
|
|
7618
|
-
bin.values.push(point[valueField]);
|
|
7619
|
-
}
|
|
7620
|
-
}
|
|
7621
|
-
const result = [];
|
|
7622
|
-
for (const [key, bin] of bins) {
|
|
7623
|
-
const [bx, by] = key.split(",").map(Number);
|
|
7624
|
-
const centerX = xDomain[0] + (bx + 0.5) * binWidth;
|
|
7625
|
-
const centerY = yDomain[0] + (by + 0.5) * binHeight;
|
|
7626
|
-
result.push({
|
|
7627
|
-
x: centerX,
|
|
7628
|
-
y: centerY,
|
|
7629
|
-
count: bin.points.length,
|
|
7630
|
-
value: aggregateValues(bin.values.length > 0 ? bin.values : [bin.points.length], aggregate),
|
|
7631
|
-
width: binWidth,
|
|
7632
|
-
height: binHeight,
|
|
7633
|
-
points: bin.points
|
|
7634
|
-
});
|
|
7635
|
-
}
|
|
7636
|
-
return result;
|
|
7637
|
-
}
|
|
7638
|
-
function hexbin(data, options) {
|
|
7639
|
-
const { xField, yField, aggregate = "count", valueField, radius = 10 } = options;
|
|
7640
|
-
if (data.length === 0)
|
|
7641
|
-
return [];
|
|
7642
|
-
const xDomain = options.xDomain ?? computeDomain2(data, xField);
|
|
7643
|
-
const yDomain = options.yDomain ?? computeDomain2(data, yField);
|
|
7644
|
-
const hexWidth = radius * 2;
|
|
7645
|
-
const hexHeight = radius * Math.sqrt(3);
|
|
7646
|
-
const bins = new Map;
|
|
7647
|
-
for (const point of data) {
|
|
7648
|
-
const x = point[xField];
|
|
7649
|
-
const y = point[yField];
|
|
7650
|
-
if (typeof x !== "number" || typeof y !== "number")
|
|
7651
|
-
continue;
|
|
7652
|
-
const col = Math.round((x - xDomain[0]) / (hexWidth * 0.75));
|
|
7653
|
-
const row = Math.round((y - yDomain[0]) / hexHeight - col % 2 * 0.5);
|
|
7654
|
-
const key = `${col},${row}`;
|
|
7655
|
-
if (!bins.has(key)) {
|
|
7656
|
-
bins.set(key, { points: [], values: [], col, row });
|
|
7657
|
-
}
|
|
7658
|
-
const bin = bins.get(key);
|
|
7659
|
-
bin.points.push(point);
|
|
7660
|
-
if (valueField && typeof point[valueField] === "number") {
|
|
7661
|
-
bin.values.push(point[valueField]);
|
|
8098
|
+
case "binned":
|
|
8099
|
+
return binData(data, level.binResolution || 50, this.options.xField, this.options.yField);
|
|
8100
|
+
case "systematic":
|
|
8101
|
+
default:
|
|
8102
|
+
return systematicSample(data, level.maxPoints);
|
|
7662
8103
|
}
|
|
7663
8104
|
}
|
|
7664
|
-
|
|
7665
|
-
|
|
7666
|
-
|
|
7667
|
-
|
|
7668
|
-
|
|
7669
|
-
|
|
7670
|
-
y: cy + r * Math.sin(angle)
|
|
7671
|
-
});
|
|
8105
|
+
updateRenderTime(renderMs) {
|
|
8106
|
+
this.lastRenderMs = renderMs;
|
|
8107
|
+
if (renderMs > this.options.targetRenderMs * 1.5) {
|
|
8108
|
+
this.adaptiveMaxPoints = Math.max(50, Math.floor(this.adaptiveMaxPoints * 0.8));
|
|
8109
|
+
} else if (renderMs < this.options.targetRenderMs * 0.5) {
|
|
8110
|
+
this.adaptiveMaxPoints = Math.min(this.currentLevel.maxPoints * 2, Math.floor(this.adaptiveMaxPoints * 1.2));
|
|
7672
8111
|
}
|
|
7673
|
-
return vertices;
|
|
7674
8112
|
}
|
|
7675
|
-
|
|
7676
|
-
|
|
7677
|
-
const centerX = xDomain[0] + bin.col * hexWidth * 0.75;
|
|
7678
|
-
const centerY = yDomain[0] + (bin.row + bin.col % 2 * 0.5) * hexHeight;
|
|
7679
|
-
result.push({
|
|
7680
|
-
x: centerX,
|
|
7681
|
-
y: centerY,
|
|
7682
|
-
count: bin.points.length,
|
|
7683
|
-
value: aggregateValues(bin.values.length > 0 ? bin.values : [bin.points.length], aggregate),
|
|
7684
|
-
width: hexWidth,
|
|
7685
|
-
height: hexHeight,
|
|
7686
|
-
points: bin.points,
|
|
7687
|
-
vertices: hexVertices(centerX, centerY, radius),
|
|
7688
|
-
col: bin.col,
|
|
7689
|
-
row: bin.row
|
|
7690
|
-
});
|
|
8113
|
+
getCurrentLevel() {
|
|
8114
|
+
return this.currentLevel;
|
|
7691
8115
|
}
|
|
7692
|
-
|
|
7693
|
-
|
|
7694
|
-
|
|
7695
|
-
class Binner {
|
|
7696
|
-
options;
|
|
7697
|
-
type;
|
|
7698
|
-
hexRadius;
|
|
7699
|
-
constructor(options) {
|
|
7700
|
-
this.options = options;
|
|
7701
|
-
this.type = options.type ?? "rect";
|
|
7702
|
-
this.hexRadius = options.hexRadius ?? 10;
|
|
8116
|
+
getLevels() {
|
|
8117
|
+
return [...this.options.levels];
|
|
7703
8118
|
}
|
|
7704
|
-
|
|
7705
|
-
|
|
7706
|
-
|
|
8119
|
+
setLevel(name) {
|
|
8120
|
+
const level = this.options.levels.find((l) => l.name === name);
|
|
8121
|
+
if (level) {
|
|
8122
|
+
this.currentLevel = level;
|
|
8123
|
+
this.adaptiveMaxPoints = level.maxPoints;
|
|
8124
|
+
return true;
|
|
7707
8125
|
}
|
|
7708
|
-
return
|
|
8126
|
+
return false;
|
|
7709
8127
|
}
|
|
7710
|
-
|
|
7711
|
-
|
|
7712
|
-
|
|
7713
|
-
|
|
7714
|
-
|
|
7715
|
-
|
|
7716
|
-
|
|
7717
|
-
|
|
7718
|
-
count: bin.count,
|
|
7719
|
-
value: bin.value,
|
|
7720
|
-
size: minSize + bin.count / maxCount * (maxSize - minSize)
|
|
7721
|
-
}));
|
|
8128
|
+
getStats() {
|
|
8129
|
+
return {
|
|
8130
|
+
currentLevel: this.currentLevel.name,
|
|
8131
|
+
maxPoints: this.currentLevel.maxPoints,
|
|
8132
|
+
adaptiveMaxPoints: this.adaptiveMaxPoints,
|
|
8133
|
+
lastRenderMs: this.lastRenderMs,
|
|
8134
|
+
targetRenderMs: this.options.targetRenderMs
|
|
8135
|
+
};
|
|
7722
8136
|
}
|
|
7723
|
-
|
|
7724
|
-
|
|
7725
|
-
|
|
7726
|
-
for (const bin of bins) {
|
|
7727
|
-
const t = bin.count / maxCount;
|
|
7728
|
-
colors.set(bin, colorScale(t));
|
|
8137
|
+
processAdaptive(data) {
|
|
8138
|
+
if (data.length <= this.adaptiveMaxPoints) {
|
|
8139
|
+
return data;
|
|
7729
8140
|
}
|
|
7730
|
-
return
|
|
8141
|
+
return lttbSample(data, this.adaptiveMaxPoints, this.options.xField, this.options.yField);
|
|
7731
8142
|
}
|
|
7732
8143
|
}
|
|
7733
|
-
function
|
|
7734
|
-
return new
|
|
8144
|
+
function createLOD(options = {}) {
|
|
8145
|
+
return new LevelOfDetail({
|
|
8146
|
+
levels: options.levels ?? DEFAULT_LOD_LEVELS,
|
|
8147
|
+
xField: options.xField,
|
|
8148
|
+
yField: options.yField,
|
|
8149
|
+
autoSelect: options.autoSelect,
|
|
8150
|
+
targetRenderMs: options.targetRenderMs
|
|
8151
|
+
});
|
|
7735
8152
|
}
|
|
8153
|
+
var DEFAULT_LOD_LEVELS;
|
|
8154
|
+
var init_level_of_detail = __esm(() => {
|
|
8155
|
+
DEFAULT_LOD_LEVELS = [
|
|
8156
|
+
{ name: "full", maxPoints: 500, threshold: 0 },
|
|
8157
|
+
{ name: "medium", maxPoints: 1000, threshold: 1000, samplingMethod: "lttb" },
|
|
8158
|
+
{ name: "low", maxPoints: 500, threshold: 5000, samplingMethod: "lttb" },
|
|
8159
|
+
{ name: "veryLow", maxPoints: 200, threshold: 20000, samplingMethod: "systematic" },
|
|
8160
|
+
{ name: "minimal", maxPoints: 100, threshold: 1e5, samplingMethod: "binned", binResolution: 50 }
|
|
8161
|
+
];
|
|
8162
|
+
});
|
|
8163
|
+
|
|
7736
8164
|
// src/performance/canvas-diff.ts
|
|
7737
8165
|
function colorsEqual(a, b, tolerance = 0) {
|
|
7738
8166
|
if (tolerance === 0) {
|
|
@@ -7913,8 +8341,15 @@ function quickDiff(oldCanvas, newCanvas) {
|
|
|
7913
8341
|
}
|
|
7914
8342
|
return false;
|
|
7915
8343
|
}
|
|
8344
|
+
|
|
8345
|
+
// src/performance/index.ts
|
|
8346
|
+
var init_performance = __esm(() => {
|
|
8347
|
+
init_level_of_detail();
|
|
8348
|
+
});
|
|
8349
|
+
|
|
7916
8350
|
// src/repl/repl.ts
|
|
7917
8351
|
import * as readline from "readline";
|
|
8352
|
+
|
|
7918
8353
|
class GGTermREPL {
|
|
7919
8354
|
rl = null;
|
|
7920
8355
|
state;
|
|
@@ -8549,25 +8984,18 @@ function startREPL(options) {
|
|
|
8549
8984
|
repl.start();
|
|
8550
8985
|
return repl;
|
|
8551
8986
|
}
|
|
8987
|
+
var init_repl = __esm(() => {
|
|
8988
|
+
init_grammar();
|
|
8989
|
+
init_geoms();
|
|
8990
|
+
init_scales2();
|
|
8991
|
+
});
|
|
8992
|
+
|
|
8993
|
+
// src/repl/index.ts
|
|
8994
|
+
var init_repl2 = __esm(() => {
|
|
8995
|
+
init_repl();
|
|
8996
|
+
});
|
|
8997
|
+
|
|
8552
8998
|
// src/export/vega-lite.ts
|
|
8553
|
-
var GEOM_TO_MARK = {
|
|
8554
|
-
point: "point",
|
|
8555
|
-
line: "line",
|
|
8556
|
-
bar: "bar",
|
|
8557
|
-
area: "area",
|
|
8558
|
-
boxplot: "boxplot",
|
|
8559
|
-
rect: "rect",
|
|
8560
|
-
text: "text",
|
|
8561
|
-
rule: "rule",
|
|
8562
|
-
histogram: "bar",
|
|
8563
|
-
freqpoly: "line",
|
|
8564
|
-
violin: "area",
|
|
8565
|
-
step: "line",
|
|
8566
|
-
path: "line",
|
|
8567
|
-
segment: "rule",
|
|
8568
|
-
smooth: "line",
|
|
8569
|
-
errorbar: "errorbar"
|
|
8570
|
-
};
|
|
8571
8999
|
function inferFieldType(data, field) {
|
|
8572
9000
|
const values = data.map((d) => d[field]).filter((v) => v != null);
|
|
8573
9001
|
if (values.length === 0)
|
|
@@ -8587,11 +9015,12 @@ function inferFieldType(data, field) {
|
|
|
8587
9015
|
}
|
|
8588
9016
|
function buildEncoding(aes, data, geom) {
|
|
8589
9017
|
const encoding = {};
|
|
9018
|
+
const isHeatmap = geom.type === "tile" || geom.type === "raster";
|
|
8590
9019
|
if (aes.x) {
|
|
8591
9020
|
const xType = inferFieldType(data, aes.x);
|
|
8592
9021
|
encoding.x = {
|
|
8593
9022
|
field: aes.x,
|
|
8594
|
-
type: xType,
|
|
9023
|
+
type: isHeatmap && xType === "quantitative" ? "ordinal" : xType,
|
|
8595
9024
|
...xType === "temporal" ? { timeUnit: "yearmonthdate" } : {}
|
|
8596
9025
|
};
|
|
8597
9026
|
}
|
|
@@ -8602,18 +9031,25 @@ function buildEncoding(aes, data, geom) {
|
|
|
8602
9031
|
const yType = inferFieldType(data, aes.y);
|
|
8603
9032
|
encoding.y = {
|
|
8604
9033
|
field: aes.y,
|
|
8605
|
-
type: yType
|
|
9034
|
+
type: isHeatmap && yType === "quantitative" ? "ordinal" : yType
|
|
8606
9035
|
};
|
|
8607
9036
|
}
|
|
8608
9037
|
}
|
|
8609
|
-
if (aes.
|
|
9038
|
+
if (isHeatmap && aes.fill) {
|
|
9039
|
+
const fillType = inferFieldType(data, aes.fill);
|
|
9040
|
+
encoding.color = {
|
|
9041
|
+
field: aes.fill,
|
|
9042
|
+
type: fillType === "nominal" ? "quantitative" : fillType,
|
|
9043
|
+
scale: { scheme: "viridis" }
|
|
9044
|
+
};
|
|
9045
|
+
} else if (aes.color) {
|
|
8610
9046
|
const colorType = inferFieldType(data, aes.color);
|
|
8611
9047
|
encoding.color = {
|
|
8612
9048
|
field: aes.color,
|
|
8613
9049
|
type: colorType
|
|
8614
9050
|
};
|
|
8615
9051
|
}
|
|
8616
|
-
if (aes.fill && !aes.color) {
|
|
9052
|
+
if (aes.fill && !aes.color && !isHeatmap) {
|
|
8617
9053
|
const fillType = inferFieldType(data, aes.fill);
|
|
8618
9054
|
encoding.color = {
|
|
8619
9055
|
field: aes.fill,
|
|
@@ -8646,16 +9082,39 @@ function buildMark(geom) {
|
|
|
8646
9082
|
markProps.color = geom.params.color;
|
|
8647
9083
|
if (geom.params.fill)
|
|
8648
9084
|
markProps.fill = geom.params.fill;
|
|
9085
|
+
if (geom.params.linetype === "dashed")
|
|
9086
|
+
markProps.strokeDash = [4, 4];
|
|
9087
|
+
if (geom.params.linetype === "dotted")
|
|
9088
|
+
markProps.strokeDash = [2, 2];
|
|
8649
9089
|
}
|
|
8650
9090
|
if (geom.type === "step") {
|
|
8651
9091
|
markProps.interpolate = "step-after";
|
|
8652
9092
|
}
|
|
8653
|
-
if (geom.type === "smooth") {
|
|
9093
|
+
if (geom.type === "smooth" || geom.type === "curve") {
|
|
8654
9094
|
markProps.interpolate = "monotone";
|
|
8655
9095
|
}
|
|
8656
9096
|
if (geom.type === "histogram") {
|
|
8657
9097
|
markProps.type = "bar";
|
|
8658
9098
|
}
|
|
9099
|
+
if (geom.type === "tile" || geom.type === "raster" || geom.type === "density_2d") {
|
|
9100
|
+
markProps.type = "rect";
|
|
9101
|
+
markProps.tooltip = true;
|
|
9102
|
+
}
|
|
9103
|
+
if (geom.type === "contour") {
|
|
9104
|
+
markProps.type = "line";
|
|
9105
|
+
markProps.strokeWidth = 1;
|
|
9106
|
+
}
|
|
9107
|
+
if (geom.type === "contour_filled") {
|
|
9108
|
+
markProps.type = "area";
|
|
9109
|
+
markProps.opacity = 0.7;
|
|
9110
|
+
}
|
|
9111
|
+
if (geom.type === "qq") {
|
|
9112
|
+
markProps.type = "point";
|
|
9113
|
+
}
|
|
9114
|
+
if (geom.type === "qq_line") {
|
|
9115
|
+
markProps.type = "line";
|
|
9116
|
+
markProps.strokeDash = [4, 4];
|
|
9117
|
+
}
|
|
8659
9118
|
if (Object.keys(markProps).length === 1) {
|
|
8660
9119
|
return markType;
|
|
8661
9120
|
}
|
|
@@ -8705,6 +9164,184 @@ function buildBoxplotSpec(data, aes) {
|
|
|
8705
9164
|
}
|
|
8706
9165
|
};
|
|
8707
9166
|
}
|
|
9167
|
+
function buildHLineSpec(geom, _data) {
|
|
9168
|
+
const yintercept = geom.params?.yintercept;
|
|
9169
|
+
if (yintercept !== undefined) {
|
|
9170
|
+
return {
|
|
9171
|
+
mark: { type: "rule", strokeDash: geom.params?.linetype === "dashed" ? [4, 4] : undefined },
|
|
9172
|
+
encoding: {
|
|
9173
|
+
y: { datum: yintercept },
|
|
9174
|
+
...geom.params?.color ? { color: { value: geom.params.color } } : {}
|
|
9175
|
+
}
|
|
9176
|
+
};
|
|
9177
|
+
}
|
|
9178
|
+
return {
|
|
9179
|
+
mark: "rule",
|
|
9180
|
+
encoding: {
|
|
9181
|
+
y: { field: "y", type: "quantitative" }
|
|
9182
|
+
}
|
|
9183
|
+
};
|
|
9184
|
+
}
|
|
9185
|
+
function buildVLineSpec(geom, _data) {
|
|
9186
|
+
const xintercept = geom.params?.xintercept;
|
|
9187
|
+
if (xintercept !== undefined) {
|
|
9188
|
+
return {
|
|
9189
|
+
mark: { type: "rule", strokeDash: geom.params?.linetype === "dashed" ? [4, 4] : undefined },
|
|
9190
|
+
encoding: {
|
|
9191
|
+
x: { datum: xintercept },
|
|
9192
|
+
...geom.params?.color ? { color: { value: geom.params.color } } : {}
|
|
9193
|
+
}
|
|
9194
|
+
};
|
|
9195
|
+
}
|
|
9196
|
+
return {
|
|
9197
|
+
mark: "rule",
|
|
9198
|
+
encoding: {
|
|
9199
|
+
x: { field: "x", type: "quantitative" }
|
|
9200
|
+
}
|
|
9201
|
+
};
|
|
9202
|
+
}
|
|
9203
|
+
function buildAblineSpec(geom, data, aes) {
|
|
9204
|
+
const slope = geom.params?.slope ?? 1;
|
|
9205
|
+
const intercept = geom.params?.intercept ?? 0;
|
|
9206
|
+
const xValues = data.map((d) => Number(d[aes.x])).filter((x) => !isNaN(x));
|
|
9207
|
+
const xMin = Math.min(...xValues);
|
|
9208
|
+
const xMax = Math.max(...xValues);
|
|
9209
|
+
const yMin = slope * xMin + intercept;
|
|
9210
|
+
const yMax = slope * xMax + intercept;
|
|
9211
|
+
return {
|
|
9212
|
+
data: {
|
|
9213
|
+
values: [
|
|
9214
|
+
{ x: xMin, y: yMin },
|
|
9215
|
+
{ x: xMax, y: yMax }
|
|
9216
|
+
]
|
|
9217
|
+
},
|
|
9218
|
+
mark: { type: "line", strokeDash: geom.params?.linetype === "dashed" ? [4, 4] : undefined },
|
|
9219
|
+
encoding: {
|
|
9220
|
+
x: { field: "x", type: "quantitative" },
|
|
9221
|
+
y: { field: "y", type: "quantitative" },
|
|
9222
|
+
...geom.params?.color ? { color: { value: geom.params.color } } : {}
|
|
9223
|
+
}
|
|
9224
|
+
};
|
|
9225
|
+
}
|
|
9226
|
+
function buildLinerangeSpec(data, aes) {
|
|
9227
|
+
return {
|
|
9228
|
+
mark: "rule",
|
|
9229
|
+
encoding: {
|
|
9230
|
+
x: { field: aes.x, type: inferFieldType(data, aes.x) },
|
|
9231
|
+
y: { field: aes.ymin || "ymin", type: "quantitative" },
|
|
9232
|
+
y2: { field: aes.ymax || "ymax" },
|
|
9233
|
+
...aes.color ? { color: { field: aes.color, type: inferFieldType(data, aes.color) } } : {}
|
|
9234
|
+
}
|
|
9235
|
+
};
|
|
9236
|
+
}
|
|
9237
|
+
function buildPointrangeSpec(data, aes) {
|
|
9238
|
+
const colorEncoding = aes.color ? { color: { field: aes.color, type: inferFieldType(data, aes.color) } } : {};
|
|
9239
|
+
return [
|
|
9240
|
+
{
|
|
9241
|
+
mark: "rule",
|
|
9242
|
+
encoding: {
|
|
9243
|
+
x: { field: aes.x, type: inferFieldType(data, aes.x) },
|
|
9244
|
+
y: { field: aes.ymin || "ymin", type: "quantitative" },
|
|
9245
|
+
y2: { field: aes.ymax || "ymax" },
|
|
9246
|
+
...colorEncoding
|
|
9247
|
+
}
|
|
9248
|
+
},
|
|
9249
|
+
{
|
|
9250
|
+
mark: { type: "point", filled: true },
|
|
9251
|
+
encoding: {
|
|
9252
|
+
x: { field: aes.x, type: inferFieldType(data, aes.x) },
|
|
9253
|
+
y: { field: aes.y, type: "quantitative" },
|
|
9254
|
+
...colorEncoding
|
|
9255
|
+
}
|
|
9256
|
+
}
|
|
9257
|
+
];
|
|
9258
|
+
}
|
|
9259
|
+
function buildCrossbarSpec(data, aes) {
|
|
9260
|
+
const colorEncoding = aes.color ? { color: { field: aes.color, type: inferFieldType(data, aes.color) } } : {};
|
|
9261
|
+
return [
|
|
9262
|
+
{
|
|
9263
|
+
mark: { type: "bar", width: 20 },
|
|
9264
|
+
encoding: {
|
|
9265
|
+
x: { field: aes.x, type: inferFieldType(data, aes.x) },
|
|
9266
|
+
y: { field: aes.ymin || "ymin", type: "quantitative" },
|
|
9267
|
+
y2: { field: aes.ymax || "ymax" },
|
|
9268
|
+
...colorEncoding
|
|
9269
|
+
}
|
|
9270
|
+
},
|
|
9271
|
+
{
|
|
9272
|
+
mark: { type: "tick", thickness: 2 },
|
|
9273
|
+
encoding: {
|
|
9274
|
+
x: { field: aes.x, type: inferFieldType(data, aes.x) },
|
|
9275
|
+
y: { field: aes.y, type: "quantitative" },
|
|
9276
|
+
color: { value: "black" }
|
|
9277
|
+
}
|
|
9278
|
+
}
|
|
9279
|
+
];
|
|
9280
|
+
}
|
|
9281
|
+
function buildErrorbarhSpec(data, aes) {
|
|
9282
|
+
return {
|
|
9283
|
+
mark: "rule",
|
|
9284
|
+
encoding: {
|
|
9285
|
+
y: { field: aes.y, type: inferFieldType(data, aes.y) },
|
|
9286
|
+
x: { field: aes.xmin || "xmin", type: "quantitative" },
|
|
9287
|
+
x2: { field: aes.xmax || "xmax" },
|
|
9288
|
+
...aes.color ? { color: { field: aes.color, type: inferFieldType(data, aes.color) } } : {}
|
|
9289
|
+
}
|
|
9290
|
+
};
|
|
9291
|
+
}
|
|
9292
|
+
function buildRibbonSpec(data, aes) {
|
|
9293
|
+
return {
|
|
9294
|
+
mark: { type: "area", opacity: 0.3 },
|
|
9295
|
+
encoding: {
|
|
9296
|
+
x: { field: aes.x, type: inferFieldType(data, aes.x) },
|
|
9297
|
+
y: { field: aes.ymin || "ymin", type: "quantitative" },
|
|
9298
|
+
y2: { field: aes.ymax || "ymax" },
|
|
9299
|
+
...aes.color ? { color: { field: aes.color, type: inferFieldType(data, aes.color) } } : {},
|
|
9300
|
+
...aes.fill ? { fill: { field: aes.fill, type: inferFieldType(data, aes.fill) } } : {}
|
|
9301
|
+
}
|
|
9302
|
+
};
|
|
9303
|
+
}
|
|
9304
|
+
function buildRugSpec(data, aes, geom) {
|
|
9305
|
+
const sides = geom.params?.sides || "b";
|
|
9306
|
+
const encoding = {};
|
|
9307
|
+
if (sides.includes("b") || sides.includes("t")) {
|
|
9308
|
+
encoding.x = { field: aes.x, type: inferFieldType(data, aes.x) };
|
|
9309
|
+
}
|
|
9310
|
+
if (sides.includes("l") || sides.includes("r")) {
|
|
9311
|
+
encoding.y = { field: aes.y, type: inferFieldType(data, aes.y) };
|
|
9312
|
+
}
|
|
9313
|
+
if (Object.keys(encoding).length === 0) {
|
|
9314
|
+
encoding.x = { field: aes.x, type: inferFieldType(data, aes.x) };
|
|
9315
|
+
}
|
|
9316
|
+
return {
|
|
9317
|
+
mark: { type: "tick", thickness: 1 },
|
|
9318
|
+
encoding
|
|
9319
|
+
};
|
|
9320
|
+
}
|
|
9321
|
+
function buildBin2dSpec(_data, aes, geom) {
|
|
9322
|
+
const binX = geom.params?.binwidth_x || geom.params?.bins || 10;
|
|
9323
|
+
const binY = geom.params?.binwidth_y || geom.params?.bins || 10;
|
|
9324
|
+
return {
|
|
9325
|
+
mark: "rect",
|
|
9326
|
+
encoding: {
|
|
9327
|
+
x: {
|
|
9328
|
+
field: aes.x,
|
|
9329
|
+
bin: { maxbins: binX },
|
|
9330
|
+
type: "quantitative"
|
|
9331
|
+
},
|
|
9332
|
+
y: {
|
|
9333
|
+
field: aes.y,
|
|
9334
|
+
bin: { maxbins: binY },
|
|
9335
|
+
type: "quantitative"
|
|
9336
|
+
},
|
|
9337
|
+
color: {
|
|
9338
|
+
aggregate: "count",
|
|
9339
|
+
type: "quantitative",
|
|
9340
|
+
scale: { scheme: "viridis" }
|
|
9341
|
+
}
|
|
9342
|
+
}
|
|
9343
|
+
};
|
|
9344
|
+
}
|
|
8708
9345
|
function getPublicationConfig() {
|
|
8709
9346
|
return {
|
|
8710
9347
|
font: "Arial",
|
|
@@ -8808,40 +9445,107 @@ function plotSpecToVegaLite(spec, options = {}) {
|
|
|
8808
9445
|
vlSpec.title = spec.labels.title;
|
|
8809
9446
|
}
|
|
8810
9447
|
}
|
|
8811
|
-
|
|
8812
|
-
|
|
8813
|
-
|
|
8814
|
-
|
|
8815
|
-
return {
|
|
8816
|
-
mark: histSpec.mark,
|
|
8817
|
-
encoding: histSpec.encoding
|
|
8818
|
-
};
|
|
8819
|
-
}
|
|
8820
|
-
if (geom.type === "boxplot") {
|
|
8821
|
-
const boxSpec = buildBoxplotSpec(spec.data, spec.aes);
|
|
8822
|
-
return {
|
|
8823
|
-
mark: boxSpec.mark,
|
|
8824
|
-
encoding: boxSpec.encoding
|
|
8825
|
-
};
|
|
8826
|
-
}
|
|
9448
|
+
function buildGeomLayer(geom) {
|
|
9449
|
+
const data = spec.data;
|
|
9450
|
+
if (geom.type === "histogram" || geom.stat === "bin") {
|
|
9451
|
+
const histSpec = buildHistogramSpec(data, spec.aes, geom);
|
|
8827
9452
|
return {
|
|
8828
|
-
mark:
|
|
8829
|
-
encoding:
|
|
9453
|
+
mark: histSpec.mark,
|
|
9454
|
+
encoding: histSpec.encoding
|
|
8830
9455
|
};
|
|
8831
|
-
}
|
|
9456
|
+
}
|
|
9457
|
+
if (geom.type === "boxplot") {
|
|
9458
|
+
const boxSpec = buildBoxplotSpec(data, spec.aes);
|
|
9459
|
+
return {
|
|
9460
|
+
mark: boxSpec.mark,
|
|
9461
|
+
encoding: boxSpec.encoding
|
|
9462
|
+
};
|
|
9463
|
+
}
|
|
9464
|
+
if (geom.type === "hline") {
|
|
9465
|
+
const hlineSpec = buildHLineSpec(geom, data);
|
|
9466
|
+
return {
|
|
9467
|
+
mark: hlineSpec.mark,
|
|
9468
|
+
encoding: hlineSpec.encoding
|
|
9469
|
+
};
|
|
9470
|
+
}
|
|
9471
|
+
if (geom.type === "vline") {
|
|
9472
|
+
const vlineSpec = buildVLineSpec(geom, data);
|
|
9473
|
+
return {
|
|
9474
|
+
mark: vlineSpec.mark,
|
|
9475
|
+
encoding: vlineSpec.encoding
|
|
9476
|
+
};
|
|
9477
|
+
}
|
|
9478
|
+
if (geom.type === "abline") {
|
|
9479
|
+
const ablineSpec = buildAblineSpec(geom, data, spec.aes);
|
|
9480
|
+
return {
|
|
9481
|
+
mark: ablineSpec.mark,
|
|
9482
|
+
encoding: ablineSpec.encoding
|
|
9483
|
+
};
|
|
9484
|
+
}
|
|
9485
|
+
if (geom.type === "linerange") {
|
|
9486
|
+
const linerangeSpec = buildLinerangeSpec(data, spec.aes);
|
|
9487
|
+
return {
|
|
9488
|
+
mark: linerangeSpec.mark,
|
|
9489
|
+
encoding: linerangeSpec.encoding
|
|
9490
|
+
};
|
|
9491
|
+
}
|
|
9492
|
+
if (geom.type === "pointrange") {
|
|
9493
|
+
return buildPointrangeSpec(data, spec.aes);
|
|
9494
|
+
}
|
|
9495
|
+
if (geom.type === "crossbar") {
|
|
9496
|
+
return buildCrossbarSpec(data, spec.aes);
|
|
9497
|
+
}
|
|
9498
|
+
if (geom.type === "errorbarh") {
|
|
9499
|
+
const errorhSpec = buildErrorbarhSpec(data, spec.aes);
|
|
9500
|
+
return {
|
|
9501
|
+
mark: errorhSpec.mark,
|
|
9502
|
+
encoding: errorhSpec.encoding
|
|
9503
|
+
};
|
|
9504
|
+
}
|
|
9505
|
+
if (geom.type === "ribbon") {
|
|
9506
|
+
const ribbonSpec = buildRibbonSpec(data, spec.aes);
|
|
9507
|
+
return {
|
|
9508
|
+
mark: ribbonSpec.mark,
|
|
9509
|
+
encoding: ribbonSpec.encoding
|
|
9510
|
+
};
|
|
9511
|
+
}
|
|
9512
|
+
if (geom.type === "rug") {
|
|
9513
|
+
const rugSpec = buildRugSpec(data, spec.aes, geom);
|
|
9514
|
+
return {
|
|
9515
|
+
mark: rugSpec.mark,
|
|
9516
|
+
encoding: rugSpec.encoding
|
|
9517
|
+
};
|
|
9518
|
+
}
|
|
9519
|
+
if (geom.type === "bin2d") {
|
|
9520
|
+
const bin2dSpec = buildBin2dSpec(data, spec.aes, geom);
|
|
9521
|
+
return {
|
|
9522
|
+
mark: bin2dSpec.mark,
|
|
9523
|
+
encoding: bin2dSpec.encoding
|
|
9524
|
+
};
|
|
9525
|
+
}
|
|
9526
|
+
return {
|
|
9527
|
+
mark: buildMark(geom),
|
|
9528
|
+
encoding: buildEncoding(spec.aes, data, geom)
|
|
9529
|
+
};
|
|
9530
|
+
}
|
|
9531
|
+
if (spec.geoms.length > 1) {
|
|
9532
|
+
vlSpec.layer = [];
|
|
9533
|
+
for (const geom of spec.geoms) {
|
|
9534
|
+
const layerResult = buildGeomLayer(geom);
|
|
9535
|
+
if (Array.isArray(layerResult)) {
|
|
9536
|
+
vlSpec.layer.push(...layerResult);
|
|
9537
|
+
} else {
|
|
9538
|
+
vlSpec.layer.push(layerResult);
|
|
9539
|
+
}
|
|
9540
|
+
}
|
|
8832
9541
|
} else if (spec.geoms.length === 1) {
|
|
8833
9542
|
const geom = spec.geoms[0];
|
|
8834
|
-
|
|
8835
|
-
|
|
8836
|
-
vlSpec.
|
|
8837
|
-
vlSpec.encoding = histSpec.encoding;
|
|
8838
|
-
} else if (geom.type === "boxplot") {
|
|
8839
|
-
const boxSpec = buildBoxplotSpec(spec.data, spec.aes);
|
|
8840
|
-
vlSpec.mark = boxSpec.mark;
|
|
8841
|
-
vlSpec.encoding = boxSpec.encoding;
|
|
9543
|
+
const layerResult = buildGeomLayer(geom);
|
|
9544
|
+
if (Array.isArray(layerResult)) {
|
|
9545
|
+
vlSpec.layer = layerResult;
|
|
8842
9546
|
} else {
|
|
8843
|
-
vlSpec.mark =
|
|
8844
|
-
vlSpec.encoding =
|
|
9547
|
+
vlSpec.mark = layerResult.mark;
|
|
9548
|
+
vlSpec.encoding = layerResult.encoding;
|
|
8845
9549
|
}
|
|
8846
9550
|
} else {
|
|
8847
9551
|
vlSpec.mark = "point";
|
|
@@ -8938,6 +9642,306 @@ function exportToVegaLiteJSON(spec, options = {}) {
|
|
|
8938
9642
|
const vlSpec = plotSpecToVegaLite(spec, options);
|
|
8939
9643
|
return JSON.stringify(vlSpec, null, 2);
|
|
8940
9644
|
}
|
|
9645
|
+
var GEOM_TO_MARK;
|
|
9646
|
+
var init_vega_lite = __esm(() => {
|
|
9647
|
+
GEOM_TO_MARK = {
|
|
9648
|
+
point: "point",
|
|
9649
|
+
line: "line",
|
|
9650
|
+
bar: "bar",
|
|
9651
|
+
col: "bar",
|
|
9652
|
+
area: "area",
|
|
9653
|
+
rect: "rect",
|
|
9654
|
+
text: "text",
|
|
9655
|
+
label: "text",
|
|
9656
|
+
rule: "rule",
|
|
9657
|
+
boxplot: "boxplot",
|
|
9658
|
+
histogram: "bar",
|
|
9659
|
+
freqpoly: "line",
|
|
9660
|
+
violin: "area",
|
|
9661
|
+
tile: "rect",
|
|
9662
|
+
raster: "rect",
|
|
9663
|
+
bin2d: "rect",
|
|
9664
|
+
density_2d: "rect",
|
|
9665
|
+
contour: "line",
|
|
9666
|
+
contour_filled: "area",
|
|
9667
|
+
step: "line",
|
|
9668
|
+
path: "line",
|
|
9669
|
+
smooth: "line",
|
|
9670
|
+
curve: "line",
|
|
9671
|
+
segment: "rule",
|
|
9672
|
+
linerange: "rule",
|
|
9673
|
+
pointrange: "rule",
|
|
9674
|
+
errorbar: "errorbar",
|
|
9675
|
+
errorbarh: "rule",
|
|
9676
|
+
crossbar: "rule",
|
|
9677
|
+
ribbon: "area",
|
|
9678
|
+
hline: "rule",
|
|
9679
|
+
vline: "rule",
|
|
9680
|
+
abline: "line",
|
|
9681
|
+
qq: "point",
|
|
9682
|
+
qq_line: "line",
|
|
9683
|
+
rug: "tick"
|
|
9684
|
+
};
|
|
9685
|
+
});
|
|
9686
|
+
|
|
9687
|
+
// src/export/index.ts
|
|
9688
|
+
var exports_export = {};
|
|
9689
|
+
__export(exports_export, {
|
|
9690
|
+
plotSpecToVegaLite: () => plotSpecToVegaLite,
|
|
9691
|
+
exportToVegaLiteJSON: () => exportToVegaLiteJSON
|
|
9692
|
+
});
|
|
9693
|
+
var init_export = __esm(() => {
|
|
9694
|
+
init_vega_lite();
|
|
9695
|
+
});
|
|
9696
|
+
|
|
9697
|
+
// src/index.ts
|
|
9698
|
+
var exports_src = {};
|
|
9699
|
+
__export(exports_src, {
|
|
9700
|
+
themeVoid: () => themeVoid,
|
|
9701
|
+
themeMinimal: () => themeMinimal,
|
|
9702
|
+
themeDark: () => themeDark,
|
|
9703
|
+
themeClassic: () => themeClassic,
|
|
9704
|
+
systematicSample: () => systematicSample,
|
|
9705
|
+
stratifiedSample: () => stratifiedSample,
|
|
9706
|
+
stat_summary: () => stat_summary,
|
|
9707
|
+
stat_smooth: () => stat_smooth,
|
|
9708
|
+
stat_qq_line: () => stat_qq_line,
|
|
9709
|
+
stat_qq: () => stat_qq,
|
|
9710
|
+
stat_density: () => stat_density,
|
|
9711
|
+
stat_boxplot: () => stat_boxplot,
|
|
9712
|
+
stat_bin2d: () => stat_bin2d,
|
|
9713
|
+
stat_bin: () => stat_bin,
|
|
9714
|
+
startREPL: () => startREPL,
|
|
9715
|
+
selectRenderer: () => selectRenderer,
|
|
9716
|
+
selectColorMode: () => selectColorMode,
|
|
9717
|
+
scale_y_time: () => scale_y_time,
|
|
9718
|
+
scale_y_sqrt: () => scale_y_sqrt,
|
|
9719
|
+
scale_y_reverse: () => scale_y_reverse,
|
|
9720
|
+
scale_y_log10: () => scale_y_log10,
|
|
9721
|
+
scale_y_duration: () => scale_y_duration,
|
|
9722
|
+
scale_y_discrete: () => scale_y_discrete,
|
|
9723
|
+
scale_y_datetime: () => scale_y_datetime,
|
|
9724
|
+
scale_y_date: () => scale_y_date,
|
|
9725
|
+
scale_y_continuous: () => scale_y_continuous,
|
|
9726
|
+
scale_y2_sqrt: () => scale_y2_sqrt,
|
|
9727
|
+
scale_y2_reverse: () => scale_y2_reverse,
|
|
9728
|
+
scale_y2_log10: () => scale_y2_log10,
|
|
9729
|
+
scale_y2_continuous: () => scale_y2_continuous,
|
|
9730
|
+
scale_x_time: () => scale_x_time,
|
|
9731
|
+
scale_x_sqrt: () => scale_x_sqrt,
|
|
9732
|
+
scale_x_reverse: () => scale_x_reverse,
|
|
9733
|
+
scale_x_log10: () => scale_x_log10,
|
|
9734
|
+
scale_x_duration: () => scale_x_duration,
|
|
9735
|
+
scale_x_discrete: () => scale_x_discrete,
|
|
9736
|
+
scale_x_datetime: () => scale_x_datetime,
|
|
9737
|
+
scale_x_date: () => scale_x_date,
|
|
9738
|
+
scale_x_continuous: () => scale_x_continuous,
|
|
9739
|
+
scale_size_radius: () => scale_size_radius,
|
|
9740
|
+
scale_size_identity: () => scale_size_identity,
|
|
9741
|
+
scale_size_continuous: () => scale_size_continuous,
|
|
9742
|
+
scale_size_binned: () => scale_size_binned,
|
|
9743
|
+
scale_size_area: () => scale_size_area,
|
|
9744
|
+
scale_shape_ordinal: () => scale_shape_ordinal,
|
|
9745
|
+
scale_shape_manual: () => scale_shape_manual,
|
|
9746
|
+
scale_shape_identity: () => scale_shape_identity,
|
|
9747
|
+
scale_shape_discrete: () => scale_shape_discrete,
|
|
9748
|
+
scale_fill_viridis: () => scale_fill_viridis,
|
|
9749
|
+
scale_fill_manual: () => scale_fill_manual,
|
|
9750
|
+
scale_fill_gradientn: () => scale_fill_gradientn,
|
|
9751
|
+
scale_fill_gradient2: () => scale_fill_gradient2,
|
|
9752
|
+
scale_fill_gradient: () => scale_fill_gradient,
|
|
9753
|
+
scale_fill_distiller: () => scale_fill_distiller,
|
|
9754
|
+
scale_fill_discrete: () => scale_fill_discrete,
|
|
9755
|
+
scale_fill_continuous: () => scale_fill_continuous,
|
|
9756
|
+
scale_fill_brewer: () => scale_fill_brewer,
|
|
9757
|
+
scale_color_viridis: () => scale_color_viridis,
|
|
9758
|
+
scale_color_manual: () => scale_color_manual,
|
|
9759
|
+
scale_color_gradientn: () => scale_color_gradientn,
|
|
9760
|
+
scale_color_gradient2: () => scale_color_gradient2,
|
|
9761
|
+
scale_color_gradient: () => scale_color_gradient,
|
|
9762
|
+
scale_color_distiller: () => scale_color_distiller,
|
|
9763
|
+
scale_color_discrete: () => scale_color_discrete,
|
|
9764
|
+
scale_color_continuous: () => scale_color_continuous,
|
|
9765
|
+
scale_color_brewer: () => scale_color_brewer,
|
|
9766
|
+
scale_alpha_manual: () => scale_alpha_manual,
|
|
9767
|
+
scale_alpha_identity: () => scale_alpha_identity,
|
|
9768
|
+
scale_alpha_discrete: () => scale_alpha_discrete,
|
|
9769
|
+
scale_alpha_continuous: () => scale_alpha_continuous,
|
|
9770
|
+
scale_alpha_binned: () => scale_alpha_binned,
|
|
9771
|
+
scale_alpha: () => scale_alpha,
|
|
9772
|
+
rgbToAnsi256: () => rgbToAnsi256,
|
|
9773
|
+
rgbToAnsi16: () => rgbToAnsi16,
|
|
9774
|
+
reservoirSample: () => reservoirSample,
|
|
9775
|
+
renderToString: () => renderToString,
|
|
9776
|
+
renderToCanvas: () => renderToCanvas,
|
|
9777
|
+
rectbin: () => rectbin,
|
|
9778
|
+
randomSample: () => randomSample,
|
|
9779
|
+
quickDiff: () => quickDiff,
|
|
9780
|
+
querySixelSupport: () => querySixelSupport,
|
|
9781
|
+
quantizeColor: () => quantizeColor,
|
|
9782
|
+
position_stack: () => position_stack,
|
|
9783
|
+
position_jitter: () => position_jitter,
|
|
9784
|
+
position_identity: () => position_identity,
|
|
9785
|
+
position_fill: () => position_fill,
|
|
9786
|
+
position_dodge: () => position_dodge,
|
|
9787
|
+
plotSpecToVegaLite: () => plotSpecToVegaLite,
|
|
9788
|
+
lttbSample: () => lttbSample,
|
|
9789
|
+
label_wrap: () => label_wrap,
|
|
9790
|
+
label_value: () => label_value,
|
|
9791
|
+
label_parsed: () => label_parsed,
|
|
9792
|
+
label_both: () => label_both,
|
|
9793
|
+
isStackPosition: () => isStackPosition,
|
|
9794
|
+
isRendererAvailable: () => isRendererAvailable,
|
|
9795
|
+
isDodgePosition: () => isDodgePosition,
|
|
9796
|
+
isCI: () => isCI,
|
|
9797
|
+
inferDiscreteDomain: () => inferDiscreteDomain,
|
|
9798
|
+
inferContinuousDomain: () => inferContinuousDomain,
|
|
9799
|
+
hexbin: () => hexbin,
|
|
9800
|
+
gg: () => gg,
|
|
9801
|
+
getTerminalName: () => getTerminalName,
|
|
9802
|
+
getTerminalInfo: () => getTerminalInfo,
|
|
9803
|
+
getRecommendedRenderer: () => getRecommendedRenderer,
|
|
9804
|
+
getPositionType: () => getPositionType,
|
|
9805
|
+
getPaletteColors: () => getPaletteColors,
|
|
9806
|
+
getPalette256: () => getPalette256,
|
|
9807
|
+
getColorEscape: () => getColorEscape,
|
|
9808
|
+
getCapabilities: () => getCapabilities,
|
|
9809
|
+
getAvailablePalettes: () => getAvailablePalettes,
|
|
9810
|
+
geom_vline: () => geom_vline,
|
|
9811
|
+
geom_violin: () => geom_violin,
|
|
9812
|
+
geom_tile: () => geom_tile,
|
|
9813
|
+
geom_text: () => geom_text,
|
|
9814
|
+
geom_step: () => geom_step,
|
|
9815
|
+
geom_smooth: () => geom_smooth,
|
|
9816
|
+
geom_segment: () => geom_segment,
|
|
9817
|
+
geom_rug: () => geom_rug,
|
|
9818
|
+
geom_ribbon: () => geom_ribbon,
|
|
9819
|
+
geom_rect: () => geom_rect,
|
|
9820
|
+
geom_raster: () => geom_raster,
|
|
9821
|
+
geom_qq_line: () => geom_qq_line,
|
|
9822
|
+
geom_qq: () => geom_qq,
|
|
9823
|
+
geom_pointrange: () => geom_pointrange,
|
|
9824
|
+
geom_point: () => geom_point,
|
|
9825
|
+
geom_path: () => geom_path,
|
|
9826
|
+
geom_linerange: () => geom_linerange,
|
|
9827
|
+
geom_line: () => geom_line,
|
|
9828
|
+
geom_label: () => geom_label,
|
|
9829
|
+
geom_hline: () => geom_hline,
|
|
9830
|
+
geom_histogram: () => geom_histogram,
|
|
9831
|
+
geom_freqpoly: () => geom_freqpoly,
|
|
9832
|
+
geom_errorbarh: () => geom_errorbarh,
|
|
9833
|
+
geom_errorbar: () => geom_errorbar,
|
|
9834
|
+
geom_density_2d: () => geom_density_2d,
|
|
9835
|
+
geom_curve: () => geom_curve,
|
|
9836
|
+
geom_crossbar: () => geom_crossbar,
|
|
9837
|
+
geom_contour_filled: () => geom_contour_filled,
|
|
9838
|
+
geom_contour: () => geom_contour,
|
|
9839
|
+
geom_col: () => geom_col,
|
|
9840
|
+
geom_boxplot: () => geom_boxplot,
|
|
9841
|
+
geom_bin2d: () => geom_bin2d,
|
|
9842
|
+
geom_bar: () => geom_bar,
|
|
9843
|
+
geom_area: () => geom_area,
|
|
9844
|
+
geom_abline: () => geom_abline,
|
|
9845
|
+
generate256Palette: () => generate256Palette,
|
|
9846
|
+
formatDateTime: () => formatDateTime,
|
|
9847
|
+
findClosestPaletteColor: () => findClosestPaletteColor,
|
|
9848
|
+
fgEscape: () => fgEscape,
|
|
9849
|
+
facet_wrap: () => facet_wrap,
|
|
9850
|
+
facet_grid: () => facet_grid,
|
|
9851
|
+
exportToVegaLiteJSON: () => exportToVegaLiteJSON,
|
|
9852
|
+
ditherPixels: () => ditherPixels,
|
|
9853
|
+
detectUnicodeSupport: () => detectUnicodeSupport,
|
|
9854
|
+
detectTerminalSize: () => detectTerminalSize,
|
|
9855
|
+
detectGraphicsProtocol: () => detectGraphicsProtocol,
|
|
9856
|
+
detectColorCapability: () => detectColorCapability,
|
|
9857
|
+
detectCapabilities: () => detectCapabilities,
|
|
9858
|
+
defaultTheme: () => defaultTheme,
|
|
9859
|
+
createTimeSeriesPlot: () => createTimeSeriesPlot,
|
|
9860
|
+
createStreamingPlot: () => createStreamingPlot,
|
|
9861
|
+
createSampler: () => createSampler,
|
|
9862
|
+
createRollingAggregator: () => createRollingAggregator,
|
|
9863
|
+
createRendererChain: () => createRendererChain,
|
|
9864
|
+
createOptimizedPalette: () => createOptimizedPalette,
|
|
9865
|
+
createMultiAggregator: () => createMultiAggregator,
|
|
9866
|
+
createLOD: () => createLOD,
|
|
9867
|
+
createDataWindow: () => createDataWindow,
|
|
9868
|
+
createDataBuffer: () => createDataBuffer,
|
|
9869
|
+
createCanvasDiff: () => createCanvasDiff,
|
|
9870
|
+
createCanvas: () => createCanvas,
|
|
9871
|
+
createBinner: () => createBinner,
|
|
9872
|
+
coordTrans: () => coordTrans,
|
|
9873
|
+
coordPolar: () => coordPolar,
|
|
9874
|
+
coordFlipWithLimits: () => coordFlipWithLimits,
|
|
9875
|
+
coordFlip: () => coordFlip,
|
|
9876
|
+
coordFixed: () => coordFixed,
|
|
9877
|
+
coordEqual: () => coordEqual,
|
|
9878
|
+
coordCartesian: () => coordCartesian,
|
|
9879
|
+
computeSummary: () => computeSummary,
|
|
9880
|
+
computeSmooth: () => computeSmooth,
|
|
9881
|
+
computeQQLine: () => computeQQLine,
|
|
9882
|
+
computeQQ: () => computeQQ,
|
|
9883
|
+
computeFacetPanels: () => computeFacetPanels,
|
|
9884
|
+
computeDensity: () => computeDensity,
|
|
9885
|
+
computeBoxplotStats: () => computeBoxplotStats,
|
|
9886
|
+
computeBins2d: () => computeBins2d,
|
|
9887
|
+
computeBins: () => computeBins,
|
|
9888
|
+
colorDistance: () => colorDistance,
|
|
9889
|
+
clearCapabilityCache: () => clearCapabilityCache,
|
|
9890
|
+
calculatePanelLayouts: () => calculatePanelLayouts,
|
|
9891
|
+
calculateLayout: () => calculateLayout,
|
|
9892
|
+
calculateGridStripLayout: () => calculateGridStripLayout,
|
|
9893
|
+
calculateDateTimeTicks: () => calculateDateTimeTicks,
|
|
9894
|
+
buildScaleContext: () => buildScaleContext,
|
|
9895
|
+
bgEscape: () => bgEscape,
|
|
9896
|
+
autoSample: () => autoSample,
|
|
9897
|
+
autoRenderer: () => autoRenderer,
|
|
9898
|
+
as_labeller: () => as_labeller,
|
|
9899
|
+
applyPositionAdjustment: () => applyPositionAdjustment,
|
|
9900
|
+
annotate_vline: () => annotate_vline,
|
|
9901
|
+
annotate_text: () => annotate_text,
|
|
9902
|
+
annotate_segment: () => annotate_segment,
|
|
9903
|
+
annotate_rect: () => annotate_rect,
|
|
9904
|
+
annotate_label: () => annotate_label,
|
|
9905
|
+
annotate_hline: () => annotate_hline,
|
|
9906
|
+
annotate: () => annotate,
|
|
9907
|
+
TerminalCanvas: () => TerminalCanvas,
|
|
9908
|
+
StreamingPlot: () => StreamingPlot,
|
|
9909
|
+
SHAPE_CHARS: () => SHAPE_CHARS,
|
|
9910
|
+
RollingAggregator: () => RollingAggregator,
|
|
9911
|
+
RendererChain: () => RendererChain,
|
|
9912
|
+
RESET_FG: () => RESET_FG,
|
|
9913
|
+
RESET_BG: () => RESET_BG,
|
|
9914
|
+
RESET: () => RESET,
|
|
9915
|
+
LevelOfDetail: () => LevelOfDetail,
|
|
9916
|
+
GGTermREPL: () => GGTermREPL,
|
|
9917
|
+
GGPlot: () => GGPlot,
|
|
9918
|
+
ExponentialMovingAverage: () => ExponentialMovingAverage,
|
|
9919
|
+
DataWindow: () => DataWindow,
|
|
9920
|
+
DataSampler: () => DataSampler,
|
|
9921
|
+
DataBuffer: () => DataBuffer,
|
|
9922
|
+
DEFAULT_SHAPES: () => DEFAULT_SHAPES,
|
|
9923
|
+
DEFAULT_LOD_LEVELS: () => DEFAULT_LOD_LEVELS,
|
|
9924
|
+
DEFAULT_FG: () => DEFAULT_FG,
|
|
9925
|
+
DEFAULT_BG: () => DEFAULT_BG,
|
|
9926
|
+
CanvasDiff: () => CanvasDiff,
|
|
9927
|
+
Binner: () => Binner,
|
|
9928
|
+
ANSI_16_COLORS: () => ANSI_16_COLORS
|
|
9929
|
+
});
|
|
9930
|
+
var init_src = __esm(() => {
|
|
9931
|
+
init_grammar();
|
|
9932
|
+
init_canvas2();
|
|
9933
|
+
init_pipeline2();
|
|
9934
|
+
init_geoms();
|
|
9935
|
+
init_stats();
|
|
9936
|
+
init_scales2();
|
|
9937
|
+
init_terminal();
|
|
9938
|
+
init_streaming();
|
|
9939
|
+
init_performance();
|
|
9940
|
+
init_repl2();
|
|
9941
|
+
init_export();
|
|
9942
|
+
});
|
|
9943
|
+
init_src();
|
|
9944
|
+
|
|
8941
9945
|
export {
|
|
8942
9946
|
themeVoid,
|
|
8943
9947
|
themeMinimal,
|
|
@@ -8951,6 +9955,7 @@ export {
|
|
|
8951
9955
|
stat_qq,
|
|
8952
9956
|
stat_density,
|
|
8953
9957
|
stat_boxplot,
|
|
9958
|
+
stat_bin2d,
|
|
8954
9959
|
stat_bin,
|
|
8955
9960
|
startREPL,
|
|
8956
9961
|
selectRenderer,
|
|
@@ -9079,6 +10084,7 @@ export {
|
|
|
9079
10084
|
geom_contour,
|
|
9080
10085
|
geom_col,
|
|
9081
10086
|
geom_boxplot,
|
|
10087
|
+
geom_bin2d,
|
|
9082
10088
|
geom_bar,
|
|
9083
10089
|
geom_area,
|
|
9084
10090
|
geom_abline,
|
|
@@ -9123,6 +10129,7 @@ export {
|
|
|
9123
10129
|
computeFacetPanels,
|
|
9124
10130
|
computeDensity,
|
|
9125
10131
|
computeBoxplotStats,
|
|
10132
|
+
computeBins2d,
|
|
9126
10133
|
computeBins,
|
|
9127
10134
|
colorDistance,
|
|
9128
10135
|
clearCapabilityCache,
|