@carto/ps-react-ui 4.12.0 → 4.12.2
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/{echart-BMPpj7n_.js → echart-Bdvbfx9s.js} +2 -2
- package/dist/echart-Bdvbfx9s.js.map +1 -0
- package/dist/{option-builders-F-c9ELi1.js → option-builders-DPeoyQaM.js} +41 -33
- package/dist/option-builders-DPeoyQaM.js.map +1 -0
- package/dist/types/widgets/utils/chart-config/index.d.ts +1 -1
- package/dist/types/widgets-v2/pie/skeleton.d.ts +9 -0
- package/dist/widgets/bar.js +1 -1
- package/dist/widgets/histogram.js +1 -1
- package/dist/widgets/pie.js +1 -1
- package/dist/widgets/scatterplot.js +5 -5
- package/dist/widgets/timeseries.js +1 -1
- package/dist/widgets/utils.js +1 -1
- package/dist/widgets-v2/bar.js +67 -63
- package/dist/widgets-v2/bar.js.map +1 -1
- package/dist/widgets-v2/echart.js +1 -1
- package/dist/widgets-v2/histogram.js +92 -87
- package/dist/widgets-v2/histogram.js.map +1 -1
- package/dist/widgets-v2/pie.js +149 -95
- package/dist/widgets-v2/pie.js.map +1 -1
- package/dist/widgets-v2/scatterplot.js +153 -157
- package/dist/widgets-v2/scatterplot.js.map +1 -1
- package/dist/widgets-v2/timeseries.js +74 -74
- package/dist/widgets-v2/timeseries.js.map +1 -1
- package/dist/widgets-v2.js +2 -2
- package/package.json +1 -1
- package/src/widgets/utils/chart-config/index.ts +1 -0
- package/src/widgets/utils/chart-config/option-builders.test.ts +34 -0
- package/src/widgets/utils/chart-config/option-builders.ts +21 -0
- package/src/widgets-v2/bar/options.ts +7 -2
- package/src/widgets-v2/echart/edge-label-clamp.ts +7 -4
- package/src/widgets-v2/histogram/options.ts +8 -2
- package/src/widgets-v2/pie/skeleton.test.tsx +6 -3
- package/src/widgets-v2/pie/skeleton.tsx +69 -7
- package/src/widgets-v2/scatterplot/options.ts +3 -6
- package/src/widgets-v2/timeseries/options.ts +3 -2
- package/dist/echart-BMPpj7n_.js.map +0 -1
- package/dist/option-builders-F-c9ELi1.js.map +0 -1
- package/dist/types/widgets/utils/chart-config/option-builders.d.ts +0 -124
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import { n as
|
|
3
|
-
import { jsx as b, jsxs as
|
|
4
|
-
import { c as
|
|
5
|
-
import { Skeleton as
|
|
1
|
+
import * as E from "echarts";
|
|
2
|
+
import { n as I, h as O, d as W, g as Y, c as q, f as z } from "../option-builders-DPeoyQaM.js";
|
|
3
|
+
import { jsx as b, jsxs as $ } from "react/jsx-runtime";
|
|
4
|
+
import { c as U } from "react/compiler-runtime";
|
|
5
|
+
import { Skeleton as M, Box as A } from "@mui/material";
|
|
6
6
|
import "../widget-store-Bw5zRUGg.js";
|
|
7
7
|
import "zustand/shallow";
|
|
8
8
|
import "@mui/icons-material";
|
|
@@ -20,12 +20,12 @@ import "zustand";
|
|
|
20
20
|
import "zustand/vanilla";
|
|
21
21
|
import "zustand/middleware";
|
|
22
22
|
import "zustand/react/shallow";
|
|
23
|
-
import { Z as
|
|
24
|
-
import { m as
|
|
25
|
-
import { p as
|
|
26
|
-
import { b as
|
|
27
|
-
import { b as
|
|
28
|
-
function
|
|
23
|
+
import { Z as _ } from "../transforms-Cdx4fkU5.js";
|
|
24
|
+
import { m as V, r as J } from "../resolve-theme-color-BdojIw0K.js";
|
|
25
|
+
import { p as K } from "../data-zoom-layout-CkVnm6ej.js";
|
|
26
|
+
import { b as Q } from "../png-item-9dNbB37T.js";
|
|
27
|
+
import { b as X } from "../csv-item-hH_Gt7ur.js";
|
|
28
|
+
function tt({
|
|
29
29
|
theme: t,
|
|
30
30
|
formatter: e
|
|
31
31
|
}) {
|
|
@@ -36,7 +36,7 @@ function X({
|
|
|
36
36
|
top: parseInt(t.spacing(3)),
|
|
37
37
|
right: parseInt(t.spacing(1)),
|
|
38
38
|
// Default: no legend. Merger bumps this when there are >1 series.
|
|
39
|
-
...
|
|
39
|
+
...q(!1, t),
|
|
40
40
|
containLabel: !0
|
|
41
41
|
},
|
|
42
42
|
tooltip: {
|
|
@@ -52,7 +52,7 @@ function X({
|
|
|
52
52
|
axisPointer: {
|
|
53
53
|
type: "line"
|
|
54
54
|
},
|
|
55
|
-
position:
|
|
55
|
+
position: Y(t),
|
|
56
56
|
formatter: D(e)
|
|
57
57
|
},
|
|
58
58
|
// Legend styling baked here; `show` is toggled by the merger based on
|
|
@@ -60,7 +60,7 @@ function X({
|
|
|
60
60
|
// options layer (bin labels are pre-formatted in the merger), so we
|
|
61
61
|
// skip the legend `labelFormatter` argument too.
|
|
62
62
|
legend: {
|
|
63
|
-
...
|
|
63
|
+
...W({
|
|
64
64
|
hasLegend: !1
|
|
65
65
|
})
|
|
66
66
|
},
|
|
@@ -79,15 +79,21 @@ function X({
|
|
|
79
79
|
show: !1
|
|
80
80
|
},
|
|
81
81
|
axisLabel: {
|
|
82
|
+
...O(t),
|
|
82
83
|
padding: [parseInt(t.spacing(0.5)), 0, 0, 0],
|
|
83
84
|
margin: 0,
|
|
85
|
+
// `interval: 0` makes every bin label a candidate so `hideOverlap`
|
|
86
|
+
// can pack the maximum number that physically fit. The category-axis
|
|
87
|
+
// default (`'auto'`) sub-samples first and leaves only one/two labels
|
|
88
|
+
// even when there's room for more.
|
|
89
|
+
interval: 0,
|
|
84
90
|
hideOverlap: !0
|
|
85
91
|
}
|
|
86
92
|
},
|
|
87
93
|
yAxis: {
|
|
88
94
|
type: "value",
|
|
89
|
-
min: (r) => (s = r.min < 0 ?
|
|
90
|
-
max: (r) => (i = r.max <= 0 ? 1 :
|
|
95
|
+
min: (r) => (s = r.min < 0 ? I(r.min) : 0, s),
|
|
96
|
+
max: (r) => (i = r.max <= 0 ? 1 : I(r.max), i),
|
|
91
97
|
axisLine: {
|
|
92
98
|
show: !1
|
|
93
99
|
},
|
|
@@ -101,8 +107,7 @@ function X({
|
|
|
101
107
|
}
|
|
102
108
|
},
|
|
103
109
|
axisLabel: {
|
|
104
|
-
|
|
105
|
-
fontFamily: t.typography.overlineDelicate?.fontFamily,
|
|
110
|
+
...O(t),
|
|
106
111
|
margin: parseInt(t.spacing(1)),
|
|
107
112
|
show: !0,
|
|
108
113
|
showMaxLabel: !0,
|
|
@@ -114,7 +119,7 @@ function X({
|
|
|
114
119
|
}
|
|
115
120
|
};
|
|
116
121
|
}
|
|
117
|
-
function
|
|
122
|
+
function Nt(t) {
|
|
118
123
|
const {
|
|
119
124
|
theme: e,
|
|
120
125
|
formatter: s,
|
|
@@ -122,43 +127,43 @@ function Mt(t) {
|
|
|
122
127
|
series: r,
|
|
123
128
|
labelFormatter: c,
|
|
124
129
|
selection: l
|
|
125
|
-
} = t,
|
|
130
|
+
} = t, a = t.optionsOverride, p = l && l.length > 0 ? new Set(l) : null, m = [];
|
|
126
131
|
for (let o = 0; o < i.length - 1; o++) {
|
|
127
|
-
const
|
|
128
|
-
m.push(c ? c(
|
|
132
|
+
const u = i[o], f = i[o + 1], d = `${j(u)}–${j(f)}`;
|
|
133
|
+
m.push(c ? c(d) : d);
|
|
129
134
|
}
|
|
130
|
-
return (o,
|
|
135
|
+
return (o, u, f) => {
|
|
131
136
|
if (o == null) {
|
|
132
|
-
const
|
|
137
|
+
const n = tt({
|
|
133
138
|
theme: e,
|
|
134
139
|
formatter: s
|
|
135
140
|
});
|
|
136
|
-
return
|
|
141
|
+
return a ? V(n, a) : n;
|
|
137
142
|
}
|
|
138
|
-
const
|
|
139
|
-
if (
|
|
143
|
+
const d = Array.isArray(u) ? u : [];
|
|
144
|
+
if (d.length === 0 || m.length === 0)
|
|
140
145
|
return {
|
|
141
146
|
...o,
|
|
142
147
|
dataset: [],
|
|
143
148
|
series: []
|
|
144
149
|
};
|
|
145
|
-
const y =
|
|
150
|
+
const y = d.length > 1, x = Array.isArray(o.series) ? o.series : [], H = x[0] ?? {}, v = typeof o.yAxis == "object" && !Array.isArray(o.yAxis) ? o.yAxis : {}, L = typeof o.grid == "object" && !Array.isArray(o.grid) ? o.grid : {}, Z = typeof o.tooltip == "object" && !Array.isArray(o.tooltip) ? o.tooltip : {}, B = typeof o.legend == "object" && !Array.isArray(o.legend) ? o.legend : {}, S = f?.formatter;
|
|
146
151
|
let k = 0, C = 1;
|
|
147
|
-
const
|
|
148
|
-
color: (
|
|
149
|
-
const g =
|
|
150
|
-
return p ? p.has(
|
|
152
|
+
const T = K(o.dataZoom, y), P = typeof L.bottom == "number" ? L.bottom : 24, F = y ? 56 : P, G = T ? F + _.sliderHeight + _.sliderGap : F, R = {
|
|
153
|
+
color: (n) => {
|
|
154
|
+
const g = n.color;
|
|
155
|
+
return p ? p.has(n.dataIndex) ? g : E.color.modifyAlpha(g, 0.15) : g;
|
|
151
156
|
}
|
|
152
157
|
};
|
|
153
158
|
return {
|
|
154
159
|
...o,
|
|
155
|
-
dataset:
|
|
156
|
-
source: m.map((g,
|
|
160
|
+
dataset: d.map((n) => ({
|
|
161
|
+
source: m.map((g, h) => [g, n[h] ?? 0])
|
|
157
162
|
})),
|
|
158
|
-
series:
|
|
159
|
-
const
|
|
163
|
+
series: d.map((n, g) => {
|
|
164
|
+
const h = x[g] ?? H, N = J(e, r?.[g]?.color);
|
|
160
165
|
return {
|
|
161
|
-
...typeof
|
|
166
|
+
...typeof h == "object" ? h : {},
|
|
162
167
|
type: "bar",
|
|
163
168
|
datasetIndex: g,
|
|
164
169
|
name: r?.[g]?.name ?? `Series ${g + 1}`,
|
|
@@ -170,41 +175,41 @@ function Mt(t) {
|
|
|
170
175
|
emphasis: {
|
|
171
176
|
focus: "series"
|
|
172
177
|
},
|
|
173
|
-
itemStyle:
|
|
178
|
+
itemStyle: R,
|
|
174
179
|
...N ? {
|
|
175
180
|
color: N
|
|
176
181
|
} : {}
|
|
177
182
|
};
|
|
178
183
|
}),
|
|
179
184
|
legend: {
|
|
180
|
-
...
|
|
185
|
+
...B,
|
|
181
186
|
show: y
|
|
182
187
|
},
|
|
183
188
|
grid: {
|
|
184
|
-
...
|
|
185
|
-
bottom:
|
|
189
|
+
...L,
|
|
190
|
+
bottom: G
|
|
186
191
|
},
|
|
187
|
-
...
|
|
188
|
-
dataZoom:
|
|
192
|
+
...T ? {
|
|
193
|
+
dataZoom: T
|
|
189
194
|
} : {},
|
|
190
195
|
yAxis: {
|
|
191
196
|
...v,
|
|
192
|
-
min: (
|
|
193
|
-
max: (
|
|
197
|
+
min: (n) => (k = n.min < 0 ? I(n.min) : 0, k),
|
|
198
|
+
max: (n) => (C = n.max <= 0 ? 1 : I(n.max), C),
|
|
194
199
|
axisLabel: {
|
|
195
200
|
...v.axisLabel ?? {},
|
|
196
|
-
formatter: (
|
|
201
|
+
formatter: (n) => n !== C && n !== k || n === 0 ? "" : S ? S(n) : String(n)
|
|
197
202
|
}
|
|
198
203
|
},
|
|
199
204
|
tooltip: {
|
|
200
|
-
...
|
|
201
|
-
formatter: D(
|
|
205
|
+
...Z,
|
|
206
|
+
formatter: D(S)
|
|
202
207
|
}
|
|
203
208
|
};
|
|
204
209
|
};
|
|
205
210
|
}
|
|
206
211
|
function D(t) {
|
|
207
|
-
return
|
|
212
|
+
return z((e) => {
|
|
208
213
|
const i = e.value?.[1], r = typeof i == "number" && t ? t(i) : i ?? "", c = typeof e.marker == "string" ? e.marker : "", l = e.seriesName ? `${e.seriesName}: ` : "";
|
|
209
214
|
return {
|
|
210
215
|
name: String(e.name ?? ""),
|
|
@@ -214,7 +219,7 @@ function D(t) {
|
|
|
214
219
|
};
|
|
215
220
|
});
|
|
216
221
|
}
|
|
217
|
-
function
|
|
222
|
+
function j(t) {
|
|
218
223
|
return Number.isInteger(t) ? String(t) : Number(t.toFixed(2)).toString();
|
|
219
224
|
}
|
|
220
225
|
const w = {
|
|
@@ -254,81 +259,81 @@ const w = {
|
|
|
254
259
|
spacing: t
|
|
255
260
|
}) => t(1.5)
|
|
256
261
|
}
|
|
257
|
-
},
|
|
262
|
+
}, et = (t) => ({
|
|
258
263
|
flex: 1,
|
|
259
264
|
height: `${t}%`,
|
|
260
265
|
minWidth: 8
|
|
261
266
|
});
|
|
262
|
-
function
|
|
263
|
-
const e =
|
|
267
|
+
function Ot(t) {
|
|
268
|
+
const e = U(15), {
|
|
264
269
|
bins: s
|
|
265
270
|
} = t, i = s === void 0 ? 12 : s;
|
|
266
|
-
let r, c, l,
|
|
271
|
+
let r, c, l, a, p;
|
|
267
272
|
if (e[0] !== i) {
|
|
268
|
-
const
|
|
273
|
+
const f = Array.from({
|
|
269
274
|
length: i
|
|
270
|
-
}, (
|
|
271
|
-
const
|
|
272
|
-
return Math.round(20 + 80 * Math.exp(-((
|
|
275
|
+
}, (d, y) => {
|
|
276
|
+
const x = y / Math.max(1, i - 1);
|
|
277
|
+
return Math.round(20 + 80 * Math.exp(-((x - 0.5) ** 2) * 8));
|
|
273
278
|
});
|
|
274
|
-
c = A, p = w.container, r = A, l = w.grid,
|
|
279
|
+
c = A, p = w.container, r = A, l = w.grid, a = f.map(ot), e[0] = i, e[1] = r, e[2] = c, e[3] = l, e[4] = a, e[5] = p;
|
|
275
280
|
} else
|
|
276
|
-
r = e[1], c = e[2], l = e[3],
|
|
281
|
+
r = e[1], c = e[2], l = e[3], a = e[4], p = e[5];
|
|
277
282
|
let m;
|
|
278
|
-
e[6] !== r || e[7] !== l || e[8] !==
|
|
283
|
+
e[6] !== r || e[7] !== l || e[8] !== a ? (m = /* @__PURE__ */ b(r, { sx: l, children: a }), e[6] = r, e[7] = l, e[8] = a, e[9] = m) : m = e[9];
|
|
279
284
|
let o;
|
|
280
|
-
e[10] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (o = /* @__PURE__ */ b(A, { sx: w.legend, children: [0, 1].map(
|
|
281
|
-
let
|
|
282
|
-
return e[11] !== c || e[12] !== p || e[13] !== m ? (
|
|
285
|
+
e[10] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (o = /* @__PURE__ */ b(A, { sx: w.legend, children: [0, 1].map(rt) }), e[10] = o) : o = e[10];
|
|
286
|
+
let u;
|
|
287
|
+
return e[11] !== c || e[12] !== p || e[13] !== m ? (u = /* @__PURE__ */ $(c, { sx: p, children: [
|
|
283
288
|
m,
|
|
284
289
|
o
|
|
285
|
-
] }), e[11] = c, e[12] = p, e[13] = m, e[14] =
|
|
290
|
+
] }), e[11] = c, e[12] = p, e[13] = m, e[14] = u) : u = e[14], u;
|
|
286
291
|
}
|
|
287
|
-
function
|
|
288
|
-
return /* @__PURE__ */
|
|
289
|
-
/* @__PURE__ */ b(
|
|
290
|
-
/* @__PURE__ */ b(
|
|
292
|
+
function rt(t) {
|
|
293
|
+
return /* @__PURE__ */ $(A, { sx: w.legendItem, children: [
|
|
294
|
+
/* @__PURE__ */ b(M, { variant: "circular", width: 8, height: 8 }),
|
|
295
|
+
/* @__PURE__ */ b(M, { width: 48, height: 8 })
|
|
291
296
|
] }, `legend-${t}`);
|
|
292
297
|
}
|
|
293
|
-
function
|
|
294
|
-
return /* @__PURE__ */ b(
|
|
298
|
+
function ot(t, e) {
|
|
299
|
+
return /* @__PURE__ */ b(M, { variant: "rectangular", sx: et(t) }, `bar-${e}`);
|
|
295
300
|
}
|
|
296
|
-
function
|
|
301
|
+
function _t(t) {
|
|
297
302
|
const e = [];
|
|
298
|
-
return t.getCaptureEl && e.push(
|
|
303
|
+
return t.getCaptureEl && e.push(Q({
|
|
299
304
|
filename: t.filename,
|
|
300
305
|
getCaptureEl: t.getCaptureEl,
|
|
301
306
|
pixelRatio: t.pngPixelRatio,
|
|
302
307
|
backgroundColor: t.pngBackgroundColor
|
|
303
|
-
})), e.push(
|
|
308
|
+
})), e.push(X({
|
|
304
309
|
filename: t.filename,
|
|
305
310
|
getRows: () => {
|
|
306
311
|
const s = t.getData(), i = t.getTicks(), r = s.length, c = ["bin_low", "bin_high"];
|
|
307
|
-
for (let
|
|
308
|
-
c.push(t.seriesNames?.[
|
|
312
|
+
for (let a = 0; a < r; a++)
|
|
313
|
+
c.push(t.seriesNames?.[a] ?? `series_${a + 1}`);
|
|
309
314
|
const l = [c];
|
|
310
|
-
for (let
|
|
311
|
-
const p = [i[
|
|
312
|
-
for (let m = 0; m < r; m++) p.push(s[m]?.[
|
|
315
|
+
for (let a = 0; a < Math.max(0, i.length - 1); a++) {
|
|
316
|
+
const p = [i[a], i[a + 1]];
|
|
317
|
+
for (let m = 0; m < r; m++) p.push(s[m]?.[a] ?? 0);
|
|
313
318
|
l.push(p);
|
|
314
319
|
}
|
|
315
320
|
return l;
|
|
316
321
|
}
|
|
317
322
|
})), e;
|
|
318
323
|
}
|
|
319
|
-
const
|
|
320
|
-
if (!
|
|
324
|
+
const jt = (t) => Array.isArray(t) ? t.map((e) => {
|
|
325
|
+
if (!it(e)) return e;
|
|
321
326
|
const s = e.reduce((i, r) => i + Math.abs(r), 0);
|
|
322
327
|
return s <= 0 ? e : e.map((i) => i / s * 100);
|
|
323
328
|
}) : t;
|
|
324
|
-
function
|
|
329
|
+
function it(t) {
|
|
325
330
|
return Array.isArray(t) ? t.every((e) => typeof e == "number" && Number.isFinite(e)) : !1;
|
|
326
331
|
}
|
|
327
332
|
export {
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
+
Ot as HistogramSkeleton,
|
|
334
|
+
_t as createHistogramDownloadConfig,
|
|
335
|
+
Nt as createHistogramOptionFactory,
|
|
336
|
+
tt as histogramOptions,
|
|
337
|
+
jt as toRelativeHistogramData
|
|
333
338
|
};
|
|
334
339
|
//# sourceMappingURL=histogram.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"histogram.js","sources":["../../src/widgets-v2/histogram/options.ts","../../src/widgets-v2/histogram/skeleton.tsx","../../src/widgets-v2/histogram/download.ts","../../src/widgets-v2/histogram/transforms.ts"],"sourcesContent":["import type { EChartsOption } from 'echarts'\nimport * as echarts from 'echarts'\nimport type { CallbackDataParams } from 'echarts/types/dist/shared'\nimport {\n buildGridConfig,\n buildLegendConfig,\n createTooltipFormatter,\n createTooltipPositioner,\n niceNum,\n} from '../../widgets/utils/chart-config'\nimport { ZOOM_LAYOUT } from '../actions/zoom-toggle'\nimport type { OptionFactory } from '../echart'\nimport { mergeOptions, resolveThemeColor } from '../utils'\nimport { positionDataZoomForLegend } from '../utils/data-zoom-layout'\nimport type {\n HistogramEChartsOption,\n HistogramOptionFactoryInput,\n HistogramOptionsInput,\n HistogramWidgetData,\n} from './types'\n\n/**\n * Builds the **structural** ECharts option for a histogram widget — axes,\n * grid, tooltip, value-axis label formatter, themed legend. Mirrors\n * {@link import('../bar/options').barOptions} so the two widgets share v1\n * look-and-feel: themed dark tooltip with positioner, CARTO color palette,\n * structural legend (`show` toggled by the merger based on series count),\n * y-axis labels rendered inside the plot via the `niceNum` closure pattern.\n *\n * Intentional deviations from bar (histogram-specific):\n * - **No `xAxis.axisLabel.formatter`.** Bin labels are pre-formatted in\n * the merger via `formatNumber(lo)–formatNumber(hi)` and optionally\n * the consumer's `labelFormatter`. The strings on the axis are\n * already display-ready, so there's nothing to post-format here.\n * - **Tooltip formatter reads the array-tuple row shape.** The dataset\n * uses positional `encode: { x: 0, y: 1 }`, so `item.value` comes in\n * as `[binLabel, count]` rather than bar's `{ name, value }` object.\n *\n * Intentionally data-agnostic: no series, no dataset, no x-axis category\n * data (those depend on data + ticks and are added by the option factory's\n * merge phase via {@link createHistogramOptionFactory}).\n */\nexport function histogramOptions({\n theme,\n formatter,\n}: HistogramOptionsInput): HistogramEChartsOption {\n // Closure shared between yAxis min/max callbacks and the label formatter,\n // so only the rounded extents are labelled (matches v1 + bar).\n let niceMin = 0\n let niceMax = 1\n\n return {\n grid: {\n left: parseInt(theme.spacing(1)),\n top: parseInt(theme.spacing(3)),\n right: parseInt(theme.spacing(1)),\n // Default: no legend. Merger bumps this when there are >1 series.\n ...buildGridConfig(false, theme),\n containLabel: true,\n },\n tooltip: {\n trigger: 'axis',\n backgroundColor: theme.palette.grey[900],\n borderWidth: 0,\n padding: [parseInt(theme.spacing(1)), parseInt(theme.spacing(1))],\n textStyle: {\n color: theme.palette.common.white,\n fontSize: 11,\n fontFamily: theme.typography.caption.fontFamily,\n },\n axisPointer: { type: 'line' },\n position: createTooltipPositioner(theme),\n formatter: buildHistogramTooltipFormatter(formatter),\n },\n // Legend styling baked here; `show` is toggled by the merger based on\n // series count. Histogram doesn't accept `labelFormatter` at the\n // options layer (bin labels are pre-formatted in the merger), so we\n // skip the legend `labelFormatter` argument too.\n legend: {\n ...buildLegendConfig({ hasLegend: false }),\n },\n axisPointer: { lineStyle: { color: theme.palette.grey[400] } },\n color: [\n theme.palette.secondary.main,\n ...Object.values(\n (theme.palette as { qualitative?: { bold?: Record<string, string> } })\n .qualitative?.bold ?? {},\n ),\n ],\n xAxis: {\n type: 'category',\n axisLine: { show: false },\n axisTick: { show: false },\n axisLabel: {\n padding: [parseInt(theme.spacing(0.5)), 0, 0, 0],\n margin: 0,\n hideOverlap: true,\n },\n },\n yAxis: {\n type: 'value',\n min: (extent: { min: number }) => {\n niceMin = extent.min < 0 ? niceNum(extent.min) : 0\n return niceMin\n },\n max: (extent: { min: number; max: number }) => {\n niceMax = extent.max <= 0 ? 1 : niceNum(extent.max)\n return niceMax\n },\n axisLine: { show: false },\n axisTick: { show: false },\n splitLine: {\n show: true,\n lineStyle: { color: theme.palette.black?.[4] ?? theme.palette.divider },\n },\n axisLabel: {\n fontSize: theme.typography.overlineDelicate?.fontSize,\n fontFamily: theme.typography.overlineDelicate?.fontFamily,\n margin: parseInt(theme.spacing(1)),\n show: true,\n showMaxLabel: true,\n showMinLabel: true,\n verticalAlign: 'bottom',\n inside: true,\n formatter: (value: number) => {\n if (value !== niceMax && value !== niceMin) return ''\n if (value === 0) return ''\n return formatter ? formatter(value) : String(value)\n },\n },\n },\n } as HistogramEChartsOption\n}\n\n/**\n * Returns the histogram widget's {@link OptionFactory} — one closure that\n * owns BOTH phases of option construction:\n *\n * - **Structural phase** (`option == null`) — builds the theme-aware\n * structural option via {@link histogramOptions}, optionally merging\n * the consumer-supplied `optionsOverride`. Called once by Provider to\n * seed `rawOptions` in the store.\n * - **Merge phase** (`option != null`) — fuses post-pipeline `state.data`\n * (`HistogramWidgetData` — `number[][]`) into the option via the\n * dataset API. Each series gets its own dataset of `[binLabel, count]`\n * pairs derived from `ticks`; series reference their dataset by\n * `datasetIndex` and are encoded by column position. Reactive\n * `ctx.formatter` (driven by RelativeData → `%`) plus `niceMin`/`niceMax`\n * are re-derived here so the y-axis label formatter and the tooltip\n * pick up live store values, mirroring bar.\n */\nexport function createHistogramOptionFactory(\n options: HistogramOptionFactoryInput,\n): OptionFactory {\n const { theme, formatter, ticks, series, labelFormatter, selection } = options\n const optionsOverride = options.optionsOverride\n const selectionSet =\n selection && selection.length > 0 ? new Set<number>(selection) : null\n\n const binLabels: string[] = []\n for (let i = 0; i < ticks.length - 1; i++) {\n const lo = ticks[i]!\n const hi = ticks[i + 1]!\n const raw = `${formatNumber(lo)}–${formatNumber(hi)}`\n binLabels.push(labelFormatter ? labelFormatter(raw) : raw)\n }\n\n return (option, data, ctx) => {\n if (option == null) {\n const structural = histogramOptions({ theme, formatter })\n return optionsOverride\n ? (mergeOptions(\n structural as unknown as Record<string, unknown>,\n optionsOverride as Partial<Record<string, unknown>>,\n ) as EChartsOption)\n : structural\n }\n\n const seriesArr: HistogramWidgetData = Array.isArray(data)\n ? (data as HistogramWidgetData)\n : []\n if (seriesArr.length === 0 || binLabels.length === 0) {\n return { ...option, dataset: [], series: [] }\n }\n\n const hasLegend = seriesArr.length > 1\n const seriesTemplates = Array.isArray(option.series) ? option.series : []\n const broadcastTemplate = seriesTemplates[0] ?? {}\n const baseYAxis =\n typeof option.yAxis === 'object' && !Array.isArray(option.yAxis)\n ? option.yAxis\n : {}\n const baseGrid =\n typeof option.grid === 'object' && !Array.isArray(option.grid)\n ? option.grid\n : {}\n const baseTooltip =\n typeof option.tooltip === 'object' && !Array.isArray(option.tooltip)\n ? option.tooltip\n : {}\n const baseLegend =\n typeof option.legend === 'object' && !Array.isArray(option.legend)\n ? option.legend\n : {}\n // Reactive (live store) formatter from ctx — distinct from the\n // closure-time `formatter` captured for the structural-build branch\n // above. RelativeData can install a percent formatter on the store\n // after the factory was constructed; the merge phase reads `ctx` to\n // pick that up.\n const liveFormatter = ctx?.formatter\n\n // Closure shared between the yAxis min/max callbacks and the label\n // formatter, so only the rounded extents are labelled (matches v1 +\n // bar). Delegating the extent to ECharts (rather than precomputing\n // scalars from the raw counts) keeps stacked bins inside the plot:\n // when StackToggle marks the series, ECharts feeds the *post-stack*\n // extent to these callbacks, so `niceNum` rounds the stacked total.\n let niceMin = 0\n let niceMax = 1\n\n // Zoom slider layout: when ZoomToggle has installed `dataZoom`, push\n // the slider above the legend (if any) and reserve room in the grid.\n const dataZoomLayout = positionDataZoomForLegend(option.dataZoom, hasLegend)\n const fallbackBottom =\n typeof baseGrid.bottom === 'number' ? baseGrid.bottom : 24\n const baseBottom = hasLegend ? 56 : fallbackBottom\n const gridBottom = dataZoomLayout\n ? baseBottom + ZOOM_LAYOUT.sliderHeight + ZOOM_LAYOUT.sliderGap\n : baseBottom\n\n // Dim non-selected bins via `series.itemStyle.color`. Per-row\n // `itemStyle` on dataset sources is silently ignored when\n // `series.encode` is in play.\n //\n // We *always* emit `itemStyle.color` (a passthrough when nothing is\n // selected), not conditionally — dropping the key between renders\n // would let ECharts' default merge keep the previous callback alive\n // and bins would stay dimmed forever after an external clear. Always\n // emitting lets normal merge swap the callback in place, no\n // `replaceMerge` and no entry-animation flash on selection on/off.\n const dimItemStyle = {\n color: (params: CallbackDataParams) => {\n const base = params.color as string\n if (!selectionSet) return base\n return selectionSet.has(params.dataIndex)\n ? base\n : echarts.color.modifyAlpha(base, 0.15)\n },\n }\n\n return {\n ...option,\n dataset: seriesArr.map((counts) => ({\n source: binLabels.map(\n (label, i) => [label, counts[i] ?? 0] as [string, number],\n ),\n })),\n series: seriesArr.map((_, i) => {\n const template =\n (seriesTemplates[i] as object | undefined) ??\n (broadcastTemplate as object)\n const overrideColor = resolveThemeColor(theme, series?.[i]?.color)\n return {\n ...(typeof template === 'object' ? template : {}),\n type: 'bar' as const,\n datasetIndex: i,\n name: series?.[i]?.name ?? `Series ${i + 1}`,\n encode: { x: 0, y: 1 },\n barCategoryGap: '0%',\n emphasis: { focus: 'series' },\n itemStyle: dimItemStyle,\n ...(overrideColor ? { color: overrideColor } : {}),\n }\n }),\n legend: { ...baseLegend, show: hasLegend },\n grid: { ...baseGrid, bottom: gridBottom },\n ...(dataZoomLayout ? { dataZoom: dataZoomLayout } : {}),\n yAxis: {\n ...baseYAxis,\n min: (extent: { min: number }) => {\n niceMin = extent.min < 0 ? niceNum(extent.min) : 0\n return niceMin\n },\n max: (extent: { min: number; max: number }) => {\n niceMax = extent.max <= 0 ? 1 : niceNum(extent.max)\n return niceMax\n },\n axisLabel: {\n ...((baseYAxis as { axisLabel?: object }).axisLabel ?? {}),\n formatter: (value: number) => {\n if (value !== niceMax && value !== niceMin) return ''\n if (value === 0) return ''\n return liveFormatter ? liveFormatter(value) : String(value)\n },\n },\n } as EChartsOption['yAxis'],\n tooltip: {\n ...baseTooltip,\n formatter: buildHistogramTooltipFormatter(liveFormatter),\n },\n } as EChartsOption\n }\n}\n\n/**\n * Tooltip formatter for the histogram's positional `[binLabel, count]`\n * row shape. ECharts surfaces the x-axis category through `item.name`\n * (already pre-formatted by the bin-label generator), and `item.value`\n * comes in as the array tuple — distinct from bar's `{ name, value }`\n * object row.\n */\nfunction buildHistogramTooltipFormatter(\n formatter: ((value: number) => string) | undefined,\n) {\n return createTooltipFormatter((item) => {\n const row = item.value as [string, number] | undefined\n const raw = row?.[1]\n const formattedValue =\n typeof raw === 'number' && formatter ? formatter(raw) : (raw ?? '')\n const marker = typeof item.marker === 'string' ? item.marker : ''\n const seriesName = item.seriesName ? `${item.seriesName}: ` : ''\n return {\n name: String(item.name ?? ''),\n seriesName,\n marker,\n value: formattedValue,\n }\n })\n}\n\nfunction formatNumber(n: number): string {\n if (Number.isInteger(n)) return String(n)\n return Number(n.toFixed(2)).toString()\n}\n","import { Box, Skeleton, type SxProps, type Theme } from '@mui/material'\n\nconst styles = {\n container: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n flexDirection: 'column',\n gap: ({ spacing }) => spacing(1),\n height: ({ spacing }) => spacing(38),\n },\n grid: {\n display: 'flex',\n alignItems: 'flex-end',\n flex: '1 1 auto',\n gap: 0.5,\n width: '100%',\n },\n legend: {\n display: 'flex',\n alignItems: 'center',\n gap: ({ spacing }) => spacing(2),\n height: ({ spacing }) => spacing(5),\n },\n legendItem: {\n display: 'flex',\n alignItems: 'center',\n gap: ({ spacing }) => spacing(1.5),\n },\n} satisfies Record<string, SxProps<Theme>>\n\nconst barSx = (height: number): SxProps<Theme> => ({\n flex: 1,\n height: `${height}%`,\n minWidth: 8,\n})\n\nexport interface HistogramSkeletonProps {\n bins?: number\n}\n\n/**\n * Loading state for the Histogram widget. Mirrors Bar's skeleton structure\n * — a grid of bars (bin-shaped silhouette, anchored to the bottom) plus a\n * legend stub — so the placeholder reads consistently with Bar.\n */\nexport function HistogramSkeleton({ bins = 12 }: HistogramSkeletonProps) {\n // Sample heights mimicking a typical bell-shaped distribution.\n const heights = Array.from({ length: bins }, (_, i) => {\n const t = i / Math.max(1, bins - 1)\n return Math.round(20 + 80 * Math.exp(-((t - 0.5) ** 2) * 8))\n })\n return (\n <Box sx={styles.container}>\n <Box sx={styles.grid}>\n {heights.map((h, i) => (\n <Skeleton key={`bar-${i}`} variant='rectangular' sx={barSx(h)} />\n ))}\n </Box>\n <Box sx={styles.legend}>\n {[0, 1].map((i) => (\n <Box key={`legend-${i}`} sx={styles.legendItem}>\n <Skeleton variant='circular' width={8} height={8} />\n <Skeleton width={48} height={8} />\n </Box>\n ))}\n </Box>\n </Box>\n )\n}\n","import {\n buildCsvDownloadItem,\n buildPngDownloadItem,\n type DownloadItem,\n} from '../actions/download'\nimport type { HistogramWidgetData } from './types'\n\n/**\n * Download menu items for histograms. Always includes a CSV item with\n * `bin_low, bin_high, series_1_count, series_2_count, …` columns (one row\n * per bin). When `getCaptureEl` is supplied, prepends a PNG item that\n * rasterises the captured element via `html2canvas`.\n */\nexport function createHistogramDownloadConfig(args: {\n filename: string\n getData: () => HistogramWidgetData\n getTicks: () => readonly number[]\n seriesNames?: readonly string[]\n getCaptureEl?: () => HTMLElement | null\n pngPixelRatio?: number\n pngBackgroundColor?: string | null\n}): DownloadItem[] {\n const items: DownloadItem[] = []\n if (args.getCaptureEl) {\n items.push(\n buildPngDownloadItem({\n filename: args.filename,\n getCaptureEl: args.getCaptureEl,\n pixelRatio: args.pngPixelRatio,\n backgroundColor: args.pngBackgroundColor,\n }),\n )\n }\n items.push(\n buildCsvDownloadItem({\n filename: args.filename,\n getRows: () => {\n const data = args.getData()\n const ticks = args.getTicks()\n const seriesCount = data.length\n const header: unknown[] = ['bin_low', 'bin_high']\n for (let i = 0; i < seriesCount; i++) {\n header.push(args.seriesNames?.[i] ?? `series_${i + 1}`)\n }\n const rows: unknown[][] = [header]\n for (let bin = 0; bin < Math.max(0, ticks.length - 1); bin++) {\n const row: unknown[] = [ticks[bin], ticks[bin + 1]]\n for (let s = 0; s < seriesCount; s++) row.push(data[s]?.[bin] ?? 0)\n rows.push(row)\n }\n return rows\n },\n }),\n )\n return items\n}\n","/**\n * Histogram-specific `RelativeData` transform. Histogram data is\n * `number[][]` — each series is a flat list of bin counts. This\n * rewrites each count to its share of the series total (0–100), so\n * pairing with `createPercentFormatter` renders the y-axis as\n * percentages.\n *\n * Pass to `<Widget.RelativeData transform={toRelativeHistogramData} />`.\n *\n * The denominator is the sum of |value| across the series so mixed-sign\n * inputs produce sane signed shares-of-magnitude. A series whose total\n * magnitude is zero (all-zero or empty input) is returned unchanged so\n * a stalled or empty data set doesn't show misleading 0% values. Inputs\n * whose shape isn't `number[][]` fall through untouched (same defensive\n * shape-check pattern as the default transform).\n */\nexport const toRelativeHistogramData = (input: unknown): unknown => {\n if (!Array.isArray(input)) return input\n return input.map((series: unknown): unknown => {\n if (!isFlatNumberArray(series)) return series\n const total = series.reduce((acc, v) => acc + Math.abs(v), 0)\n if (total <= 0) return series\n return series.map((v) => (v / total) * 100)\n })\n}\n\nfunction isFlatNumberArray(v: unknown): v is number[] {\n if (!Array.isArray(v)) return false\n return v.every((item) => typeof item === 'number' && Number.isFinite(item))\n}\n"],"names":["histogramOptions","theme","formatter","niceMin","niceMax","grid","left","parseInt","spacing","top","right","buildGridConfig","containLabel","tooltip","trigger","backgroundColor","palette","grey","borderWidth","padding","textStyle","color","common","white","fontSize","fontFamily","typography","caption","axisPointer","type","position","createTooltipPositioner","buildHistogramTooltipFormatter","legend","buildLegendConfig","hasLegend","lineStyle","secondary","main","Object","values","qualitative","bold","xAxis","axisLine","show","axisTick","axisLabel","margin","hideOverlap","yAxis","min","extent","niceNum","max","splitLine","black","divider","overlineDelicate","showMaxLabel","showMinLabel","verticalAlign","inside","value","String","createHistogramOptionFactory","options","ticks","series","labelFormatter","selection","optionsOverride","selectionSet","length","Set","binLabels","i","lo","hi","raw","formatNumber","push","option","data","ctx","structural","mergeOptions","seriesArr","Array","isArray","dataset","seriesTemplates","broadcastTemplate","baseYAxis","baseGrid","baseTooltip","baseLegend","liveFormatter","dataZoomLayout","positionDataZoomForLegend","dataZoom","fallbackBottom","bottom","baseBottom","gridBottom","ZOOM_LAYOUT","sliderHeight","sliderGap","dimItemStyle","params","base","has","dataIndex","echarts","modifyAlpha","map","counts","source","label","_","template","overrideColor","resolveThemeColor","datasetIndex","name","encode","x","y","barCategoryGap","emphasis","focus","itemStyle","createTooltipFormatter","item","formattedValue","marker","seriesName","n","Number","isInteger","toFixed","toString","styles","container","display","alignItems","justifyContent","flexDirection","gap","height","flex","width","legendItem","barSx","minWidth","HistogramSkeleton","t0","$","_c","bins","t1","undefined","T0","T1","t2","t3","t4","heights","from","t","Math","round","exp","Box","_temp","t5","jsx","t6","Symbol","for","_temp2","t7","i_1","jsxs","Skeleton","h","i_0","createHistogramDownloadConfig","args","items","getCaptureEl","buildPngDownloadItem","filename","pixelRatio","pngPixelRatio","pngBackgroundColor","buildCsvDownloadItem","getRows","getData","getTicks","seriesCount","header","seriesNames","rows","bin","row","s","toRelativeHistogramData","input","isFlatNumberArray","total","reduce","acc","v","abs","every","isFinite"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"histogram.js","sources":["../../src/widgets-v2/histogram/options.ts","../../src/widgets-v2/histogram/skeleton.tsx","../../src/widgets-v2/histogram/download.ts","../../src/widgets-v2/histogram/transforms.ts"],"sourcesContent":["import type { EChartsOption } from 'echarts'\nimport * as echarts from 'echarts'\nimport type { CallbackDataParams } from 'echarts/types/dist/shared'\nimport {\n buildAxisLabelStyle,\n buildGridConfig,\n buildLegendConfig,\n createTooltipFormatter,\n createTooltipPositioner,\n niceNum,\n} from '../../widgets/utils/chart-config'\nimport { ZOOM_LAYOUT } from '../actions/zoom-toggle'\nimport type { OptionFactory } from '../echart'\nimport { mergeOptions, resolveThemeColor } from '../utils'\nimport { positionDataZoomForLegend } from '../utils/data-zoom-layout'\nimport type {\n HistogramEChartsOption,\n HistogramOptionFactoryInput,\n HistogramOptionsInput,\n HistogramWidgetData,\n} from './types'\n\n/**\n * Builds the **structural** ECharts option for a histogram widget — axes,\n * grid, tooltip, value-axis label formatter, themed legend. Mirrors\n * {@link import('../bar/options').barOptions} so the two widgets share v1\n * look-and-feel: themed dark tooltip with positioner, CARTO color palette,\n * structural legend (`show` toggled by the merger based on series count),\n * y-axis labels rendered inside the plot via the `niceNum` closure pattern.\n *\n * Intentional deviations from bar (histogram-specific):\n * - **No `xAxis.axisLabel.formatter`.** Bin labels are pre-formatted in\n * the merger via `formatNumber(lo)–formatNumber(hi)` and optionally\n * the consumer's `labelFormatter`. The strings on the axis are\n * already display-ready, so there's nothing to post-format here.\n * - **Tooltip formatter reads the array-tuple row shape.** The dataset\n * uses positional `encode: { x: 0, y: 1 }`, so `item.value` comes in\n * as `[binLabel, count]` rather than bar's `{ name, value }` object.\n *\n * Intentionally data-agnostic: no series, no dataset, no x-axis category\n * data (those depend on data + ticks and are added by the option factory's\n * merge phase via {@link createHistogramOptionFactory}).\n */\nexport function histogramOptions({\n theme,\n formatter,\n}: HistogramOptionsInput): HistogramEChartsOption {\n // Closure shared between yAxis min/max callbacks and the label formatter,\n // so only the rounded extents are labelled (matches v1 + bar).\n let niceMin = 0\n let niceMax = 1\n\n return {\n grid: {\n left: parseInt(theme.spacing(1)),\n top: parseInt(theme.spacing(3)),\n right: parseInt(theme.spacing(1)),\n // Default: no legend. Merger bumps this when there are >1 series.\n ...buildGridConfig(false, theme),\n containLabel: true,\n },\n tooltip: {\n trigger: 'axis',\n backgroundColor: theme.palette.grey[900],\n borderWidth: 0,\n padding: [parseInt(theme.spacing(1)), parseInt(theme.spacing(1))],\n textStyle: {\n color: theme.palette.common.white,\n fontSize: 11,\n fontFamily: theme.typography.caption.fontFamily,\n },\n axisPointer: { type: 'line' },\n position: createTooltipPositioner(theme),\n formatter: buildHistogramTooltipFormatter(formatter),\n },\n // Legend styling baked here; `show` is toggled by the merger based on\n // series count. Histogram doesn't accept `labelFormatter` at the\n // options layer (bin labels are pre-formatted in the merger), so we\n // skip the legend `labelFormatter` argument too.\n legend: {\n ...buildLegendConfig({ hasLegend: false }),\n },\n axisPointer: { lineStyle: { color: theme.palette.grey[400] } },\n color: [\n theme.palette.secondary.main,\n ...Object.values(\n (theme.palette as { qualitative?: { bold?: Record<string, string> } })\n .qualitative?.bold ?? {},\n ),\n ],\n xAxis: {\n type: 'category',\n axisLine: { show: false },\n axisTick: { show: false },\n axisLabel: {\n ...buildAxisLabelStyle(theme),\n padding: [parseInt(theme.spacing(0.5)), 0, 0, 0],\n margin: 0,\n // `interval: 0` makes every bin label a candidate so `hideOverlap`\n // can pack the maximum number that physically fit. The category-axis\n // default (`'auto'`) sub-samples first and leaves only one/two labels\n // even when there's room for more.\n interval: 0,\n hideOverlap: true,\n },\n },\n yAxis: {\n type: 'value',\n min: (extent: { min: number }) => {\n niceMin = extent.min < 0 ? niceNum(extent.min) : 0\n return niceMin\n },\n max: (extent: { min: number; max: number }) => {\n niceMax = extent.max <= 0 ? 1 : niceNum(extent.max)\n return niceMax\n },\n axisLine: { show: false },\n axisTick: { show: false },\n splitLine: {\n show: true,\n lineStyle: { color: theme.palette.black?.[4] ?? theme.palette.divider },\n },\n axisLabel: {\n ...buildAxisLabelStyle(theme),\n margin: parseInt(theme.spacing(1)),\n show: true,\n showMaxLabel: true,\n showMinLabel: true,\n verticalAlign: 'bottom',\n inside: true,\n formatter: (value: number) => {\n if (value !== niceMax && value !== niceMin) return ''\n if (value === 0) return ''\n return formatter ? formatter(value) : String(value)\n },\n },\n },\n } as HistogramEChartsOption\n}\n\n/**\n * Returns the histogram widget's {@link OptionFactory} — one closure that\n * owns BOTH phases of option construction:\n *\n * - **Structural phase** (`option == null`) — builds the theme-aware\n * structural option via {@link histogramOptions}, optionally merging\n * the consumer-supplied `optionsOverride`. Called once by Provider to\n * seed `rawOptions` in the store.\n * - **Merge phase** (`option != null`) — fuses post-pipeline `state.data`\n * (`HistogramWidgetData` — `number[][]`) into the option via the\n * dataset API. Each series gets its own dataset of `[binLabel, count]`\n * pairs derived from `ticks`; series reference their dataset by\n * `datasetIndex` and are encoded by column position. Reactive\n * `ctx.formatter` (driven by RelativeData → `%`) plus `niceMin`/`niceMax`\n * are re-derived here so the y-axis label formatter and the tooltip\n * pick up live store values, mirroring bar.\n */\nexport function createHistogramOptionFactory(\n options: HistogramOptionFactoryInput,\n): OptionFactory {\n const { theme, formatter, ticks, series, labelFormatter, selection } = options\n const optionsOverride = options.optionsOverride\n const selectionSet =\n selection && selection.length > 0 ? new Set<number>(selection) : null\n\n const binLabels: string[] = []\n for (let i = 0; i < ticks.length - 1; i++) {\n const lo = ticks[i]!\n const hi = ticks[i + 1]!\n const raw = `${formatNumber(lo)}–${formatNumber(hi)}`\n binLabels.push(labelFormatter ? labelFormatter(raw) : raw)\n }\n\n return (option, data, ctx) => {\n if (option == null) {\n const structural = histogramOptions({ theme, formatter })\n return optionsOverride\n ? (mergeOptions(\n structural as unknown as Record<string, unknown>,\n optionsOverride as Partial<Record<string, unknown>>,\n ) as EChartsOption)\n : structural\n }\n\n const seriesArr: HistogramWidgetData = Array.isArray(data)\n ? (data as HistogramWidgetData)\n : []\n if (seriesArr.length === 0 || binLabels.length === 0) {\n return { ...option, dataset: [], series: [] }\n }\n\n const hasLegend = seriesArr.length > 1\n const seriesTemplates = Array.isArray(option.series) ? option.series : []\n const broadcastTemplate = seriesTemplates[0] ?? {}\n const baseYAxis =\n typeof option.yAxis === 'object' && !Array.isArray(option.yAxis)\n ? option.yAxis\n : {}\n const baseGrid =\n typeof option.grid === 'object' && !Array.isArray(option.grid)\n ? option.grid\n : {}\n const baseTooltip =\n typeof option.tooltip === 'object' && !Array.isArray(option.tooltip)\n ? option.tooltip\n : {}\n const baseLegend =\n typeof option.legend === 'object' && !Array.isArray(option.legend)\n ? option.legend\n : {}\n // Reactive (live store) formatter from ctx — distinct from the\n // closure-time `formatter` captured for the structural-build branch\n // above. RelativeData can install a percent formatter on the store\n // after the factory was constructed; the merge phase reads `ctx` to\n // pick that up.\n const liveFormatter = ctx?.formatter\n\n // Closure shared between the yAxis min/max callbacks and the label\n // formatter, so only the rounded extents are labelled (matches v1 +\n // bar). Delegating the extent to ECharts (rather than precomputing\n // scalars from the raw counts) keeps stacked bins inside the plot:\n // when StackToggle marks the series, ECharts feeds the *post-stack*\n // extent to these callbacks, so `niceNum` rounds the stacked total.\n let niceMin = 0\n let niceMax = 1\n\n // Zoom slider layout: when ZoomToggle has installed `dataZoom`, push\n // the slider above the legend (if any) and reserve room in the grid.\n const dataZoomLayout = positionDataZoomForLegend(option.dataZoom, hasLegend)\n const fallbackBottom =\n typeof baseGrid.bottom === 'number' ? baseGrid.bottom : 24\n const baseBottom = hasLegend ? 56 : fallbackBottom\n const gridBottom = dataZoomLayout\n ? baseBottom + ZOOM_LAYOUT.sliderHeight + ZOOM_LAYOUT.sliderGap\n : baseBottom\n\n // Dim non-selected bins via `series.itemStyle.color`. Per-row\n // `itemStyle` on dataset sources is silently ignored when\n // `series.encode` is in play.\n //\n // We *always* emit `itemStyle.color` (a passthrough when nothing is\n // selected), not conditionally — dropping the key between renders\n // would let ECharts' default merge keep the previous callback alive\n // and bins would stay dimmed forever after an external clear. Always\n // emitting lets normal merge swap the callback in place, no\n // `replaceMerge` and no entry-animation flash on selection on/off.\n const dimItemStyle = {\n color: (params: CallbackDataParams) => {\n const base = params.color as string\n if (!selectionSet) return base\n return selectionSet.has(params.dataIndex)\n ? base\n : echarts.color.modifyAlpha(base, 0.15)\n },\n }\n\n return {\n ...option,\n dataset: seriesArr.map((counts) => ({\n source: binLabels.map(\n (label, i) => [label, counts[i] ?? 0] as [string, number],\n ),\n })),\n series: seriesArr.map((_, i) => {\n const template =\n (seriesTemplates[i] as object | undefined) ??\n (broadcastTemplate as object)\n const overrideColor = resolveThemeColor(theme, series?.[i]?.color)\n return {\n ...(typeof template === 'object' ? template : {}),\n type: 'bar' as const,\n datasetIndex: i,\n name: series?.[i]?.name ?? `Series ${i + 1}`,\n encode: { x: 0, y: 1 },\n barCategoryGap: '0%',\n emphasis: { focus: 'series' },\n itemStyle: dimItemStyle,\n ...(overrideColor ? { color: overrideColor } : {}),\n }\n }),\n legend: { ...baseLegend, show: hasLegend },\n grid: { ...baseGrid, bottom: gridBottom },\n ...(dataZoomLayout ? { dataZoom: dataZoomLayout } : {}),\n yAxis: {\n ...baseYAxis,\n min: (extent: { min: number }) => {\n niceMin = extent.min < 0 ? niceNum(extent.min) : 0\n return niceMin\n },\n max: (extent: { min: number; max: number }) => {\n niceMax = extent.max <= 0 ? 1 : niceNum(extent.max)\n return niceMax\n },\n axisLabel: {\n ...((baseYAxis as { axisLabel?: object }).axisLabel ?? {}),\n formatter: (value: number) => {\n if (value !== niceMax && value !== niceMin) return ''\n if (value === 0) return ''\n return liveFormatter ? liveFormatter(value) : String(value)\n },\n },\n } as EChartsOption['yAxis'],\n tooltip: {\n ...baseTooltip,\n formatter: buildHistogramTooltipFormatter(liveFormatter),\n },\n } as EChartsOption\n }\n}\n\n/**\n * Tooltip formatter for the histogram's positional `[binLabel, count]`\n * row shape. ECharts surfaces the x-axis category through `item.name`\n * (already pre-formatted by the bin-label generator), and `item.value`\n * comes in as the array tuple — distinct from bar's `{ name, value }`\n * object row.\n */\nfunction buildHistogramTooltipFormatter(\n formatter: ((value: number) => string) | undefined,\n) {\n return createTooltipFormatter((item) => {\n const row = item.value as [string, number] | undefined\n const raw = row?.[1]\n const formattedValue =\n typeof raw === 'number' && formatter ? formatter(raw) : (raw ?? '')\n const marker = typeof item.marker === 'string' ? item.marker : ''\n const seriesName = item.seriesName ? `${item.seriesName}: ` : ''\n return {\n name: String(item.name ?? ''),\n seriesName,\n marker,\n value: formattedValue,\n }\n })\n}\n\nfunction formatNumber(n: number): string {\n if (Number.isInteger(n)) return String(n)\n return Number(n.toFixed(2)).toString()\n}\n","import { Box, Skeleton, type SxProps, type Theme } from '@mui/material'\n\nconst styles = {\n container: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n flexDirection: 'column',\n gap: ({ spacing }) => spacing(1),\n height: ({ spacing }) => spacing(38),\n },\n grid: {\n display: 'flex',\n alignItems: 'flex-end',\n flex: '1 1 auto',\n gap: 0.5,\n width: '100%',\n },\n legend: {\n display: 'flex',\n alignItems: 'center',\n gap: ({ spacing }) => spacing(2),\n height: ({ spacing }) => spacing(5),\n },\n legendItem: {\n display: 'flex',\n alignItems: 'center',\n gap: ({ spacing }) => spacing(1.5),\n },\n} satisfies Record<string, SxProps<Theme>>\n\nconst barSx = (height: number): SxProps<Theme> => ({\n flex: 1,\n height: `${height}%`,\n minWidth: 8,\n})\n\nexport interface HistogramSkeletonProps {\n bins?: number\n}\n\n/**\n * Loading state for the Histogram widget. Mirrors Bar's skeleton structure\n * — a grid of bars (bin-shaped silhouette, anchored to the bottom) plus a\n * legend stub — so the placeholder reads consistently with Bar.\n */\nexport function HistogramSkeleton({ bins = 12 }: HistogramSkeletonProps) {\n // Sample heights mimicking a typical bell-shaped distribution.\n const heights = Array.from({ length: bins }, (_, i) => {\n const t = i / Math.max(1, bins - 1)\n return Math.round(20 + 80 * Math.exp(-((t - 0.5) ** 2) * 8))\n })\n return (\n <Box sx={styles.container}>\n <Box sx={styles.grid}>\n {heights.map((h, i) => (\n <Skeleton key={`bar-${i}`} variant='rectangular' sx={barSx(h)} />\n ))}\n </Box>\n <Box sx={styles.legend}>\n {[0, 1].map((i) => (\n <Box key={`legend-${i}`} sx={styles.legendItem}>\n <Skeleton variant='circular' width={8} height={8} />\n <Skeleton width={48} height={8} />\n </Box>\n ))}\n </Box>\n </Box>\n )\n}\n","import {\n buildCsvDownloadItem,\n buildPngDownloadItem,\n type DownloadItem,\n} from '../actions/download'\nimport type { HistogramWidgetData } from './types'\n\n/**\n * Download menu items for histograms. Always includes a CSV item with\n * `bin_low, bin_high, series_1_count, series_2_count, …` columns (one row\n * per bin). When `getCaptureEl` is supplied, prepends a PNG item that\n * rasterises the captured element via `html2canvas`.\n */\nexport function createHistogramDownloadConfig(args: {\n filename: string\n getData: () => HistogramWidgetData\n getTicks: () => readonly number[]\n seriesNames?: readonly string[]\n getCaptureEl?: () => HTMLElement | null\n pngPixelRatio?: number\n pngBackgroundColor?: string | null\n}): DownloadItem[] {\n const items: DownloadItem[] = []\n if (args.getCaptureEl) {\n items.push(\n buildPngDownloadItem({\n filename: args.filename,\n getCaptureEl: args.getCaptureEl,\n pixelRatio: args.pngPixelRatio,\n backgroundColor: args.pngBackgroundColor,\n }),\n )\n }\n items.push(\n buildCsvDownloadItem({\n filename: args.filename,\n getRows: () => {\n const data = args.getData()\n const ticks = args.getTicks()\n const seriesCount = data.length\n const header: unknown[] = ['bin_low', 'bin_high']\n for (let i = 0; i < seriesCount; i++) {\n header.push(args.seriesNames?.[i] ?? `series_${i + 1}`)\n }\n const rows: unknown[][] = [header]\n for (let bin = 0; bin < Math.max(0, ticks.length - 1); bin++) {\n const row: unknown[] = [ticks[bin], ticks[bin + 1]]\n for (let s = 0; s < seriesCount; s++) row.push(data[s]?.[bin] ?? 0)\n rows.push(row)\n }\n return rows\n },\n }),\n )\n return items\n}\n","/**\n * Histogram-specific `RelativeData` transform. Histogram data is\n * `number[][]` — each series is a flat list of bin counts. This\n * rewrites each count to its share of the series total (0–100), so\n * pairing with `createPercentFormatter` renders the y-axis as\n * percentages.\n *\n * Pass to `<Widget.RelativeData transform={toRelativeHistogramData} />`.\n *\n * The denominator is the sum of |value| across the series so mixed-sign\n * inputs produce sane signed shares-of-magnitude. A series whose total\n * magnitude is zero (all-zero or empty input) is returned unchanged so\n * a stalled or empty data set doesn't show misleading 0% values. Inputs\n * whose shape isn't `number[][]` fall through untouched (same defensive\n * shape-check pattern as the default transform).\n */\nexport const toRelativeHistogramData = (input: unknown): unknown => {\n if (!Array.isArray(input)) return input\n return input.map((series: unknown): unknown => {\n if (!isFlatNumberArray(series)) return series\n const total = series.reduce((acc, v) => acc + Math.abs(v), 0)\n if (total <= 0) return series\n return series.map((v) => (v / total) * 100)\n })\n}\n\nfunction isFlatNumberArray(v: unknown): v is number[] {\n if (!Array.isArray(v)) return false\n return v.every((item) => typeof item === 'number' && Number.isFinite(item))\n}\n"],"names":["histogramOptions","theme","formatter","niceMin","niceMax","grid","left","parseInt","spacing","top","right","buildGridConfig","containLabel","tooltip","trigger","backgroundColor","palette","grey","borderWidth","padding","textStyle","color","common","white","fontSize","fontFamily","typography","caption","axisPointer","type","position","createTooltipPositioner","buildHistogramTooltipFormatter","legend","buildLegendConfig","hasLegend","lineStyle","secondary","main","Object","values","qualitative","bold","xAxis","axisLine","show","axisTick","axisLabel","buildAxisLabelStyle","margin","interval","hideOverlap","yAxis","min","extent","niceNum","max","splitLine","black","divider","showMaxLabel","showMinLabel","verticalAlign","inside","value","String","createHistogramOptionFactory","options","ticks","series","labelFormatter","selection","optionsOverride","selectionSet","length","Set","binLabels","i","lo","hi","raw","formatNumber","push","option","data","ctx","structural","mergeOptions","seriesArr","Array","isArray","dataset","seriesTemplates","broadcastTemplate","baseYAxis","baseGrid","baseTooltip","baseLegend","liveFormatter","dataZoomLayout","positionDataZoomForLegend","dataZoom","fallbackBottom","bottom","baseBottom","gridBottom","ZOOM_LAYOUT","sliderHeight","sliderGap","dimItemStyle","params","base","has","dataIndex","echarts","modifyAlpha","map","counts","source","label","_","template","overrideColor","resolveThemeColor","datasetIndex","name","encode","x","y","barCategoryGap","emphasis","focus","itemStyle","createTooltipFormatter","item","formattedValue","marker","seriesName","n","Number","isInteger","toFixed","toString","styles","container","display","alignItems","justifyContent","flexDirection","gap","height","flex","width","legendItem","barSx","minWidth","HistogramSkeleton","t0","$","_c","bins","t1","undefined","T0","T1","t2","t3","t4","heights","from","t","Math","round","exp","Box","_temp","t5","jsx","t6","Symbol","for","_temp2","t7","i_1","jsxs","Skeleton","h","i_0","createHistogramDownloadConfig","args","items","getCaptureEl","buildPngDownloadItem","filename","pixelRatio","pngPixelRatio","pngBackgroundColor","buildCsvDownloadItem","getRows","getData","getTicks","seriesCount","header","seriesNames","rows","bin","row","s","toRelativeHistogramData","input","isFlatNumberArray","total","reduce","acc","v","abs","every","isFinite"],"mappings":"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"}
|