@embeddable.com/remarkable-ui 0.1.14 → 0.1.16

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 (70) hide show
  1. package/dist/BarChartDefaultHorizontalPro.js +3 -3
  2. package/dist/BarChartDefaultPro.js +3 -3
  3. package/dist/BarChartGroupedHorizontalPro.js +3 -3
  4. package/dist/BarChartGroupedPro.js +3 -3
  5. package/dist/BarChartStackedHorizontalPro.js +3 -3
  6. package/dist/BarChartStackedPro.js +3 -3
  7. package/dist/{BaseButton-BbhHQD9t.js → BaseButton-BJ_6r0uk.js} +2 -2
  8. package/dist/{BaseButton-BbhHQD9t.js.map → BaseButton-BJ_6r0uk.js.map} +1 -1
  9. package/dist/{ChartCard-11lQWjXq.js → ChartCard-Cb0QE9kP.js} +3 -3
  10. package/dist/{ChartCard-11lQWjXq.js.map → ChartCard-Cb0QE9kP.js.map} +1 -1
  11. package/dist/ComparisonPeriod.type.emb-BHz2X91i.js +14 -0
  12. package/dist/ComparisonPeriod.type.emb-BHz2X91i.js.map +1 -0
  13. package/dist/ComparisonPeriodSelectFieldPro.js +4 -4
  14. package/dist/DateRangeSelectFieldPro.js +2 -2
  15. package/dist/DonutChartPro.js +2 -2
  16. package/dist/DonutLabelChartPro.js +2 -2
  17. package/dist/{EditorCard-BriyqUva.js → EditorCard-DWz8Bm-e.js} +2 -2
  18. package/dist/{EditorCard-BriyqUva.js.map → EditorCard-DWz8Bm-e.js.map} +1 -1
  19. package/dist/KpiChart-B2OqbXRg.js +79 -0
  20. package/dist/KpiChart-B2OqbXRg.js.map +1 -0
  21. package/dist/KpiChartNumberComparisonPro.js +58 -50
  22. package/dist/KpiChartNumberComparisonPro.js.map +1 -1
  23. package/dist/KpiChartNumberPro.js +4 -4
  24. package/dist/MultiSelectFieldPro.js +2 -2
  25. package/dist/PieChartPro.js +2 -2
  26. package/dist/{SingleSelectField-D1E9OJxC.js → SingleSelectField-BJnoOYrw.js} +3 -3
  27. package/dist/{SingleSelectField-D1E9OJxC.js.map → SingleSelectField-BJnoOYrw.js.map} +1 -1
  28. package/dist/SingleSelectFieldPro.js +2 -2
  29. package/dist/{charts.fillGaps.hooks-t2xhHbW-.js → charts.fillGaps.hooks-C5Gy3QoW.js} +148 -132
  30. package/dist/charts.fillGaps.hooks-C5Gy3QoW.js.map +1 -0
  31. package/dist/{component.constants-DIhZCTG3.js → component.constants-Bn9l4N1t.js} +3 -2
  32. package/dist/{component.constants-DIhZCTG3.js.map → component.constants-Bn9l4N1t.js.map} +1 -1
  33. package/dist/embeddable-components.json +8 -8
  34. package/dist/embeddable-theme-2b917.js +1 -1
  35. package/dist/embeddable-types-4ace4.js +4 -5
  36. package/dist/embeddable-types.js.map +1 -1
  37. package/dist/{formatter.utils-CuZlh4EL.js → formatter.utils-Ba_5cIcm.js} +2 -2
  38. package/dist/{formatter.utils-CuZlh4EL.js.map → formatter.utils-Ba_5cIcm.js.map} +1 -1
  39. package/dist/{index-C-zjH8iP.js → index-6ilf5W1J.js} +5 -5
  40. package/dist/{index-C-zjH8iP.js.map → index-6ilf5W1J.js.map} +1 -1
  41. package/dist/{index-9F910tDw.js → index-BOzeG3mG.js} +4 -4
  42. package/dist/{index-9F910tDw.js.map → index-BOzeG3mG.js.map} +1 -1
  43. package/dist/{index-B8y21zu2.js → index-Chlmh1dF.js} +4 -4
  44. package/dist/{index-B8y21zu2.js.map → index-Chlmh1dF.js.map} +1 -1
  45. package/dist/{index-Ddf7wtBP.js → index-CjS39lkd.js} +5 -5
  46. package/dist/{index-Ddf7wtBP.js.map → index-CjS39lkd.js.map} +1 -1
  47. package/dist/{index-YRbjfwIA.js → index-CobXKlOi.js} +4 -4
  48. package/dist/{index-YRbjfwIA.js.map → index-CobXKlOi.js.map} +1 -1
  49. package/dist/{index-DqKfDjMs.js → index-DYBt2TuY.js} +5 -5
  50. package/dist/{index-DqKfDjMs.js.map → index-DYBt2TuY.js.map} +1 -1
  51. package/dist/index.js +18 -18
  52. package/dist/{object.utils-DhhMwS2t.js → object.utils-9RGrU0vr.js} +4 -4
  53. package/dist/object.utils-9RGrU0vr.js.map +1 -0
  54. package/dist/{pies.utils-Cmzdr27l.js → pies.utils-BecIV2nV.js} +4 -4
  55. package/dist/{pies.utils-Cmzdr27l.js.map → pies.utils-BecIV2nV.js.map} +1 -1
  56. package/dist/remarkable-pro/components/charts/bars/bars.utils.d.ts.map +1 -1
  57. package/dist/remarkable-pro/components/charts/kpis/KpiChartNumberComparisonPro/index.d.ts +1 -0
  58. package/dist/remarkable-pro/components/charts/kpis/KpiChartNumberComparisonPro/index.d.ts.map +1 -1
  59. package/dist/remarkable-pro/components/component.constants.d.ts +1 -0
  60. package/dist/remarkable-pro/components/component.constants.d.ts.map +1 -1
  61. package/dist/remarkable-ui/charts/kpis/KpiChart.d.ts.map +1 -1
  62. package/dist/remarkable-ui/charts/kpis/KpiChart.types.d.ts +1 -0
  63. package/dist/remarkable-ui/charts/kpis/KpiChart.types.d.ts.map +1 -1
  64. package/package.json +1 -1
  65. package/dist/ComparisonPeriod.type.emb-D51Sg3wt.js +0 -15
  66. package/dist/ComparisonPeriod.type.emb-D51Sg3wt.js.map +0 -1
  67. package/dist/KpiChart-Cp9ZUyRz.js +0 -77
  68. package/dist/KpiChart-Cp9ZUyRz.js.map +0 -1
  69. package/dist/charts.fillGaps.hooks-t2xhHbW-.js.map +0 -1
  70. package/dist/object.utils-DhhMwS2t.js.map +0 -1
@@ -1,7 +1,7 @@
1
- import { B as f, C as O, D as Q, m as I, E as R, F as J, G as X, L as tt, H as et, I as at, J as rt, K as st, M as nt, j as N, N as ot, O as lt, P as it, Q as L, R as ct } from "./component.constants-DIhZCTG3.js";
1
+ import { B as f, C as O, D as Q, m as I, E as R, F as J, G as X, L as tt, H as et, I as at, J as rt, K as st, M as nt, j as N, N as ot, O as lt, P as it, Q as L, R as ct } from "./component.constants-Bn9l4N1t.js";
2
2
  import { useRef as dt, useMemo as ut } from "react";
3
- import { r as mt, g as W, a as ft, b as H } from "./object.utils-DhhMwS2t.js";
4
- import { g as Y } from "./formatter.utils-CuZlh4EL.js";
3
+ import { r as mt, g as W, a as ft, b as H } from "./object.utils-9RGrU0vr.js";
4
+ import { g as Y } from "./formatter.utils-Ba_5cIcm.js";
5
5
  import { d as D } from "./utc-B2gCnkBk.js";
6
6
  import { useTheme as ht } from "@embeddable.com/react";
7
7
  const j = {
@@ -73,20 +73,20 @@ const j = {
73
73
  return {
74
74
  ...t,
75
75
  datasets: (e = t.datasets) == null ? void 0 : e.map((a, n) => {
76
- const r = R[n % R.length], s = {
76
+ const s = R[n % R.length], r = {
77
77
  ...a,
78
- backgroundColor: r,
79
- borderColor: r
78
+ backgroundColor: s,
79
+ borderColor: s
80
80
  };
81
- return I(s, a);
81
+ return I(r, a);
82
82
  })
83
83
  };
84
84
  }, G = (t, e) => e && t.datasetIndex === t.chart.data.datasets.length - 1 ? "auto" : !1, z = (t, e) => {
85
- const { datasets: a } = e.chart.data, n = e.dataIndex, r = a.reduce((s, o) => {
86
- const i = o.data[n];
87
- return s + (i || 0);
85
+ const { datasets: a } = e.chart.data, n = e.dataIndex, s = a.reduce((r, o) => {
86
+ const l = o.data[n];
87
+ return r + (l || 0);
88
88
  }, 0);
89
- return r > 0 ? r : "";
89
+ return s > 0 ? s : "";
90
90
  }, pt = (t) => I(j, {
91
91
  indexAxis: "x",
92
92
  plugins: {
@@ -186,15 +186,15 @@ const j = {
186
186
  horizontal: e = !1,
187
187
  showLegend: a = !1,
188
188
  showTooltips: n = !0,
189
- showValueLabels: r = !1,
190
- showTotalLabels: s = !1
191
- } = t, i = (e ? Dt : pt)(t);
192
- return I(i, {
189
+ showValueLabels: s = !1,
190
+ showTotalLabels: r = !1
191
+ } = t, l = (e ? Dt : pt)(t);
192
+ return I(l, {
193
193
  layout: {
194
194
  padding: {
195
195
  // Hack: dataLabels can get cut off if they are at the edge of the chart
196
- top: !e && (r || s) ? 30 : 0,
197
- right: e && (r || s) ? 30 : 0
196
+ top: !e && (s || r) ? 30 : 0,
197
+ right: e && (s || r) ? 30 : 0
198
198
  }
199
199
  },
200
200
  elements: {
@@ -206,7 +206,7 @@ const j = {
206
206
  plugins: {
207
207
  legend: { display: a },
208
208
  datalabels: {
209
- display: (c) => r && c.dataset.data[c.dataIndex] !== 0 ? "auto" : !1
209
+ display: (c) => s && c.dataset.data[c.dataIndex] !== 0 ? "auto" : !1
210
210
  },
211
211
  tooltip: {
212
212
  enabled: n
@@ -215,23 +215,23 @@ const j = {
215
215
  });
216
216
  };
217
217
  J.register(X, tt, et, at, rt, st, nt);
218
- const Lt = ({ data: t, onSegmentClick: e, options: a = {}, ...n }) => {
219
- const r = dt(null), s = I(yt(n), a), o = (i) => {
220
- const c = it(i, r);
218
+ const Ut = ({ data: t, onSegmentClick: e, options: a = {}, ...n }) => {
219
+ const s = dt(null), r = I(yt(n), a), o = (l) => {
220
+ const c = it(l, s);
221
221
  e == null || e(c);
222
222
  };
223
223
  return /* @__PURE__ */ N.jsx("div", { className: ot.chartContainer, children: /* @__PURE__ */ N.jsx(
224
224
  lt,
225
225
  {
226
- ref: r,
226
+ ref: s,
227
227
  data: gt(t),
228
- options: s,
228
+ options: r,
229
229
  onClick: o
230
230
  }
231
231
  ) });
232
- }, Ut = (t, e) => {
233
- const a = Y(e), { data: n = [], dimension: r, groupDimension: s, measure: o } = t, i = [...new Set(n.map((d) => d[r.name]).filter(Boolean))].sort(), c = [...new Set(n.map((d) => d[s.name]))], u = W(e), h = c.map((d, x) => {
234
- const C = H(
232
+ }, _t = (t, e) => {
233
+ const a = Y(e), { data: n = [], dimension: s, groupDimension: r, measure: o } = t, l = [...new Set(n.map((d) => d[s.name]).filter(Boolean))].sort(), c = [...new Set(n.map((d) => d[r.name]))], u = W(e), h = c.map((d, x) => {
234
+ const v = H(
235
235
  `${u}.charts.backgroundColors`,
236
236
  d,
237
237
  e.charts.backgroundColors ?? R,
@@ -243,67 +243,83 @@ const Lt = ({ data: t, onSegmentClick: e, options: a = {}, ...n }) => {
243
243
  x
244
244
  );
245
245
  return {
246
- label: a.data(s, d),
247
- backgroundColor: C,
246
+ label: a.data(r, d),
247
+ backgroundColor: v,
248
248
  borderColor: A,
249
- data: i.map((k) => {
250
- const v = n.find(
251
- (b) => b[s.name] === d && b[r.name] === k
249
+ data: l.map((C) => {
250
+ const k = n.find(
251
+ (b) => b[r.name] === d && b[s.name] === C
252
252
  );
253
- return v ? Number(v[o.name]) : 0;
253
+ return k ? Number(k[o.name]) : 0;
254
254
  })
255
255
  };
256
256
  });
257
257
  return {
258
- labels: i.map((d) => a.data(r, d)),
258
+ labels: l.map((d) => a.data(s, d)),
259
259
  datasets: h
260
260
  };
261
- }, _t = (t, e = mt) => {
261
+ }, Ft = (t, e = mt) => {
262
262
  const a = Y(e);
263
263
  if (!t.data)
264
264
  return {
265
265
  labels: [],
266
266
  datasets: [{ data: [] }]
267
267
  };
268
- const n = W(e), r = ft(t.data, t.dimension, t.measures, t.maxItems);
268
+ const n = W(e), s = ft(t.data, t.dimension, t.measures, t.maxItems);
269
269
  return {
270
- labels: r.map((s) => {
271
- const o = s[t.dimension.name], i = a.data(t.dimension, o);
272
- return o === i ? ct.t(o) : i;
270
+ labels: s.map((r) => {
271
+ const o = r[t.dimension.name], l = a.data(t.dimension, o);
272
+ return o === l ? ct.t(o) : l;
273
273
  }),
274
- datasets: t.measures.map((s, o) => {
275
- const i = H(
274
+ datasets: t.measures.map((r, o) => {
275
+ const l = H(
276
276
  `${n}.charts.backgroundColors`,
277
- s.name,
277
+ r.name,
278
278
  e.charts.backgroundColors ?? L,
279
279
  o
280
280
  ), c = H(
281
281
  `${n}.charts.borderColors`,
282
- s.name,
282
+ r.name,
283
283
  e.charts.borderColors ?? L,
284
284
  o
285
285
  );
286
286
  return {
287
- label: a.dimensionOrMeasureTitle(s),
288
- data: r.map((u) => u[s.name]),
289
- backgroundColor: i,
287
+ label: a.dimensionOrMeasureTitle(r),
288
+ data: s.map((u) => u[r.name]),
289
+ backgroundColor: l,
290
290
  borderColor: c
291
291
  };
292
292
  })
293
293
  };
294
- }, Ft = (t, e) => {
295
- const { onBarClicked: a, measure: n, horizontal: r } = t, s = Y(e);
294
+ }, Tt = (t, e) => {
295
+ const { datasets: a } = t.chart.data, n = t.dataIndex, s = a.reduce((r, o) => {
296
+ const l = o.data[n];
297
+ return r + (l || 0);
298
+ }, 0);
299
+ return e(s);
300
+ }, $t = (t, e) => {
301
+ const { onBarClicked: a, measure: n, horizontal: s } = t, r = Y(e);
296
302
  return {
297
303
  plugins: {
298
304
  legend: { position: e.charts.legendPosition ?? "bottom" },
299
305
  datalabels: {
300
- formatter: (o) => s.data(t.measure, o)
306
+ labels: {
307
+ total: {
308
+ formatter: (o, l) => Tt(
309
+ l,
310
+ (c) => r.data(t.measure, c)
311
+ )
312
+ },
313
+ value: {
314
+ formatter: (o) => r.data(t.measure, o)
315
+ }
316
+ }
301
317
  },
302
318
  tooltip: {
303
319
  callbacks: {
304
320
  label(o) {
305
- const i = o.raw;
306
- return `${o.dataset.label || ""}: ${s.data(n, i)}`;
321
+ const l = o.raw;
322
+ return `${o.dataset.label || ""}: ${r.data(n, l)}`;
307
323
  }
308
324
  }
309
325
  }
@@ -311,21 +327,21 @@ const Lt = ({ data: t, onSegmentClick: e, options: a = {}, ...n }) => {
311
327
  scales: {
312
328
  x: {
313
329
  ticks: {
314
- ...r && {
315
- callback: (o) => s.data(n, o)
330
+ ...s && {
331
+ callback: (o) => r.data(n, o)
316
332
  }
317
333
  }
318
334
  },
319
335
  y: {
320
336
  ticks: {
321
- ...!r && {
322
- callback: (o) => s.data(n, o)
337
+ ...!s && {
338
+ callback: (o) => r.data(n, o)
323
339
  }
324
340
  }
325
341
  }
326
342
  },
327
- onClick: (o, i, c) => {
328
- const u = i[0], h = u ? c.data.labels[u.index] : null, d = u ? c.data.datasets[u.datasetIndex].label : null;
343
+ onClick: (o, l, c) => {
344
+ const u = l[0], h = u ? c.data.labels[u.index] : null, d = u ? c.data.datasets[u.datasetIndex].label : null;
329
345
  a({
330
346
  axisDimensionValue: h,
331
347
  groupingDimensionValue: d
@@ -347,20 +363,20 @@ const Lt = ({ data: t, onSegmentClick: e, options: a = {}, ...n }) => {
347
363
  quarter: "month",
348
364
  // Will be handled specially
349
365
  year: "year"
350
- }, Tt = (t) => `${t.getFullYear()}-${String(t.getMonth() + 1).padStart(2, "0")}-${String(t.getDate()).padStart(2, "0")}`, bt = (t) => `${t.getUTCFullYear()}-${String(t.getUTCMonth() + 1).padStart(2, "0")}-${String(t.getUTCDate()).padStart(2, "0")}`, St = (t) => t.toISOString().includes("Z"), _ = (t) => St(t) ? bt(t) : Tt(t), Ot = (t) => t.startOf("month").month(Math.floor(t.month() / 3) * 3).startOf("month"), F = (t, e) => {
366
+ }, bt = (t) => `${t.getFullYear()}-${String(t.getMonth() + 1).padStart(2, "0")}-${String(t.getDate()).padStart(2, "0")}`, St = (t) => `${t.getUTCFullYear()}-${String(t.getUTCMonth() + 1).padStart(2, "0")}-${String(t.getUTCDate()).padStart(2, "0")}`, Ot = (t) => t.toISOString().includes("Z"), _ = (t) => Ot(t) ? St(t) : bt(t), xt = (t) => t.startOf("month").month(Math.floor(t.month() / 3) * 3).startOf("month"), F = (t, e) => {
351
367
  const a = K(e);
352
- return e === "week" ? t.startOf("week") : e === "quarter" ? Ot(t) : t.startOf(a);
353
- }, xt = (t, e) => {
354
- var r, s;
355
- const a = (r = t.inputs) == null ? void 0 : r.dateBounds;
368
+ return e === "week" ? t.startOf("week") : e === "quarter" ? xt(t) : t.startOf(a);
369
+ }, vt = (t, e) => {
370
+ var s, r;
371
+ const a = (s = t.inputs) == null ? void 0 : s.dateBounds;
356
372
  if (!a) return;
357
373
  if (a.from && a.to)
358
374
  return a;
359
375
  const n = a.relativeTimeString;
360
376
  if (n) {
361
- const i = (((s = e == null ? void 0 : e.defaults) == null ? void 0 : s.dateRangesOptions) ?? []).find((c) => c.value === n);
362
- if (i) {
363
- const c = i.getRange();
377
+ const l = (((r = e == null ? void 0 : e.defaults) == null ? void 0 : r.dateRangesOptions) ?? []).find((c) => c.value === n);
378
+ if (l) {
379
+ const c = l.getRange();
364
380
  return {
365
381
  from: c.from,
366
382
  to: c.to,
@@ -369,37 +385,37 @@ const Lt = ({ data: t, onSegmentClick: e, options: a = {}, ...n }) => {
369
385
  }
370
386
  }
371
387
  }, Ct = (t, e) => {
372
- const { dimension: a, granularity: n = "day", sortOrder: r = "asc", dateBounds: s, theme: o } = e, i = s || xt(a, o);
388
+ const { dimension: a, granularity: n = "day", sortOrder: s = "asc", dateBounds: r, theme: o } = e, l = r || vt(a, o);
373
389
  if (!t || t.length === 0)
374
390
  return t;
375
391
  if (!(a != null && a.name))
376
392
  throw new Error("dimension.name is required");
377
- const c = kt(a.name, n, t), u = t.map((l) => {
378
- const m = l[c];
393
+ const c = kt(a.name, n, t), u = t.map((i) => {
394
+ const m = i[c];
379
395
  if (typeof m != "string")
380
396
  return null;
381
397
  const g = D(m);
382
- return g.isValid() ? { ...l, _parsedDate: g } : null;
398
+ return g.isValid() ? { ...i, _parsedDate: g } : null;
383
399
  }).filter(
384
- (l) => l !== null
400
+ (i) => i !== null
385
401
  );
386
402
  if (u.length === 0)
387
403
  return console.warn("fillGaps: No valid dates found in data"), t;
388
404
  let h, d;
389
- if (i) {
390
- const l = i.from instanceof Date ? i.from : new Date(i.from), m = i.to instanceof Date ? i.to : new Date(i.to);
405
+ if (l) {
406
+ const i = l.from instanceof Date ? l.from : new Date(l.from), m = l.to instanceof Date ? l.to : new Date(l.to);
391
407
  if (n === "second" || n === "minute" || n === "hour")
392
- h = D(l), d = D(m);
408
+ h = D(i), d = D(m);
393
409
  else {
394
- const g = _(l), p = _(m);
410
+ const g = _(i), p = _(m);
395
411
  h = D(g), d = D(p);
396
412
  }
397
413
  h = F(h, n), d = F(d, n);
398
414
  } else {
399
- const l = u[0];
400
- if (!l)
415
+ const i = u[0];
416
+ if (!i)
401
417
  return t;
402
- let m = l._parsedDate, g = l._parsedDate;
418
+ let m = i._parsedDate, g = i._parsedDate;
403
419
  for (let p = 1; p < u.length; p++) {
404
420
  const w = u[p];
405
421
  if (w) {
@@ -409,29 +425,29 @@ const Lt = ({ data: t, onSegmentClick: e, options: a = {}, ...n }) => {
409
425
  }
410
426
  h = m, d = g;
411
427
  }
412
- const x = [], C = K(n), A = h.startOf(C), k = d.startOf(C);
428
+ const x = [], v = K(n), A = h.startOf(v), C = d.startOf(v);
413
429
  if (n === "week") {
414
- let l = A;
415
- for (; l.isBefore(k) || l.isSame(k, "day"); )
416
- x.push(l), l = l.add(7, "day");
430
+ let i = A;
431
+ for (; i.isBefore(C) || i.isSame(C, "day"); )
432
+ x.push(i), i = i.add(7, "day");
417
433
  } else {
418
- let l = A;
419
- for (; l.isBefore(k) || l.isSame(k, C); )
420
- x.push(l), n === "quarter" ? l = l.add(3, "month") : l = l.add(1, C);
434
+ let i = A;
435
+ for (; i.isBefore(C) || i.isSame(C, v); )
436
+ x.push(i), n === "quarter" ? i = i.add(3, "month") : i = i.add(1, v);
421
437
  }
422
- const v = /* @__PURE__ */ new Map();
423
- u.forEach((l) => {
424
- const m = $(l._parsedDate);
425
- v.set(m, l);
438
+ const k = /* @__PURE__ */ new Map();
439
+ u.forEach((i) => {
440
+ const m = $(i._parsedDate);
441
+ k.set(m, i);
426
442
  });
427
443
  const b = [];
428
- return x.forEach((l) => {
429
- const m = $(l), g = v.get(m);
444
+ return x.forEach((i) => {
445
+ const m = $(i), g = k.get(m);
430
446
  if (g) {
431
447
  const p = { ...g };
432
448
  delete p._parsedDate, b.push(p);
433
449
  } else {
434
- const p = vt(t), w = wt(l, p), S = {
450
+ const p = wt(t), w = Mt(i, p), S = {
435
451
  [c]: w
436
452
  }, P = a.name, B = t[0];
437
453
  if (B)
@@ -439,18 +455,18 @@ const Lt = ({ data: t, onSegmentClick: e, options: a = {}, ...n }) => {
439
455
  M !== c && (M.startsWith(P) && M !== c ? S[M] = w : S[M] = null);
440
456
  b.push(S);
441
457
  }
442
- }), r === "desc" ? b.sort(
443
- (l, m) => D(m[c]).valueOf() - D(l[c]).valueOf()
458
+ }), s === "desc" ? b.sort(
459
+ (i, m) => D(m[c]).valueOf() - D(i[c]).valueOf()
444
460
  ) : b.sort(
445
- (l, m) => D(l[c]).valueOf() - D(m[c]).valueOf()
461
+ (i, m) => D(i[c]).valueOf() - D(m[c]).valueOf()
446
462
  ), b;
447
463
  }, $ = (t) => t.format("YYYY-MM-DDTHH:mm:ss"), kt = (t, e, a) => {
448
464
  if (!a || a.length === 0) return t;
449
465
  const n = a[0];
450
466
  if (!n) return t;
451
- const r = `${t}.${e}`;
452
- return r in n ? r : t;
453
- }, vt = (t) => {
467
+ const s = `${t}.${e}`;
468
+ return s in n ? s : t;
469
+ }, wt = (t) => {
454
470
  if (!(t != null && t.length)) return T.DEFAULT;
455
471
  const e = t[0];
456
472
  if (!e) return T.DEFAULT;
@@ -458,60 +474,60 @@ const Lt = ({ data: t, onSegmentClick: e, options: a = {}, ...n }) => {
458
474
  if (typeof a == "string" && a.includes("T") && a.includes(":"))
459
475
  return a.endsWith("Z") ? T.WITH_TIMEZONE : a.includes(".") ? T.WITHOUT_TIMEZONE : T.WITHOUT_MILLISECONDS;
460
476
  return T.DEFAULT;
461
- }, wt = (t, e) => e.includes("[Z]") ? t.format(T.WITH_TIMEZONE) : e.includes(".SSS") ? t.format(T.WITHOUT_TIMEZONE) : t.format(T.WITHOUT_MILLISECONDS), K = (t) => U[t] || U.day, $t = (t, e) => {
477
+ }, Mt = (t, e) => e.includes("[Z]") ? t.format(T.WITH_TIMEZONE) : e.includes(".SSS") ? t.format(T.WITHOUT_TIMEZONE) : t.format(T.WITHOUT_MILLISECONDS), K = (t) => U[t] || U.day, Wt = (t, e) => {
462
478
  const a = ht(), n = ut(() => {
463
479
  var u, h;
464
- const r = t.data;
465
- if (e.nativeType !== "time" || !r || r.length === 0)
466
- return r;
467
- const s = ((u = e.inputs) == null ? void 0 : u.granularity) || Et(r, e);
468
- if (!s || !(((h = e.inputs) == null ? void 0 : h.dateBounds) ?? Mt(r, e, s)))
469
- return r;
480
+ const s = t.data;
481
+ if (e.nativeType !== "time" || !s || s.length === 0)
482
+ return s;
483
+ const r = ((u = e.inputs) == null ? void 0 : u.granularity) || It(s, e);
484
+ if (!r || !(((h = e.inputs) == null ? void 0 : h.dateBounds) ?? Et(s, e, r)))
485
+ return s;
470
486
  const c = {
471
487
  dimension: e,
472
- granularity: s,
488
+ granularity: r,
473
489
  sortOrder: "asc",
474
490
  theme: a
475
491
  };
476
492
  try {
477
- return Ct(r, c);
493
+ return Ct(s, c);
478
494
  } catch (d) {
479
- return console.warn("Failed to apply fillGaps to chart data:", d), r;
495
+ return console.warn("Failed to apply fillGaps to chart data:", d), s;
480
496
  }
481
497
  }, [t.data, e, a]);
482
498
  return {
483
499
  ...t,
484
500
  data: n
485
501
  };
486
- }, Mt = (t, e, a) => {
502
+ }, Et = (t, e, a) => {
487
503
  if (!t || t.length < 2)
488
504
  return !1;
489
- const n = e.name, r = t.map((o) => o[n]).filter(Boolean).map((o) => new Date(o)).filter((o) => !isNaN(o.getTime())).sort((o, i) => o.getTime() - i.getTime());
490
- if (r.length < 2)
505
+ const n = e.name, s = t.map((o) => o[n]).filter(Boolean).map((o) => new Date(o)).filter((o) => !isNaN(o.getTime())).sort((o, l) => o.getTime() - l.getTime());
506
+ if (s.length < 2)
491
507
  return !1;
492
- const s = It(a);
493
- for (let o = 1; o < r.length; o++) {
494
- const i = r[o], c = r[o - 1];
495
- if (i && c && i.getTime() - c.getTime() > s * 1.5)
508
+ const r = At(a);
509
+ for (let o = 1; o < s.length; o++) {
510
+ const l = s[o], c = s[o - 1];
511
+ if (l && c && l.getTime() - c.getTime() > r * 1.5)
496
512
  return !0;
497
513
  }
498
514
  return !1;
499
- }, Et = (t, e) => {
515
+ }, It = (t, e) => {
500
516
  if (!t || t.length === 0) return null;
501
517
  const a = t[0];
502
518
  if (!a) return null;
503
- const n = e.name, r = Object.keys(a).filter(
504
- (s) => s.startsWith(n) && s !== n
519
+ const n = e.name, s = Object.keys(a).filter(
520
+ (r) => r.startsWith(n) && r !== n
505
521
  );
506
- for (const s of r) {
507
- if (s.includes(".second")) return "second";
508
- if (s.includes(".minute")) return "minute";
509
- if (s.includes(".hour")) return "hour";
510
- if (s.includes(".day")) return "day";
511
- if (s.includes(".week")) return "week";
512
- if (s.includes(".month")) return "month";
513
- if (s.includes(".quarter")) return "quarter";
514
- if (s.includes(".year")) return "year";
522
+ for (const r of s) {
523
+ if (r.includes(".second")) return "second";
524
+ if (r.includes(".minute")) return "minute";
525
+ if (r.includes(".hour")) return "hour";
526
+ if (r.includes(".day")) return "day";
527
+ if (r.includes(".week")) return "week";
528
+ if (r.includes(".month")) return "month";
529
+ if (r.includes(".quarter")) return "quarter";
530
+ if (r.includes(".year")) return "year";
515
531
  }
516
532
  return null;
517
533
  }, Z = 1e3, q = 60 * Z, V = 60 * q, E = 24 * V, y = {
@@ -526,7 +542,7 @@ const Lt = ({ data: t, onSegmentClick: e, options: a = {}, ...n }) => {
526
542
  // Approximate
527
543
  YEAR: 365 * E
528
544
  // Approximate
529
- }, It = (t) => {
545
+ }, At = (t) => {
530
546
  switch (t) {
531
547
  case "second":
532
548
  return y.SECOND;
@@ -549,10 +565,10 @@ const Lt = ({ data: t, onSegmentClick: e, options: a = {}, ...n }) => {
549
565
  }
550
566
  };
551
567
  export {
552
- Lt as B,
553
- Ft as a,
554
- Ut as b,
555
- _t as g,
556
- $t as u
568
+ Ut as B,
569
+ $t as a,
570
+ _t as b,
571
+ Ft as g,
572
+ Wt as u
557
573
  };
558
- //# sourceMappingURL=charts.fillGaps.hooks-t2xhHbW-.js.map
574
+ //# sourceMappingURL=charts.fillGaps.hooks-C5Gy3QoW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"charts.fillGaps.hooks-C5Gy3QoW.js","sources":["../src/remarkable-ui/charts/bars/bars.constants.ts","../src/remarkable-ui/charts/bars/bars.utils.ts","../src/remarkable-ui/charts/bars/BarChart.tsx","../src/remarkable-pro/components/charts/bars/bars.utils.ts","../src/remarkable-pro/components/charts/charts.fillGaps.utils.ts","../src/remarkable-pro/components/charts/charts.fillGaps.hooks.ts"],"sourcesContent":["import { ChartOptions } from 'chart.js';\nimport { getStyle, getStyleNumber } from '../../styles/styles.utils';\nimport { chartjsOptions } from '../chartjs.constants';\n\nexport const defaultBarChartOptions: Partial<ChartOptions<'bar'>> = {\n ...chartjsOptions,\n scales: {\n x: {\n title: {\n display: true,\n color: getStyle('--em-chart-grid-font-color-default'),\n font: {\n size: getStyleNumber('--em-chart-grid-font-title-size'),\n weight: getStyleNumber('--em-chart-grid-font-title-weight'),\n // TODO: fix family on dedicated ticket\n // family: getStyle('--em-chart-grid-font-font-family'),\n lineHeight: `${getStyleNumber('--em-chart-grid-font-line-height')}px`,\n },\n },\n ticks: {\n font: {\n size: getStyleNumber('--em-chart-grid-font-subtitle-size'),\n weight: getStyleNumber('--em-chart-grid-font-label-weight'),\n // TODO: fix family on dedicated ticket\n // family: getStyle('--em-chart-grid-font-font-family'),\n lineHeight: `${getStyleNumber('--em-chart-grid-font-line-height')}px`,\n },\n },\n grid: {\n display: false,\n color: getStyle('--em-chart-grid-line-color-light'),\n lineWidth: getStyleNumber('--em-chart-grid-line-width-default'),\n },\n border: {\n display: false,\n },\n },\n y: {\n title: {\n display: true,\n color: getStyle('--em-chart-grid-font-color-default'),\n font: {\n size: getStyleNumber('--em-chart-grid-font-title-size'),\n weight: getStyleNumber('--em-chart-grid-font-title-weight'),\n // TODO: fix family on dedicated ticket\n // family: getStyle('--em-chart-grid-font-font-family'),\n lineHeight: `${getStyleNumber('--em-chart-grid-font-line-height')}px`,\n },\n },\n ticks: {\n font: {\n size: getStyleNumber('--em-chart-grid-font-subtitle-size'),\n weight: getStyleNumber('--em-chart-grid-font-label-weight'),\n // TODO: fix family on dedicated ticket\n // family: getStyle('--em-chart-grid-font-font-family'),\n lineHeight: `${getStyleNumber('--em-chart-grid-font-line-height')}px`,\n },\n },\n grid: {\n display: false,\n color: getStyle('--em-chart-grid-line-color-light'),\n lineWidth: getStyleNumber('--em-chart-grid-line-width-default'),\n },\n border: {\n display: false,\n },\n },\n },\n};\n","import { ChartData, ChartOptions } from 'chart.js';\nimport { chartContrastColors } from '../charts.constants';\nimport { getStyle, getStyleNumber } from '../../styles/styles.utils';\nimport { mergician } from 'mergician';\nimport { BarChartConfigurationProps, BarChartHorizontalConfigurationProps } from './bars.types';\nimport { defaultBarChartOptions } from './bars.constants';\nimport { Context } from 'chartjs-plugin-datalabels';\n\nexport const getBarChartData = (data: ChartData<'bar'>): ChartData<'bar'> => {\n return {\n ...data,\n datasets: data.datasets?.map((dataset, index) => {\n const colors = chartContrastColors[index % chartContrastColors.length];\n const defaultDataset = {\n ...dataset,\n backgroundColor: colors,\n borderColor: colors,\n };\n\n return mergician(defaultDataset, dataset) as typeof dataset;\n }),\n };\n};\n\nconst getDatalabelTotalDisplay = (context: Context, showTotalLabels: boolean | undefined) =>\n showTotalLabels && context.datasetIndex === context.chart.data.datasets.length - 1\n ? 'auto'\n : false;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst getDatalabelTotalFormatter = (_value: any, context: Context) => {\n const { datasets } = context.chart.data;\n const i = context.dataIndex;\n\n const total = datasets.reduce((sum, ds) => {\n const val = ds.data[i] as number;\n return sum + (val || 0);\n }, 0);\n\n return total > 0 ? total : '';\n};\n\nconst getBarVerticalChartOptions = (\n config: BarChartConfigurationProps,\n): Partial<ChartOptions<'bar'>> => {\n return mergician(defaultBarChartOptions, {\n indexAxis: 'x',\n plugins: {\n datalabels: {\n labels: {\n total: {\n anchor: (context) => {\n const value = context.dataset.data[context.dataIndex] as number;\n return value >= 0 ? 'end' : 'start';\n },\n align: (context) => {\n const value = context.dataset.data[context.dataIndex] as number;\n return value >= 0 ? 'top' : 'bottom';\n },\n display: (context) => getDatalabelTotalDisplay(context, config.showTotalLabels),\n formatter: getDatalabelTotalFormatter,\n },\n value: {\n anchor: (context) => {\n if (config.stacked) {\n return 'center';\n }\n const value = context.dataset.data[context.dataIndex] as number;\n return value >= 0 ? 'end' : 'start';\n },\n align: (context) => {\n if (config.stacked) {\n return 'center';\n }\n const value = context.dataset.data[context.dataIndex] as number;\n return value >= 0 ? 'top' : 'bottom';\n },\n },\n },\n },\n },\n scales: {\n y: {\n stacked: config.stacked,\n grid: { display: true },\n ticks: {\n color: getStyle('--em-chart-grid-font-color-muted'),\n // ...(config.stacked === 'percentage' && {\n // callback: (value: number | string) => value + '%',\n // }),\n },\n min: config.yAxisRangeMin,\n // max: config.stacked === 'percentage' ? 100 : config.yAxisRangeMax,\n max: config.yAxisRangeMax,\n type: config.showLogarithmicScale ? 'logarithmic' : 'linear',\n title: {\n text: config.yAxisLabel ?? '',\n },\n },\n x: {\n stacked: config.stacked,\n ticks: {\n color: getStyle('--em-chart-grid-font-color-default'),\n },\n reverse: config.reverseXAxis,\n title: {\n text: config.xAxisLabel ?? '',\n },\n },\n },\n } as Partial<ChartOptions<'bar'>>);\n};\n\nconst getBarHorizontalChartOptions = (\n config: BarChartHorizontalConfigurationProps,\n): Partial<ChartOptions<'bar'>> => {\n return mergician(defaultBarChartOptions, {\n indexAxis: 'y',\n plugins: {\n datalabels: {\n labels: {\n total: {\n anchor: (context) => {\n const value = context.dataset.data[context.dataIndex] as number;\n return value >= 0 ? 'end' : 'start';\n },\n align: (context) => {\n const value = context.dataset.data[context.dataIndex] as number;\n return value >= 0 ? 'right' : 'left';\n },\n display: (context) => getDatalabelTotalDisplay(context, config.showTotalLabels),\n formatter: getDatalabelTotalFormatter,\n },\n value: {\n anchor: (context) => {\n if (config.stacked) {\n return 'center';\n }\n const value = context.dataset.data[context.dataIndex] as number;\n return value >= 0 ? 'end' : 'start';\n },\n align: (context) => {\n if (config.stacked) {\n return 'center';\n }\n const value = context.dataset.data[context.dataIndex] as number;\n return value >= 0 ? 'right' : 'left';\n },\n },\n },\n },\n },\n scales: {\n x: {\n stacked: config.stacked,\n grid: { display: true },\n ticks: {\n color: getStyle('--em-chart-grid-font-color-muted'),\n // ...(config.stacked === 'percentage' && {\n // callback: (value: number | string) => value + '%',\n // }),\n },\n min: config.xAxisRangeMin,\n // max: config.stacked === 'percentage' ? 100 : config.xAxisRangeMax,\n max: config.xAxisRangeMax,\n type: config.showLogarithmicScale ? 'logarithmic' : 'linear',\n title: {\n text: config.xAxisLabel ?? '',\n },\n },\n y: {\n stacked: config.stacked,\n ticks: {\n color: getStyle('--em-chart-grid-font-color-default'),\n },\n reverse: config.reverseYAxis,\n title: {\n text: config.yAxisLabel ?? '',\n },\n },\n },\n } as Partial<ChartOptions<'bar'>>);\n};\n\nexport const getBarChartOptions = (\n props: BarChartConfigurationProps,\n): Partial<ChartOptions<'bar'>> => {\n const {\n horizontal = false,\n showLegend = false,\n showTooltips = true,\n showValueLabels = false,\n showTotalLabels = false,\n } = props;\n\n const getOptions = horizontal ? getBarHorizontalChartOptions : getBarVerticalChartOptions;\n const options = getOptions(props);\n\n return mergician(options, {\n layout: {\n padding: {\n // Hack: dataLabels can get cut off if they are at the edge of the chart\n top: !horizontal && (showValueLabels || showTotalLabels) ? 30 : 0,\n right: horizontal && (showValueLabels || showTotalLabels) ? 30 : 0,\n },\n },\n elements: {\n bar: {\n borderRadius: getStyleNumber('--em-chart-style-border-radius-default'),\n // stacked === 'percentage' ? 0 : getStyleNumber('--em-chart-style-border-radius-default'),\n },\n },\n plugins: {\n legend: { display: showLegend },\n datalabels: {\n display: (context) => {\n return showValueLabels && context.dataset.data[context.dataIndex] !== 0 ? 'auto' : false;\n },\n },\n tooltip: {\n enabled: showTooltips,\n },\n },\n } as Partial<ChartOptions<'bar'>>);\n};\n","import { FC, useRef } from 'react';\nimport { Bar } from 'react-chartjs-2';\nimport {\n Chart as ChartJS,\n CategoryScale,\n LinearScale,\n BarElement,\n Title,\n Tooltip,\n Legend,\n LogarithmicScale,\n} from 'chart.js';\nimport { BaseBarChartProps } from './bars.types';\nimport { getSegmentIndexClicked } from '../chartjs.utils';\nimport { getBarChartData, getBarChartOptions } from './bars.utils';\nimport styles from '../charts.module.css';\nimport { mergician } from 'mergician';\n\nChartJS.register(CategoryScale, LinearScale, BarElement, LogarithmicScale, Title, Tooltip, Legend);\n\nexport type BarChartProps = BaseBarChartProps;\n\nexport const BarChart: FC<BarChartProps> = ({ data, onSegmentClick, options = {}, ...props }) => {\n const chartRef = useRef(null);\n\n const barChartOptions = mergician(getBarChartOptions(props), options);\n\n const handleSegmentClick = (event: React.MouseEvent<HTMLCanvasElement>) => {\n const indexClicked = getSegmentIndexClicked(event, chartRef);\n onSegmentClick?.(indexClicked);\n };\n\n return (\n <div className={styles.chartContainer}>\n <Bar\n ref={chartRef}\n data={getBarChartData(data)}\n options={barChartOptions}\n onClick={handleSegmentClick}\n />\n </div>\n );\n};\n","import { DataResponse, Dimension, Measure } from '@embeddable.com/core';\nimport { Theme } from '../../../theme/theme.types';\nimport { remarkableTheme } from '../../../theme/theme.constants';\nimport { ChartData, ChartOptions } from 'chart.js';\nimport { getThemeFormatter } from '../../../theme/formatter/formatter.utils';\nimport { groupTailAsOther } from '../charts.utils';\nimport { i18n } from '../../../theme/i18n/i18n';\nimport { getColor } from '../../../theme/styles/styles.utils';\nimport { chartColors } from '../../../../remarkable-ui';\nimport { getObjectStableKey } from '../../../utils.ts/object.utils';\nimport { chartContrastColors } from '../../../../remarkable-ui/charts/charts.constants';\nimport { Context } from 'chartjs-plugin-datalabels';\n\nexport const getBarStackedChartProData = (\n props: {\n data: DataResponse['data'];\n dimension: Dimension;\n groupDimension: Dimension;\n measure: Measure;\n },\n theme: Theme,\n): ChartData<'bar'> => {\n const themeFormatter = getThemeFormatter(theme);\n const { data = [], dimension, groupDimension, measure } = props;\n\n const axis = [...new Set(data.map((d) => d[dimension.name]).filter(Boolean))].sort();\n\n const groupBy = [...new Set(data.map((d) => d[groupDimension.name]))];\n\n const themeKey = getObjectStableKey(theme);\n\n const datasets = groupBy.map((groupByItem, index) => {\n const backgroundColor = getColor(\n `${themeKey}.charts.backgroundColors`,\n groupByItem,\n theme.charts.backgroundColors ?? chartContrastColors,\n index,\n );\n\n const borderColor = getColor(\n `${themeKey}.charts.borderColors`,\n groupByItem,\n theme.charts.borderColors ?? chartContrastColors,\n index,\n );\n\n return {\n label: themeFormatter.data(groupDimension, groupByItem),\n backgroundColor,\n borderColor,\n data: axis.map((axisItem) => {\n const record = data.find(\n (d) => d[groupDimension.name] === groupByItem && d[dimension.name] === axisItem,\n );\n return record ? Number(record[measure.name]) : 0;\n }),\n };\n });\n\n return {\n labels: axis.map((axisItem) => themeFormatter.data(dimension, axisItem)),\n datasets,\n };\n};\nexport const getBarChartProData = (\n props: {\n data: DataResponse['data'];\n dimension: Dimension;\n measures: Measure[];\n maxItems?: number;\n },\n theme: Theme = remarkableTheme,\n): ChartData<'bar'> => {\n const themeFormatter = getThemeFormatter(theme);\n\n if (!props.data) {\n return {\n labels: [],\n datasets: [{ data: [] }],\n };\n }\n\n const themeKey = getObjectStableKey(theme);\n const groupedData = groupTailAsOther(props.data, props.dimension, props.measures, props.maxItems);\n\n return {\n labels: groupedData.map((item) => {\n const value = item[props.dimension.name];\n const formattedValue = themeFormatter.data(props.dimension, value);\n\n // If formatter did not work, try i18n translation\n if (value === formattedValue) {\n return i18n.t(value);\n }\n return formattedValue;\n }),\n datasets: props.measures.map((measure, index) => {\n const backgroundColor = getColor(\n `${themeKey}.charts.backgroundColors`,\n measure.name,\n theme.charts.backgroundColors ?? chartColors,\n index,\n );\n\n const borderColor = getColor(\n `${themeKey}.charts.borderColors`,\n measure.name,\n theme.charts.borderColors ?? chartColors,\n index,\n );\n\n return {\n label: themeFormatter.dimensionOrMeasureTitle(measure),\n data: groupedData.map((item) => item[measure.name]),\n backgroundColor,\n borderColor,\n };\n }),\n };\n};\n\nconst getBarChartProDatalabelTotalFormatter = (\n context: Context,\n formatter: (value: number) => string,\n) => {\n const { datasets } = context.chart.data;\n const i = context.dataIndex;\n\n const total = datasets.reduce((sum, ds) => {\n const val = ds.data[i] as number;\n return sum + (val || 0);\n }, 0);\n\n return formatter(total);\n};\n\nexport const getBarChartProOptions = (\n options: {\n onBarClicked: (args: {\n axisDimensionValue: string | null;\n groupingDimensionValue: string | null;\n }) => void;\n measure: Measure;\n horizontal: boolean;\n },\n theme: Theme,\n): Partial<ChartOptions<'bar'>> => {\n const { onBarClicked, measure, horizontal } = options;\n\n const themeFormatter = getThemeFormatter(theme);\n return {\n plugins: {\n legend: { position: theme.charts.legendPosition ?? 'bottom' },\n datalabels: {\n labels: {\n total: {\n formatter: (_value: string | number, context: Context) =>\n getBarChartProDatalabelTotalFormatter(context, (value: number) =>\n themeFormatter.data(options.measure, value),\n ),\n },\n value: {\n formatter: (value: string | number) => themeFormatter.data(options.measure, value),\n },\n },\n },\n tooltip: {\n callbacks: {\n label(context) {\n const raw = context.raw as number;\n return `${context.dataset.label || ''}: ${themeFormatter.data(measure, raw)}`;\n },\n },\n },\n },\n scales: {\n x: {\n ticks: {\n ...(horizontal && {\n callback: (value) => themeFormatter.data(measure, value),\n }),\n },\n },\n y: {\n ticks: {\n ...(!horizontal && {\n callback: (value) => themeFormatter.data(measure, value),\n }),\n },\n },\n },\n onClick: (_event, elements, chart) => {\n const element = elements[0];\n const axisDimensionValue = (element ? chart.data.labels![element.index] : null) as\n | string\n | null;\n const groupingDimensionValue = (\n element ? chart.data.datasets[element.datasetIndex]!.label : null\n ) as string | null;\n\n onBarClicked({\n axisDimensionValue,\n groupingDimensionValue,\n });\n },\n };\n};\n","import dayjs from 'dayjs';\nimport {\n DataResponse,\n Dimension,\n Granularity,\n TimeRange,\n TimeRangeDeserializedValue,\n} from '@embeddable.com/core';\nimport { Theme } from '../../theme/theme.types';\n\ntype DataResponseDataRecord = NonNullable<DataResponse['data']>[number];\n\nconst DATE_FORMATS = {\n DEFAULT: 'YYYY-MM-DDTHH:mm:ss.SSS',\n WITH_TIMEZONE: 'YYYY-MM-DDTHH:mm:ss.SSS[Z]',\n WITHOUT_TIMEZONE: 'YYYY-MM-DDTHH:mm:ss.SSS',\n WITHOUT_MILLISECONDS: 'YYYY-MM-DDTHH:mm:ss',\n};\n\n/**\n * Maps granularity to dayjs unit for date manipulation\n */\nconst granularityToDayjsUnitMap: Record<Granularity, dayjs.ManipulateType> = {\n second: 'second',\n minute: 'minute',\n hour: 'hour',\n day: 'day',\n week: 'week',\n month: 'month',\n quarter: 'month', // Will be handled specially\n year: 'year',\n};\n\n/**\n * Formats a Date object as YYYY-MM-DD string in local timezone\n */\nconst formatDateAsString = (date: Date): string => {\n return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;\n};\n\n/**\n * Formats a Date object as YYYY-MM-DD string in UTC timezone\n */\nconst formatDateAsStringUTC = (date: Date): string => {\n return `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, '0')}-${String(date.getUTCDate()).padStart(2, '0')}`;\n};\n\n/**\n * Checks if a date is in UTC format (contains 'Z')\n */\nconst isUTCDate = (date: Date): boolean => {\n return date.toISOString().includes('Z');\n};\n\n/**\n * Formats a date string based on whether it's UTC or local\n */\nconst formatDateString = (date: Date): string => {\n return isUTCDate(date) ? formatDateAsStringUTC(date) : formatDateAsString(date);\n};\n\n/**\n * Gets the quarter start date for a given dayjs date\n */\nconst getQuarterStart = (date: dayjs.Dayjs): dayjs.Dayjs => {\n return date\n .startOf('month')\n .month(Math.floor(date.month() / 3) * 3)\n .startOf('month');\n};\n\n/**\n * Applies granularity-specific start/end logic to dates\n */\nconst applyGranularityBounds = (date: dayjs.Dayjs, granularity: Granularity): dayjs.Dayjs => {\n const unit = granularityToDayjsUnit(granularity);\n\n if (granularity === 'week') {\n return date.startOf('week');\n } else if (granularity === 'quarter') {\n return getQuarterStart(date);\n } else {\n return date.startOf(unit);\n }\n};\n\n/**\n * Resolves date bounds from dimension inputs, handling relative time strings\n */\nconst resolveDateBounds = (dimension: Dimension, theme?: Theme): TimeRange => {\n const dateBounds = dimension.inputs?.dateBounds;\n if (!dateBounds) return undefined;\n\n // If it already has from/to dates, use them directly\n if (dateBounds.from && dateBounds.to) {\n return dateBounds;\n }\n\n // If it has a relativeTimeString, resolve it using theme options\n const relativeTimeString = dateBounds.relativeTimeString;\n if (relativeTimeString) {\n const dateRangeOptions = theme?.defaults?.dateRangesOptions ?? [];\n const matchedOption = dateRangeOptions.find((option) => option.value === relativeTimeString);\n\n if (matchedOption) {\n const range = matchedOption.getRange() as TimeRangeDeserializedValue;\n return {\n from: range.from,\n to: range.to,\n relativeTimeString: relativeTimeString,\n };\n }\n }\n\n return undefined;\n};\n\nexport type FillGapsOptions = {\n dimension: Dimension;\n granularity?: Granularity;\n sortOrder?: 'asc' | 'desc';\n dateBounds?: TimeRangeDeserializedValue;\n theme?: Theme;\n};\n\n/**\n * Fills missing time buckets in a date-series based on granularity and sorting\n *\n * @param data - Array of date records to process\n * @param options - Configuration options for gap filling\n * @returns Array with missing time buckets filled in\n *\n * @example\n * ```typescript\n * const data = [\n * { date: '2024-01-01', value: 10 },\n * { date: '2024-01-03', value: 20 }\n * ];\n * const result = fillGaps(data, {\n * dimension: { name: 'date' },\n * granularity: 'day'\n * });\n * // Result: [{ date: '2024-01-01', value: 10 }, { date: '2024-01-02', value: null }, { date: '2024-01-03', value: 20 }]\n * ```\n */\nexport const fillGaps = (\n data: DataResponse['data'],\n options: FillGapsOptions,\n): DataResponse['data'] => {\n const { dimension, granularity = 'day', sortOrder = 'asc', dateBounds, theme } = options;\n\n // Resolve date bounds from dimension inputs if not provided directly\n const resolvedDateBounds = dateBounds || resolveDateBounds(dimension, theme);\n\n if (!data || data.length === 0) {\n return data;\n }\n\n if (!dimension?.name) {\n throw new Error('dimension.name is required');\n }\n\n // Get the dimension name - use granularity-specific name if available\n const dimensionName = getGranularityDimensionName(dimension.name, granularity, data);\n\n // Parse dates and filter valid ones\n const validData = data\n .map((record) => {\n const dateValue = record[dimensionName];\n if (typeof dateValue !== 'string') {\n return null;\n }\n const parsedDate = dayjs(dateValue);\n return parsedDate.isValid() ? { ...record, _parsedDate: parsedDate } : null;\n })\n .filter(\n (record): record is DataResponseDataRecord & { _parsedDate: dayjs.Dayjs } => record !== null,\n );\n\n if (validData.length === 0) {\n console.warn('fillGaps: No valid dates found in data');\n return data;\n }\n\n // Determine date range\n let minDate: dayjs.Dayjs;\n let maxDate: dayjs.Dayjs;\n\n if (resolvedDateBounds) {\n // Parse dates with timezone-safe approach\n const fromDate =\n resolvedDateBounds.from instanceof Date\n ? resolvedDateBounds.from\n : new Date(resolvedDateBounds.from!);\n const toDate =\n resolvedDateBounds.to instanceof Date\n ? resolvedDateBounds.to\n : new Date(resolvedDateBounds.to!);\n\n // For sub-day granularities, preserve time component\n if (granularity === 'second' || granularity === 'minute' || granularity === 'hour') {\n minDate = dayjs(fromDate);\n maxDate = dayjs(toDate);\n } else {\n // For day+ granularities, extract date only to avoid timezone issues\n const fromDateStr = formatDateString(fromDate);\n const toDateStr = formatDateString(toDate);\n\n minDate = dayjs(fromDateStr);\n maxDate = dayjs(toDateStr);\n }\n\n // Apply granularity-specific start/end logic\n minDate = applyGranularityBounds(minDate, granularity);\n maxDate = applyGranularityBounds(maxDate, granularity);\n } else {\n // Use data range - more efficient single pass\n const firstRecord = validData[0];\n if (!firstRecord) {\n return data;\n }\n\n let min = firstRecord._parsedDate;\n let max = firstRecord._parsedDate;\n\n for (let i = 1; i < validData.length; i++) {\n const record = validData[i];\n if (record) {\n const date = record._parsedDate;\n if (date.isBefore(min)) min = date;\n if (date.isAfter(max)) max = date;\n }\n }\n\n minDate = min;\n maxDate = max;\n }\n\n // Generate all possible dates in the range\n const allDates: dayjs.Dayjs[] = [];\n\n // Normalize both dates to the start of their respective granularity units\n const dayjsUnit = granularityToDayjsUnit(granularity);\n const minDateStart = minDate.startOf(dayjsUnit);\n const maxDateStart = maxDate.startOf(dayjsUnit);\n\n if (granularity === 'week') {\n // For week granularity, start from the first day and add exactly 7 days\n let currentDate = minDateStart;\n while (currentDate.isBefore(maxDateStart) || currentDate.isSame(maxDateStart, 'day')) {\n allDates.push(currentDate);\n currentDate = currentDate.add(7, 'day'); // Add exactly 7 days\n }\n } else {\n // For other granularities, use the standard approach\n let currentDate = minDateStart;\n\n while (currentDate.isBefore(maxDateStart) || currentDate.isSame(maxDateStart, dayjsUnit)) {\n allDates.push(currentDate);\n\n if (granularity === 'quarter') {\n currentDate = currentDate.add(3, 'month');\n } else {\n currentDate = currentDate.add(1, dayjsUnit);\n }\n }\n }\n\n // Create a map of existing data by date\n const existingDataMap = new Map<string, DataResponseDataRecord>();\n validData.forEach((record) => {\n const dateKey = generateDateKey(record._parsedDate);\n existingDataMap.set(dateKey, record);\n });\n\n // Fill gaps\n const result: DataResponse['data'] = [];\n allDates.forEach((date) => {\n const dateKey = generateDateKey(date);\n const existingRecord = existingDataMap.get(dateKey);\n\n if (existingRecord) {\n // Use existing data - exclude internal _parsedDate field\n const cleanRecord = { ...existingRecord };\n delete cleanRecord._parsedDate;\n result.push(cleanRecord);\n } else {\n // Create gap record with zero/null values\n // Use the same date format as the original data\n const dateFormat = getDateFormatFromSample(data);\n const formattedDate = formatDateForGapRecord(date, dateFormat);\n\n const gapRecord: DataResponseDataRecord = {\n [dimensionName]: formattedDate,\n };\n\n // Set all other dimensions to null/zero, but preserve date fields\n const baseDimensionName = dimension.name;\n const sampleRecord = data[0];\n if (sampleRecord) {\n for (const key of Object.keys(sampleRecord)) {\n if (key !== dimensionName) {\n // If this is another date dimension (same base name), use the same date\n if (key.startsWith(baseDimensionName) && key !== dimensionName) {\n gapRecord[key] = formattedDate;\n } else {\n gapRecord[key] = null;\n }\n }\n }\n }\n\n result.push(gapRecord);\n }\n });\n\n // Sort the result\n if (sortOrder === 'desc') {\n result.sort(\n (a, b) =>\n dayjs(b[dimensionName] as string).valueOf() - dayjs(a[dimensionName] as string).valueOf(),\n );\n } else {\n result.sort(\n (a, b) =>\n dayjs(a[dimensionName] as string).valueOf() - dayjs(b[dimensionName] as string).valueOf(),\n );\n }\n\n return result;\n};\n\n/**\n * Generates a consistent date key for mapping\n * Includes time component to support second/minute granularities\n */\nconst generateDateKey = (date: dayjs.Dayjs): string => {\n return date.format('YYYY-MM-DDTHH:mm:ss');\n};\n\n/**\n * Gets the correct dimension name based on granularity\n */\nconst getGranularityDimensionName = (\n baseDimensionName: string,\n granularity: Granularity,\n data: DataResponse['data'],\n): string => {\n if (!data || data.length === 0) return baseDimensionName;\n\n const sampleRecord = data[0];\n if (!sampleRecord) return baseDimensionName;\n\n const granularityKey = `${baseDimensionName}.${granularity}`;\n\n // Check if granularity-specific dimension exists in the data\n if (granularityKey in sampleRecord) {\n return granularityKey;\n }\n\n // Fallback to base dimension name\n return baseDimensionName;\n};\n\n/**\n * Detects the date format from sample data\n */\nconst getDateFormatFromSample = (data: DataResponse['data']): string => {\n if (!data?.length) return DATE_FORMATS.DEFAULT;\n\n const sampleRecord = data[0];\n if (!sampleRecord) return DATE_FORMATS.DEFAULT;\n\n // Look for any date field to determine format\n for (const value of Object.values(sampleRecord)) {\n if (typeof value === 'string' && value.includes('T') && value.includes(':')) {\n if (value.endsWith('Z')) {\n return DATE_FORMATS.WITH_TIMEZONE;\n }\n if (value.includes('.')) {\n return DATE_FORMATS.WITHOUT_TIMEZONE;\n }\n return DATE_FORMATS.WITHOUT_MILLISECONDS;\n }\n }\n\n return DATE_FORMATS.DEFAULT;\n};\n\n/**\n * Formats a date for gap records using the detected format\n */\nconst formatDateForGapRecord = (date: dayjs.Dayjs, dateFormat: string): string => {\n if (dateFormat.includes('[Z]')) {\n return date.format(DATE_FORMATS.WITH_TIMEZONE);\n } else if (dateFormat.includes('.SSS')) {\n return date.format(DATE_FORMATS.WITHOUT_TIMEZONE);\n } else {\n return date.format(DATE_FORMATS.WITHOUT_MILLISECONDS);\n }\n};\n\n/**\n * Maps granularity to dayjs unit\n */\nconst granularityToDayjsUnit = (granularity: Granularity): dayjs.ManipulateType => {\n return granularityToDayjsUnitMap[granularity] || granularityToDayjsUnitMap.day;\n};\n","import { useMemo } from 'react';\nimport { DataResponse, Dimension, Granularity } from '@embeddable.com/core';\nimport { fillGaps, type FillGapsOptions } from './charts.fillGaps.utils';\nimport { useTheme } from '@embeddable.com/react';\nimport { Theme } from '../../theme/theme.types';\n\n/**\n * Hook that automatically applies fillGaps to chart data when beneficial.\n *\n * This hook intelligently fills missing time buckets in date-series data based on:\n * - The granularity from dimension inputs or auto-detected granularity from data\n * - Date bounds from dimension inputs (including relative time strings)\n * - Data sparsity analysis to determine if gap filling is needed\n *\n * @param results - The data response containing the chart data\n * @param dimension - The dimension being used for the chart axis (includes granularity in inputs)\n * @returns Enhanced data with filled time gaps, or original data if no gaps need filling\n */\nexport const useChartDataWithFillGaps = (\n results: DataResponse,\n dimension: Dimension,\n): DataResponse => {\n const theme = useTheme() as Theme;\n\n const data = useMemo(() => {\n const data = results.data;\n\n // Only apply fillGaps if:\n // 1. The dimension is a date/time dimension\n // 2. We have data to process\n if (dimension.nativeType !== 'time' || !data || data.length === 0) {\n return data;\n }\n\n // Get granularity from dimension inputs or auto-detect from data\n const effectiveGranularity =\n dimension.inputs?.granularity || detectGranularityFromData(data, dimension);\n\n if (!effectiveGranularity) {\n return data;\n }\n\n // Check if this looks like a sparse time series that would benefit from fillGaps\n // If dimension has date bounds, always apply fillGaps to ensure the specified range is filled\n const hasDateBounds = dimension.inputs?.dateBounds;\n const shouldApply = hasDateBounds ?? shouldApplyFillGaps(data, dimension, effectiveGranularity);\n\n if (!shouldApply) {\n return data;\n }\n\n // Use the effective granularity\n const options: FillGapsOptions = {\n dimension: dimension,\n granularity: effectiveGranularity,\n sortOrder: 'asc',\n theme: theme,\n };\n\n try {\n return fillGaps(data, options);\n } catch (error) {\n console.warn('Failed to apply fillGaps to chart data:', error);\n return data;\n }\n }, [results.data, dimension, theme]);\n return {\n ...results,\n data,\n };\n};\n\n/**\n * Determines if fillGaps should be applied based on data characteristics.\n *\n * Analyzes the time series data to detect if there are significant gaps that would\n * benefit from gap filling. Uses the expected step size for the given granularity\n * to determine if the data appears sparse.\n *\n * @param data - The chart data to analyze\n * @param dimension - The dimension being used for the time axis\n * @param granularity - The granularity to use for gap analysis (e.g., 'day', 'week')\n * @returns True if gap filling should be applied, false otherwise\n */\nconst shouldApplyFillGaps = (\n data: DataResponse['data'],\n dimension: Dimension,\n granularity: string,\n): boolean => {\n if (!data || data.length < 2) {\n return false; // Too few data points\n }\n\n const dimensionName = dimension.name;\n const dates = data\n .map((record) => record[dimensionName])\n .filter(Boolean)\n .map((dateStr) => new Date(dateStr as string))\n .filter((date) => !isNaN(date.getTime()))\n .sort((a, b) => a.getTime() - b.getTime());\n\n if (dates.length < 2) {\n return false; // Not enough valid dates\n }\n\n // Calculate expected step size based on granularity\n const expectedStepMs = getGranularityStepMs(granularity);\n\n // Check if there are gaps larger than expected step\n for (let i = 1; i < dates.length; i++) {\n const currentDate = dates[i];\n const previousDate = dates[i - 1];\n if (currentDate && previousDate) {\n const actualStep = currentDate.getTime() - previousDate.getTime();\n // If actual step is more than 1.5x the expected step, we have a gap\n if (actualStep > expectedStepMs * 1.5) {\n return true;\n }\n }\n }\n\n return false;\n};\n\n/**\n * Detects granularity from data by examining dimension names in the data.\n *\n * Looks for granularity-specific dimension names (e.g., 'events.date.week')\n * to infer the appropriate granularity for gap filling. Falls back to the\n * base dimension name if no granularity-specific dimension is found.\n *\n * @param data - The chart data to analyze\n * @param dimension - The base dimension being used\n * @returns Detected granularity or null if none can be determined\n */\nconst detectGranularityFromData = (\n data: DataResponse['data'],\n dimension: Dimension,\n): Granularity | null => {\n if (!data || data.length === 0) return null;\n\n const sampleRecord = data[0];\n if (!sampleRecord) return null;\n\n const baseDimensionName = dimension.name;\n\n // Look for granularity-specific dimension names in the data\n const granularityKeys = Object.keys(sampleRecord).filter(\n (key) => key.startsWith(baseDimensionName) && key !== baseDimensionName,\n );\n\n // Check for common granularity patterns\n for (const key of granularityKeys) {\n if (key.includes('.second')) return 'second';\n if (key.includes('.minute')) return 'minute';\n if (key.includes('.hour')) return 'hour';\n if (key.includes('.day')) return 'day';\n if (key.includes('.week')) return 'week';\n if (key.includes('.month')) return 'month';\n if (key.includes('.quarter')) return 'quarter';\n if (key.includes('.year')) return 'year';\n }\n\n // If no granularity-specific dimension found, return null\n return null;\n};\n\nconst SECOND = 1000;\nconst MINUTE = 60 * SECOND;\nconst HOUR = 60 * MINUTE;\nconst DAY = 24 * HOUR;\n\nexport const TIME_CONSTANTS = {\n SECOND,\n MINUTE,\n HOUR,\n DAY,\n WEEK: 7 * DAY,\n MONTH: 30 * DAY, // Approximate\n QUARTER: 90 * DAY, // Approximate\n YEAR: 365 * DAY, // Approximate\n} as const;\n\n/**\n * Gets the expected step size in milliseconds for a given granularity.\n *\n * Returns the expected time interval between consecutive data points for\n * the specified granularity. Used to detect if there are gaps in the\n * time series data that would benefit from gap filling.\n *\n * @param granularity - The time granularity (e.g., 'day', 'week', 'month')\n * @returns Expected step size in milliseconds\n */\nconst getGranularityStepMs = (granularity: string): number => {\n switch (granularity) {\n case 'second':\n return TIME_CONSTANTS.SECOND;\n case 'minute':\n return TIME_CONSTANTS.MINUTE;\n case 'hour':\n return TIME_CONSTANTS.HOUR;\n case 'day':\n return TIME_CONSTANTS.DAY;\n case 'week':\n return TIME_CONSTANTS.WEEK;\n case 'month':\n return TIME_CONSTANTS.MONTH;\n case 'quarter':\n return TIME_CONSTANTS.QUARTER;\n case 'year':\n return TIME_CONSTANTS.YEAR;\n default:\n return TIME_CONSTANTS.DAY; // Default fallback\n }\n};\n"],"names":["defaultBarChartOptions","chartjsOptions","getStyle","getStyleNumber","getBarChartData","data","_a","dataset","index","colors","chartContrastColors","defaultDataset","mergician","getDatalabelTotalDisplay","context","showTotalLabels","getDatalabelTotalFormatter","_value","datasets","i","total","sum","ds","val","getBarVerticalChartOptions","config","getBarHorizontalChartOptions","getBarChartOptions","props","horizontal","showLegend","showTooltips","showValueLabels","options","ChartJS","CategoryScale","LinearScale","BarElement","LogarithmicScale","Title","Tooltip","Legend","BarChart","onSegmentClick","chartRef","useRef","barChartOptions","handleSegmentClick","event","indexClicked","getSegmentIndexClicked","jsx","styles","Bar","getBarStackedChartProData","theme","themeFormatter","getThemeFormatter","dimension","groupDimension","measure","axis","groupBy","themeKey","getObjectStableKey","groupByItem","backgroundColor","getColor","borderColor","axisItem","record","d","getBarChartProData","remarkableTheme","groupedData","groupTailAsOther","item","value","formattedValue","i18n","chartColors","getBarChartProDatalabelTotalFormatter","formatter","getBarChartProOptions","onBarClicked","raw","_event","elements","chart","element","axisDimensionValue","groupingDimensionValue","DATE_FORMATS","granularityToDayjsUnitMap","formatDateAsString","date","formatDateAsStringUTC","isUTCDate","formatDateString","getQuarterStart","applyGranularityBounds","granularity","unit","granularityToDayjsUnit","resolveDateBounds","dateBounds","relativeTimeString","matchedOption","_b","option","range","fillGaps","sortOrder","resolvedDateBounds","dimensionName","getGranularityDimensionName","validData","dateValue","parsedDate","dayjs","minDate","maxDate","fromDate","toDate","fromDateStr","toDateStr","firstRecord","min","max","allDates","dayjsUnit","minDateStart","maxDateStart","currentDate","existingDataMap","dateKey","generateDateKey","result","existingRecord","cleanRecord","dateFormat","getDateFormatFromSample","formattedDate","formatDateForGapRecord","gapRecord","baseDimensionName","sampleRecord","key","a","b","granularityKey","useChartDataWithFillGaps","results","useTheme","useMemo","effectiveGranularity","detectGranularityFromData","shouldApplyFillGaps","error","dates","dateStr","expectedStepMs","getGranularityStepMs","previousDate","granularityKeys","SECOND","MINUTE","HOUR","DAY","TIME_CONSTANTS"],"mappings":"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"}