@carto/ps-react-ui 4.11.3 → 4.12.0

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.
Files changed (77) hide show
  1. package/dist/chat.js +962 -733
  2. package/dist/chat.js.map +1 -1
  3. package/dist/csv-item-hH_Gt7ur.js +32 -0
  4. package/dist/csv-item-hH_Gt7ur.js.map +1 -0
  5. package/dist/png-item-9dNbB37T.js +57 -0
  6. package/dist/png-item-9dNbB37T.js.map +1 -0
  7. package/dist/table-B3ZWWhJt.js +383 -0
  8. package/dist/table-B3ZWWhJt.js.map +1 -0
  9. package/dist/types/chat/containers/chat-footer.d.ts +1 -1
  10. package/dist/types/chat/containers/styles.d.ts +79 -12
  11. package/dist/types/chat/index.d.ts +1 -1
  12. package/dist/types/chat/types.d.ts +21 -0
  13. package/dist/types/chat/use-typewriter.d.ts +5 -3
  14. package/dist/types/widgets-v2/actions/download/constants.d.ts +12 -0
  15. package/dist/types/widgets-v2/actions/download/csv-item.d.ts +38 -0
  16. package/dist/types/widgets-v2/actions/download/icons.d.ts +6 -0
  17. package/dist/types/widgets-v2/actions/download/index.d.ts +3 -1
  18. package/dist/types/widgets-v2/actions/index.d.ts +1 -1
  19. package/dist/widgets-v2/actions.js +40 -36
  20. package/dist/widgets-v2/actions.js.map +1 -1
  21. package/dist/widgets-v2/bar.js +77 -84
  22. package/dist/widgets-v2/bar.js.map +1 -1
  23. package/dist/widgets-v2/category.js +50 -55
  24. package/dist/widgets-v2/category.js.map +1 -1
  25. package/dist/widgets-v2/formula.js +37 -43
  26. package/dist/widgets-v2/formula.js.map +1 -1
  27. package/dist/widgets-v2/histogram.js +138 -144
  28. package/dist/widgets-v2/histogram.js.map +1 -1
  29. package/dist/widgets-v2/markdown.js +18 -17
  30. package/dist/widgets-v2/markdown.js.map +1 -1
  31. package/dist/widgets-v2/pie.js +67 -73
  32. package/dist/widgets-v2/pie.js.map +1 -1
  33. package/dist/widgets-v2/scatterplot.js +75 -81
  34. package/dist/widgets-v2/scatterplot.js.map +1 -1
  35. package/dist/widgets-v2/spread.js +36 -41
  36. package/dist/widgets-v2/spread.js.map +1 -1
  37. package/dist/widgets-v2/table.js +46 -55
  38. package/dist/widgets-v2/table.js.map +1 -1
  39. package/dist/widgets-v2/timeseries.js +81 -87
  40. package/dist/widgets-v2/timeseries.js.map +1 -1
  41. package/dist/widgets-v2.js +1 -1
  42. package/package.json +1 -1
  43. package/src/chat/bubbles/styles.ts +5 -1
  44. package/src/chat/containers/chat-content.tsx +4 -1
  45. package/src/chat/containers/chat-footer.test.tsx +59 -0
  46. package/src/chat/containers/chat-footer.tsx +124 -36
  47. package/src/chat/containers/styles.ts +107 -16
  48. package/src/chat/feedback/styles.ts +11 -4
  49. package/src/chat/index.ts +1 -0
  50. package/src/chat/types.ts +22 -0
  51. package/src/chat/use-typewriter.ts +32 -24
  52. package/src/widgets-v2/actions/download/constants.ts +14 -0
  53. package/src/widgets-v2/actions/download/csv-item.test.tsx +77 -0
  54. package/src/widgets-v2/actions/download/csv-item.tsx +71 -0
  55. package/src/widgets-v2/actions/download/icons.tsx +10 -1
  56. package/src/widgets-v2/actions/download/index.ts +3 -1
  57. package/src/widgets-v2/actions/download/png-item.tsx +2 -1
  58. package/src/widgets-v2/actions/index.ts +5 -0
  59. package/src/widgets-v2/bar/download.tsx +16 -22
  60. package/src/widgets-v2/category/download.test.ts +9 -0
  61. package/src/widgets-v2/category/download.ts +16 -20
  62. package/src/widgets-v2/formula/download.tsx +23 -29
  63. package/src/widgets-v2/histogram/download.ts +22 -26
  64. package/src/widgets-v2/markdown/{download.ts → download.tsx} +5 -2
  65. package/src/widgets-v2/pie/download.ts +16 -20
  66. package/src/widgets-v2/scatterplot/download.ts +16 -20
  67. package/src/widgets-v2/spread/download.ts +23 -27
  68. package/src/widgets-v2/table/download.test.ts +10 -0
  69. package/src/widgets-v2/table/download.ts +11 -15
  70. package/src/widgets-v2/table/helpers.test.ts +19 -0
  71. package/src/widgets-v2/table/helpers.ts +7 -12
  72. package/src/widgets-v2/timeseries/download.ts +36 -40
  73. package/dist/png-item-BE9uEqlD.js +0 -45
  74. package/dist/png-item-BE9uEqlD.js.map +0 -1
  75. package/dist/table-C9IMbTr0.js +0 -385
  76. package/dist/table-C9IMbTr0.js.map +0 -1
  77. package/dist/types/chat/feedback/styles.d.ts +0 -211
@@ -1,8 +1,8 @@
1
1
  import * as E from "echarts";
2
- import { d as H, g as V, c as W, n as S, f as F } from "../option-builders-F-c9ELi1.js";
2
+ import { d as H, g as W, c as q, n as A, f as C } from "../option-builders-F-c9ELi1.js";
3
3
  import { jsx as x, jsxs as M } from "react/jsx-runtime";
4
- import { c as q } from "react/compiler-runtime";
5
- import { Skeleton as I, Box as A } from "@mui/material";
4
+ import { c as U } from "react/compiler-runtime";
5
+ import { Skeleton as I, Box as S } from "@mui/material";
6
6
  import "../widget-store-Bw5zRUGg.js";
7
7
  import "zustand/shallow";
8
8
  import "@mui/icons-material";
@@ -21,9 +21,9 @@ import "zustand/vanilla";
21
21
  import "zustand/middleware";
22
22
  import "zustand/react/shallow";
23
23
  import { Z as b } from "../transforms-Cdx4fkU5.js";
24
- import { m as U, r as J } from "../resolve-theme-color-BdojIw0K.js";
25
- import { a as K } from "../exports-Cx-f6m6U.js";
26
- import { b as Q } from "../png-item-BE9uEqlD.js";
24
+ import { m as J, r as K } from "../resolve-theme-color-BdojIw0K.js";
25
+ import { b as Q } from "../png-item-9dNbB37T.js";
26
+ import { b as V } from "../csv-item-hH_Gt7ur.js";
27
27
  function ee({
28
28
  theme: e,
29
29
  xFormatter: t,
@@ -35,7 +35,7 @@ function ee({
35
35
  top: parseInt(e.spacing(3)),
36
36
  right: parseInt(e.spacing(1)),
37
37
  // Default: no legend. Merger bumps `bottom` when there are >1 series.
38
- ...W(!1, e),
38
+ ...q(!1, e),
39
39
  containLabel: !0
40
40
  },
41
41
  tooltip: {
@@ -50,7 +50,7 @@ function ee({
50
50
  fontSize: 11,
51
51
  fontFamily: e.typography.caption.fontFamily
52
52
  },
53
- position: V(e),
53
+ position: W(e),
54
54
  formatter: oe(t, r)
55
55
  },
56
56
  // Legend styling baked here; `show` is toggled by the merger based on
@@ -123,32 +123,32 @@ function ee({
123
123
  }
124
124
  };
125
125
  }
126
- function De(e) {
126
+ function Te(e) {
127
127
  const {
128
128
  theme: t,
129
129
  xFormatter: r,
130
- yFormatter: i,
131
- optionsOverride: n
130
+ yFormatter: o,
131
+ optionsOverride: i
132
132
  } = e, s = e.series, a = e.symbolSize ?? 8, l = e.selection, c = l && l.length > 0 ? new Set(l) : null;
133
- return (o, u, p) => {
134
- if (o == null) {
133
+ return (n, u, p) => {
134
+ if (n == null) {
135
135
  const d = ee({
136
136
  theme: t,
137
137
  xFormatter: r,
138
- yFormatter: i
138
+ yFormatter: o
139
139
  });
140
- return n ? U(d, n) : d;
140
+ return i ? J(d, i) : d;
141
141
  }
142
142
  const f = Array.isArray(u) ? u : [];
143
143
  if (f.length === 0)
144
144
  return {
145
- ...o,
145
+ ...n,
146
146
  dataset: [],
147
147
  series: []
148
148
  };
149
- const k = f.length > 1, Y = typeof o.legend == "object" && !Array.isArray(o.legend) ? o.legend : {}, g = typeof o.grid == "object" && !Array.isArray(o.grid) ? o.grid : {}, L = typeof o.tooltip == "object" && !Array.isArray(o.tooltip) ? o.tooltip : {}, T = typeof o.xAxis == "object" && !Array.isArray(o.xAxis) ? o.xAxis : {}, N = typeof o.yAxis == "object" && !Array.isArray(o.yAxis) ? o.yAxis : {}, w = p?.formatter, {
150
- niceMinX: X,
151
- niceMaxX: D,
149
+ const w = f.length > 1, Y = typeof n.legend == "object" && !Array.isArray(n.legend) ? n.legend : {}, g = typeof n.grid == "object" && !Array.isArray(n.grid) ? n.grid : {}, L = typeof n.tooltip == "object" && !Array.isArray(n.tooltip) ? n.tooltip : {}, X = typeof n.xAxis == "object" && !Array.isArray(n.xAxis) ? n.xAxis : {}, N = typeof n.yAxis == "object" && !Array.isArray(n.yAxis) ? n.yAxis : {}, k = p?.formatter, {
150
+ niceMinX: D,
151
+ niceMaxX: T,
152
152
  niceMinY: j,
153
153
  niceMaxY: O
154
154
  } = ie(f), z = (d) => (m) => {
@@ -156,16 +156,16 @@ function De(e) {
156
156
  if (!c) return y;
157
157
  const Z = `${d}:${m.dataIndex}`;
158
158
  return c.has(Z) ? y : E.color.modifyAlpha(y, 0.15);
159
- }, h = te(o.dataZoom, k), _ = h?.hasXSlider ?? !1, B = h?.hasYSlider ?? !1, R = typeof g.bottom == "number" ? g.bottom : 24, $ = k ? 56 : R, P = _ ? $ + b.sliderHeight + b.sliderGap : $, C = typeof g.right == "number" ? g.right : 8, G = B ? C + b.sliderHeight + b.sliderGap : C;
159
+ }, h = te(n.dataZoom, w), _ = h?.hasXSlider ?? !1, R = h?.hasYSlider ?? !1, B = typeof g.bottom == "number" ? g.bottom : 24, F = w ? 56 : B, G = _ ? F + b.sliderHeight + b.sliderGap : F, $ = typeof g.right == "number" ? g.right : 8, P = R ? $ + b.sliderHeight + b.sliderGap : $;
160
160
  return {
161
- ...o,
161
+ ...n,
162
162
  // ECharts dataset.source wants a mutable [number, number][] shape; we
163
163
  // hold readonly tuples internally, so cast at the boundary.
164
164
  dataset: f.map((d) => ({
165
165
  source: d
166
166
  })),
167
167
  series: f.map((d, m) => {
168
- const y = J(t, s?.[m]?.color);
168
+ const y = K(t, s?.[m]?.color);
169
169
  return {
170
170
  type: "scatter",
171
171
  datasetIndex: m,
@@ -188,20 +188,20 @@ function De(e) {
188
188
  }),
189
189
  legend: {
190
190
  ...Y,
191
- show: k
191
+ show: w
192
192
  },
193
193
  grid: {
194
194
  ...g,
195
- bottom: P,
196
- right: G
195
+ bottom: G,
196
+ right: P
197
197
  },
198
198
  ...h ? {
199
199
  dataZoom: h.entries
200
200
  } : {},
201
201
  xAxis: {
202
- ...T,
203
- min: X,
204
- max: D
202
+ ...X,
203
+ min: D,
204
+ max: T
205
205
  },
206
206
  yAxis: {
207
207
  ...N,
@@ -214,8 +214,8 @@ function De(e) {
214
214
  // without rebuilding the structural option. Falls back to the
215
215
  // structural `yFormatter` already baked in `baseYAxis.axisLabel`
216
216
  // (which `String(value)` if neither is set).
217
- ...w ? {
218
- formatter: w
217
+ ...k ? {
218
+ formatter: k
219
219
  } : {}
220
220
  }
221
221
  },
@@ -225,57 +225,57 @@ function De(e) {
225
225
  // applied to the y-coordinate in the (x, y) label. xFormatter is
226
226
  // structural — relative is a values-axis concept, so xFormatter
227
227
  // doesn't change under RelativeData.
228
- formatter: re(L.formatter, w, r)
228
+ formatter: re(L.formatter, k, r)
229
229
  }
230
230
  };
231
231
  };
232
232
  }
233
233
  function te(e, t) {
234
234
  if (!Array.isArray(e) || e.length === 0) return null;
235
- let r = !1, i = !1;
235
+ let r = !1, o = !1;
236
236
  return {
237
237
  entries: e.map((s) => {
238
238
  if (s == null || typeof s != "object") return s;
239
239
  const a = s;
240
- return a.type !== "slider" ? a : a.yAxisIndex !== void 0 ? (i = !0, a) : (r = !0, t ? {
240
+ return a.type !== "slider" ? a : a.yAxisIndex !== void 0 ? (o = !0, a) : (r = !0, t ? {
241
241
  ...a,
242
242
  bottom: b.sliderBottomWithLegend
243
243
  } : a);
244
244
  }),
245
245
  hasXSlider: r,
246
- hasYSlider: i
246
+ hasYSlider: o
247
247
  };
248
248
  }
249
249
  function re(e, t, r) {
250
- return t ? F((i) => {
251
- const n = i.value, s = n?.[0], a = n?.[1], l = typeof s == "number" ? r ? r(s) : String(s) : "", c = typeof a == "number" ? t(a) : String(a ?? ""), o = typeof i.marker == "string" ? i.marker : "", u = i.seriesName ? `${i.seriesName}: ` : "";
250
+ return t ? C((o) => {
251
+ const i = o.value, s = i?.[0], a = i?.[1], l = typeof s == "number" ? r ? r(s) : String(s) : "", c = typeof a == "number" ? t(a) : String(a ?? ""), n = typeof o.marker == "string" ? o.marker : "", u = o.seriesName ? `${o.seriesName}: ` : "";
252
252
  return {
253
253
  name: `(${l}, ${c})`,
254
254
  seriesName: u,
255
- marker: o,
255
+ marker: n,
256
256
  value: ""
257
257
  };
258
258
  }) : e;
259
259
  }
260
260
  function oe(e, t) {
261
- return F((r) => {
262
- const i = r.value, n = i?.[0], s = i?.[1], a = typeof n == "number" ? e ? e(n) : String(n) : "", l = typeof s == "number" ? t ? t(s) : String(s) : "", c = typeof r.marker == "string" ? r.marker : "", o = r.seriesName ? `${r.seriesName}: ` : "";
261
+ return C((r) => {
262
+ const o = r.value, i = o?.[0], s = o?.[1], a = typeof i == "number" ? e ? e(i) : String(i) : "", l = typeof s == "number" ? t ? t(s) : String(s) : "", c = typeof r.marker == "string" ? r.marker : "", n = r.seriesName ? `${r.seriesName}: ` : "";
263
263
  return {
264
264
  name: `(${a}, ${l})`,
265
- seriesName: o,
265
+ seriesName: n,
266
266
  marker: c,
267
267
  value: ""
268
268
  };
269
269
  });
270
270
  }
271
271
  function ie(e) {
272
- let t = 1 / 0, r = -1 / 0, i = 1 / 0, n = -1 / 0;
273
- for (const o of e)
274
- for (const u of o) {
272
+ let t = 1 / 0, r = -1 / 0, o = 1 / 0, i = -1 / 0;
273
+ for (const n of e)
274
+ for (const u of n) {
275
275
  const p = u?.[0], f = u?.[1];
276
- typeof p == "number" && Number.isFinite(p) && (p < t && (t = p), p > r && (r = p)), typeof f == "number" && Number.isFinite(f) && (f < i && (i = f), f > n && (n = f));
276
+ typeof p == "number" && Number.isFinite(p) && (p < t && (t = p), p > r && (r = p)), typeof f == "number" && Number.isFinite(f) && (f < o && (o = f), f > i && (i = f));
277
277
  }
278
- const s = Number.isFinite(r) ? r <= 0 ? 1 : S(r) : 1, a = Number.isFinite(n) ? n <= 0 ? 1 : S(n) : 1, l = Number.isFinite(t) && t < 0 ? S(t) : 0, c = Number.isFinite(i) && i < 0 ? S(i) : 0;
278
+ const s = Number.isFinite(r) ? r <= 0 ? 1 : A(r) : 1, a = Number.isFinite(i) ? i <= 0 ? 1 : A(i) : 1, l = Number.isFinite(t) && t < 0 ? A(t) : 0, c = Number.isFinite(o) && o < 0 ? A(o) : 0;
279
279
  return {
280
280
  niceMinX: l,
281
281
  niceMaxX: s,
@@ -327,29 +327,29 @@ const v = {
327
327
  borderRadius: "50%"
328
328
  });
329
329
  function je(e) {
330
- const t = q(15), {
330
+ const t = U(15), {
331
331
  count: r
332
- } = e, i = r === void 0 ? 24 : r;
333
- let n, s, a, l, c;
334
- if (t[0] !== i) {
332
+ } = e, o = r === void 0 ? 24 : r;
333
+ let i, s, a, l, c;
334
+ if (t[0] !== o) {
335
335
  const f = Array.from({
336
- length: i
336
+ length: o
337
337
  }, le);
338
- s = A, c = v.container, n = A, a = v.grid, l = f.map(ae), t[0] = i, t[1] = n, t[2] = s, t[3] = a, t[4] = l, t[5] = c;
338
+ s = S, c = v.container, i = S, a = v.grid, l = f.map(ae), t[0] = o, t[1] = i, t[2] = s, t[3] = a, t[4] = l, t[5] = c;
339
339
  } else
340
- n = t[1], s = t[2], a = t[3], l = t[4], c = t[5];
341
- let o;
342
- t[6] !== n || t[7] !== a || t[8] !== l ? (o = /* @__PURE__ */ x(n, { sx: a, children: l }), t[6] = n, t[7] = a, t[8] = l, t[9] = o) : o = t[9];
340
+ i = t[1], s = t[2], a = t[3], l = t[4], c = t[5];
341
+ let n;
342
+ t[6] !== i || t[7] !== a || t[8] !== l ? (n = /* @__PURE__ */ x(i, { sx: a, children: l }), t[6] = i, t[7] = a, t[8] = l, t[9] = n) : n = t[9];
343
343
  let u;
344
- t[10] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (u = /* @__PURE__ */ x(A, { sx: v.legend, children: [0, 1].map(se) }), t[10] = u) : u = t[10];
344
+ t[10] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (u = /* @__PURE__ */ x(S, { sx: v.legend, children: [0, 1].map(se) }), t[10] = u) : u = t[10];
345
345
  let p;
346
- return t[11] !== s || t[12] !== c || t[13] !== o ? (p = /* @__PURE__ */ M(s, { sx: c, children: [
347
- o,
346
+ return t[11] !== s || t[12] !== c || t[13] !== n ? (p = /* @__PURE__ */ M(s, { sx: c, children: [
347
+ n,
348
348
  u
349
- ] }), t[11] = s, t[12] = c, t[13] = o, t[14] = p) : p = t[14], p;
349
+ ] }), t[11] = s, t[12] = c, t[13] = n, t[14] = p) : p = t[14], p;
350
350
  }
351
351
  function se(e) {
352
- return /* @__PURE__ */ M(A, { sx: v.legendItem, children: [
352
+ return /* @__PURE__ */ M(S, { sx: v.legendItem, children: [
353
353
  /* @__PURE__ */ x(I, { variant: "circular", width: 8, height: 8 }),
354
354
  /* @__PURE__ */ x(I, { width: 48, height: 8 })
355
355
  ] }, `legend-${e}`);
@@ -358,11 +358,11 @@ function ae(e, t) {
358
358
  return /* @__PURE__ */ x(I, { variant: "circular", sx: ne(e.top, e.left, e.size) }, `dot-${t}`);
359
359
  }
360
360
  function le(e, t) {
361
- const r = 10 + t * 37 % 80, i = 5 + t * 53 % 90, n = 8 + t * 7 % 6;
361
+ const r = 10 + t * 37 % 80, o = 5 + t * 53 % 90, i = 8 + t * 7 % 6;
362
362
  return {
363
363
  top: `${r}%`,
364
- left: `${i}%`,
365
- size: n
364
+ left: `${o}%`,
365
+ size: i
366
366
  };
367
367
  }
368
368
  function Oe(e) {
@@ -372,29 +372,23 @@ function Oe(e) {
372
372
  getCaptureEl: e.getCaptureEl,
373
373
  pixelRatio: e.pngPixelRatio,
374
374
  backgroundColor: e.pngBackgroundColor
375
- })), t.push({
376
- id: "csv",
377
- label: "Download as CSV",
378
- resolve: () => {
379
- const r = e.getData(), i = [["series", "x", "y"]];
380
- for (const [s, a] of r.entries()) {
381
- const l = e.seriesNames?.[s] ?? `series_${s + 1}`;
382
- for (const [c, o] of a)
383
- i.push([l, c, o]);
375
+ })), t.push(V({
376
+ filename: e.filename,
377
+ getRows: () => {
378
+ const r = e.getData(), o = [["series", "x", "y"]];
379
+ for (const [i, s] of r.entries()) {
380
+ const a = e.seriesNames?.[i] ?? `series_${i + 1}`;
381
+ for (const [l, c] of s)
382
+ o.push([a, l, c]);
384
383
  }
385
- const n = K(i);
386
- return Promise.resolve({
387
- url: n.url,
388
- filename: `${e.filename}.csv`,
389
- revoke: n.revoke
390
- });
384
+ return o;
391
385
  }
392
- }), t;
386
+ })), t;
393
387
  }
394
388
  const ze = (e) => Array.isArray(e) ? e.map((t) => {
395
389
  if (!ce(t)) return t;
396
- const r = t.reduce((i, [, n]) => i + Math.abs(n), 0);
397
- return r <= 0 ? t : t.map(([i, n]) => [i, n / r * 100]);
390
+ const r = t.reduce((o, [, i]) => o + Math.abs(i), 0);
391
+ return r <= 0 ? t : t.map(([o, i]) => [o, i / r * 100]);
398
392
  }) : e;
399
393
  function ce(e) {
400
394
  return Array.isArray(e) ? e.every((t) => Array.isArray(t) && t.length === 2 && typeof t[0] == "number" && Number.isFinite(t[0]) && typeof t[1] == "number" && Number.isFinite(t[1])) : !1;
@@ -402,7 +396,7 @@ function ce(e) {
402
396
  export {
403
397
  je as ScatterplotSkeleton,
404
398
  Oe as createScatterplotDownloadConfig,
405
- De as createScatterplotOptionFactory,
399
+ Te as createScatterplotOptionFactory,
406
400
  ee as scatterplotOptions,
407
401
  ze as toRelativeScatterplotData
408
402
  };
@@ -1 +1 @@
1
- {"version":3,"file":"scatterplot.js","sources":["../../src/widgets-v2/scatterplot/options.ts","../../src/widgets-v2/scatterplot/skeleton.tsx","../../src/widgets-v2/scatterplot/download.ts","../../src/widgets-v2/scatterplot/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 type {\n ScatterplotEChartsOption,\n ScatterplotOptionFactoryInput,\n ScatterplotOptionsInput,\n ScatterplotWidgetData,\n} from './types'\n\n/**\n * Builds the **structural** ECharts option for a scatterplot widget — both\n * axes `type: 'value'` (not category, unlike Bar/Histogram), grid, tooltip\n * triggered per-item rather than per-axis. Intentionally data-agnostic: no\n * series, no dataset, no `legend.show` (those depend on data and are added\n * by {@link createScatterplotOptionFactory}).\n *\n * Styling parity with v1: dark themed tooltip via `createTooltipFormatter`\n * + `createTooltipPositioner`, `buildGridConfig`-based grid, polished\n * axisLine/Tick/splitLine, `overlineDelicate` axis labels, structural\n * legend wired via `buildLegendConfig` (toggled by the merger), and the\n * CARTO `qualitative.bold + secondary` palette — same pattern bar /\n * histogram / pie already use. {@link createScatterplotOptionFactory}\n * wraps this builder in its structural-phase branch.\n */\nexport function scatterplotOptions({\n theme,\n xFormatter,\n yFormatter,\n}: ScatterplotOptionsInput): ScatterplotEChartsOption {\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 `bottom` when there are >1 series.\n ...buildGridConfig(false, theme),\n containLabel: true,\n },\n tooltip: {\n // Per-point trigger — different from Bar's 'axis' trigger because\n // points don't share an x-coordinate.\n trigger: 'item',\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 position: createTooltipPositioner(theme),\n formatter: buildScatterTooltipFormatter(xFormatter, yFormatter),\n },\n // Legend styling baked here; `show` is toggled by the merger based on\n // series count.\n legend: {\n ...buildLegendConfig({ hasLegend: false, labelFormatter: undefined }),\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: 'value',\n axisLine: { show: false },\n axisTick: { show: false },\n axisLabel: {\n fontSize: theme.typography.overlineDelicate?.fontSize,\n fontFamily: theme.typography.overlineDelicate?.fontFamily,\n color: theme.palette.black?.[60],\n margin: parseInt(theme.spacing(1)),\n hideOverlap: true,\n showMinLabel: true,\n showMaxLabel: true,\n ...(xFormatter && { formatter: xFormatter }),\n },\n splitLine: {\n show: true,\n lineStyle: { color: theme.palette.black?.[4] ?? theme.palette.divider },\n },\n },\n yAxis: {\n type: 'value',\n axisLine: { show: false },\n axisTick: { show: false },\n axisLabel: {\n fontSize: theme.typography.overlineDelicate?.fontSize,\n fontFamily: theme.typography.overlineDelicate?.fontFamily,\n color: theme.palette.black?.[60],\n margin: parseInt(theme.spacing(1)),\n hideOverlap: true,\n showMinLabel: true,\n showMaxLabel: true,\n ...(yFormatter && { formatter: yFormatter }),\n },\n splitLine: {\n show: true,\n lineStyle: { color: theme.palette.black?.[4] ?? theme.palette.divider },\n },\n },\n } as ScatterplotEChartsOption\n}\n\n/**\n * Returns the scatterplot widget's {@link OptionFactory} — one closure\n * that owns BOTH phases of option construction:\n *\n * - **Structural phase** (`option == null`) — builds the theme-aware\n * structural option via {@link scatterplotOptions}, 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 * (`ScatterplotWidgetData`) into the option via the dataset API. Each\n * series's `[x, y]` tuples land in `dataset[i].source` as 2-column\n * rows; the series uses positional encoding (`encode: { x: 0, y: 1 }`)\n * and `type: 'scatter'`. niceMin/niceMax are computed over both axes\n * so the chart frames data on rounded extents and numeric jitters\n * don't shift gridlines per render. Reactive `ctx.formatter` (driven\n * by RelativeData) re-derives the y-axis label and tooltip at fusion\n * time; `xFormatter` stays baked at structural-build time (relative\n * is a values-axis concept; x is coordinate-space).\n *\n * When `ZoomToggle` installs a `dataZoom` slider, grid bottom is\n * extended and the slider is positioned above the legend row (if any) —\n * same layout dance bar / histogram / timeseries do.\n */\nexport function createScatterplotOptionFactory(\n options: ScatterplotOptionFactoryInput,\n): OptionFactory {\n const { theme, xFormatter, yFormatter, optionsOverride } = options\n const series = options.series\n const symbolSize = options.symbolSize ?? 8\n const selection = options.selection\n const selectionSet =\n selection && selection.length > 0 ? new Set<string>(selection) : null\n return (option, data, ctx) => {\n if (option == null) {\n const structural = scatterplotOptions({ theme, xFormatter, yFormatter })\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 = Array.isArray(data) ? (data as ScatterplotWidgetData) : []\n if (seriesArr.length === 0) {\n return { ...option, dataset: [], series: [] }\n }\n const hasLegend = seriesArr.length > 1\n const baseLegend =\n typeof option.legend === 'object' && !Array.isArray(option.legend)\n ? option.legend\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 baseXAxis =\n typeof option.xAxis === 'object' && !Array.isArray(option.xAxis)\n ? option.xAxis\n : {}\n const baseYAxis =\n typeof option.yAxis === 'object' && !Array.isArray(option.yAxis)\n ? option.yAxis\n : {}\n\n const reactiveFormatter = ctx?.formatter\n\n const { niceMinX, niceMaxX, niceMinY, niceMaxY } =\n computeScatterBounds(seriesArr)\n\n // Dim non-selected points via `series.itemStyle.color`. The selection\n // key is `${seriesIndex}:${dataIndex}`; we read those off the params\n // ECharts hands to the callback per-data.\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 items would stay dimmed forever after an external clear.\n // Keeping the key always-present means a plain setOption merge swaps\n // the callback in place, no `replaceMerge` and no entry-animation\n // flash on selection on/off.\n const makeDimColor =\n (seriesIdx: number) => (params: CallbackDataParams) => {\n const base = params.color as string\n if (!selectionSet) return base\n const key = `${seriesIdx}:${params.dataIndex}`\n return selectionSet.has(key)\n ? base\n : echarts.color.modifyAlpha(base, 0.15)\n }\n\n // Zoom slider layout: when ZoomToggle has installed `dataZoom`,\n // reserve grid space and lift any x-slider above the legend (if\n // present). Scatter supports 2D zoom via `axes: ['x', 'y']` — in\n // that case there's also a vertical y-slider on the right edge, so\n // we reserve `grid.right` separately. Inside-only dataZoom entries\n // (no `type: 'slider'`) take no grid space.\n const dataZoomLayout = layoutDataZoomForScatter(option.dataZoom, hasLegend)\n const hasXSlider = dataZoomLayout?.hasXSlider ?? false\n const hasYSlider = dataZoomLayout?.hasYSlider ?? false\n const fallbackBottom =\n typeof baseGrid.bottom === 'number' ? baseGrid.bottom : 24\n const baseBottom = hasLegend ? 56 : fallbackBottom\n const gridBottom = hasXSlider\n ? baseBottom + ZOOM_LAYOUT.sliderHeight + ZOOM_LAYOUT.sliderGap\n : baseBottom\n const fallbackRight =\n typeof baseGrid.right === 'number' ? baseGrid.right : 8\n const gridRight = hasYSlider\n ? fallbackRight + ZOOM_LAYOUT.sliderHeight + ZOOM_LAYOUT.sliderGap\n : fallbackRight\n\n return {\n ...option,\n // ECharts dataset.source wants a mutable [number, number][] shape; we\n // hold readonly tuples internally, so cast at the boundary.\n dataset: seriesArr.map((s) => ({ source: s as unknown as number[][] })),\n series: seriesArr.map((_, i) => {\n const overrideColor = resolveThemeColor(theme, series?.[i]?.color)\n return {\n type: 'scatter' as const,\n datasetIndex: i,\n name: series?.[i]?.name ?? `Series ${i + 1}`,\n encode: { x: 0, y: 1 },\n symbolSize,\n emphasis: { focus: 'series' },\n itemStyle: { color: makeDimColor(i) },\n ...(overrideColor ? { color: overrideColor } : {}),\n }\n }),\n legend: { ...baseLegend, show: hasLegend },\n grid: { ...baseGrid, bottom: gridBottom, right: gridRight },\n ...(dataZoomLayout ? { dataZoom: dataZoomLayout.entries } : {}),\n xAxis: {\n ...baseXAxis,\n min: niceMinX,\n max: niceMaxX,\n } as EChartsOption['xAxis'],\n yAxis: {\n ...baseYAxis,\n min: niceMinY,\n max: niceMaxY,\n axisLabel: {\n ...((baseYAxis as { axisLabel?: object }).axisLabel ?? {}),\n // Re-derive the y-axis formatter at fusion time so RelativeData's\n // percent formatter (written to `state.formatter`) flows through\n // without rebuilding the structural option. Falls back to the\n // structural `yFormatter` already baked in `baseYAxis.axisLabel`\n // (which `String(value)` if neither is set).\n ...(reactiveFormatter ? { formatter: reactiveFormatter } : {}),\n },\n } as EChartsOption['yAxis'],\n tooltip: {\n ...baseTooltip,\n // Rebuild the tooltip formatter so the live y-axis formatter is\n // applied to the y-coordinate in the (x, y) label. xFormatter is\n // structural — relative is a values-axis concept, so xFormatter\n // doesn't change under RelativeData.\n formatter: buildReactiveScatterTooltipFormatter(\n (baseTooltip as { formatter?: unknown }).formatter,\n reactiveFormatter,\n xFormatter,\n ),\n },\n } as EChartsOption\n }\n}\n\n/**\n * Lay out the `dataZoom` array for the scatter chart:\n * - Detect whether any horizontal (x-axis) slider is present — if so\n * lift it above the legend row when a legend is shown.\n * - Detect whether any vertical (y-axis) slider is present — the\n * caller reserves `grid.right` so the slider doesn't overlap the\n * plot area.\n *\n * Returns `null` when there's no `dataZoom` so callers can skip the\n * layout adjustment entirely. An entry is considered an \"x-slider\" if\n * it has `xAxisIndex` set (or no axis index — defaults to x in ECharts).\n * A \"y-slider\" has `yAxisIndex` set.\n */\nfunction layoutDataZoomForScatter(\n dataZoom: unknown,\n hasLegend: boolean,\n): { entries: unknown[]; hasXSlider: boolean; hasYSlider: boolean } | null {\n if (!Array.isArray(dataZoom) || dataZoom.length === 0) return null\n let hasXSlider = false\n let hasYSlider = false\n const entries = dataZoom.map((entry: unknown) => {\n if (entry == null || typeof entry !== 'object') return entry\n const dz = entry as {\n type?: string\n xAxisIndex?: unknown\n yAxisIndex?: unknown\n bottom?: number\n }\n if (dz.type !== 'slider') return dz\n const targetsY = dz.yAxisIndex !== undefined\n if (targetsY) {\n hasYSlider = true\n return dz\n }\n // Either explicit x or defaulted (ECharts defaults sliders to xAxis\n // when no axis index is provided).\n hasXSlider = true\n if (hasLegend) {\n return { ...dz, bottom: ZOOM_LAYOUT.sliderBottomWithLegend }\n }\n return dz\n })\n return { entries, hasXSlider, hasYSlider }\n}\n\n/**\n * If a reactive (store-driven) y formatter is provided, re-build the\n * scatter tooltip formatter using it. Otherwise, return the structural\n * formatter unchanged so the original `xFormatter` / `yFormatter`\n * baked into `scatterplotOptions` still applies. The structural\n * formatter has stable identity per `scatterplotOptions` call, so this\n * path doesn't churn ECharts on every render.\n */\nfunction buildReactiveScatterTooltipFormatter(\n structuralFormatter: unknown,\n reactiveYFormatter: ((value: number) => string) | undefined,\n xFormatter: ((value: number) => string) | undefined,\n) {\n if (!reactiveYFormatter) return structuralFormatter\n return createTooltipFormatter((item) => {\n const value = item.value as readonly [number, number] | undefined\n const x = value?.[0]\n const y = value?.[1]\n const formattedX =\n typeof x === 'number' ? (xFormatter ? xFormatter(x) : String(x)) : ''\n const formattedY =\n typeof y === 'number' ? reactiveYFormatter(y) : String(y ?? '')\n const marker = typeof item.marker === 'string' ? item.marker : ''\n const seriesName = item.seriesName ? `${item.seriesName}: ` : ''\n return {\n name: `(${formattedX}, ${formattedY})`,\n seriesName,\n marker,\n value: '',\n }\n })\n}\n\nfunction buildScatterTooltipFormatter(\n xFormatter: ((value: number) => string) | undefined,\n yFormatter: ((value: number) => string) | undefined,\n) {\n return createTooltipFormatter((item) => {\n const value = item.value as readonly [number, number] | undefined\n const x = value?.[0]\n const y = value?.[1]\n const formattedX =\n typeof x === 'number' ? (xFormatter ? xFormatter(x) : String(x)) : ''\n const formattedY =\n typeof y === 'number' ? (yFormatter ? yFormatter(y) : String(y)) : ''\n const marker = typeof item.marker === 'string' ? item.marker : ''\n const seriesName = item.seriesName ? `${item.seriesName}: ` : ''\n return {\n name: `(${formattedX}, ${formattedY})`,\n seriesName,\n marker,\n value: '',\n }\n })\n}\n\nfunction computeScatterBounds(seriesArr: ScatterplotWidgetData): {\n niceMinX: number\n niceMaxX: number\n niceMinY: number\n niceMaxY: number\n} {\n let minX = Infinity\n let maxX = -Infinity\n let minY = Infinity\n let maxY = -Infinity\n for (const series of seriesArr) {\n for (const point of series) {\n const x = point?.[0]\n const y = point?.[1]\n if (typeof x === 'number' && Number.isFinite(x)) {\n if (x < minX) minX = x\n if (x > maxX) maxX = x\n }\n if (typeof y === 'number' && Number.isFinite(y)) {\n if (y < minY) minY = y\n if (y > maxY) maxY = y\n }\n }\n }\n // Mirror bar's `computeNiceBounds`: clamp min to 0 when data is\n // non-negative (gridline reads cleanly from zero), apply `niceNum` to\n // negative mins, and floor max=0 to 1 so the chart always has range.\n // Scatter can have free coordinates so we apply this per-axis.\n const niceMaxX = Number.isFinite(maxX) ? (maxX <= 0 ? 1 : niceNum(maxX)) : 1\n const niceMaxY = Number.isFinite(maxY) ? (maxY <= 0 ? 1 : niceNum(maxY)) : 1\n const niceMinX = Number.isFinite(minX) ? (minX < 0 ? niceNum(minX) : 0) : 0\n const niceMinY = Number.isFinite(minY) ? (minY < 0 ? niceNum(minY) : 0) : 0\n return { niceMinX, niceMaxX, niceMinY, niceMaxY }\n}\n","import { Box, Skeleton } from '@mui/material'\nimport type { SxProps, 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 position: 'relative',\n flex: '1 1 auto',\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\n// `sx` callback that needs runtime args — extracted at module scope so the\n// `styles` object can satisfy `Record<string, SxProps<Theme>>` cleanly\n// (function `sx`-with-args isn't assignable to plain `SxProps<Theme>`).\nconst dotSx = (top: string, left: string, size: number): SxProps<Theme> => ({\n position: 'absolute',\n top,\n left,\n width: size,\n height: size,\n borderRadius: '50%',\n})\n\nexport interface ScatterplotSkeletonProps {\n /** Number of dots to render. */\n count?: number\n}\n\n/**\n * Loading state for the Scatterplot widget. Mirrors a scatter chart's\n * silhouette — a deterministic spread of small circular dots in the plot\n * area plus a legend stub — so the skeleton reads as \"a scatter chart\"\n * rather than a generic list. Matches bar/histogram/pie skeleton structure\n * (grid stub + legend stub in a flex column).\n */\nexport function ScatterplotSkeleton({ count = 24 }: ScatterplotSkeletonProps) {\n // Deterministic pseudo-scatter positions so the skeleton doesn't flicker.\n const dots = Array.from({ length: count }, (_, i) => {\n const top = 10 + ((i * 37) % 80)\n const left = 5 + ((i * 53) % 90)\n const size = 8 + ((i * 7) % 6)\n return { top: `${top}%`, left: `${left}%`, size }\n })\n return (\n <Box sx={styles.container}>\n <Box sx={styles.grid}>\n {dots.map((d, i) => (\n <Skeleton\n key={`dot-${i}`}\n variant='circular'\n sx={dotSx(d.top, d.left, d.size)}\n />\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 buildPngDownloadItem,\n downloadToCSV,\n type DownloadItem,\n} from '../actions/download'\nimport type { ScatterplotWidgetData } from './types'\n\n/**\n * Download menu items for the Scatterplot widget. Always includes a CSV\n * item with `series, x, y` columns (one row per point). When\n * `getCaptureEl` is supplied, prepends a PNG item that rasterises the\n * captured element via `html2canvas`.\n */\nexport function createScatterplotDownloadConfig(args: {\n filename: string\n getData: () => ScatterplotWidgetData\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 id: 'csv',\n label: 'Download as CSV',\n resolve: () => {\n const data = args.getData()\n const rows: unknown[][] = [['series', 'x', 'y']]\n for (const [i, series] of data.entries()) {\n const seriesName = args.seriesNames?.[i] ?? `series_${i + 1}`\n for (const [x, y] of series) {\n rows.push([seriesName, x, y])\n }\n }\n const handle = downloadToCSV(rows)\n return Promise.resolve({\n url: handle.url,\n filename: `${args.filename}.csv`,\n revoke: handle.revoke,\n })\n },\n })\n return items\n}\n","/**\n * Scatterplot-specific `RelativeData` transform. Scatter data is\n * `[number, number][]` — each series is a list of `[x, y]` tuples.\n * Relative is a values-axis concept, so this rewrites `y` to its\n * share of the series's total `y` (0–100) and leaves `x` raw — x is\n * coordinate space, not part of the cohort total.\n *\n * Pass to `<Widget.RelativeData transform={toRelativeScatterplotData} />`.\n *\n * The denominator is the sum of |y| across the series so mixed-sign\n * y values produce sane signed shares-of-magnitude. A series whose\n * total y-magnitude is zero (all-zero or empty input) is returned\n * unchanged so a stalled or empty data set doesn't show misleading 0%\n * values. Inputs whose shape isn't `[number, number][]` fall through\n * untouched.\n */\nexport const toRelativeScatterplotData = (input: unknown): unknown => {\n if (!Array.isArray(input)) return input\n return input.map((series: unknown): unknown => {\n if (!isXyTupleArray(series)) return series\n const total = series.reduce((acc, [, y]) => acc + Math.abs(y), 0)\n if (total <= 0) return series\n return series.map(([x, y]) => [x, (y / total) * 100] as [number, number])\n })\n}\n\nfunction isXyTupleArray(v: unknown): v is [number, number][] {\n if (!Array.isArray(v)) return false\n return v.every(\n (item) =>\n Array.isArray(item) &&\n item.length === 2 &&\n typeof item[0] === 'number' &&\n Number.isFinite(item[0]) &&\n typeof item[1] === 'number' &&\n Number.isFinite(item[1]),\n )\n}\n"],"names":["scatterplotOptions","theme","xFormatter","yFormatter","grid","left","parseInt","spacing","top","right","buildGridConfig","containLabel","tooltip","trigger","backgroundColor","palette","grey","borderWidth","padding","textStyle","color","common","white","fontSize","fontFamily","typography","caption","position","createTooltipPositioner","formatter","buildScatterTooltipFormatter","legend","buildLegendConfig","hasLegend","labelFormatter","undefined","axisPointer","lineStyle","secondary","main","Object","values","qualitative","bold","xAxis","type","axisLine","show","axisTick","axisLabel","overlineDelicate","black","margin","hideOverlap","showMinLabel","showMaxLabel","splitLine","divider","yAxis","createScatterplotOptionFactory","options","optionsOverride","series","symbolSize","selection","selectionSet","length","Set","option","data","ctx","structural","mergeOptions","seriesArr","Array","isArray","dataset","baseLegend","baseGrid","baseTooltip","baseXAxis","baseYAxis","reactiveFormatter","niceMinX","niceMaxX","niceMinY","niceMaxY","computeScatterBounds","makeDimColor","seriesIdx","params","base","key","dataIndex","has","echarts","modifyAlpha","dataZoomLayout","layoutDataZoomForScatter","dataZoom","hasXSlider","hasYSlider","fallbackBottom","bottom","baseBottom","gridBottom","ZOOM_LAYOUT","sliderHeight","sliderGap","fallbackRight","gridRight","map","s","source","_","i","overrideColor","resolveThemeColor","datasetIndex","name","encode","x","y","emphasis","focus","itemStyle","entries","min","max","buildReactiveScatterTooltipFormatter","entry","dz","yAxisIndex","sliderBottomWithLegend","structuralFormatter","reactiveYFormatter","createTooltipFormatter","item","value","formattedX","String","formattedY","marker","seriesName","minX","Infinity","maxX","minY","maxY","point","Number","isFinite","niceNum","styles","container","display","alignItems","justifyContent","flexDirection","gap","height","flex","width","legendItem","dotSx","size","borderRadius","ScatterplotSkeleton","t0","$","_c","count","t1","T0","T1","t2","t3","t4","dots","from","_temp","Box","_temp2","t5","jsx","t6","Symbol","for","_temp3","t7","i_1","jsxs","Skeleton","d","i_0","createScatterplotDownloadConfig","args","items","getCaptureEl","push","buildPngDownloadItem","filename","pixelRatio","pngPixelRatio","pngBackgroundColor","id","label","resolve","getData","rows","seriesNames","handle","downloadToCSV","Promise","url","revoke","toRelativeScatterplotData","input","isXyTupleArray","total","reduce","acc","Math","abs","v","every"],"mappings":"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"}
1
+ {"version":3,"file":"scatterplot.js","sources":["../../src/widgets-v2/scatterplot/options.ts","../../src/widgets-v2/scatterplot/skeleton.tsx","../../src/widgets-v2/scatterplot/download.ts","../../src/widgets-v2/scatterplot/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 type {\n ScatterplotEChartsOption,\n ScatterplotOptionFactoryInput,\n ScatterplotOptionsInput,\n ScatterplotWidgetData,\n} from './types'\n\n/**\n * Builds the **structural** ECharts option for a scatterplot widget — both\n * axes `type: 'value'` (not category, unlike Bar/Histogram), grid, tooltip\n * triggered per-item rather than per-axis. Intentionally data-agnostic: no\n * series, no dataset, no `legend.show` (those depend on data and are added\n * by {@link createScatterplotOptionFactory}).\n *\n * Styling parity with v1: dark themed tooltip via `createTooltipFormatter`\n * + `createTooltipPositioner`, `buildGridConfig`-based grid, polished\n * axisLine/Tick/splitLine, `overlineDelicate` axis labels, structural\n * legend wired via `buildLegendConfig` (toggled by the merger), and the\n * CARTO `qualitative.bold + secondary` palette — same pattern bar /\n * histogram / pie already use. {@link createScatterplotOptionFactory}\n * wraps this builder in its structural-phase branch.\n */\nexport function scatterplotOptions({\n theme,\n xFormatter,\n yFormatter,\n}: ScatterplotOptionsInput): ScatterplotEChartsOption {\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 `bottom` when there are >1 series.\n ...buildGridConfig(false, theme),\n containLabel: true,\n },\n tooltip: {\n // Per-point trigger — different from Bar's 'axis' trigger because\n // points don't share an x-coordinate.\n trigger: 'item',\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 position: createTooltipPositioner(theme),\n formatter: buildScatterTooltipFormatter(xFormatter, yFormatter),\n },\n // Legend styling baked here; `show` is toggled by the merger based on\n // series count.\n legend: {\n ...buildLegendConfig({ hasLegend: false, labelFormatter: undefined }),\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: 'value',\n axisLine: { show: false },\n axisTick: { show: false },\n axisLabel: {\n fontSize: theme.typography.overlineDelicate?.fontSize,\n fontFamily: theme.typography.overlineDelicate?.fontFamily,\n color: theme.palette.black?.[60],\n margin: parseInt(theme.spacing(1)),\n hideOverlap: true,\n showMinLabel: true,\n showMaxLabel: true,\n ...(xFormatter && { formatter: xFormatter }),\n },\n splitLine: {\n show: true,\n lineStyle: { color: theme.palette.black?.[4] ?? theme.palette.divider },\n },\n },\n yAxis: {\n type: 'value',\n axisLine: { show: false },\n axisTick: { show: false },\n axisLabel: {\n fontSize: theme.typography.overlineDelicate?.fontSize,\n fontFamily: theme.typography.overlineDelicate?.fontFamily,\n color: theme.palette.black?.[60],\n margin: parseInt(theme.spacing(1)),\n hideOverlap: true,\n showMinLabel: true,\n showMaxLabel: true,\n ...(yFormatter && { formatter: yFormatter }),\n },\n splitLine: {\n show: true,\n lineStyle: { color: theme.palette.black?.[4] ?? theme.palette.divider },\n },\n },\n } as ScatterplotEChartsOption\n}\n\n/**\n * Returns the scatterplot widget's {@link OptionFactory} — one closure\n * that owns BOTH phases of option construction:\n *\n * - **Structural phase** (`option == null`) — builds the theme-aware\n * structural option via {@link scatterplotOptions}, 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 * (`ScatterplotWidgetData`) into the option via the dataset API. Each\n * series's `[x, y]` tuples land in `dataset[i].source` as 2-column\n * rows; the series uses positional encoding (`encode: { x: 0, y: 1 }`)\n * and `type: 'scatter'`. niceMin/niceMax are computed over both axes\n * so the chart frames data on rounded extents and numeric jitters\n * don't shift gridlines per render. Reactive `ctx.formatter` (driven\n * by RelativeData) re-derives the y-axis label and tooltip at fusion\n * time; `xFormatter` stays baked at structural-build time (relative\n * is a values-axis concept; x is coordinate-space).\n *\n * When `ZoomToggle` installs a `dataZoom` slider, grid bottom is\n * extended and the slider is positioned above the legend row (if any) —\n * same layout dance bar / histogram / timeseries do.\n */\nexport function createScatterplotOptionFactory(\n options: ScatterplotOptionFactoryInput,\n): OptionFactory {\n const { theme, xFormatter, yFormatter, optionsOverride } = options\n const series = options.series\n const symbolSize = options.symbolSize ?? 8\n const selection = options.selection\n const selectionSet =\n selection && selection.length > 0 ? new Set<string>(selection) : null\n return (option, data, ctx) => {\n if (option == null) {\n const structural = scatterplotOptions({ theme, xFormatter, yFormatter })\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 = Array.isArray(data) ? (data as ScatterplotWidgetData) : []\n if (seriesArr.length === 0) {\n return { ...option, dataset: [], series: [] }\n }\n const hasLegend = seriesArr.length > 1\n const baseLegend =\n typeof option.legend === 'object' && !Array.isArray(option.legend)\n ? option.legend\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 baseXAxis =\n typeof option.xAxis === 'object' && !Array.isArray(option.xAxis)\n ? option.xAxis\n : {}\n const baseYAxis =\n typeof option.yAxis === 'object' && !Array.isArray(option.yAxis)\n ? option.yAxis\n : {}\n\n const reactiveFormatter = ctx?.formatter\n\n const { niceMinX, niceMaxX, niceMinY, niceMaxY } =\n computeScatterBounds(seriesArr)\n\n // Dim non-selected points via `series.itemStyle.color`. The selection\n // key is `${seriesIndex}:${dataIndex}`; we read those off the params\n // ECharts hands to the callback per-data.\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 items would stay dimmed forever after an external clear.\n // Keeping the key always-present means a plain setOption merge swaps\n // the callback in place, no `replaceMerge` and no entry-animation\n // flash on selection on/off.\n const makeDimColor =\n (seriesIdx: number) => (params: CallbackDataParams) => {\n const base = params.color as string\n if (!selectionSet) return base\n const key = `${seriesIdx}:${params.dataIndex}`\n return selectionSet.has(key)\n ? base\n : echarts.color.modifyAlpha(base, 0.15)\n }\n\n // Zoom slider layout: when ZoomToggle has installed `dataZoom`,\n // reserve grid space and lift any x-slider above the legend (if\n // present). Scatter supports 2D zoom via `axes: ['x', 'y']` — in\n // that case there's also a vertical y-slider on the right edge, so\n // we reserve `grid.right` separately. Inside-only dataZoom entries\n // (no `type: 'slider'`) take no grid space.\n const dataZoomLayout = layoutDataZoomForScatter(option.dataZoom, hasLegend)\n const hasXSlider = dataZoomLayout?.hasXSlider ?? false\n const hasYSlider = dataZoomLayout?.hasYSlider ?? false\n const fallbackBottom =\n typeof baseGrid.bottom === 'number' ? baseGrid.bottom : 24\n const baseBottom = hasLegend ? 56 : fallbackBottom\n const gridBottom = hasXSlider\n ? baseBottom + ZOOM_LAYOUT.sliderHeight + ZOOM_LAYOUT.sliderGap\n : baseBottom\n const fallbackRight =\n typeof baseGrid.right === 'number' ? baseGrid.right : 8\n const gridRight = hasYSlider\n ? fallbackRight + ZOOM_LAYOUT.sliderHeight + ZOOM_LAYOUT.sliderGap\n : fallbackRight\n\n return {\n ...option,\n // ECharts dataset.source wants a mutable [number, number][] shape; we\n // hold readonly tuples internally, so cast at the boundary.\n dataset: seriesArr.map((s) => ({ source: s as unknown as number[][] })),\n series: seriesArr.map((_, i) => {\n const overrideColor = resolveThemeColor(theme, series?.[i]?.color)\n return {\n type: 'scatter' as const,\n datasetIndex: i,\n name: series?.[i]?.name ?? `Series ${i + 1}`,\n encode: { x: 0, y: 1 },\n symbolSize,\n emphasis: { focus: 'series' },\n itemStyle: { color: makeDimColor(i) },\n ...(overrideColor ? { color: overrideColor } : {}),\n }\n }),\n legend: { ...baseLegend, show: hasLegend },\n grid: { ...baseGrid, bottom: gridBottom, right: gridRight },\n ...(dataZoomLayout ? { dataZoom: dataZoomLayout.entries } : {}),\n xAxis: {\n ...baseXAxis,\n min: niceMinX,\n max: niceMaxX,\n } as EChartsOption['xAxis'],\n yAxis: {\n ...baseYAxis,\n min: niceMinY,\n max: niceMaxY,\n axisLabel: {\n ...((baseYAxis as { axisLabel?: object }).axisLabel ?? {}),\n // Re-derive the y-axis formatter at fusion time so RelativeData's\n // percent formatter (written to `state.formatter`) flows through\n // without rebuilding the structural option. Falls back to the\n // structural `yFormatter` already baked in `baseYAxis.axisLabel`\n // (which `String(value)` if neither is set).\n ...(reactiveFormatter ? { formatter: reactiveFormatter } : {}),\n },\n } as EChartsOption['yAxis'],\n tooltip: {\n ...baseTooltip,\n // Rebuild the tooltip formatter so the live y-axis formatter is\n // applied to the y-coordinate in the (x, y) label. xFormatter is\n // structural — relative is a values-axis concept, so xFormatter\n // doesn't change under RelativeData.\n formatter: buildReactiveScatterTooltipFormatter(\n (baseTooltip as { formatter?: unknown }).formatter,\n reactiveFormatter,\n xFormatter,\n ),\n },\n } as EChartsOption\n }\n}\n\n/**\n * Lay out the `dataZoom` array for the scatter chart:\n * - Detect whether any horizontal (x-axis) slider is present — if so\n * lift it above the legend row when a legend is shown.\n * - Detect whether any vertical (y-axis) slider is present — the\n * caller reserves `grid.right` so the slider doesn't overlap the\n * plot area.\n *\n * Returns `null` when there's no `dataZoom` so callers can skip the\n * layout adjustment entirely. An entry is considered an \"x-slider\" if\n * it has `xAxisIndex` set (or no axis index — defaults to x in ECharts).\n * A \"y-slider\" has `yAxisIndex` set.\n */\nfunction layoutDataZoomForScatter(\n dataZoom: unknown,\n hasLegend: boolean,\n): { entries: unknown[]; hasXSlider: boolean; hasYSlider: boolean } | null {\n if (!Array.isArray(dataZoom) || dataZoom.length === 0) return null\n let hasXSlider = false\n let hasYSlider = false\n const entries = dataZoom.map((entry: unknown) => {\n if (entry == null || typeof entry !== 'object') return entry\n const dz = entry as {\n type?: string\n xAxisIndex?: unknown\n yAxisIndex?: unknown\n bottom?: number\n }\n if (dz.type !== 'slider') return dz\n const targetsY = dz.yAxisIndex !== undefined\n if (targetsY) {\n hasYSlider = true\n return dz\n }\n // Either explicit x or defaulted (ECharts defaults sliders to xAxis\n // when no axis index is provided).\n hasXSlider = true\n if (hasLegend) {\n return { ...dz, bottom: ZOOM_LAYOUT.sliderBottomWithLegend }\n }\n return dz\n })\n return { entries, hasXSlider, hasYSlider }\n}\n\n/**\n * If a reactive (store-driven) y formatter is provided, re-build the\n * scatter tooltip formatter using it. Otherwise, return the structural\n * formatter unchanged so the original `xFormatter` / `yFormatter`\n * baked into `scatterplotOptions` still applies. The structural\n * formatter has stable identity per `scatterplotOptions` call, so this\n * path doesn't churn ECharts on every render.\n */\nfunction buildReactiveScatterTooltipFormatter(\n structuralFormatter: unknown,\n reactiveYFormatter: ((value: number) => string) | undefined,\n xFormatter: ((value: number) => string) | undefined,\n) {\n if (!reactiveYFormatter) return structuralFormatter\n return createTooltipFormatter((item) => {\n const value = item.value as readonly [number, number] | undefined\n const x = value?.[0]\n const y = value?.[1]\n const formattedX =\n typeof x === 'number' ? (xFormatter ? xFormatter(x) : String(x)) : ''\n const formattedY =\n typeof y === 'number' ? reactiveYFormatter(y) : String(y ?? '')\n const marker = typeof item.marker === 'string' ? item.marker : ''\n const seriesName = item.seriesName ? `${item.seriesName}: ` : ''\n return {\n name: `(${formattedX}, ${formattedY})`,\n seriesName,\n marker,\n value: '',\n }\n })\n}\n\nfunction buildScatterTooltipFormatter(\n xFormatter: ((value: number) => string) | undefined,\n yFormatter: ((value: number) => string) | undefined,\n) {\n return createTooltipFormatter((item) => {\n const value = item.value as readonly [number, number] | undefined\n const x = value?.[0]\n const y = value?.[1]\n const formattedX =\n typeof x === 'number' ? (xFormatter ? xFormatter(x) : String(x)) : ''\n const formattedY =\n typeof y === 'number' ? (yFormatter ? yFormatter(y) : String(y)) : ''\n const marker = typeof item.marker === 'string' ? item.marker : ''\n const seriesName = item.seriesName ? `${item.seriesName}: ` : ''\n return {\n name: `(${formattedX}, ${formattedY})`,\n seriesName,\n marker,\n value: '',\n }\n })\n}\n\nfunction computeScatterBounds(seriesArr: ScatterplotWidgetData): {\n niceMinX: number\n niceMaxX: number\n niceMinY: number\n niceMaxY: number\n} {\n let minX = Infinity\n let maxX = -Infinity\n let minY = Infinity\n let maxY = -Infinity\n for (const series of seriesArr) {\n for (const point of series) {\n const x = point?.[0]\n const y = point?.[1]\n if (typeof x === 'number' && Number.isFinite(x)) {\n if (x < minX) minX = x\n if (x > maxX) maxX = x\n }\n if (typeof y === 'number' && Number.isFinite(y)) {\n if (y < minY) minY = y\n if (y > maxY) maxY = y\n }\n }\n }\n // Mirror bar's `computeNiceBounds`: clamp min to 0 when data is\n // non-negative (gridline reads cleanly from zero), apply `niceNum` to\n // negative mins, and floor max=0 to 1 so the chart always has range.\n // Scatter can have free coordinates so we apply this per-axis.\n const niceMaxX = Number.isFinite(maxX) ? (maxX <= 0 ? 1 : niceNum(maxX)) : 1\n const niceMaxY = Number.isFinite(maxY) ? (maxY <= 0 ? 1 : niceNum(maxY)) : 1\n const niceMinX = Number.isFinite(minX) ? (minX < 0 ? niceNum(minX) : 0) : 0\n const niceMinY = Number.isFinite(minY) ? (minY < 0 ? niceNum(minY) : 0) : 0\n return { niceMinX, niceMaxX, niceMinY, niceMaxY }\n}\n","import { Box, Skeleton } from '@mui/material'\nimport type { SxProps, 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 position: 'relative',\n flex: '1 1 auto',\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\n// `sx` callback that needs runtime args — extracted at module scope so the\n// `styles` object can satisfy `Record<string, SxProps<Theme>>` cleanly\n// (function `sx`-with-args isn't assignable to plain `SxProps<Theme>`).\nconst dotSx = (top: string, left: string, size: number): SxProps<Theme> => ({\n position: 'absolute',\n top,\n left,\n width: size,\n height: size,\n borderRadius: '50%',\n})\n\nexport interface ScatterplotSkeletonProps {\n /** Number of dots to render. */\n count?: number\n}\n\n/**\n * Loading state for the Scatterplot widget. Mirrors a scatter chart's\n * silhouette — a deterministic spread of small circular dots in the plot\n * area plus a legend stub — so the skeleton reads as \"a scatter chart\"\n * rather than a generic list. Matches bar/histogram/pie skeleton structure\n * (grid stub + legend stub in a flex column).\n */\nexport function ScatterplotSkeleton({ count = 24 }: ScatterplotSkeletonProps) {\n // Deterministic pseudo-scatter positions so the skeleton doesn't flicker.\n const dots = Array.from({ length: count }, (_, i) => {\n const top = 10 + ((i * 37) % 80)\n const left = 5 + ((i * 53) % 90)\n const size = 8 + ((i * 7) % 6)\n return { top: `${top}%`, left: `${left}%`, size }\n })\n return (\n <Box sx={styles.container}>\n <Box sx={styles.grid}>\n {dots.map((d, i) => (\n <Skeleton\n key={`dot-${i}`}\n variant='circular'\n sx={dotSx(d.top, d.left, d.size)}\n />\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 { ScatterplotWidgetData } from './types'\n\n/**\n * Download menu items for the Scatterplot widget. Always includes a CSV\n * item with `series, x, y` columns (one row per point). When\n * `getCaptureEl` is supplied, prepends a PNG item that rasterises the\n * captured element via `html2canvas`.\n */\nexport function createScatterplotDownloadConfig(args: {\n filename: string\n getData: () => ScatterplotWidgetData\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 rows: unknown[][] = [['series', 'x', 'y']]\n for (const [i, series] of data.entries()) {\n const seriesName = args.seriesNames?.[i] ?? `series_${i + 1}`\n for (const [x, y] of series) {\n rows.push([seriesName, x, y])\n }\n }\n return rows\n },\n }),\n )\n return items\n}\n","/**\n * Scatterplot-specific `RelativeData` transform. Scatter data is\n * `[number, number][]` — each series is a list of `[x, y]` tuples.\n * Relative is a values-axis concept, so this rewrites `y` to its\n * share of the series's total `y` (0–100) and leaves `x` raw — x is\n * coordinate space, not part of the cohort total.\n *\n * Pass to `<Widget.RelativeData transform={toRelativeScatterplotData} />`.\n *\n * The denominator is the sum of |y| across the series so mixed-sign\n * y values produce sane signed shares-of-magnitude. A series whose\n * total y-magnitude is zero (all-zero or empty input) is returned\n * unchanged so a stalled or empty data set doesn't show misleading 0%\n * values. Inputs whose shape isn't `[number, number][]` fall through\n * untouched.\n */\nexport const toRelativeScatterplotData = (input: unknown): unknown => {\n if (!Array.isArray(input)) return input\n return input.map((series: unknown): unknown => {\n if (!isXyTupleArray(series)) return series\n const total = series.reduce((acc, [, y]) => acc + Math.abs(y), 0)\n if (total <= 0) return series\n return series.map(([x, y]) => [x, (y / total) * 100] as [number, number])\n })\n}\n\nfunction isXyTupleArray(v: unknown): v is [number, number][] {\n if (!Array.isArray(v)) return false\n return v.every(\n (item) =>\n Array.isArray(item) &&\n item.length === 2 &&\n typeof item[0] === 'number' &&\n Number.isFinite(item[0]) &&\n typeof item[1] === 'number' &&\n Number.isFinite(item[1]),\n )\n}\n"],"names":["scatterplotOptions","theme","xFormatter","yFormatter","grid","left","parseInt","spacing","top","right","buildGridConfig","containLabel","tooltip","trigger","backgroundColor","palette","grey","borderWidth","padding","textStyle","color","common","white","fontSize","fontFamily","typography","caption","position","createTooltipPositioner","formatter","buildScatterTooltipFormatter","legend","buildLegendConfig","hasLegend","labelFormatter","undefined","axisPointer","lineStyle","secondary","main","Object","values","qualitative","bold","xAxis","type","axisLine","show","axisTick","axisLabel","overlineDelicate","black","margin","hideOverlap","showMinLabel","showMaxLabel","splitLine","divider","yAxis","createScatterplotOptionFactory","options","optionsOverride","series","symbolSize","selection","selectionSet","length","Set","option","data","ctx","structural","mergeOptions","seriesArr","Array","isArray","dataset","baseLegend","baseGrid","baseTooltip","baseXAxis","baseYAxis","reactiveFormatter","niceMinX","niceMaxX","niceMinY","niceMaxY","computeScatterBounds","makeDimColor","seriesIdx","params","base","key","dataIndex","has","echarts","modifyAlpha","dataZoomLayout","layoutDataZoomForScatter","dataZoom","hasXSlider","hasYSlider","fallbackBottom","bottom","baseBottom","gridBottom","ZOOM_LAYOUT","sliderHeight","sliderGap","fallbackRight","gridRight","map","s","source","_","i","overrideColor","resolveThemeColor","datasetIndex","name","encode","x","y","emphasis","focus","itemStyle","entries","min","max","buildReactiveScatterTooltipFormatter","entry","dz","yAxisIndex","sliderBottomWithLegend","structuralFormatter","reactiveYFormatter","createTooltipFormatter","item","value","formattedX","String","formattedY","marker","seriesName","minX","Infinity","maxX","minY","maxY","point","Number","isFinite","niceNum","styles","container","display","alignItems","justifyContent","flexDirection","gap","height","flex","width","legendItem","dotSx","size","borderRadius","ScatterplotSkeleton","t0","$","_c","count","t1","T0","T1","t2","t3","t4","dots","from","_temp","Box","_temp2","t5","jsx","t6","Symbol","for","_temp3","t7","i_1","jsxs","Skeleton","d","i_0","createScatterplotDownloadConfig","args","items","getCaptureEl","push","buildPngDownloadItem","filename","pixelRatio","pngPixelRatio","pngBackgroundColor","buildCsvDownloadItem","getRows","getData","rows","seriesNames","toRelativeScatterplotData","input","isXyTupleArray","total","reduce","acc","Math","abs","v","every"],"mappings":"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"}
@@ -1,15 +1,16 @@
1
- import { S as P, a as $, b as B } from "../spread-DYNpzgh_.js";
2
- import { jsx as a } from "react/jsx-runtime";
3
- import { c as s } from "react/compiler-runtime";
4
- import { Box as p, Skeleton as m } from "@mui/material";
1
+ import { S as R, a as B, b as P } from "../spread-DYNpzgh_.js";
2
+ import { jsx as i } from "react/jsx-runtime";
3
+ import { c as m } from "react/compiler-runtime";
4
+ import { Box as p, Skeleton as l } from "@mui/material";
5
5
  import "react";
6
6
  import "@mui/icons-material";
7
7
  import "../lasso-tool-CDFj4zKY.js";
8
8
  import "../cjs-D4KH3azB.js";
9
9
  import "@carto/ps-utils";
10
- import { a as c } from "../exports-Cx-f6m6U.js";
11
- import { b as f } from "../png-item-BE9uEqlD.js";
12
- const l = {
10
+ import "html2canvas";
11
+ import { b as s } from "../png-item-9dNbB37T.js";
12
+ import { b as f } from "../csv-item-hH_Gt7ur.js";
13
+ const a = {
13
14
  root: {
14
15
  display: "flex",
15
16
  flexDirection: "column",
@@ -26,46 +27,40 @@ const l = {
26
27
  height: 32
27
28
  }
28
29
  };
29
- function y(o) {
30
- const e = s(2), {
31
- count: i
32
- } = o, r = i === void 0 ? 1 : i;
33
- let t;
34
- return e[0] !== r ? (t = /* @__PURE__ */ a(p, { sx: l.root, children: Array.from({
30
+ function D(t) {
31
+ const e = m(2), {
32
+ count: n
33
+ } = t, r = n === void 0 ? 1 : n;
34
+ let o;
35
+ return e[0] !== r ? (o = /* @__PURE__ */ i(p, { sx: a.root, children: Array.from({
35
36
  length: r
36
- }).map(u) }), e[0] = r, e[1] = t) : t = e[1], t;
37
+ }).map(c) }), e[0] = r, e[1] = o) : o = e[1], o;
37
38
  }
38
- function u(o, e) {
39
- return /* @__PURE__ */ a(p, { sx: l.row, children: /* @__PURE__ */ a(m, { variant: "rectangular", sx: l.block }) }, `row-${e}`);
39
+ function c(t, e) {
40
+ return /* @__PURE__ */ i(p, { sx: a.row, children: /* @__PURE__ */ i(l, { variant: "rectangular", sx: a.block }) }, `row-${e}`);
40
41
  }
41
- function D(o) {
42
+ function I(t) {
42
43
  const e = [];
43
- return o.getCaptureEl && e.push(f({
44
- filename: o.filename,
45
- getCaptureEl: o.getCaptureEl,
46
- pixelRatio: o.pngPixelRatio,
47
- backgroundColor: o.pngBackgroundColor
48
- })), e.push({
49
- id: "csv",
50
- label: "Download as CSV",
51
- resolve: () => {
52
- const i = o.getData(), r = [["series", "prefix", "min", "max", "suffix", "note"]];
53
- for (const n of i)
54
- r.push([n.series?.name ?? "", n.prefix ?? "", n.min, n.max, n.suffix ?? "", n.note ?? ""]);
55
- const t = c(r);
56
- return Promise.resolve({
57
- url: t.url,
58
- filename: `${o.filename}.csv`,
59
- revoke: t.revoke
60
- });
44
+ return t.getCaptureEl && e.push(s({
45
+ filename: t.filename,
46
+ getCaptureEl: t.getCaptureEl,
47
+ pixelRatio: t.pngPixelRatio,
48
+ backgroundColor: t.pngBackgroundColor
49
+ })), e.push(f({
50
+ filename: t.filename,
51
+ getRows: () => {
52
+ const n = t.getData(), r = [["series", "prefix", "min", "max", "suffix", "note"]];
53
+ for (const o of n)
54
+ r.push([o.series?.name ?? "", o.prefix ?? "", o.min, o.max, o.suffix ?? "", o.note ?? ""]);
55
+ return r;
61
56
  }
62
- }), e;
57
+ })), e;
63
58
  }
64
59
  export {
65
- P as Separator,
66
- $ as Spread,
67
- y as SpreadSkeleton,
68
- B as SpreadUI,
69
- D as createSpreadDownloadConfig
60
+ R as Separator,
61
+ B as Spread,
62
+ D as SpreadSkeleton,
63
+ P as SpreadUI,
64
+ I as createSpreadDownloadConfig
70
65
  };
71
66
  //# sourceMappingURL=spread.js.map