@classic-homes/charts-react 0.2.2 → 0.3.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.
package/dist/index.cjs CHANGED
@@ -34,6 +34,7 @@ __export(index_exports, {
34
34
  BarChart: () => BarChart,
35
35
  CandlestickChart: () => CandlestickChart,
36
36
  ChartContainer: () => ChartContainer,
37
+ ChartDataTable: () => ChartDataTable,
37
38
  ChartEmpty: () => ChartEmpty,
38
39
  ChartError: () => ChartError,
39
40
  ChartLegend: () => ChartLegend,
@@ -49,7 +50,9 @@ __export(index_exports, {
49
50
  ScatterChart: () => ScatterChart,
50
51
  TreemapChart: () => TreemapChart,
51
52
  cn: () => cn,
53
+ exportChartImage: () => exportChartImage,
52
54
  registerClassicThemes: () => registerClassicThemes,
55
+ registerEchartsModules: () => registerEchartsModules,
53
56
  useChart: () => useChart,
54
57
  useChartLegend: () => useChartLegend,
55
58
  useChartResize: () => useChartResize,
@@ -60,6 +63,7 @@ module.exports = __toCommonJS(index_exports);
60
63
 
61
64
  // src/components/base/ChartContainer.tsx
62
65
  var React4 = __toESM(require("react"), 1);
66
+ var import_charts_core2 = require("@classic-homes/charts-core");
63
67
 
64
68
  // src/lib/utils.ts
65
69
  var import_clsx = require("clsx");
@@ -143,7 +147,7 @@ var ChartError = React2.forwardRef(
143
147
  {
144
148
  type: "button",
145
149
  onClick: onRetry,
146
- className: "rounded-md bg-destructive px-3 py-1.5 text-xs font-medium text-destructive-foreground transition-colors hover:bg-destructive/90",
150
+ className: "rounded-md bg-destructive px-3 py-1.5 text-xs font-medium text-destructive-foreground hover:bg-destructive/90",
147
151
  children: "Retry"
148
152
  }
149
153
  )
@@ -199,20 +203,62 @@ var ChartEmpty = React3.forwardRef(
199
203
  );
200
204
  ChartEmpty.displayName = "ChartEmpty";
201
205
 
202
- // src/components/base/ChartContainer.tsx
206
+ // src/components/base/ChartDataTable.tsx
207
+ var import_charts_core = require("@classic-homes/charts-core");
203
208
  var import_jsx_runtime4 = require("react/jsx-runtime");
209
+ function ChartDataTable({
210
+ table,
211
+ caption,
212
+ format,
213
+ srOnly = false,
214
+ className
215
+ }) {
216
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
217
+ "div",
218
+ {
219
+ "data-testid": "chart-data-table",
220
+ className: cn(srOnly ? "sr-only" : "max-h-80 overflow-auto", className),
221
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("table", { className: "w-full border-collapse text-sm", children: [
222
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("caption", { className: srOnly ? void 0 : "sr-only", children: caption }),
223
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("tr", { children: table.headers.map((header, column) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
224
+ "th",
225
+ {
226
+ scope: "col",
227
+ className: cn(
228
+ "sticky top-0 border-b border-border bg-card px-3 py-2 font-medium text-muted-foreground",
229
+ column === 0 ? "text-left" : "text-right"
230
+ ),
231
+ children: header
232
+ },
233
+ column
234
+ )) }) }),
235
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("tbody", { children: table.rows.map((row, rowIndex) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("tr", { className: "border-b border-border last:border-0", children: row.map(
236
+ (cell, column) => column === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
237
+ "th",
238
+ {
239
+ scope: "row",
240
+ className: "px-3 py-1.5 text-left font-normal text-foreground",
241
+ children: (0, import_charts_core.formatTableCell)(table, cell, column, format)
242
+ },
243
+ column
244
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("td", { className: "px-3 py-1.5 text-right tabular-nums text-foreground", children: (0, import_charts_core.formatTableCell)(table, cell, column, format) }, column)
245
+ ) }, rowIndex)) })
246
+ ] })
247
+ }
248
+ );
249
+ }
250
+
251
+ // src/components/base/ChartContainer.tsx
252
+ var import_jsx_runtime5 = require("react/jsx-runtime");
204
253
  var CHART_ONLY_PROPS = [
205
- "minHeight",
206
- "maxHeight",
207
254
  "rowHeight",
208
255
  "showLegend",
209
256
  "showGrid",
210
257
  "valueFormat",
211
258
  "locale",
212
259
  "onReady",
260
+ "onHover",
213
261
  "events",
214
- "showDataTable",
215
- "exportable",
216
262
  "patterns",
217
263
  "referenceLines",
218
264
  "referenceBands",
@@ -225,11 +271,15 @@ function domProps(props) {
225
271
  for (const key of CHART_ONLY_PROPS) delete rest[key];
226
272
  return rest;
227
273
  }
274
+ var SR_TABLE_MAX_ROWS = 500;
275
+ var buttonClass = "rounded-md px-2 py-1 text-xs font-medium text-muted-foreground hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring";
228
276
  var ChartContainer = React4.forwardRef(
229
277
  ({
230
278
  title,
231
279
  description,
232
280
  height = 400,
281
+ minHeight,
282
+ maxHeight,
233
283
  loading,
234
284
  error,
235
285
  empty,
@@ -239,16 +289,24 @@ var ChartContainer = React4.forwardRef(
239
289
  wrapperClassName,
240
290
  legend,
241
291
  legendPosition = "bottom",
292
+ dataTable,
293
+ showDataTable = "sr-only",
294
+ format,
295
+ exportable,
296
+ exportImage,
242
297
  children,
243
298
  ...props
244
299
  }, ref) => {
245
300
  const heightStyle = typeof height === "number" ? `${height}px` : height;
246
- const descriptionId = `${React4.useId()}-desc`;
301
+ const uid = React4.useId();
302
+ const descriptionId = `${uid}-desc`;
303
+ const tableId = `${uid}-table`;
304
+ const [tableOpen, setTableOpen] = React4.useState(false);
247
305
  if (loading) {
248
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ChartSkeleton, { height, className: wrapperClassName });
306
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ChartSkeleton, { height, className: wrapperClassName });
249
307
  }
250
308
  if (error) {
251
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
309
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
252
310
  ChartError,
253
311
  {
254
312
  message: error,
@@ -259,9 +317,19 @@ var ChartContainer = React4.forwardRef(
259
317
  );
260
318
  }
261
319
  if (empty) {
262
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ChartEmpty, { message: emptyMessage, height, className: wrapperClassName });
320
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ChartEmpty, { message: emptyMessage, height, className: wrapperClassName });
263
321
  }
264
- const chart = /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
322
+ const exportConfig = exportable ? exportable === true ? {} : exportable : void 0;
323
+ const canExportImage = !!exportConfig && exportConfig.image !== false && !!exportImage;
324
+ const canExportCsv = !!exportConfig && exportConfig.csv !== false && !!dataTable;
325
+ const filename = exportConfig?.filename ?? (0, import_charts_core2.chartFilename)(title);
326
+ const toggleTable = showDataTable === true && !!dataTable;
327
+ const toolbar = canExportImage || canExportCsv || toggleTable;
328
+ const downloadImage = () => {
329
+ const url = exportImage?.();
330
+ if (url) (0, import_charts_core2.downloadFile)(url, `${filename}.png`);
331
+ };
332
+ const chart = (chartClassName) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
265
333
  "div",
266
334
  {
267
335
  ref,
@@ -269,37 +337,95 @@ var ChartContainer = React4.forwardRef(
269
337
  "aria-label": title,
270
338
  "aria-describedby": description ? descriptionId : void 0,
271
339
  "data-testid": "chart-container",
272
- className: legend ? "min-h-0 min-w-0 flex-1" : cn("rounded-lg border border-border bg-card", wrapperClassName),
340
+ className: chartClassName,
273
341
  ...domProps(props),
274
342
  children: [
275
- description && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { id: descriptionId, className: "sr-only", children: description }),
276
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: cn("h-full w-full", className), style: { height: heightStyle }, children })
343
+ description && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { id: descriptionId, className: "sr-only", children: description }),
344
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
345
+ "div",
346
+ {
347
+ className: cn("h-full w-full", className),
348
+ style: {
349
+ height: heightStyle,
350
+ minHeight: minHeight !== void 0 ? `${minHeight}px` : void 0,
351
+ maxHeight: maxHeight !== void 0 ? `${maxHeight}px` : void 0
352
+ },
353
+ children
354
+ }
355
+ )
277
356
  ]
278
357
  }
279
358
  );
280
- if (!legend) return chart;
359
+ const srTable = dataTable && showDataTable === "sr-only" && dataTable.rows.length <= SR_TABLE_MAX_ROWS ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ChartDataTable, { table: dataTable, caption: `${title} data`, format, srOnly: true }) : null;
360
+ if (!legend && !toolbar) {
361
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
362
+ chart(cn("rounded-lg border border-border bg-card", wrapperClassName)),
363
+ srTable
364
+ ] });
365
+ }
281
366
  const side = legendPosition === "left" || legendPosition === "right";
282
367
  const leading = legendPosition === "top" || legendPosition === "left";
283
- const legendNode = /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
368
+ const legendNode = legend ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
284
369
  "div",
285
370
  {
286
371
  "data-testid": "chart-legend",
287
372
  className: cn("flex shrink-0 p-2", side ? "items-center" : "justify-center"),
288
373
  children: legend
289
374
  }
290
- );
291
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
375
+ ) : null;
376
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
292
377
  "div",
293
378
  {
294
- className: cn(
295
- "flex rounded-lg border border-border bg-card",
296
- side ? "flex-row" : "flex-col",
297
- wrapperClassName
298
- ),
379
+ "data-testid": "chart-frame",
380
+ className: cn("flex flex-col rounded-lg border border-border bg-card", wrapperClassName),
299
381
  children: [
300
- leading && legendNode,
301
- chart,
302
- !leading && legendNode
382
+ toolbar && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
383
+ "div",
384
+ {
385
+ "data-testid": "chart-toolbar",
386
+ className: "flex justify-end gap-1 px-2 pt-2 print:hidden",
387
+ children: [
388
+ toggleTable && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
389
+ "button",
390
+ {
391
+ type: "button",
392
+ className: buttonClass,
393
+ "aria-expanded": tableOpen,
394
+ "aria-controls": tableId,
395
+ onClick: () => setTableOpen((open) => !open),
396
+ children: tableOpen ? "Hide data" : "Show data"
397
+ }
398
+ ),
399
+ canExportImage && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
400
+ "button",
401
+ {
402
+ type: "button",
403
+ className: buttonClass,
404
+ "aria-label": `Download ${title} as PNG`,
405
+ onClick: downloadImage,
406
+ children: "PNG"
407
+ }
408
+ ),
409
+ canExportCsv && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
410
+ "button",
411
+ {
412
+ type: "button",
413
+ className: buttonClass,
414
+ "aria-label": `Download ${title} data as CSV`,
415
+ onClick: () => (0, import_charts_core2.downloadCsv)(dataTable, filename),
416
+ children: "CSV"
417
+ }
418
+ )
419
+ ]
420
+ }
421
+ ),
422
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: cn("flex min-h-0 flex-1", side ? "flex-row" : "flex-col"), children: [
423
+ leading && legendNode,
424
+ chart("min-h-0 min-w-0 flex-1"),
425
+ !leading && legendNode
426
+ ] }),
427
+ toggleTable && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { id: tableId, hidden: !tableOpen, className: "border-t border-border p-2", children: tableOpen && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ChartDataTable, { table: dataTable, caption: `${title} data`, format }) }),
428
+ srTable
303
429
  ]
304
430
  }
305
431
  );
@@ -309,11 +435,11 @@ ChartContainer.displayName = "ChartContainer";
309
435
 
310
436
  // src/components/base/ChartLegend.tsx
311
437
  var React5 = __toESM(require("react"), 1);
312
- var import_jsx_runtime5 = require("react/jsx-runtime");
438
+ var import_jsx_runtime6 = require("react/jsx-runtime");
313
439
  var ChartLegend = React5.forwardRef(
314
440
  ({ items, toggle, position = "bottom", chartTitle, orientation, className }, ref) => {
315
441
  const vertical = (orientation ?? (position === "left" || position === "right" ? "vertical" : "horizontal")) === "vertical";
316
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
442
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
317
443
  "ul",
318
444
  {
319
445
  ref,
@@ -323,7 +449,7 @@ var ChartLegend = React5.forwardRef(
323
449
  vertical ? "flex-col" : "flex-wrap justify-center",
324
450
  className
325
451
  ),
326
- children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
452
+ children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
327
453
  "button",
328
454
  {
329
455
  type: "button",
@@ -334,7 +460,7 @@ var ChartLegend = React5.forwardRef(
334
460
  item.visible ? "text-foreground" : "text-muted-foreground line-through"
335
461
  ),
336
462
  children: [
337
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
463
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
338
464
  "span",
339
465
  {
340
466
  "aria-hidden": "true",
@@ -356,32 +482,78 @@ ChartLegend.displayName = "ChartLegend";
356
482
  var React6 = __toESM(require("react"), 1);
357
483
  var echarts3 = __toESM(require("echarts/core"), 1);
358
484
  var import_charts = require("echarts/charts");
359
- var import_components = require("echarts/components");
360
- var import_renderers = require("echarts/renderers");
361
- var import_charts_core4 = require("@classic-homes/charts-core");
485
+ var import_components2 = require("echarts/components");
486
+ var import_renderers2 = require("echarts/renderers");
487
+ var import_charts_core6 = require("@classic-homes/charts-core");
488
+
489
+ // src/lib/events.ts
490
+ var raw = (params) => params ?? {};
491
+ function toDataPointParams(params, fallbackType) {
492
+ const p = raw(params);
493
+ return {
494
+ type: p.type || fallbackType,
495
+ componentType: p.componentType || "series",
496
+ seriesIndex: p.seriesIndex,
497
+ seriesName: p.seriesName || "",
498
+ dataIndex: p.dataIndex ?? 0,
499
+ name: p.name || "",
500
+ value: p.value,
501
+ color: typeof p.color === "string" ? p.color : void 0,
502
+ event: p.event?.event
503
+ };
504
+ }
505
+ function toSliceParams(params, fallbackType) {
506
+ const p = raw(params);
507
+ return {
508
+ type: p.type || fallbackType,
509
+ componentType: p.componentType || "series",
510
+ seriesIndex: p.seriesIndex,
511
+ seriesName: p.seriesName,
512
+ dataIndex: p.dataIndex,
513
+ name: p.name || "",
514
+ value: p.value,
515
+ percent: p.percent,
516
+ color: typeof p.color === "string" ? p.color : void 0,
517
+ event: p.event?.event
518
+ };
519
+ }
520
+ function chartEvents(events, mapped) {
521
+ const merged = { ...events };
522
+ for (const [name, handler] of Object.entries(mapped)) {
523
+ if (!handler) continue;
524
+ const own = events?.[name];
525
+ merged[name] = own ? (params) => {
526
+ handler(params);
527
+ own(params);
528
+ } : handler;
529
+ }
530
+ return merged;
531
+ }
362
532
 
363
533
  // src/hooks/useChart.ts
364
534
  var import_react4 = require("react");
365
535
  var echarts2 = __toESM(require("echarts/core"), 1);
366
- var import_charts_core2 = require("@classic-homes/charts-core");
536
+ var import_components = require("echarts/components");
537
+ var import_renderers = require("echarts/renderers");
538
+ var import_charts_core4 = require("@classic-homes/charts-core");
367
539
 
368
540
  // src/hooks/useChartTheme.ts
369
541
  var import_react = require("react");
370
542
  var echarts = __toESM(require("echarts/core"), 1);
371
- var import_charts_core = require("@classic-homes/charts-core");
543
+ var import_charts_core3 = require("@classic-homes/charts-core");
372
544
  var themesRegistered = false;
373
545
  function registerClassicThemes() {
374
546
  if (themesRegistered) return;
375
- echarts.registerTheme(import_charts_core.THEME_LIGHT, import_charts_core.lightTheme);
376
- echarts.registerTheme(import_charts_core.THEME_DARK, import_charts_core.darkTheme);
547
+ echarts.registerTheme(import_charts_core3.THEME_LIGHT, import_charts_core3.lightTheme);
548
+ echarts.registerTheme(import_charts_core3.THEME_DARK, import_charts_core3.darkTheme);
377
549
  themesRegistered = true;
378
550
  }
379
551
  function resolveTheme(preference) {
380
552
  if (preference !== "auto") {
381
- return preference === "dark" ? import_charts_core.THEME_DARK : import_charts_core.THEME_LIGHT;
553
+ return preference === "dark" ? import_charts_core3.THEME_DARK : import_charts_core3.THEME_LIGHT;
382
554
  }
383
- if (typeof document === "undefined") return import_charts_core.THEME_LIGHT;
384
- return document.documentElement.classList.contains("dark") ? import_charts_core.THEME_DARK : import_charts_core.THEME_LIGHT;
555
+ if (typeof document === "undefined") return import_charts_core3.THEME_LIGHT;
556
+ return document.documentElement.classList.contains("dark") ? import_charts_core3.THEME_DARK : import_charts_core3.THEME_LIGHT;
385
557
  }
386
558
  function useChartTheme(preference = "auto") {
387
559
  const [currentTheme, setCurrentTheme] = (0, import_react.useState)(() => resolveTheme(preference));
@@ -459,64 +631,141 @@ function useReducedMotion() {
459
631
  }
460
632
 
461
633
  // src/hooks/useChart.ts
634
+ echarts2.use([
635
+ import_components.AriaComponent,
636
+ import_components.DataZoomInsideComponent,
637
+ import_components.DataZoomSliderComponent,
638
+ import_components.DatasetComponent,
639
+ import_components.GraphicComponent,
640
+ import_components.MarkAreaComponent,
641
+ import_components.MarkLineComponent,
642
+ import_renderers.CanvasRenderer
643
+ ]);
644
+ var registerEchartsModules = (modules) => echarts2.use(modules);
645
+ function exportChartImage(chart, { type = "png", pixelRatio = 2, backgroundColor } = {}) {
646
+ if (!chart || chart.isDisposed()) return null;
647
+ const background = backgroundColor ?? (typeof document !== "undefined" ? getComputedStyle(chart.getDom()).getPropertyValue("--card").trim() : "");
648
+ const color = !background ? "#ffffff" : /^[\d.]+\s/.test(background) ? `hsl(${background})` : background;
649
+ return chart.getDataURL({ type, pixelRatio, backgroundColor: color });
650
+ }
462
651
  var isComponentType = (mainType) => echarts2.ComponentModel.hasClass(mainType);
463
652
  function applyOption(chart, prev, next) {
464
653
  chart.setOption(next, {
465
- replaceMerge: (0, import_charts_core2.getReplaceMerge)(prev, next, isComponentType),
654
+ replaceMerge: (0, import_charts_core4.getReplaceMerge)(prev, next, isComponentType),
466
655
  lazyUpdate: true
467
656
  });
468
657
  }
658
+ function captureState(chart) {
659
+ if (chart.isDisposed()) return null;
660
+ const option = chart.getOption();
661
+ const selected = option.legend?.[0]?.selected ?? {};
662
+ return {
663
+ hidden: Object.keys(selected).filter((name) => selected[name] === false),
664
+ zoom: (option.dataZoom ?? []).map(({ start, end }) => ({ start, end }))
665
+ };
666
+ }
667
+ function restoreState(chart, state) {
668
+ if (!state) return;
669
+ for (const name of state.hidden) chart.dispatchAction({ type: "legendUnSelect", name });
670
+ state.zoom.forEach(({ start, end }, dataZoomIndex) => {
671
+ if (start !== void 0 && end !== void 0 && (start !== 0 || end !== 100)) {
672
+ chart.dispatchAction({ type: "dataZoom", dataZoomIndex, start, end });
673
+ }
674
+ });
675
+ }
469
676
  function useChart({
470
677
  option,
471
678
  theme = "auto",
472
679
  animation,
473
- onReady
680
+ patterns,
681
+ events,
682
+ onReady,
683
+ onCreated
474
684
  }) {
475
685
  const containerRef = (0, import_react4.useRef)(null);
476
686
  const container = useRefElement(containerRef);
477
687
  const chartRef = (0, import_react4.useRef)(null);
688
+ const [chart, setChart] = (0, import_react4.useState)(null);
478
689
  const currentTheme = useChartTheme(theme);
479
690
  const reducedMotion = useReducedMotion();
480
691
  const onReadyRef = (0, import_react4.useRef)(onReady);
481
692
  onReadyRef.current = onReady;
693
+ const onCreatedRef = (0, import_react4.useRef)(onCreated);
694
+ onCreatedRef.current = onCreated;
695
+ const eventsRef = (0, import_react4.useRef)(events);
696
+ eventsRef.current = events;
482
697
  const optionRef = (0, import_react4.useRef)(option);
483
698
  optionRef.current = {
484
699
  ...option,
485
700
  // Reduced motion always wins over the animation prop
486
- animation: (animation ?? true) && !reducedMotion
701
+ animation: (animation ?? true) && !reducedMotion,
702
+ // Labels stay off: the container already describes the chart
703
+ ...patterns && {
704
+ aria: { enabled: true, label: { enabled: false }, decal: { show: true } }
705
+ }
487
706
  };
488
707
  const appliedRef = (0, import_react4.useRef)(null);
708
+ const carriedRef = (0, import_react4.useRef)(null);
489
709
  (0, import_react4.useEffect)(() => {
490
710
  if (!container) return;
491
- const chart = echarts2.init(container, currentTheme);
492
- chartRef.current = chart;
493
- applyOption(chart, null, optionRef.current);
711
+ const instance = echarts2.init(container, currentTheme);
712
+ chartRef.current = instance;
713
+ onReadyRef.current?.(instance);
714
+ applyOption(instance, null, optionRef.current);
494
715
  appliedRef.current = optionRef.current;
495
- onReadyRef.current?.(chart);
716
+ const carried = carriedRef.current;
717
+ carriedRef.current = null;
718
+ if (carried) instance.setOption({}, { lazyUpdate: false });
719
+ restoreState(instance, carried);
720
+ onCreatedRef.current?.(instance);
721
+ setChart(instance);
496
722
  return () => {
497
- chart.dispose();
498
- if (chartRef.current === chart) {
723
+ carriedRef.current = captureState(instance);
724
+ instance.dispose();
725
+ if (chartRef.current === instance) {
499
726
  chartRef.current = null;
500
727
  }
728
+ setChart((current) => current === instance ? null : current);
501
729
  };
502
730
  }, [container, currentTheme]);
503
731
  (0, import_react4.useEffect)(() => {
504
- const chart = chartRef.current;
505
- if (!chart || chart.isDisposed()) return;
506
- applyOption(chart, appliedRef.current, optionRef.current);
732
+ const instance = chartRef.current;
733
+ if (!instance || instance.isDisposed()) return;
734
+ applyOption(instance, appliedRef.current, optionRef.current);
507
735
  appliedRef.current = optionRef.current;
508
- }, [option, animation, reducedMotion]);
736
+ }, [option, animation, reducedMotion, patterns]);
737
+ const eventNames = JSON.stringify(
738
+ Object.keys(events ?? {}).filter((name) => events?.[name]).sort()
739
+ );
740
+ (0, import_react4.useEffect)(() => {
741
+ if (!chart || chart.isDisposed()) return;
742
+ const bound = JSON.parse(eventNames).map((name) => {
743
+ const listener = (params) => eventsRef.current?.[name]?.(params);
744
+ chart.on(name, listener);
745
+ return [name, listener];
746
+ });
747
+ return () => {
748
+ if (chart.isDisposed()) return;
749
+ for (const [name, listener] of bound) chart.off(name, listener);
750
+ };
751
+ }, [chart, eventNames]);
509
752
  useChartResize(chartRef, containerRef);
753
+ const exportImage = (0, import_react4.useCallback)(
754
+ (options) => exportChartImage(chartRef.current, options),
755
+ []
756
+ );
510
757
  return {
511
758
  chartRef,
512
759
  containerRef,
513
- currentTheme
760
+ chart,
761
+ currentTheme,
762
+ exportImage
514
763
  };
515
764
  }
516
765
 
517
766
  // src/hooks/useChartLegend.ts
518
767
  var import_react6 = require("react");
519
- var import_charts_core3 = require("@classic-homes/charts-core");
768
+ var import_charts_core5 = require("@classic-homes/charts-core");
520
769
 
521
770
  // src/hooks/useLatestRef.ts
522
771
  var import_react5 = require("react");
@@ -565,7 +814,7 @@ function useChartLegend({
565
814
  return {
566
815
  attach,
567
816
  renderProps: {
568
- items: (0, import_charts_core3.getLegendItems)(names, palette, colors, visible),
817
+ items: (0, import_charts_core5.getLegendItems)(names, palette, colors, visible),
569
818
  position: config?.position ?? "bottom",
570
819
  chartTitle: title,
571
820
  toggle: (name) => dispatch({ type: "legendToggleSelect", name }),
@@ -581,14 +830,14 @@ function useChartLegend({
581
830
  }
582
831
 
583
832
  // src/components/core/LineChart.tsx
584
- var import_jsx_runtime6 = require("react/jsx-runtime");
833
+ var import_jsx_runtime7 = require("react/jsx-runtime");
585
834
  echarts3.use([
586
835
  import_charts.LineChart,
587
- import_components.GridComponent,
588
- import_components.TooltipComponent,
589
- import_components.LegendComponent,
590
- import_components.TitleComponent,
591
- import_renderers.CanvasRenderer
836
+ import_components2.GridComponent,
837
+ import_components2.TooltipComponent,
838
+ import_components2.LegendComponent,
839
+ import_components2.TitleComponent,
840
+ import_renderers2.CanvasRenderer
592
841
  ]);
593
842
  var LineChart = React6.forwardRef(
594
843
  ({
@@ -596,6 +845,8 @@ var LineChart = React6.forwardRef(
596
845
  description,
597
846
  data,
598
847
  height = 400,
848
+ minHeight,
849
+ maxHeight,
599
850
  loading,
600
851
  error,
601
852
  emptyMessage,
@@ -608,24 +859,36 @@ var LineChart = React6.forwardRef(
608
859
  areaFilled = false,
609
860
  showDataPoints = false,
610
861
  stacked = false,
862
+ connectNulls = false,
611
863
  showLabels = false,
864
+ valueFormat,
865
+ locale,
612
866
  labelFormatter,
613
867
  xAxisConfig,
614
868
  yAxisConfig,
869
+ referenceLines,
870
+ referenceBands,
871
+ dataZoom,
615
872
  tooltipFormatter,
616
873
  tooltipValueFormatter,
617
874
  legend: legendConfig,
618
875
  renderLegend,
619
876
  onLegendChange,
620
877
  option: optionOverride,
878
+ onReady,
879
+ events,
880
+ showDataTable,
881
+ exportable,
882
+ patterns,
621
883
  onClick,
622
884
  onHover,
623
885
  class: className,
624
886
  ...props
625
887
  }, ref) => {
626
888
  const isEmpty = !data?.categories?.length || !data?.series?.length || data.series.every((s) => !s.data?.length);
889
+ const isPercent = stacked === "percent";
627
890
  const currentTheme = useChartTheme(theme);
628
- const chartColors = (0, import_charts_core4.getChartColors)(currentTheme);
891
+ const chartColors = (0, import_charts_core6.getChartColors)(currentTheme);
629
892
  const legend = useChartLegend({
630
893
  names: data?.series?.map((s) => s.name) ?? [],
631
894
  colors: data?.series?.map((s) => s.color) ?? [],
@@ -635,20 +898,55 @@ var LineChart = React6.forwardRef(
635
898
  onLegendChange
636
899
  });
637
900
  const customLegend = renderLegend !== void 0;
901
+ const builtInLegend = showLegend && !customLegend;
638
902
  const option = React6.useMemo(() => {
639
903
  if (isEmpty) return {};
640
- const getLabel = (0, import_charts_core4.seriesLabelLookup)(data.series);
641
- const showSymbol = showDataPoints || showLabels || (0, import_charts_core4.hasPointLabels)(data.series);
642
- return (0, import_charts_core4.mergeChartOption)(
904
+ const formatters = (0, import_charts_core6.chartFormatters)({
905
+ valueFormat: isPercent ? "percentValue" : valueFormat,
906
+ locale,
907
+ tooltipValueFormatter,
908
+ labelFormatter
909
+ });
910
+ const plotted = isPercent ? (0, import_charts_core6.toPercentStack)(data.series) : data.series;
911
+ const getLabel = (0, import_charts_core6.seriesLabelLookup)(data.series);
912
+ const showSymbol = showDataPoints || showLabels || (0, import_charts_core6.hasPointLabels)(data.series);
913
+ const legendBottom = builtInLegend && (legendConfig?.position ?? "bottom") === "bottom";
914
+ const series = data.series.map((source, index) => ({
915
+ name: source.name,
916
+ type: "line",
917
+ data: (0, import_charts_core6.withPointLabels)(plotted[index].data, source.labels, formatters.label, {
918
+ position: "top"
919
+ }),
920
+ smooth,
921
+ showSymbol,
922
+ symbolSize: showDataPoints ? 6 : 0,
923
+ connectNulls,
924
+ stack: stacked ? "Total" : void 0,
925
+ areaStyle: areaFilled ? { opacity: 0.3 } : void 0,
926
+ itemStyle: source.color ? { color: source.color } : void 0,
927
+ label: (0, import_charts_core6.buildDataLabel)({ show: true, position: "top" }, void 0, {
928
+ show: showLabels,
929
+ formatter: formatters.label,
930
+ getLabel
931
+ }),
932
+ emphasis: {
933
+ focus: "series"
934
+ }
935
+ }));
936
+ return (0, import_charts_core6.mergeChartOption)(
643
937
  {
644
938
  grid: {
645
939
  left: "3%",
646
940
  right: "4%",
647
941
  bottom: "3%",
648
942
  containLabel: true,
649
- ...(0, import_charts_core4.gridInset)(legendConfig, showLegend && !customLegend, xAxisConfig, yAxisConfig)
943
+ ...(0, import_charts_core6.withZoomInset)(
944
+ (0, import_charts_core6.gridInset)(legendConfig, builtInLegend, xAxisConfig, yAxisConfig),
945
+ dataZoom,
946
+ "x"
947
+ )
650
948
  },
651
- tooltip: (0, import_charts_core4.buildTooltip)(
949
+ tooltip: (0, import_charts_core6.buildTooltip)(
652
950
  {
653
951
  trigger: "axis",
654
952
  axisPointer: {
@@ -661,16 +959,17 @@ var LineChart = React6.forwardRef(
661
959
  {
662
960
  show: showTooltip,
663
961
  formatter: tooltipFormatter,
664
- valueFormatter: tooltipValueFormatter,
962
+ valueFormatter: formatters.tooltip,
665
963
  getLabel
666
964
  }
667
965
  ),
668
- legend: (0, import_charts_core4.buildLegend)(
966
+ legend: (0, import_charts_core6.buildLegend)(
669
967
  data.series.map((s) => s.name),
670
968
  legendConfig,
671
969
  { show: showLegend, custom: customLegend }
672
970
  ),
673
- xAxis: (0, import_charts_core4.buildAxis)(
971
+ dataZoom: (0, import_charts_core6.buildDataZoom)(dataZoom, "x", legendBottom ? 36 : 0),
972
+ xAxis: (0, import_charts_core6.buildAxis)(
674
973
  {
675
974
  type: "category",
676
975
  boundaryGap: false,
@@ -681,34 +980,22 @@ var LineChart = React6.forwardRef(
681
980
  },
682
981
  xAxisConfig
683
982
  ),
684
- yAxis: (0, import_charts_core4.buildAxis)(
983
+ yAxis: (0, import_charts_core6.buildAxis)(
685
984
  {
686
985
  type: "value",
986
+ ...isPercent && { max: 100 },
687
987
  splitLine: {
688
988
  show: showGrid
689
989
  }
690
990
  },
691
- yAxisConfig
991
+ formatters.axis(yAxisConfig)
692
992
  ),
693
- series: data.series.map((series) => ({
694
- name: series.name,
695
- type: "line",
696
- data: (0, import_charts_core4.withPointLabels)(series.data, series.labels, labelFormatter, { position: "top" }),
697
- smooth,
698
- showSymbol,
699
- symbolSize: showDataPoints ? 6 : 0,
700
- stack: stacked ? "Total" : void 0,
701
- areaStyle: areaFilled ? { opacity: 0.3 } : void 0,
702
- itemStyle: series.color ? { color: series.color } : void 0,
703
- label: (0, import_charts_core4.buildDataLabel)({ show: true, position: "top" }, void 0, {
704
- show: showLabels,
705
- formatter: labelFormatter,
706
- getLabel
707
- }),
708
- emphasis: {
709
- focus: "series"
710
- }
711
- }))
993
+ series: (0, import_charts_core6.withReferenceMarks)(series, referenceLines, referenceBands, {
994
+ valueAxis: "y",
995
+ format: formatters.format,
996
+ color: chartColors.reference,
997
+ bandColor: chartColors.referenceBand
998
+ })
712
999
  },
713
1000
  optionOverride
714
1001
  );
@@ -722,62 +1009,48 @@ var LineChart = React6.forwardRef(
722
1009
  areaFilled,
723
1010
  showDataPoints,
724
1011
  stacked,
1012
+ isPercent,
1013
+ connectNulls,
725
1014
  chartColors,
726
1015
  showLabels,
1016
+ valueFormat,
1017
+ locale,
727
1018
  labelFormatter,
728
1019
  xAxisConfig,
729
1020
  yAxisConfig,
1021
+ referenceLines,
1022
+ referenceBands,
1023
+ dataZoom,
730
1024
  tooltipFormatter,
731
1025
  tooltipValueFormatter,
732
1026
  legendConfig,
733
1027
  customLegend,
1028
+ builtInLegend,
734
1029
  optionOverride
735
1030
  ]);
736
- const latest = useLatestRef({ onClick, onHover });
737
- const { containerRef } = useChart({
1031
+ const { containerRef, exportImage } = useChart({
738
1032
  option,
739
- theme: currentTheme === import_charts_core4.THEME_DARK ? "dark" : "light",
1033
+ theme: currentTheme === import_charts_core6.THEME_DARK ? "dark" : "light",
740
1034
  animation,
741
- onReady: (chart) => {
742
- legend.attach(chart);
743
- chart.on("click", (params) => {
744
- const { onClick: onClick2 } = latest.current;
745
- if (!onClick2) return;
746
- onClick2({
747
- type: params.type || "click",
748
- componentType: params.componentType || "series",
749
- seriesIndex: params.seriesIndex,
750
- seriesName: params.seriesName || "",
751
- dataIndex: params.dataIndex || 0,
752
- name: params.name || "",
753
- value: params.value,
754
- color: params.color
755
- });
756
- });
757
- chart.on("mouseover", (params) => {
758
- const { onHover: onHover2 } = latest.current;
759
- if (!onHover2) return;
760
- onHover2({
761
- type: params.type || "mouseover",
762
- componentType: params.componentType || "series",
763
- seriesIndex: params.seriesIndex,
764
- seriesName: params.seriesName || "",
765
- dataIndex: params.dataIndex || 0,
766
- name: params.name || "",
767
- value: params.value,
768
- color: params.color
769
- });
770
- });
771
- }
1035
+ patterns,
1036
+ events: chartEvents(events, {
1037
+ click: onClick && ((params) => onClick(toDataPointParams(params, "click"))),
1038
+ mouseover: onHover && ((params) => onHover(toDataPointParams(params, "mouseover")))
1039
+ }),
1040
+ onReady: legend.attach,
1041
+ onCreated: onReady
772
1042
  });
773
- const accessibilityDescription = description || (!isEmpty ? (0, import_charts_core4.generateLineChartDescription)(title, data) : void 0);
774
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1043
+ const format = (0, import_charts_core6.resolveValueFormatter)(valueFormat, locale);
1044
+ const accessibilityDescription = description || (!isEmpty ? (0, import_charts_core6.generateLineChartDescription)(title, data, format) : void 0);
1045
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
775
1046
  ChartContainer,
776
1047
  {
777
1048
  ref,
778
1049
  title,
779
1050
  description: accessibilityDescription,
780
1051
  height,
1052
+ minHeight,
1053
+ maxHeight,
781
1054
  loading,
782
1055
  error,
783
1056
  empty: isEmpty,
@@ -785,8 +1058,13 @@ var LineChart = React6.forwardRef(
785
1058
  className: cn(className),
786
1059
  legend: !isEmpty && renderLegend ? renderLegend(legend.renderProps) : void 0,
787
1060
  legendPosition: legendConfig?.position,
1061
+ dataTable: isEmpty ? void 0 : (0, import_charts_core6.categoryTable)(data),
1062
+ showDataTable,
1063
+ format,
1064
+ exportable,
1065
+ exportImage,
788
1066
  ...props,
789
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { ref: containerRef, className: "h-full w-full" })
1067
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { ref: containerRef, className: "h-full w-full" })
790
1068
  }
791
1069
  );
792
1070
  }
@@ -797,17 +1075,17 @@ LineChart.displayName = "LineChart";
797
1075
  var React7 = __toESM(require("react"), 1);
798
1076
  var echarts4 = __toESM(require("echarts/core"), 1);
799
1077
  var import_charts2 = require("echarts/charts");
800
- var import_components2 = require("echarts/components");
801
- var import_renderers2 = require("echarts/renderers");
802
- var import_charts_core5 = require("@classic-homes/charts-core");
803
- var import_jsx_runtime7 = require("react/jsx-runtime");
1078
+ var import_components3 = require("echarts/components");
1079
+ var import_renderers3 = require("echarts/renderers");
1080
+ var import_charts_core7 = require("@classic-homes/charts-core");
1081
+ var import_jsx_runtime8 = require("react/jsx-runtime");
804
1082
  echarts4.use([
805
1083
  import_charts2.BarChart,
806
- import_components2.GridComponent,
807
- import_components2.TooltipComponent,
808
- import_components2.LegendComponent,
809
- import_components2.TitleComponent,
810
- import_renderers2.CanvasRenderer
1084
+ import_components3.GridComponent,
1085
+ import_components3.TooltipComponent,
1086
+ import_components3.LegendComponent,
1087
+ import_components3.TitleComponent,
1088
+ import_renderers3.CanvasRenderer
811
1089
  ]);
812
1090
  var BarChart = React7.forwardRef(
813
1091
  ({
@@ -815,6 +1093,9 @@ var BarChart = React7.forwardRef(
815
1093
  description,
816
1094
  data,
817
1095
  height = 400,
1096
+ minHeight,
1097
+ maxHeight,
1098
+ rowHeight,
818
1099
  loading,
819
1100
  error,
820
1101
  emptyMessage,
@@ -826,33 +1107,54 @@ var BarChart = React7.forwardRef(
826
1107
  orientation = "vertical",
827
1108
  stacked = false,
828
1109
  showValues = false,
1110
+ valueFormat,
1111
+ locale,
829
1112
  labelFormatter,
830
1113
  xAxisConfig,
831
1114
  yAxisConfig,
1115
+ referenceLines,
1116
+ referenceBands,
1117
+ dataZoom,
832
1118
  tooltipFormatter,
833
1119
  tooltipValueFormatter,
834
1120
  legend: legendConfig,
835
1121
  renderLegend,
836
1122
  onLegendChange,
837
1123
  option: optionOverride,
1124
+ onReady,
1125
+ events,
1126
+ showDataTable,
1127
+ exportable,
1128
+ patterns,
838
1129
  onClick,
1130
+ onHover,
839
1131
  class: className,
840
1132
  ...props
841
1133
  }, ref) => {
842
1134
  const isEmpty = !data?.categories?.length || !data?.series?.length || data.series.every((s) => !s.data?.length);
843
1135
  const isHorizontal = orientation === "horizontal";
1136
+ const isPercent = stacked === "percent";
844
1137
  const currentTheme = useChartTheme(theme);
1138
+ const chartColors = (0, import_charts_core7.getChartColors)(currentTheme);
845
1139
  const legend = useChartLegend({
846
1140
  names: data?.series?.map((s) => s.name) ?? [],
847
1141
  colors: data?.series?.map((s) => s.color) ?? [],
848
- palette: (0, import_charts_core5.getChartColors)(currentTheme).series,
1142
+ palette: chartColors.series,
849
1143
  config: legendConfig,
850
1144
  title,
851
1145
  onLegendChange
852
1146
  });
853
1147
  const customLegend = renderLegend !== void 0;
1148
+ const builtInLegend = showLegend && !customLegend;
854
1149
  const option = React7.useMemo(() => {
855
1150
  if (isEmpty) return {};
1151
+ const formatters = (0, import_charts_core7.chartFormatters)({
1152
+ valueFormat: isPercent ? "percentValue" : valueFormat,
1153
+ locale,
1154
+ tooltipValueFormatter,
1155
+ labelFormatter
1156
+ });
1157
+ const plotted = isPercent ? (0, import_charts_core7.toPercentStack)(data.series) : data.series;
856
1158
  const categoryAxis = {
857
1159
  type: "category",
858
1160
  data: data.categories,
@@ -864,21 +1166,46 @@ var BarChart = React7.forwardRef(
864
1166
  };
865
1167
  const valueAxis = {
866
1168
  type: "value",
1169
+ ...isPercent && { max: 100 },
867
1170
  splitLine: {
868
1171
  show: showGrid
869
1172
  }
870
1173
  };
871
- const getLabel = (0, import_charts_core5.seriesLabelLookup)(data.series);
872
- return (0, import_charts_core5.mergeChartOption)(
1174
+ const getLabel = (0, import_charts_core7.seriesLabelLookup)(data.series);
1175
+ const labelPosition = isHorizontal ? "right" : "top";
1176
+ const zoomAxis = isHorizontal ? "y" : "x";
1177
+ const legendBottom = builtInLegend && (legendConfig?.position ?? "bottom") === "bottom";
1178
+ const series = data.series.map((source, index) => ({
1179
+ name: source.name,
1180
+ type: "bar",
1181
+ data: (0, import_charts_core7.withPointLabels)(plotted[index].data, source.labels, formatters.label, {
1182
+ position: labelPosition
1183
+ }),
1184
+ stack: stacked ? "Total" : void 0,
1185
+ itemStyle: source.color ? { color: source.color } : void 0,
1186
+ label: (0, import_charts_core7.buildDataLabel)({ show: true, position: labelPosition }, void 0, {
1187
+ show: showValues,
1188
+ formatter: formatters.label,
1189
+ getLabel
1190
+ }),
1191
+ emphasis: {
1192
+ focus: "series"
1193
+ }
1194
+ }));
1195
+ return (0, import_charts_core7.mergeChartOption)(
873
1196
  {
874
1197
  grid: {
875
1198
  left: "3%",
876
1199
  right: "4%",
877
1200
  bottom: "3%",
878
1201
  containLabel: true,
879
- ...(0, import_charts_core5.gridInset)(legendConfig, showLegend && !customLegend, xAxisConfig, yAxisConfig)
1202
+ ...(0, import_charts_core7.withZoomInset)(
1203
+ (0, import_charts_core7.gridInset)(legendConfig, builtInLegend, xAxisConfig, yAxisConfig),
1204
+ dataZoom,
1205
+ zoomAxis
1206
+ )
880
1207
  },
881
- tooltip: (0, import_charts_core5.buildTooltip)(
1208
+ tooltip: (0, import_charts_core7.buildTooltip)(
882
1209
  {
883
1210
  trigger: "axis",
884
1211
  axisPointer: {
@@ -888,37 +1215,31 @@ var BarChart = React7.forwardRef(
888
1215
  {
889
1216
  show: showTooltip,
890
1217
  formatter: tooltipFormatter,
891
- valueFormatter: tooltipValueFormatter,
1218
+ valueFormatter: formatters.tooltip,
892
1219
  getLabel
893
1220
  }
894
1221
  ),
895
- legend: (0, import_charts_core5.buildLegend)(
1222
+ legend: (0, import_charts_core7.buildLegend)(
896
1223
  data.series.map((s) => s.name),
897
1224
  legendConfig,
898
1225
  { show: showLegend, custom: customLegend }
899
1226
  ),
900
- xAxis: (0, import_charts_core5.buildAxis)(isHorizontal ? valueAxis : categoryAxis, xAxisConfig),
901
- yAxis: (0, import_charts_core5.buildAxis)(isHorizontal ? categoryAxis : valueAxis, yAxisConfig),
902
- series: data.series.map((series) => ({
903
- name: series.name,
904
- type: "bar",
905
- data: (0, import_charts_core5.withPointLabels)(series.data, series.labels, labelFormatter, {
906
- position: isHorizontal ? "right" : "top"
907
- }),
908
- stack: stacked ? "Total" : void 0,
909
- itemStyle: series.color ? { color: series.color } : void 0,
910
- label: (0, import_charts_core5.buildDataLabel)(
911
- {
912
- show: true,
913
- position: isHorizontal ? "right" : "top"
914
- },
915
- void 0,
916
- { show: showValues, formatter: labelFormatter, getLabel }
917
- ),
918
- emphasis: {
919
- focus: "series"
920
- }
921
- }))
1227
+ dataZoom: (0, import_charts_core7.buildDataZoom)(dataZoom, zoomAxis, legendBottom ? 36 : 0),
1228
+ xAxis: (0, import_charts_core7.buildAxis)(
1229
+ isHorizontal ? valueAxis : categoryAxis,
1230
+ isHorizontal ? formatters.axis(xAxisConfig) : xAxisConfig
1231
+ ),
1232
+ yAxis: (0, import_charts_core7.buildAxis)(
1233
+ isHorizontal ? categoryAxis : valueAxis,
1234
+ isHorizontal ? yAxisConfig : formatters.axis(yAxisConfig)
1235
+ ),
1236
+ series: (0, import_charts_core7.withReferenceMarks)(series, referenceLines, referenceBands, {
1237
+ valueAxis: isHorizontal ? "x" : "y",
1238
+ inverse: isHorizontal,
1239
+ format: formatters.format,
1240
+ color: chartColors.reference,
1241
+ bandColor: chartColors.referenceBand
1242
+ })
922
1243
  },
923
1244
  optionOverride
924
1245
  );
@@ -929,48 +1250,54 @@ var BarChart = React7.forwardRef(
929
1250
  showLegend,
930
1251
  showGrid,
931
1252
  isHorizontal,
1253
+ isPercent,
932
1254
  stacked,
933
1255
  showValues,
1256
+ valueFormat,
1257
+ locale,
934
1258
  labelFormatter,
935
1259
  xAxisConfig,
936
1260
  yAxisConfig,
1261
+ referenceLines,
1262
+ referenceBands,
1263
+ dataZoom,
937
1264
  tooltipFormatter,
938
1265
  tooltipValueFormatter,
939
1266
  legendConfig,
940
1267
  customLegend,
1268
+ builtInLegend,
1269
+ chartColors,
941
1270
  optionOverride
942
1271
  ]);
943
- const latest = useLatestRef({ onClick });
944
- const { containerRef } = useChart({
1272
+ const { containerRef, exportImage } = useChart({
945
1273
  option,
946
1274
  theme,
947
1275
  animation,
948
- onReady: (chart) => {
949
- legend.attach(chart);
950
- chart.on("click", (params) => {
951
- const { onClick: onClick2 } = latest.current;
952
- if (!onClick2) return;
953
- onClick2({
954
- type: params.type || "click",
955
- componentType: params.componentType || "series",
956
- seriesIndex: params.seriesIndex,
957
- seriesName: params.seriesName || "",
958
- dataIndex: params.dataIndex || 0,
959
- name: params.name || "",
960
- value: params.value,
961
- color: params.color
962
- });
963
- });
964
- }
1276
+ patterns,
1277
+ events: chartEvents(events, {
1278
+ click: onClick && ((params) => onClick(toDataPointParams(params, "click"))),
1279
+ mouseover: onHover && ((params) => onHover(toDataPointParams(params, "mouseover")))
1280
+ }),
1281
+ onReady: legend.attach,
1282
+ onCreated: onReady
965
1283
  });
966
- const accessibilityDescription = description || (!isEmpty ? (0, import_charts_core5.generateBarChartDescription)(title, data) : void 0);
967
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1284
+ const format = (0, import_charts_core7.resolveValueFormatter)(valueFormat, locale);
1285
+ const accessibilityDescription = description || (!isEmpty ? (0, import_charts_core7.generateBarChartDescription)(title, data, format) : void 0);
1286
+ const resolvedHeight = isHorizontal ? (0, import_charts_core7.resolveChartHeight)(height, data?.categories?.length ?? 0, {
1287
+ rowHeight,
1288
+ minHeight,
1289
+ maxHeight,
1290
+ chrome: 56 + (builtInLegend ? 36 : 0) + (dataZoom ? 36 : 0)
1291
+ }) : height === "auto" ? 400 : height;
1292
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
968
1293
  ChartContainer,
969
1294
  {
970
1295
  ref,
971
1296
  title,
972
1297
  description: accessibilityDescription,
973
- height,
1298
+ height: resolvedHeight,
1299
+ minHeight,
1300
+ maxHeight,
974
1301
  loading,
975
1302
  error,
976
1303
  empty: isEmpty,
@@ -978,8 +1305,13 @@ var BarChart = React7.forwardRef(
978
1305
  className: cn(className),
979
1306
  legend: !isEmpty && renderLegend ? renderLegend(legend.renderProps) : void 0,
980
1307
  legendPosition: legendConfig?.position,
1308
+ dataTable: isEmpty ? void 0 : (0, import_charts_core7.categoryTable)(data),
1309
+ showDataTable,
1310
+ format,
1311
+ exportable,
1312
+ exportImage,
981
1313
  ...props,
982
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { ref: containerRef, className: "h-full w-full" })
1314
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { ref: containerRef, className: "h-full w-full" })
983
1315
  }
984
1316
  );
985
1317
  }
@@ -990,17 +1322,19 @@ BarChart.displayName = "BarChart";
990
1322
  var React8 = __toESM(require("react"), 1);
991
1323
  var echarts5 = __toESM(require("echarts/core"), 1);
992
1324
  var import_charts3 = require("echarts/charts");
993
- var import_components3 = require("echarts/components");
994
- var import_renderers3 = require("echarts/renderers");
995
- var import_charts_core6 = require("@classic-homes/charts-core");
996
- var import_jsx_runtime8 = require("react/jsx-runtime");
997
- echarts5.use([import_charts3.PieChart, import_components3.TooltipComponent, import_components3.LegendComponent, import_components3.TitleComponent, import_renderers3.CanvasRenderer]);
1325
+ var import_components4 = require("echarts/components");
1326
+ var import_renderers4 = require("echarts/renderers");
1327
+ var import_charts_core8 = require("@classic-homes/charts-core");
1328
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1329
+ echarts5.use([import_charts3.PieChart, import_components4.TooltipComponent, import_components4.LegendComponent, import_components4.TitleComponent, import_renderers4.CanvasRenderer]);
998
1330
  var PieChart = React8.forwardRef(
999
1331
  ({
1000
1332
  title,
1001
1333
  description,
1002
1334
  data,
1003
1335
  height = 400,
1336
+ minHeight,
1337
+ maxHeight,
1004
1338
  loading,
1005
1339
  error,
1006
1340
  emptyMessage,
@@ -1011,6 +1345,8 @@ var PieChart = React8.forwardRef(
1011
1345
  showLabels = true,
1012
1346
  labelPosition = "outside",
1013
1347
  innerRadius = 0,
1348
+ valueFormat,
1349
+ locale,
1014
1350
  labelFormatter,
1015
1351
  tooltipFormatter,
1016
1352
  tooltipValueFormatter,
@@ -1018,6 +1354,11 @@ var PieChart = React8.forwardRef(
1018
1354
  renderLegend,
1019
1355
  onLegendChange,
1020
1356
  option: optionOverride,
1357
+ onReady,
1358
+ events,
1359
+ showDataTable,
1360
+ exportable,
1361
+ patterns,
1021
1362
  onClick,
1022
1363
  class: className,
1023
1364
  ...props
@@ -1027,31 +1368,36 @@ var PieChart = React8.forwardRef(
1027
1368
  const legend = useChartLegend({
1028
1369
  names: data?.map((d) => d.name) ?? [],
1029
1370
  colors: data?.map((d) => d.color) ?? [],
1030
- palette: (0, import_charts_core6.getChartColors)(currentTheme).series,
1371
+ palette: (0, import_charts_core8.getChartColors)(currentTheme).series,
1031
1372
  config: legendConfig,
1032
1373
  title,
1033
1374
  onLegendChange
1034
1375
  });
1035
1376
  const customLegend = renderLegend !== void 0;
1377
+ const format = React8.useMemo(
1378
+ () => (0, import_charts_core8.resolveValueFormatter)(valueFormat, locale),
1379
+ [valueFormat, locale]
1380
+ );
1381
+ const tooltipValues = tooltipValueFormatter ?? format;
1036
1382
  const option = React8.useMemo(() => {
1037
1383
  if (isEmpty) return {};
1038
- const valueFormatter = tooltipFormatter === void 0 ? tooltipValueFormatter : void 0;
1384
+ const valueFormatter = tooltipFormatter === void 0 ? tooltipValues : void 0;
1039
1385
  const tooltipBase = {
1040
1386
  trigger: "item",
1041
1387
  formatter: valueFormatter ? (params) => {
1042
1388
  const p = params;
1043
- return `${(0, import_charts_core6.escapeHtml)(p.seriesName)} <br/>${(0, import_charts_core6.escapeHtml)(p.name)}: ${(0, import_charts_core6.escapeHtml)((0, import_charts_core6.formatTooltipValue)(p.value, valueFormatter))} (${p.percent}%)`;
1389
+ return `${(0, import_charts_core8.escapeHtml)(p.seriesName)} <br/>${(0, import_charts_core8.escapeHtml)(p.name)}: ${(0, import_charts_core8.escapeHtml)((0, import_charts_core8.formatTooltipValue)(p.value, valueFormatter))} (${p.percent}%)`;
1044
1390
  } : "{a} <br/>{b}: {c} ({d}%)"
1045
1391
  };
1046
- return (0, import_charts_core6.mergeChartOption)(
1392
+ return (0, import_charts_core8.mergeChartOption)(
1047
1393
  {
1048
- tooltip: (0, import_charts_core6.buildTooltip)(tooltipBase, {
1394
+ tooltip: (0, import_charts_core8.buildTooltip)(tooltipBase, {
1049
1395
  show: showTooltip,
1050
1396
  formatter: tooltipFormatter,
1051
- valueFormatter: tooltipValueFormatter,
1052
- getLabel: (0, import_charts_core6.itemLabelLookup)(data)
1397
+ valueFormatter: tooltipValues,
1398
+ getLabel: (0, import_charts_core8.itemLabelLookup)(data)
1053
1399
  }),
1054
- legend: (0, import_charts_core6.buildLegend)(
1400
+ legend: (0, import_charts_core8.buildLegend)(
1055
1401
  data.map((d) => d.name),
1056
1402
  legendConfig,
1057
1403
  { show: showLegend, custom: customLegend, defaults: { orient: "horizontal" } }
@@ -1061,21 +1407,21 @@ var PieChart = React8.forwardRef(
1061
1407
  name: title,
1062
1408
  type: "pie",
1063
1409
  radius: innerRadius ? [innerRadius, "70%"] : "70%",
1064
- center: (0, import_charts_core6.legendCenter)(legendConfig, showLegend && !customLegend, ["50%", "45%"]),
1410
+ center: (0, import_charts_core8.legendCenter)(legendConfig, showLegend && !customLegend, ["50%", "45%"]),
1065
1411
  data: data.map((item) => ({
1066
1412
  name: item.name,
1067
1413
  value: item.value,
1068
1414
  itemStyle: item.color ? { color: item.color } : void 0,
1069
- label: (0, import_charts_core6.pointLabel)(item.label, labelFormatter, { position: labelPosition })
1415
+ label: (0, import_charts_core8.pointLabel)(item.label, labelFormatter, { position: labelPosition })
1070
1416
  })),
1071
- label: (0, import_charts_core6.buildDataLabel)(
1417
+ label: (0, import_charts_core8.buildDataLabel)(
1072
1418
  {
1073
1419
  show: true,
1074
1420
  position: labelPosition,
1075
1421
  formatter: labelPosition === "inside" ? "{d}%" : "{b}: {d}%"
1076
1422
  },
1077
1423
  { show: false },
1078
- { show: showLabels, formatter: labelFormatter, getLabel: (0, import_charts_core6.itemLabelLookup)(data) }
1424
+ { show: showLabels, formatter: labelFormatter, getLabel: (0, import_charts_core8.itemLabelLookup)(data) }
1079
1425
  ),
1080
1426
  emphasis: {
1081
1427
  itemStyle: {
@@ -1100,40 +1446,32 @@ var PieChart = React8.forwardRef(
1100
1446
  title,
1101
1447
  labelFormatter,
1102
1448
  tooltipFormatter,
1103
- tooltipValueFormatter,
1449
+ tooltipValues,
1104
1450
  legendConfig,
1105
1451
  customLegend,
1106
1452
  optionOverride
1107
1453
  ]);
1108
- const latest = useLatestRef({ onClick });
1109
- const { containerRef } = useChart({
1454
+ const { containerRef, exportImage } = useChart({
1110
1455
  option,
1111
1456
  theme,
1112
1457
  animation,
1113
- onReady: (chart) => {
1114
- legend.attach(chart);
1115
- chart.on("click", (params) => {
1116
- const { onClick: onClick2 } = latest.current;
1117
- if (!onClick2) return;
1118
- onClick2({
1119
- type: params.type || "click",
1120
- componentType: params.componentType || "series",
1121
- name: params.name || "",
1122
- value: params.value,
1123
- percent: params.percent,
1124
- color: params.color
1125
- });
1126
- });
1127
- }
1458
+ patterns,
1459
+ events: chartEvents(events, {
1460
+ click: onClick && ((params) => onClick(toSliceParams(params, "click")))
1461
+ }),
1462
+ onReady: legend.attach,
1463
+ onCreated: onReady
1128
1464
  });
1129
- const accessibilityDescription = description || (!isEmpty ? (0, import_charts_core6.generatePieChartDescription)(title, data, false) : void 0);
1130
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1465
+ const accessibilityDescription = description || (!isEmpty ? (0, import_charts_core8.generatePieChartDescription)(title, data, false) : void 0);
1466
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1131
1467
  ChartContainer,
1132
1468
  {
1133
1469
  ref,
1134
1470
  title,
1135
1471
  description: accessibilityDescription,
1136
1472
  height,
1473
+ minHeight,
1474
+ maxHeight,
1137
1475
  loading,
1138
1476
  error,
1139
1477
  empty: isEmpty,
@@ -1141,8 +1479,13 @@ var PieChart = React8.forwardRef(
1141
1479
  className: cn(className),
1142
1480
  legend: !isEmpty && renderLegend ? renderLegend(legend.renderProps) : void 0,
1143
1481
  legendPosition: legendConfig?.position,
1482
+ dataTable: isEmpty ? void 0 : (0, import_charts_core8.sliceTable)(data),
1483
+ showDataTable,
1484
+ format,
1485
+ exportable,
1486
+ exportImage,
1144
1487
  ...props,
1145
- children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { ref: containerRef, className: "h-full w-full" })
1488
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { ref: containerRef, className: "h-full w-full" })
1146
1489
  }
1147
1490
  );
1148
1491
  }
@@ -1153,17 +1496,17 @@ PieChart.displayName = "PieChart";
1153
1496
  var React9 = __toESM(require("react"), 1);
1154
1497
  var echarts6 = __toESM(require("echarts/core"), 1);
1155
1498
  var import_charts4 = require("echarts/charts");
1156
- var import_components4 = require("echarts/components");
1157
- var import_renderers4 = require("echarts/renderers");
1158
- var import_charts_core7 = require("@classic-homes/charts-core");
1159
- var import_jsx_runtime9 = require("react/jsx-runtime");
1499
+ var import_components5 = require("echarts/components");
1500
+ var import_renderers5 = require("echarts/renderers");
1501
+ var import_charts_core9 = require("@classic-homes/charts-core");
1502
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1160
1503
  echarts6.use([
1161
1504
  import_charts4.LineChart,
1162
- import_components4.GridComponent,
1163
- import_components4.TooltipComponent,
1164
- import_components4.LegendComponent,
1165
- import_components4.TitleComponent,
1166
- import_renderers4.CanvasRenderer
1505
+ import_components5.GridComponent,
1506
+ import_components5.TooltipComponent,
1507
+ import_components5.LegendComponent,
1508
+ import_components5.TitleComponent,
1509
+ import_renderers5.CanvasRenderer
1167
1510
  ]);
1168
1511
  var AreaChart = React9.forwardRef(
1169
1512
  ({
@@ -1171,6 +1514,8 @@ var AreaChart = React9.forwardRef(
1171
1514
  description,
1172
1515
  data,
1173
1516
  height = 400,
1517
+ minHeight,
1518
+ maxHeight,
1174
1519
  loading,
1175
1520
  error,
1176
1521
  emptyMessage,
@@ -1181,24 +1526,37 @@ var AreaChart = React9.forwardRef(
1181
1526
  showGrid = true,
1182
1527
  smooth = false,
1183
1528
  stacked = false,
1529
+ connectNulls = false,
1184
1530
  gradient = true,
1185
1531
  showLabels = false,
1532
+ valueFormat,
1533
+ locale,
1186
1534
  labelFormatter,
1187
1535
  xAxisConfig,
1188
1536
  yAxisConfig,
1537
+ referenceLines,
1538
+ referenceBands,
1539
+ dataZoom,
1189
1540
  tooltipFormatter,
1190
1541
  tooltipValueFormatter,
1191
1542
  legend: legendConfig,
1192
1543
  renderLegend,
1193
1544
  onLegendChange,
1194
1545
  option: optionOverride,
1546
+ onReady,
1547
+ events,
1548
+ showDataTable,
1549
+ exportable,
1550
+ patterns,
1195
1551
  onClick,
1552
+ onHover,
1196
1553
  class: className,
1197
1554
  ...props
1198
1555
  }, ref) => {
1199
1556
  const isEmpty = !data?.categories?.length || !data?.series?.length || data.series.every((s) => !s.data?.length);
1557
+ const isPercent = stacked === "percent";
1200
1558
  const currentTheme = useChartTheme(theme);
1201
- const chartColors = (0, import_charts_core7.getChartColors)(currentTheme);
1559
+ const chartColors = (0, import_charts_core9.getChartColors)(currentTheme);
1202
1560
  const legend = useChartLegend({
1203
1561
  names: data?.series?.map((s) => s.name) ?? [],
1204
1562
  colors: data?.series?.map((s) => s.color) ?? [],
@@ -1208,20 +1566,63 @@ var AreaChart = React9.forwardRef(
1208
1566
  onLegendChange
1209
1567
  });
1210
1568
  const customLegend = renderLegend !== void 0;
1569
+ const builtInLegend = showLegend && !customLegend;
1211
1570
  const option = React9.useMemo(() => {
1212
1571
  if (isEmpty) return {};
1213
- const getLabel = (0, import_charts_core7.seriesLabelLookup)(data.series);
1214
- const showSymbol = showLabels || (0, import_charts_core7.hasPointLabels)(data.series);
1215
- return (0, import_charts_core7.mergeChartOption)(
1572
+ const formatters = (0, import_charts_core9.chartFormatters)({
1573
+ valueFormat: isPercent ? "percentValue" : valueFormat,
1574
+ locale,
1575
+ tooltipValueFormatter,
1576
+ labelFormatter
1577
+ });
1578
+ const plotted = isPercent ? (0, import_charts_core9.toPercentStack)(data.series) : data.series;
1579
+ const getLabel = (0, import_charts_core9.seriesLabelLookup)(data.series);
1580
+ const showSymbol = showLabels || (0, import_charts_core9.hasPointLabels)(data.series);
1581
+ const legendBottom = builtInLegend && (legendConfig?.position ?? "bottom") === "bottom";
1582
+ const series = data.series.map((source, index) => {
1583
+ const base = source.color || chartColors.series[index % chartColors.series.length];
1584
+ return {
1585
+ name: source.name,
1586
+ type: "line",
1587
+ data: (0, import_charts_core9.withPointLabels)(plotted[index].data, source.labels, formatters.label, {
1588
+ position: "top"
1589
+ }),
1590
+ smooth,
1591
+ connectNulls,
1592
+ stack: stacked ? "Total" : void 0,
1593
+ areaStyle: gradient ? {
1594
+ opacity: 0.8,
1595
+ color: new echarts6.graphic.LinearGradient(0, 0, 0, 1, [
1596
+ { offset: 0, color: (0, import_charts_core9.colorWithAlpha)(base, 0.8) },
1597
+ { offset: 1, color: (0, import_charts_core9.colorWithAlpha)(base, 0.1) }
1598
+ ])
1599
+ } : { opacity: 0.5 },
1600
+ itemStyle: source.color ? { color: source.color } : void 0,
1601
+ label: (0, import_charts_core9.buildDataLabel)({ show: true, position: "top" }, void 0, {
1602
+ show: showLabels,
1603
+ formatter: formatters.label,
1604
+ getLabel
1605
+ }),
1606
+ emphasis: {
1607
+ focus: "series"
1608
+ },
1609
+ showSymbol
1610
+ };
1611
+ });
1612
+ return (0, import_charts_core9.mergeChartOption)(
1216
1613
  {
1217
1614
  grid: {
1218
1615
  left: "3%",
1219
1616
  right: "4%",
1220
1617
  bottom: "3%",
1221
1618
  containLabel: true,
1222
- ...(0, import_charts_core7.gridInset)(legendConfig, showLegend && !customLegend, xAxisConfig, yAxisConfig)
1619
+ ...(0, import_charts_core9.withZoomInset)(
1620
+ (0, import_charts_core9.gridInset)(legendConfig, builtInLegend, xAxisConfig, yAxisConfig),
1621
+ dataZoom,
1622
+ "x"
1623
+ )
1223
1624
  },
1224
- tooltip: (0, import_charts_core7.buildTooltip)(
1625
+ tooltip: (0, import_charts_core9.buildTooltip)(
1225
1626
  {
1226
1627
  trigger: "axis",
1227
1628
  axisPointer: {
@@ -1234,16 +1635,17 @@ var AreaChart = React9.forwardRef(
1234
1635
  {
1235
1636
  show: showTooltip,
1236
1637
  formatter: tooltipFormatter,
1237
- valueFormatter: tooltipValueFormatter,
1638
+ valueFormatter: formatters.tooltip,
1238
1639
  getLabel
1239
1640
  }
1240
1641
  ),
1241
- legend: (0, import_charts_core7.buildLegend)(
1642
+ legend: (0, import_charts_core9.buildLegend)(
1242
1643
  data.series.map((s) => s.name),
1243
1644
  legendConfig,
1244
1645
  { show: showLegend, custom: customLegend }
1245
1646
  ),
1246
- xAxis: (0, import_charts_core7.buildAxis)(
1647
+ dataZoom: (0, import_charts_core9.buildDataZoom)(dataZoom, "x", legendBottom ? 36 : 0),
1648
+ xAxis: (0, import_charts_core9.buildAxis)(
1247
1649
  {
1248
1650
  type: "category",
1249
1651
  boundaryGap: false,
@@ -1251,43 +1653,21 @@ var AreaChart = React9.forwardRef(
1251
1653
  },
1252
1654
  xAxisConfig
1253
1655
  ),
1254
- yAxis: (0, import_charts_core7.buildAxis)(
1656
+ yAxis: (0, import_charts_core9.buildAxis)(
1255
1657
  {
1256
1658
  type: "value",
1659
+ ...isPercent && { max: 100 },
1257
1660
  splitLine: {
1258
1661
  show: showGrid
1259
1662
  }
1260
1663
  },
1261
- yAxisConfig
1664
+ formatters.axis(yAxisConfig)
1262
1665
  ),
1263
- series: data.series.map((series, index) => {
1264
- const base = series.color || chartColors.series[index % chartColors.series.length];
1265
- return {
1266
- name: series.name,
1267
- type: "line",
1268
- data: (0, import_charts_core7.withPointLabels)(series.data, series.labels, labelFormatter, {
1269
- position: "top"
1270
- }),
1271
- smooth,
1272
- stack: stacked ? "Total" : void 0,
1273
- areaStyle: gradient ? {
1274
- opacity: 0.8,
1275
- color: new echarts6.graphic.LinearGradient(0, 0, 0, 1, [
1276
- { offset: 0, color: (0, import_charts_core7.colorWithAlpha)(base, 0.8) },
1277
- { offset: 1, color: (0, import_charts_core7.colorWithAlpha)(base, 0.1) }
1278
- ])
1279
- } : { opacity: 0.5 },
1280
- itemStyle: series.color ? { color: series.color } : void 0,
1281
- label: (0, import_charts_core7.buildDataLabel)({ show: true, position: "top" }, void 0, {
1282
- show: showLabels,
1283
- formatter: labelFormatter,
1284
- getLabel
1285
- }),
1286
- emphasis: {
1287
- focus: "series"
1288
- },
1289
- showSymbol
1290
- };
1666
+ series: (0, import_charts_core9.withReferenceMarks)(series, referenceLines, referenceBands, {
1667
+ valueAxis: "y",
1668
+ format: formatters.format,
1669
+ color: chartColors.reference,
1670
+ bandColor: chartColors.referenceBand
1291
1671
  })
1292
1672
  },
1293
1673
  optionOverride
@@ -1300,49 +1680,49 @@ var AreaChart = React9.forwardRef(
1300
1680
  showGrid,
1301
1681
  smooth,
1302
1682
  stacked,
1683
+ isPercent,
1684
+ connectNulls,
1303
1685
  gradient,
1304
1686
  chartColors,
1305
1687
  showLabels,
1688
+ valueFormat,
1689
+ locale,
1306
1690
  labelFormatter,
1307
1691
  xAxisConfig,
1308
1692
  yAxisConfig,
1693
+ referenceLines,
1694
+ referenceBands,
1695
+ dataZoom,
1309
1696
  tooltipFormatter,
1310
1697
  tooltipValueFormatter,
1311
1698
  legendConfig,
1312
1699
  customLegend,
1700
+ builtInLegend,
1313
1701
  optionOverride
1314
1702
  ]);
1315
- const latest = useLatestRef({ onClick });
1316
- const { containerRef } = useChart({
1703
+ const { containerRef, exportImage } = useChart({
1317
1704
  option,
1318
- theme: currentTheme === import_charts_core7.THEME_DARK ? "dark" : "light",
1705
+ theme: currentTheme === import_charts_core9.THEME_DARK ? "dark" : "light",
1319
1706
  animation,
1320
- onReady: (chart) => {
1321
- legend.attach(chart);
1322
- chart.on("click", (params) => {
1323
- const { onClick: onClick2 } = latest.current;
1324
- if (!onClick2) return;
1325
- onClick2({
1326
- type: params.type || "click",
1327
- componentType: params.componentType || "series",
1328
- seriesIndex: params.seriesIndex,
1329
- seriesName: params.seriesName || "",
1330
- dataIndex: params.dataIndex || 0,
1331
- name: params.name || "",
1332
- value: params.value,
1333
- color: params.color
1334
- });
1335
- });
1336
- }
1707
+ patterns,
1708
+ events: chartEvents(events, {
1709
+ click: onClick && ((params) => onClick(toDataPointParams(params, "click"))),
1710
+ mouseover: onHover && ((params) => onHover(toDataPointParams(params, "mouseover")))
1711
+ }),
1712
+ onReady: legend.attach,
1713
+ onCreated: onReady
1337
1714
  });
1338
- const accessibilityDescription = description || (!isEmpty ? `${title}. Area chart with ${data.categories.length} data points across ${data.series.length} series.` : void 0);
1339
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1715
+ const format = (0, import_charts_core9.resolveValueFormatter)(valueFormat, locale);
1716
+ const accessibilityDescription = description || (!isEmpty ? (0, import_charts_core9.generateAreaChartDescription)(title, data, format) : void 0);
1717
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1340
1718
  ChartContainer,
1341
1719
  {
1342
1720
  ref,
1343
1721
  title,
1344
1722
  description: accessibilityDescription,
1345
1723
  height,
1724
+ minHeight,
1725
+ maxHeight,
1346
1726
  loading,
1347
1727
  error,
1348
1728
  empty: isEmpty,
@@ -1350,8 +1730,13 @@ var AreaChart = React9.forwardRef(
1350
1730
  className: cn(className),
1351
1731
  legend: !isEmpty && renderLegend ? renderLegend(legend.renderProps) : void 0,
1352
1732
  legendPosition: legendConfig?.position,
1733
+ dataTable: isEmpty ? void 0 : (0, import_charts_core9.categoryTable)(data),
1734
+ showDataTable,
1735
+ format,
1736
+ exportable,
1737
+ exportImage,
1353
1738
  ...props,
1354
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { ref: containerRef, className: "h-full w-full" })
1739
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { ref: containerRef, className: "h-full w-full" })
1355
1740
  }
1356
1741
  );
1357
1742
  }
@@ -1362,19 +1747,19 @@ AreaChart.displayName = "AreaChart";
1362
1747
  var React10 = __toESM(require("react"), 1);
1363
1748
  var echarts7 = __toESM(require("echarts/core"), 1);
1364
1749
  var import_charts5 = require("echarts/charts");
1365
- var import_components5 = require("echarts/components");
1366
- var import_renderers5 = require("echarts/renderers");
1367
- var import_charts_core8 = require("@classic-homes/charts-core");
1368
- var import_jsx_runtime10 = require("react/jsx-runtime");
1750
+ var import_components6 = require("echarts/components");
1751
+ var import_renderers6 = require("echarts/renderers");
1752
+ var import_charts_core10 = require("@classic-homes/charts-core");
1753
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1369
1754
  echarts7.use([
1370
1755
  import_charts5.ScatterChart,
1371
1756
  // Trend lines are line series
1372
1757
  import_charts5.LineChart,
1373
- import_components5.GridComponent,
1374
- import_components5.TooltipComponent,
1375
- import_components5.LegendComponent,
1376
- import_components5.TitleComponent,
1377
- import_renderers5.CanvasRenderer
1758
+ import_components6.GridComponent,
1759
+ import_components6.TooltipComponent,
1760
+ import_components6.LegendComponent,
1761
+ import_components6.TitleComponent,
1762
+ import_renderers6.CanvasRenderer
1378
1763
  ]);
1379
1764
  var ScatterChart = React10.forwardRef(
1380
1765
  ({
@@ -1382,6 +1767,8 @@ var ScatterChart = React10.forwardRef(
1382
1767
  description,
1383
1768
  data,
1384
1769
  height = 400,
1770
+ minHeight,
1771
+ maxHeight,
1385
1772
  loading,
1386
1773
  error,
1387
1774
  emptyMessage,
@@ -1393,25 +1780,36 @@ var ScatterChart = React10.forwardRef(
1393
1780
  showTrendLine = false,
1394
1781
  symbolSize = 10,
1395
1782
  showLabels = false,
1783
+ valueFormat,
1784
+ locale,
1396
1785
  labelFormatter,
1397
1786
  xAxisConfig,
1398
1787
  yAxisConfig,
1788
+ referenceLines,
1789
+ referenceBands,
1399
1790
  tooltipFormatter,
1400
1791
  tooltipValueFormatter,
1401
1792
  legend: legendConfig,
1402
1793
  renderLegend,
1403
1794
  onLegendChange,
1404
1795
  option: optionOverride,
1796
+ onReady,
1797
+ events,
1798
+ showDataTable,
1799
+ exportable,
1800
+ patterns,
1405
1801
  onClick,
1802
+ onHover,
1406
1803
  class: className,
1407
1804
  ...props
1408
1805
  }, ref) => {
1409
1806
  const isEmpty = !data?.series?.length || data.series.every((s) => !s.data?.length);
1410
1807
  const currentTheme = useChartTheme(theme);
1808
+ const chartColors = (0, import_charts_core10.getChartColors)(currentTheme);
1411
1809
  const legend = useChartLegend({
1412
1810
  names: data?.series?.map((s) => s.name) ?? [],
1413
1811
  colors: data?.series?.map((s) => s.color) ?? [],
1414
- palette: (0, import_charts_core8.getChartColors)(currentTheme).series,
1812
+ palette: chartColors.series,
1415
1813
  config: legendConfig,
1416
1814
  title,
1417
1815
  onLegendChange
@@ -1419,16 +1817,22 @@ var ScatterChart = React10.forwardRef(
1419
1817
  const customLegend = renderLegend !== void 0;
1420
1818
  const option = React10.useMemo(() => {
1421
1819
  if (isEmpty) return {};
1422
- const getLabel = (0, import_charts_core8.seriesLabelLookup)(data.series);
1820
+ const formatters = (0, import_charts_core10.chartFormatters)({
1821
+ valueFormat,
1822
+ locale,
1823
+ tooltipValueFormatter,
1824
+ labelFormatter
1825
+ });
1826
+ const getLabel = (0, import_charts_core10.seriesLabelLookup)(data.series);
1423
1827
  const series = data.series.map((s) => ({
1424
1828
  name: s.name,
1425
1829
  type: "scatter",
1426
- data: (0, import_charts_core8.withPointLabels)(s.data, s.labels, labelFormatter, { position: "top" }),
1830
+ data: (0, import_charts_core10.withPointLabels)(s.data, s.labels, formatters.label, { position: "top" }),
1427
1831
  symbolSize: typeof symbolSize === "function" ? symbolSize : symbolSize,
1428
1832
  itemStyle: s.color ? { color: s.color } : void 0,
1429
- label: (0, import_charts_core8.buildDataLabel)({ show: true, position: "top" }, void 0, {
1833
+ label: (0, import_charts_core10.buildDataLabel)({ show: true, position: "top" }, void 0, {
1430
1834
  show: showLabels,
1431
- formatter: labelFormatter,
1835
+ formatter: formatters.label,
1432
1836
  getLabel
1433
1837
  }),
1434
1838
  emphasis: {
@@ -1478,39 +1882,39 @@ var ScatterChart = React10.forwardRef(
1478
1882
  });
1479
1883
  });
1480
1884
  }
1481
- return (0, import_charts_core8.mergeChartOption)(
1885
+ return (0, import_charts_core10.mergeChartOption)(
1482
1886
  {
1483
1887
  grid: {
1484
1888
  left: "3%",
1485
1889
  right: "4%",
1486
1890
  bottom: "3%",
1487
1891
  containLabel: true,
1488
- ...(0, import_charts_core8.gridInset)(legendConfig, showLegend && !customLegend, xAxisConfig, yAxisConfig)
1892
+ ...(0, import_charts_core10.gridInset)(legendConfig, showLegend && !customLegend, xAxisConfig, yAxisConfig)
1489
1893
  },
1490
- tooltip: (0, import_charts_core8.buildTooltip)(
1894
+ tooltip: (0, import_charts_core10.buildTooltip)(
1491
1895
  {
1492
1896
  trigger: "item",
1493
1897
  formatter: (params) => {
1494
1898
  const p = params;
1495
1899
  if (!p.value) return "";
1496
- const x = (0, import_charts_core8.formatTooltipValue)(p.value[0], tooltipValueFormatter);
1497
- const y = (0, import_charts_core8.formatTooltipValue)(p.value[1], tooltipValueFormatter);
1498
- return `${(0, import_charts_core8.escapeHtml)(p.seriesName)}<br/>X: ${(0, import_charts_core8.escapeHtml)(x)}<br/>Y: ${(0, import_charts_core8.escapeHtml)(y)}`;
1900
+ const x = (0, import_charts_core10.formatTooltipValue)(p.value[0], formatters.tooltip);
1901
+ const y = (0, import_charts_core10.formatTooltipValue)(p.value[1], formatters.tooltip);
1902
+ return `${(0, import_charts_core10.escapeHtml)(p.seriesName)}<br/>X: ${(0, import_charts_core10.escapeHtml)(x)}<br/>Y: ${(0, import_charts_core10.escapeHtml)(y)}`;
1499
1903
  }
1500
1904
  },
1501
1905
  {
1502
1906
  show: showTooltip,
1503
1907
  formatter: tooltipFormatter,
1504
- valueFormatter: tooltipValueFormatter,
1908
+ valueFormatter: formatters.tooltip,
1505
1909
  getLabel
1506
1910
  }
1507
1911
  ),
1508
- legend: (0, import_charts_core8.buildLegend)(
1912
+ legend: (0, import_charts_core10.buildLegend)(
1509
1913
  data.series.map((s) => s.name),
1510
1914
  legendConfig,
1511
1915
  { show: showLegend, custom: customLegend }
1512
1916
  ),
1513
- xAxis: (0, import_charts_core8.buildAxis)(
1917
+ xAxis: (0, import_charts_core10.buildAxis)(
1514
1918
  {
1515
1919
  type: "value",
1516
1920
  splitLine: {
@@ -1519,16 +1923,26 @@ var ScatterChart = React10.forwardRef(
1519
1923
  },
1520
1924
  xAxisConfig
1521
1925
  ),
1522
- yAxis: (0, import_charts_core8.buildAxis)(
1926
+ yAxis: (0, import_charts_core10.buildAxis)(
1523
1927
  {
1524
1928
  type: "value",
1525
1929
  splitLine: {
1526
1930
  show: showGrid
1527
1931
  }
1528
1932
  },
1529
- yAxisConfig
1933
+ formatters.axis(yAxisConfig)
1530
1934
  ),
1531
- series
1935
+ series: (0, import_charts_core10.withReferenceMarks)(
1936
+ series,
1937
+ referenceLines,
1938
+ referenceBands,
1939
+ {
1940
+ valueAxis: "y",
1941
+ format: formatters.format,
1942
+ color: chartColors.reference,
1943
+ bandColor: chartColors.referenceBand
1944
+ }
1945
+ )
1532
1946
  },
1533
1947
  optionOverride
1534
1948
  );
@@ -1541,46 +1955,42 @@ var ScatterChart = React10.forwardRef(
1541
1955
  showTrendLine,
1542
1956
  symbolSize,
1543
1957
  showLabels,
1958
+ valueFormat,
1959
+ locale,
1544
1960
  labelFormatter,
1545
1961
  xAxisConfig,
1546
1962
  yAxisConfig,
1963
+ referenceLines,
1964
+ referenceBands,
1965
+ chartColors,
1547
1966
  tooltipFormatter,
1548
1967
  tooltipValueFormatter,
1549
1968
  legendConfig,
1550
1969
  customLegend,
1551
1970
  optionOverride
1552
1971
  ]);
1553
- const latest = useLatestRef({ onClick });
1554
- const { containerRef } = useChart({
1972
+ const { containerRef, exportImage } = useChart({
1555
1973
  option,
1556
1974
  theme,
1557
1975
  animation,
1558
- onReady: (chart) => {
1559
- legend.attach(chart);
1560
- chart.on("click", (params) => {
1561
- const { onClick: onClick2 } = latest.current;
1562
- if (!onClick2) return;
1563
- onClick2({
1564
- type: params.type || "click",
1565
- componentType: params.componentType || "series",
1566
- seriesIndex: params.seriesIndex,
1567
- seriesName: params.seriesName || "",
1568
- dataIndex: params.dataIndex || 0,
1569
- name: params.name || "",
1570
- value: params.value,
1571
- color: params.color
1572
- });
1573
- });
1574
- }
1976
+ patterns,
1977
+ events: chartEvents(events, {
1978
+ click: onClick && ((params) => onClick(toDataPointParams(params, "click"))),
1979
+ mouseover: onHover && ((params) => onHover(toDataPointParams(params, "mouseover")))
1980
+ }),
1981
+ onReady: legend.attach,
1982
+ onCreated: onReady
1575
1983
  });
1576
- const accessibilityDescription = description || (!isEmpty ? (0, import_charts_core8.generateScatterChartDescription)(title, data) : void 0);
1577
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1984
+ const accessibilityDescription = description || (!isEmpty ? (0, import_charts_core10.generateScatterChartDescription)(title, data) : void 0);
1985
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1578
1986
  ChartContainer,
1579
1987
  {
1580
1988
  ref,
1581
1989
  title,
1582
1990
  description: accessibilityDescription,
1583
1991
  height,
1992
+ minHeight,
1993
+ maxHeight,
1584
1994
  loading,
1585
1995
  error,
1586
1996
  empty: isEmpty,
@@ -1588,8 +1998,13 @@ var ScatterChart = React10.forwardRef(
1588
1998
  className: cn(className),
1589
1999
  legend: !isEmpty && renderLegend ? renderLegend(legend.renderProps) : void 0,
1590
2000
  legendPosition: legendConfig?.position,
2001
+ dataTable: isEmpty ? void 0 : (0, import_charts_core10.scatterTable)(data, xAxisConfig?.name, yAxisConfig?.name),
2002
+ showDataTable,
2003
+ format: (0, import_charts_core10.resolveValueFormatter)(valueFormat, locale),
2004
+ exportable,
2005
+ exportImage,
1591
2006
  ...props,
1592
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { ref: containerRef, className: "h-full w-full" })
2007
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { ref: containerRef, className: "h-full w-full" })
1593
2008
  }
1594
2009
  );
1595
2010
  }
@@ -1600,17 +2015,19 @@ ScatterChart.displayName = "ScatterChart";
1600
2015
  var React11 = __toESM(require("react"), 1);
1601
2016
  var echarts8 = __toESM(require("echarts/core"), 1);
1602
2017
  var import_charts6 = require("echarts/charts");
1603
- var import_components6 = require("echarts/components");
1604
- var import_renderers6 = require("echarts/renderers");
1605
- var import_charts_core9 = require("@classic-homes/charts-core");
1606
- var import_jsx_runtime11 = require("react/jsx-runtime");
1607
- echarts8.use([import_charts6.PieChart, import_components6.TooltipComponent, import_components6.LegendComponent, import_components6.TitleComponent, import_renderers6.CanvasRenderer]);
2018
+ var import_components7 = require("echarts/components");
2019
+ var import_renderers7 = require("echarts/renderers");
2020
+ var import_charts_core11 = require("@classic-homes/charts-core");
2021
+ var import_jsx_runtime12 = require("react/jsx-runtime");
2022
+ echarts8.use([import_charts6.PieChart, import_components7.TooltipComponent, import_components7.LegendComponent, import_components7.TitleComponent, import_renderers7.CanvasRenderer]);
1608
2023
  var DonutChart = React11.forwardRef(
1609
2024
  ({
1610
2025
  title,
1611
2026
  description,
1612
2027
  data,
1613
2028
  height = 400,
2029
+ minHeight,
2030
+ maxHeight,
1614
2031
  loading,
1615
2032
  error,
1616
2033
  emptyMessage,
@@ -1623,6 +2040,8 @@ var DonutChart = React11.forwardRef(
1623
2040
  innerRadius = "50%",
1624
2041
  centerLabel,
1625
2042
  centerValue,
2043
+ valueFormat,
2044
+ locale,
1626
2045
  labelFormatter,
1627
2046
  tooltipFormatter,
1628
2047
  tooltipValueFormatter,
@@ -1630,13 +2049,18 @@ var DonutChart = React11.forwardRef(
1630
2049
  renderLegend,
1631
2050
  onLegendChange,
1632
2051
  option: optionOverride,
2052
+ onReady,
2053
+ events,
2054
+ showDataTable,
2055
+ exportable,
2056
+ patterns,
1633
2057
  onClick,
1634
2058
  class: className,
1635
2059
  ...props
1636
2060
  }, ref) => {
1637
2061
  const isEmpty = !data?.length;
1638
2062
  const currentTheme = useChartTheme(theme);
1639
- const chartColors = (0, import_charts_core9.getChartColors)(currentTheme);
2063
+ const chartColors = (0, import_charts_core11.getChartColors)(currentTheme);
1640
2064
  const legend = useChartLegend({
1641
2065
  names: data?.map((d) => d.name) ?? [],
1642
2066
  colors: data?.map((d) => d.color) ?? [],
@@ -1646,13 +2070,18 @@ var DonutChart = React11.forwardRef(
1646
2070
  onLegendChange
1647
2071
  });
1648
2072
  const customLegend = renderLegend !== void 0;
2073
+ const format = React11.useMemo(
2074
+ () => (0, import_charts_core11.resolveValueFormatter)(valueFormat, locale),
2075
+ [valueFormat, locale]
2076
+ );
2077
+ const tooltipValues = tooltipValueFormatter ?? format;
1649
2078
  const option = React11.useMemo(() => {
1650
2079
  if (isEmpty) return {};
1651
- const pieCenter = (0, import_charts_core9.legendCenter)(legendConfig, showLegend && !customLegend, ["50%", "45%"]);
2080
+ const pieCenter = (0, import_charts_core11.legendCenter)(legendConfig, showLegend && !customLegend, ["50%", "45%"]);
1652
2081
  const graphicElements = [];
1653
2082
  if (centerLabel || centerValue) {
1654
2083
  graphicElements.push(
1655
- (0, import_charts_core9.anchorCenterGraphic)(
2084
+ (0, import_charts_core11.anchorCenterGraphic)(
1656
2085
  {
1657
2086
  type: "group",
1658
2087
  left: "center",
@@ -1692,23 +2121,23 @@ var DonutChart = React11.forwardRef(
1692
2121
  )
1693
2122
  );
1694
2123
  }
1695
- const valueFormatter = tooltipFormatter === void 0 ? tooltipValueFormatter : void 0;
2124
+ const valueFormatter = tooltipFormatter === void 0 ? tooltipValues : void 0;
1696
2125
  const tooltipBase = {
1697
2126
  trigger: "item",
1698
2127
  formatter: valueFormatter ? (params) => {
1699
2128
  const p = params;
1700
- return `${(0, import_charts_core9.escapeHtml)(p.seriesName)} <br/>${(0, import_charts_core9.escapeHtml)(p.name)}: ${(0, import_charts_core9.escapeHtml)((0, import_charts_core9.formatTooltipValue)(p.value, valueFormatter))} (${p.percent}%)`;
2129
+ return `${(0, import_charts_core11.escapeHtml)(p.seriesName)} <br/>${(0, import_charts_core11.escapeHtml)(p.name)}: ${(0, import_charts_core11.escapeHtml)((0, import_charts_core11.formatTooltipValue)(p.value, valueFormatter))} (${p.percent}%)`;
1701
2130
  } : "{a} <br/>{b}: {c} ({d}%)"
1702
2131
  };
1703
- return (0, import_charts_core9.mergeChartOption)(
2132
+ return (0, import_charts_core11.mergeChartOption)(
1704
2133
  {
1705
- tooltip: (0, import_charts_core9.buildTooltip)(tooltipBase, {
2134
+ tooltip: (0, import_charts_core11.buildTooltip)(tooltipBase, {
1706
2135
  show: showTooltip,
1707
2136
  formatter: tooltipFormatter,
1708
- valueFormatter: tooltipValueFormatter,
1709
- getLabel: (0, import_charts_core9.itemLabelLookup)(data)
2137
+ valueFormatter: tooltipValues,
2138
+ getLabel: (0, import_charts_core11.itemLabelLookup)(data)
1710
2139
  }),
1711
- legend: (0, import_charts_core9.buildLegend)(
2140
+ legend: (0, import_charts_core11.buildLegend)(
1712
2141
  data.map((d) => d.name),
1713
2142
  legendConfig,
1714
2143
  { show: showLegend, custom: customLegend, defaults: { orient: "horizontal" } }
@@ -1725,16 +2154,16 @@ var DonutChart = React11.forwardRef(
1725
2154
  name: item.name,
1726
2155
  value: item.value,
1727
2156
  itemStyle: item.color ? { color: item.color } : void 0,
1728
- label: (0, import_charts_core9.pointLabel)(item.label, labelFormatter, { position: labelPosition })
2157
+ label: (0, import_charts_core11.pointLabel)(item.label, labelFormatter, { position: labelPosition })
1729
2158
  })),
1730
- label: (0, import_charts_core9.buildDataLabel)(
2159
+ label: (0, import_charts_core11.buildDataLabel)(
1731
2160
  {
1732
2161
  show: true,
1733
2162
  position: labelPosition,
1734
2163
  formatter: labelPosition === "inside" ? "{d}%" : "{b}: {d}%"
1735
2164
  },
1736
2165
  { show: false },
1737
- { show: showLabels, formatter: labelFormatter, getLabel: (0, import_charts_core9.itemLabelLookup)(data) }
2166
+ { show: showLabels, formatter: labelFormatter, getLabel: (0, import_charts_core11.itemLabelLookup)(data) }
1738
2167
  ),
1739
2168
  labelLine: {
1740
2169
  show: showLabels && labelPosition === "outside"
@@ -1765,40 +2194,32 @@ var DonutChart = React11.forwardRef(
1765
2194
  chartColors,
1766
2195
  labelFormatter,
1767
2196
  tooltipFormatter,
1768
- tooltipValueFormatter,
2197
+ tooltipValues,
1769
2198
  legendConfig,
1770
2199
  customLegend,
1771
2200
  optionOverride
1772
2201
  ]);
1773
- const latest = useLatestRef({ onClick });
1774
- const { containerRef } = useChart({
2202
+ const { containerRef, exportImage } = useChart({
1775
2203
  option,
1776
- theme: currentTheme === import_charts_core9.THEME_DARK ? "dark" : "light",
2204
+ theme: currentTheme === import_charts_core11.THEME_DARK ? "dark" : "light",
1777
2205
  animation,
1778
- onReady: (chart) => {
1779
- legend.attach(chart);
1780
- chart.on("click", (params) => {
1781
- const { onClick: onClick2 } = latest.current;
1782
- if (!onClick2) return;
1783
- onClick2({
1784
- type: params.type || "click",
1785
- componentType: params.componentType || "series",
1786
- name: params.name || "",
1787
- value: params.value,
1788
- percent: params.percent,
1789
- color: params.color
1790
- });
1791
- });
1792
- }
2206
+ patterns,
2207
+ events: chartEvents(events, {
2208
+ click: onClick && ((params) => onClick(toSliceParams(params, "click")))
2209
+ }),
2210
+ onReady: legend.attach,
2211
+ onCreated: onReady
1793
2212
  });
1794
- const accessibilityDescription = description || (!isEmpty ? (0, import_charts_core9.generatePieChartDescription)(title, data, true) : void 0);
1795
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2213
+ const accessibilityDescription = description || (!isEmpty ? (0, import_charts_core11.generatePieChartDescription)(title, data, true) : void 0);
2214
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1796
2215
  ChartContainer,
1797
2216
  {
1798
2217
  ref,
1799
2218
  title,
1800
2219
  description: accessibilityDescription,
1801
2220
  height,
2221
+ minHeight,
2222
+ maxHeight,
1802
2223
  loading,
1803
2224
  error,
1804
2225
  empty: isEmpty,
@@ -1806,8 +2227,13 @@ var DonutChart = React11.forwardRef(
1806
2227
  className: cn(className),
1807
2228
  legend: !isEmpty && renderLegend ? renderLegend(legend.renderProps) : void 0,
1808
2229
  legendPosition: legendConfig?.position,
2230
+ dataTable: isEmpty ? void 0 : (0, import_charts_core11.sliceTable)(data),
2231
+ showDataTable,
2232
+ format,
2233
+ exportable,
2234
+ exportImage,
1809
2235
  ...props,
1810
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { ref: containerRef, className: "h-full w-full" })
2236
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { ref: containerRef, className: "h-full w-full" })
1811
2237
  }
1812
2238
  );
1813
2239
  }
@@ -1818,17 +2244,17 @@ DonutChart.displayName = "DonutChart";
1818
2244
  var React12 = __toESM(require("react"), 1);
1819
2245
  var echarts9 = __toESM(require("echarts/core"), 1);
1820
2246
  var import_charts7 = require("echarts/charts");
1821
- var import_components7 = require("echarts/components");
1822
- var import_renderers7 = require("echarts/renderers");
1823
- var import_charts_core10 = require("@classic-homes/charts-core");
1824
- var import_jsx_runtime12 = require("react/jsx-runtime");
2247
+ var import_components8 = require("echarts/components");
2248
+ var import_renderers8 = require("echarts/renderers");
2249
+ var import_charts_core12 = require("@classic-homes/charts-core");
2250
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1825
2251
  echarts9.use([
1826
2252
  import_charts7.RadarChart,
1827
- import_components7.TooltipComponent,
1828
- import_components7.LegendComponent,
1829
- import_components7.TitleComponent,
1830
- import_components7.RadarComponent,
1831
- import_renderers7.CanvasRenderer
2253
+ import_components8.TooltipComponent,
2254
+ import_components8.LegendComponent,
2255
+ import_components8.TitleComponent,
2256
+ import_components8.RadarComponent,
2257
+ import_renderers8.CanvasRenderer
1832
2258
  ]);
1833
2259
  var RadarChart = React12.forwardRef(
1834
2260
  ({
@@ -1837,6 +2263,8 @@ var RadarChart = React12.forwardRef(
1837
2263
  data,
1838
2264
  indicators,
1839
2265
  height = 400,
2266
+ minHeight,
2267
+ maxHeight,
1840
2268
  loading,
1841
2269
  error,
1842
2270
  emptyMessage,
@@ -1846,6 +2274,8 @@ var RadarChart = React12.forwardRef(
1846
2274
  showTooltip = true,
1847
2275
  shape = "polygon",
1848
2276
  showLabels = false,
2277
+ valueFormat,
2278
+ locale,
1849
2279
  labelFormatter,
1850
2280
  tooltipFormatter,
1851
2281
  tooltipValueFormatter,
@@ -1853,6 +2283,11 @@ var RadarChart = React12.forwardRef(
1853
2283
  renderLegend,
1854
2284
  onLegendChange,
1855
2285
  option: optionOverride,
2286
+ onReady,
2287
+ events,
2288
+ showDataTable,
2289
+ exportable,
2290
+ patterns,
1856
2291
  onClick,
1857
2292
  class: className,
1858
2293
  ...props
@@ -1862,27 +2297,32 @@ var RadarChart = React12.forwardRef(
1862
2297
  const legend = useChartLegend({
1863
2298
  names: data?.series?.map((s) => s.name) ?? [],
1864
2299
  colors: data?.series?.map((s) => s.color) ?? [],
1865
- palette: (0, import_charts_core10.getChartColors)(currentTheme).series,
2300
+ palette: (0, import_charts_core12.getChartColors)(currentTheme).series,
1866
2301
  config: legendConfig,
1867
2302
  title,
1868
2303
  onLegendChange
1869
2304
  });
1870
2305
  const customLegend = renderLegend !== void 0;
2306
+ const format = React12.useMemo(
2307
+ () => (0, import_charts_core12.resolveValueFormatter)(valueFormat, locale),
2308
+ [valueFormat, locale]
2309
+ );
2310
+ const valueFormatter = tooltipValueFormatter ?? format;
1871
2311
  const option = React12.useMemo(() => {
1872
2312
  if (isEmpty) return {};
1873
- return (0, import_charts_core10.mergeChartOption)(
2313
+ return (0, import_charts_core12.mergeChartOption)(
1874
2314
  {
1875
- tooltip: (0, import_charts_core10.buildTooltip)(
2315
+ tooltip: (0, import_charts_core12.buildTooltip)(
1876
2316
  {
1877
2317
  trigger: "item"
1878
2318
  },
1879
2319
  {
1880
2320
  show: showTooltip,
1881
2321
  formatter: tooltipFormatter,
1882
- valueFormatter: tooltipValueFormatter
2322
+ valueFormatter
1883
2323
  }
1884
2324
  ),
1885
- legend: (0, import_charts_core10.buildLegend)(
2325
+ legend: (0, import_charts_core12.buildLegend)(
1886
2326
  data.series.map((s) => s.name),
1887
2327
  legendConfig,
1888
2328
  { show: showLegend, custom: customLegend }
@@ -1894,12 +2334,12 @@ var RadarChart = React12.forwardRef(
1894
2334
  min: ind.min
1895
2335
  })),
1896
2336
  shape,
1897
- center: (0, import_charts_core10.legendCenter)(legendConfig, showLegend && !customLegend, ["50%", "50%"])
2337
+ center: (0, import_charts_core12.legendCenter)(legendConfig, showLegend && !customLegend, ["50%", "50%"])
1898
2338
  },
1899
2339
  series: [
1900
2340
  {
1901
2341
  type: "radar",
1902
- label: (0, import_charts_core10.buildDataLabel)({ show: true }, void 0, {
2342
+ label: (0, import_charts_core12.buildDataLabel)({ show: true }, void 0, {
1903
2343
  show: showLabels,
1904
2344
  formatter: labelFormatter
1905
2345
  }),
@@ -1926,22 +2366,20 @@ var RadarChart = React12.forwardRef(
1926
2366
  showLabels,
1927
2367
  labelFormatter,
1928
2368
  tooltipFormatter,
1929
- tooltipValueFormatter,
2369
+ valueFormatter,
1930
2370
  legendConfig,
1931
2371
  customLegend,
1932
2372
  optionOverride
1933
2373
  ]);
1934
- const latest = useLatestRef({ onClick });
1935
- const { containerRef } = useChart({
2374
+ const { containerRef, exportImage } = useChart({
1936
2375
  option,
1937
2376
  theme,
1938
2377
  animation,
1939
- onReady: (chart) => {
1940
- legend.attach(chart);
1941
- chart.on("click", (params) => {
1942
- const { onClick: onClick2 } = latest.current;
1943
- if (!onClick2) return;
1944
- onClick2({
2378
+ patterns,
2379
+ events: chartEvents(events, {
2380
+ click: onClick && ((params) => {
2381
+ if (!onClick) return;
2382
+ onClick({
1945
2383
  type: params.type || "click",
1946
2384
  componentType: params.componentType || "series",
1947
2385
  seriesIndex: params.seriesIndex,
@@ -1951,17 +2389,21 @@ var RadarChart = React12.forwardRef(
1951
2389
  value: params.value,
1952
2390
  color: params.color
1953
2391
  });
1954
- });
1955
- }
2392
+ })
2393
+ }),
2394
+ onReady: legend.attach,
2395
+ onCreated: onReady
1956
2396
  });
1957
2397
  const accessibilityDescription = description || (!isEmpty ? `${title}. Radar chart with ${indicators.length} dimensions comparing ${data.series.length} series.` : void 0);
1958
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2398
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1959
2399
  ChartContainer,
1960
2400
  {
1961
2401
  ref,
1962
2402
  title,
1963
2403
  description: accessibilityDescription,
1964
2404
  height,
2405
+ minHeight,
2406
+ maxHeight,
1965
2407
  loading,
1966
2408
  error,
1967
2409
  empty: isEmpty,
@@ -1969,8 +2411,13 @@ var RadarChart = React12.forwardRef(
1969
2411
  className: cn(className),
1970
2412
  legend: !isEmpty && renderLegend ? renderLegend(legend.renderProps) : void 0,
1971
2413
  legendPosition: legendConfig?.position,
2414
+ dataTable: isEmpty ? void 0 : (0, import_charts_core12.radarTable)(data, indicators),
2415
+ showDataTable,
2416
+ format,
2417
+ exportable,
2418
+ exportImage,
1972
2419
  ...props,
1973
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { ref: containerRef, className: "h-full w-full" })
2420
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { ref: containerRef, className: "h-full w-full" })
1974
2421
  }
1975
2422
  );
1976
2423
  }
@@ -1981,16 +2428,16 @@ RadarChart.displayName = "RadarChart";
1981
2428
  var React13 = __toESM(require("react"), 1);
1982
2429
  var echarts10 = __toESM(require("echarts/core"), 1);
1983
2430
  var import_charts8 = require("echarts/charts");
1984
- var import_components8 = require("echarts/components");
1985
- var import_renderers8 = require("echarts/renderers");
1986
- var import_charts_core11 = require("@classic-homes/charts-core");
1987
- var import_jsx_runtime13 = require("react/jsx-runtime");
2431
+ var import_components9 = require("echarts/components");
2432
+ var import_renderers9 = require("echarts/renderers");
2433
+ var import_charts_core13 = require("@classic-homes/charts-core");
2434
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1988
2435
  echarts10.use([
1989
2436
  import_charts8.FunnelChart,
1990
- import_components8.TooltipComponent,
1991
- import_components8.LegendComponent,
1992
- import_components8.TitleComponent,
1993
- import_renderers8.CanvasRenderer
2437
+ import_components9.TooltipComponent,
2438
+ import_components9.LegendComponent,
2439
+ import_components9.TitleComponent,
2440
+ import_renderers9.CanvasRenderer
1994
2441
  ]);
1995
2442
  var FunnelChart = React13.forwardRef(
1996
2443
  ({
@@ -1998,6 +2445,8 @@ var FunnelChart = React13.forwardRef(
1998
2445
  description,
1999
2446
  data,
2000
2447
  height = 400,
2448
+ minHeight,
2449
+ maxHeight,
2001
2450
  loading,
2002
2451
  error,
2003
2452
  emptyMessage,
@@ -2008,6 +2457,8 @@ var FunnelChart = React13.forwardRef(
2008
2457
  sort = "descending",
2009
2458
  orientation = "vertical",
2010
2459
  showLabels = true,
2460
+ valueFormat,
2461
+ locale,
2011
2462
  labelFormatter,
2012
2463
  tooltipFormatter,
2013
2464
  tooltipValueFormatter,
@@ -2015,6 +2466,11 @@ var FunnelChart = React13.forwardRef(
2015
2466
  renderLegend,
2016
2467
  onLegendChange,
2017
2468
  option: optionOverride,
2469
+ onReady,
2470
+ events,
2471
+ showDataTable,
2472
+ exportable,
2473
+ patterns,
2018
2474
  onClick,
2019
2475
  class: className,
2020
2476
  ...props
@@ -2024,32 +2480,37 @@ var FunnelChart = React13.forwardRef(
2024
2480
  const legend = useChartLegend({
2025
2481
  names: data?.map((d) => d.name) ?? [],
2026
2482
  colors: data?.map((d) => d.color) ?? [],
2027
- palette: (0, import_charts_core11.getChartColors)(currentTheme).series,
2483
+ palette: (0, import_charts_core13.getChartColors)(currentTheme).series,
2028
2484
  config: legendConfig,
2029
2485
  title,
2030
2486
  onLegendChange
2031
2487
  });
2032
2488
  const customLegend = renderLegend !== void 0;
2489
+ const format = React13.useMemo(
2490
+ () => (0, import_charts_core13.resolveValueFormatter)(valueFormat, locale),
2491
+ [valueFormat, locale]
2492
+ );
2493
+ const valueFormatter = tooltipValueFormatter ?? format;
2033
2494
  const option = React13.useMemo(() => {
2034
2495
  if (isEmpty) return {};
2035
- const getLabel = (0, import_charts_core11.itemLabelLookup)(data);
2036
- const valueFormatter = tooltipFormatter === void 0 ? tooltipValueFormatter : void 0;
2496
+ const getLabel = (0, import_charts_core13.itemLabelLookup)(data);
2497
+ const templateFormatter = tooltipFormatter === void 0 ? valueFormatter : void 0;
2037
2498
  const tooltipBase = {
2038
2499
  trigger: "item",
2039
- formatter: valueFormatter ? (params) => {
2500
+ formatter: templateFormatter ? (params) => {
2040
2501
  const p = params;
2041
- return `${(0, import_charts_core11.escapeHtml)(p.seriesName)} <br/>${(0, import_charts_core11.escapeHtml)(p.name)}: ${(0, import_charts_core11.escapeHtml)((0, import_charts_core11.formatTooltipValue)(p.value, valueFormatter))}`;
2502
+ return `${(0, import_charts_core13.escapeHtml)(p.seriesName)} <br/>${(0, import_charts_core13.escapeHtml)(p.name)}: ${(0, import_charts_core13.escapeHtml)((0, import_charts_core13.formatTooltipValue)(p.value, templateFormatter))}`;
2042
2503
  } : "{a} <br/>{b}: {c}"
2043
2504
  };
2044
- return (0, import_charts_core11.mergeChartOption)(
2505
+ return (0, import_charts_core13.mergeChartOption)(
2045
2506
  {
2046
- tooltip: (0, import_charts_core11.buildTooltip)(tooltipBase, {
2507
+ tooltip: (0, import_charts_core13.buildTooltip)(tooltipBase, {
2047
2508
  show: showTooltip,
2048
2509
  formatter: tooltipFormatter,
2049
- valueFormatter: tooltipValueFormatter,
2510
+ valueFormatter,
2050
2511
  getLabel
2051
2512
  }),
2052
- legend: (0, import_charts_core11.buildLegend)(
2513
+ legend: (0, import_charts_core13.buildLegend)(
2053
2514
  data.map((d) => d.name),
2054
2515
  legendConfig,
2055
2516
  { show: showLegend, custom: customLegend }
@@ -2070,7 +2531,7 @@ var FunnelChart = React13.forwardRef(
2070
2531
  sort,
2071
2532
  orient: orientation,
2072
2533
  gap: 2,
2073
- label: (0, import_charts_core11.buildDataLabel)(
2534
+ label: (0, import_charts_core13.buildDataLabel)(
2074
2535
  {
2075
2536
  show: true,
2076
2537
  position: "inside",
@@ -2091,7 +2552,7 @@ var FunnelChart = React13.forwardRef(
2091
2552
  name: item.name,
2092
2553
  value: item.value,
2093
2554
  itemStyle: item.color ? { color: item.color } : void 0,
2094
- label: (0, import_charts_core11.pointLabel)(item.label, labelFormatter, { position: "inside" })
2555
+ label: (0, import_charts_core13.pointLabel)(item.label, labelFormatter, { position: "inside" })
2095
2556
  }))
2096
2557
  }
2097
2558
  ]
@@ -2109,39 +2570,41 @@ var FunnelChart = React13.forwardRef(
2109
2570
  title,
2110
2571
  labelFormatter,
2111
2572
  tooltipFormatter,
2112
- tooltipValueFormatter,
2573
+ valueFormatter,
2113
2574
  legendConfig,
2114
2575
  customLegend,
2115
2576
  optionOverride
2116
2577
  ]);
2117
- const latest = useLatestRef({ onClick });
2118
- const { containerRef } = useChart({
2578
+ const { containerRef, exportImage } = useChart({
2119
2579
  option,
2120
2580
  theme,
2121
2581
  animation,
2122
- onReady: (chart) => {
2123
- legend.attach(chart);
2124
- chart.on("click", (params) => {
2125
- const { onClick: onClick2 } = latest.current;
2126
- if (!onClick2) return;
2127
- onClick2({
2582
+ patterns,
2583
+ events: chartEvents(events, {
2584
+ click: onClick && ((params) => {
2585
+ if (!onClick) return;
2586
+ onClick({
2128
2587
  type: params.type || "click",
2129
2588
  componentType: params.componentType || "series",
2130
2589
  name: params.name || "",
2131
2590
  value: params.value,
2132
2591
  color: params.color
2133
2592
  });
2134
- });
2135
- }
2593
+ })
2594
+ }),
2595
+ onReady: legend.attach,
2596
+ onCreated: onReady
2136
2597
  });
2137
2598
  const accessibilityDescription = description || (!isEmpty ? `${title}. Funnel chart with ${data.length} stages.` : void 0);
2138
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2599
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2139
2600
  ChartContainer,
2140
2601
  {
2141
2602
  ref,
2142
2603
  title,
2143
2604
  description: accessibilityDescription,
2144
2605
  height,
2606
+ minHeight,
2607
+ maxHeight,
2145
2608
  loading,
2146
2609
  error,
2147
2610
  empty: isEmpty,
@@ -2149,8 +2612,13 @@ var FunnelChart = React13.forwardRef(
2149
2612
  className: cn(className),
2150
2613
  legend: !isEmpty && renderLegend ? renderLegend(legend.renderProps) : void 0,
2151
2614
  legendPosition: legendConfig?.position,
2615
+ dataTable: isEmpty ? void 0 : (0, import_charts_core13.sliceTable)(data, "Stage"),
2616
+ showDataTable,
2617
+ format,
2618
+ exportable,
2619
+ exportImage,
2152
2620
  ...props,
2153
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { ref: containerRef, className: "h-full w-full" })
2621
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { ref: containerRef, className: "h-full w-full" })
2154
2622
  }
2155
2623
  );
2156
2624
  }
@@ -2161,11 +2629,11 @@ FunnelChart.displayName = "FunnelChart";
2161
2629
  var React14 = __toESM(require("react"), 1);
2162
2630
  var echarts11 = __toESM(require("echarts/core"), 1);
2163
2631
  var import_charts9 = require("echarts/charts");
2164
- var import_components9 = require("echarts/components");
2165
- var import_renderers9 = require("echarts/renderers");
2166
- var import_charts_core12 = require("@classic-homes/charts-core");
2167
- var import_jsx_runtime14 = require("react/jsx-runtime");
2168
- echarts11.use([import_charts9.GaugeChart, import_components9.TitleComponent, import_components9.TooltipComponent, import_renderers9.CanvasRenderer]);
2632
+ var import_components10 = require("echarts/components");
2633
+ var import_renderers10 = require("echarts/renderers");
2634
+ var import_charts_core14 = require("@classic-homes/charts-core");
2635
+ var import_jsx_runtime15 = require("react/jsx-runtime");
2636
+ echarts11.use([import_charts9.GaugeChart, import_components10.TitleComponent, import_components10.TooltipComponent, import_renderers10.CanvasRenderer]);
2169
2637
  var GaugeChart = React14.forwardRef(
2170
2638
  ({
2171
2639
  title,
@@ -2174,6 +2642,8 @@ var GaugeChart = React14.forwardRef(
2174
2642
  min = 0,
2175
2643
  max = 100,
2176
2644
  height = 400,
2645
+ minHeight,
2646
+ maxHeight,
2177
2647
  loading,
2178
2648
  error,
2179
2649
  emptyMessage,
@@ -2183,21 +2653,33 @@ var GaugeChart = React14.forwardRef(
2183
2653
  showProgress = true,
2184
2654
  formatValue,
2185
2655
  showTooltip = true,
2656
+ valueFormat,
2657
+ locale,
2186
2658
  tooltipFormatter,
2187
2659
  tooltipValueFormatter,
2188
2660
  option: optionOverride,
2661
+ onReady,
2662
+ events,
2663
+ showDataTable,
2664
+ exportable,
2665
+ patterns,
2189
2666
  onClick,
2190
2667
  class: className,
2191
2668
  ...props
2192
2669
  }, ref) => {
2193
2670
  const currentTheme = useChartTheme(theme);
2194
- const chartColors = (0, import_charts_core12.getChartColors)(currentTheme);
2671
+ const chartColors = (0, import_charts_core14.getChartColors)(currentTheme);
2195
2672
  const reducedMotion = useReducedMotion();
2673
+ const format = React14.useMemo(
2674
+ () => (0, import_charts_core14.resolveValueFormatter)(valueFormat, locale),
2675
+ [valueFormat, locale]
2676
+ );
2677
+ const valueFormatter = formatValue ?? format;
2196
2678
  const option = React14.useMemo(() => {
2197
- return (0, import_charts_core12.mergeChartOption)(
2679
+ return (0, import_charts_core14.mergeChartOption)(
2198
2680
  {
2199
2681
  // No tooltip by default; one appears once its content is customised
2200
- tooltip: tooltipFormatter || tooltipValueFormatter ? (0, import_charts_core12.buildTooltip)(
2682
+ tooltip: tooltipFormatter || tooltipValueFormatter ? (0, import_charts_core14.buildTooltip)(
2201
2683
  { trigger: "item" },
2202
2684
  {
2203
2685
  show: showTooltip,
@@ -2264,7 +2746,7 @@ var GaugeChart = React14.forwardRef(
2264
2746
  fontSize: 28,
2265
2747
  fontWeight: "bold",
2266
2748
  offsetCenter: [0, "40%"],
2267
- formatter: formatValue || "{value}"
2749
+ formatter: valueFormatter || "{value}"
2268
2750
  },
2269
2751
  data: [
2270
2752
  {
@@ -2283,7 +2765,7 @@ var GaugeChart = React14.forwardRef(
2283
2765
  max,
2284
2766
  splitNumber,
2285
2767
  showProgress,
2286
- formatValue,
2768
+ valueFormatter,
2287
2769
  title,
2288
2770
  animation,
2289
2771
  reducedMotion,
@@ -2293,16 +2775,15 @@ var GaugeChart = React14.forwardRef(
2293
2775
  tooltipValueFormatter,
2294
2776
  optionOverride
2295
2777
  ]);
2296
- const latest = useLatestRef({ onClick });
2297
- const { containerRef } = useChart({
2778
+ const { containerRef, exportImage } = useChart({
2298
2779
  option,
2299
- theme: currentTheme === import_charts_core12.THEME_DARK ? "dark" : "light",
2780
+ theme: currentTheme === import_charts_core14.THEME_DARK ? "dark" : "light",
2300
2781
  animation,
2301
- onReady: (chart) => {
2302
- chart.on("click", (params) => {
2303
- const { onClick: onClick2 } = latest.current;
2304
- if (!onClick2) return;
2305
- onClick2({
2782
+ patterns,
2783
+ events: chartEvents(events, {
2784
+ click: onClick && ((params) => {
2785
+ if (!onClick) return;
2786
+ onClick({
2306
2787
  type: params.type || "click",
2307
2788
  componentType: params.componentType || "series",
2308
2789
  seriesIndex: params.seriesIndex,
@@ -2312,23 +2793,35 @@ var GaugeChart = React14.forwardRef(
2312
2793
  value: params.value,
2313
2794
  color: params.color
2314
2795
  });
2315
- });
2316
- }
2796
+ })
2797
+ }),
2798
+ onCreated: onReady
2317
2799
  });
2318
- const accessibilityDescription = description || `${title}. Gauge showing value ${value} on scale from ${min} to ${max}.`;
2319
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2800
+ const show = (n) => valueFormatter ? valueFormatter(n) : String(n);
2801
+ const accessibilityDescription = description || `${title}. Gauge showing value ${show(value)} on scale from ${show(min)} to ${show(max)}.`;
2802
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2320
2803
  ChartContainer,
2321
2804
  {
2322
2805
  ref,
2323
2806
  title,
2324
2807
  description: accessibilityDescription,
2325
2808
  height,
2809
+ minHeight,
2810
+ maxHeight,
2326
2811
  loading,
2327
2812
  error,
2328
2813
  emptyMessage,
2329
2814
  className: cn(className),
2815
+ dataTable: {
2816
+ headers: ["Metric", "Value", "Minimum", "Maximum"],
2817
+ rows: [[title, value, min, max]]
2818
+ },
2819
+ showDataTable,
2820
+ format,
2821
+ exportable,
2822
+ exportImage,
2330
2823
  ...props,
2331
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { ref: containerRef, className: "h-full w-full" })
2824
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { ref: containerRef, className: "h-full w-full" })
2332
2825
  }
2333
2826
  );
2334
2827
  }
@@ -2339,17 +2832,17 @@ GaugeChart.displayName = "GaugeChart";
2339
2832
  var React15 = __toESM(require("react"), 1);
2340
2833
  var echarts12 = __toESM(require("echarts/core"), 1);
2341
2834
  var import_charts10 = require("echarts/charts");
2342
- var import_components10 = require("echarts/components");
2343
- var import_renderers10 = require("echarts/renderers");
2344
- var import_charts_core13 = require("@classic-homes/charts-core");
2345
- var import_jsx_runtime15 = require("react/jsx-runtime");
2835
+ var import_components11 = require("echarts/components");
2836
+ var import_renderers11 = require("echarts/renderers");
2837
+ var import_charts_core15 = require("@classic-homes/charts-core");
2838
+ var import_jsx_runtime16 = require("react/jsx-runtime");
2346
2839
  echarts12.use([
2347
2840
  import_charts10.HeatmapChart,
2348
- import_components10.GridComponent,
2349
- import_components10.TooltipComponent,
2350
- import_components10.TitleComponent,
2351
- import_components10.VisualMapComponent,
2352
- import_renderers10.CanvasRenderer
2841
+ import_components11.GridComponent,
2842
+ import_components11.TooltipComponent,
2843
+ import_components11.TitleComponent,
2844
+ import_components11.VisualMapComponent,
2845
+ import_renderers11.CanvasRenderer
2353
2846
  ]);
2354
2847
  var HeatmapChart = React15.forwardRef(
2355
2848
  ({
@@ -2359,6 +2852,8 @@ var HeatmapChart = React15.forwardRef(
2359
2852
  xAxis,
2360
2853
  yAxis,
2361
2854
  height = 400,
2855
+ minHeight,
2856
+ maxHeight,
2362
2857
  loading,
2363
2858
  error,
2364
2859
  emptyMessage,
@@ -2369,9 +2864,16 @@ var HeatmapChart = React15.forwardRef(
2369
2864
  labelFormatter,
2370
2865
  xAxisConfig,
2371
2866
  yAxisConfig,
2867
+ valueFormat,
2868
+ locale,
2372
2869
  tooltipFormatter,
2373
2870
  tooltipValueFormatter,
2374
2871
  option: optionOverride,
2872
+ onReady,
2873
+ events,
2874
+ showDataTable,
2875
+ exportable,
2876
+ patterns,
2375
2877
  onClick,
2376
2878
  class: className,
2377
2879
  ...props
@@ -2385,24 +2887,29 @@ var HeatmapChart = React15.forwardRef(
2385
2887
  }
2386
2888
  const minValue = data?.min ?? dataMin;
2387
2889
  const maxValue = data?.max ?? dataMax;
2890
+ const format = React15.useMemo(
2891
+ () => (0, import_charts_core15.resolveValueFormatter)(valueFormat, locale),
2892
+ [valueFormat, locale]
2893
+ );
2894
+ const valueFormatter = tooltipValueFormatter ?? format;
2388
2895
  const option = React15.useMemo(() => {
2389
2896
  if (isEmpty) return {};
2390
- return (0, import_charts_core13.mergeChartOption)(
2897
+ return (0, import_charts_core15.mergeChartOption)(
2391
2898
  {
2392
- tooltip: (0, import_charts_core13.buildTooltip)(
2899
+ tooltip: (0, import_charts_core15.buildTooltip)(
2393
2900
  {
2394
2901
  position: "top",
2395
2902
  formatter: (params) => {
2396
2903
  const p = params;
2397
2904
  if (!p.value) return "";
2398
2905
  const [xIdx, yIdx, value] = p.value;
2399
- return `${(0, import_charts_core13.escapeHtml)(xAxis[xIdx])} / ${(0, import_charts_core13.escapeHtml)(yAxis[yIdx])}: ${(0, import_charts_core13.escapeHtml)((0, import_charts_core13.formatTooltipValue)(value, tooltipValueFormatter))}`;
2906
+ return `${(0, import_charts_core15.escapeHtml)(xAxis[xIdx])} / ${(0, import_charts_core15.escapeHtml)(yAxis[yIdx])}: ${(0, import_charts_core15.escapeHtml)((0, import_charts_core15.formatTooltipValue)(value, valueFormatter))}`;
2400
2907
  }
2401
2908
  },
2402
2909
  {
2403
2910
  show: showTooltip,
2404
2911
  formatter: tooltipFormatter,
2405
- valueFormatter: tooltipValueFormatter
2912
+ valueFormatter
2406
2913
  }
2407
2914
  ),
2408
2915
  grid: {
@@ -2411,7 +2918,7 @@ var HeatmapChart = React15.forwardRef(
2411
2918
  bottom: "3%",
2412
2919
  containLabel: true
2413
2920
  },
2414
- xAxis: (0, import_charts_core13.buildAxis)(
2921
+ xAxis: (0, import_charts_core15.buildAxis)(
2415
2922
  {
2416
2923
  type: "category",
2417
2924
  data: xAxis,
@@ -2421,7 +2928,7 @@ var HeatmapChart = React15.forwardRef(
2421
2928
  },
2422
2929
  xAxisConfig
2423
2930
  ),
2424
- yAxis: (0, import_charts_core13.buildAxis)(
2931
+ yAxis: (0, import_charts_core15.buildAxis)(
2425
2932
  {
2426
2933
  type: "category",
2427
2934
  data: yAxis,
@@ -2437,14 +2944,15 @@ var HeatmapChart = React15.forwardRef(
2437
2944
  calculable: true,
2438
2945
  orient: "vertical",
2439
2946
  right: "0%",
2440
- top: "center"
2947
+ top: "center",
2948
+ formatter: valueFormatter ? (value) => valueFormatter(value) : void 0
2441
2949
  },
2442
2950
  series: [
2443
2951
  {
2444
2952
  name: title,
2445
2953
  type: "heatmap",
2446
2954
  data: data.data,
2447
- label: (0, import_charts_core13.buildDataLabel)({ show: true }, void 0, {
2955
+ label: (0, import_charts_core15.buildDataLabel)({ show: true }, void 0, {
2448
2956
  show: showValues,
2449
2957
  formatter: labelFormatter
2450
2958
  }),
@@ -2473,46 +2981,53 @@ var HeatmapChart = React15.forwardRef(
2473
2981
  xAxisConfig,
2474
2982
  yAxisConfig,
2475
2983
  tooltipFormatter,
2476
- tooltipValueFormatter,
2984
+ valueFormatter,
2477
2985
  optionOverride
2478
2986
  ]);
2479
- const latest = useLatestRef({ onClick, xAxis, yAxis });
2480
- const { containerRef } = useChart({
2987
+ const { containerRef, exportImage } = useChart({
2481
2988
  option,
2482
2989
  theme,
2483
2990
  animation,
2484
- onReady: (chart) => {
2485
- chart.on("click", (params) => {
2486
- const { onClick: onClick2, xAxis: xAxis2, yAxis: yAxis2 } = latest.current;
2487
- if (!onClick2) return;
2991
+ patterns,
2992
+ events: chartEvents(events, {
2993
+ click: onClick && ((params) => {
2994
+ if (!onClick) return;
2488
2995
  const [xIdx, yIdx, value] = params.value || [0, 0, 0];
2489
- onClick2({
2996
+ onClick({
2490
2997
  type: params.type || "click",
2491
2998
  componentType: params.componentType || "series",
2492
2999
  xIndex: xIdx,
2493
3000
  yIndex: yIdx,
2494
- xLabel: xAxis2[xIdx],
2495
- yLabel: yAxis2[yIdx],
3001
+ xLabel: xAxis[xIdx],
3002
+ yLabel: yAxis[yIdx],
2496
3003
  value
2497
3004
  });
2498
- });
2499
- }
3005
+ })
3006
+ }),
3007
+ onCreated: onReady
2500
3008
  });
2501
3009
  const accessibilityDescription = description || (!isEmpty ? `${title}. Heatmap with ${xAxis.length} columns and ${yAxis.length} rows.` : void 0);
2502
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3010
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2503
3011
  ChartContainer,
2504
3012
  {
2505
3013
  ref,
2506
3014
  title,
2507
3015
  description: accessibilityDescription,
2508
3016
  height,
3017
+ minHeight,
3018
+ maxHeight,
2509
3019
  loading,
2510
3020
  error,
2511
3021
  empty: isEmpty,
2512
3022
  emptyMessage,
2513
3023
  className: cn(className),
3024
+ dataTable: isEmpty ? void 0 : (0, import_charts_core15.heatmapTable)(data, xAxis, yAxis),
3025
+ showDataTable,
3026
+ format,
3027
+ exportable,
3028
+ exportImage,
2514
3029
  ...props,
2515
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { ref: containerRef, className: "h-full w-full" })
3030
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref: containerRef, className: "h-full w-full" })
2516
3031
  }
2517
3032
  );
2518
3033
  }
@@ -2523,11 +3038,11 @@ HeatmapChart.displayName = "HeatmapChart";
2523
3038
  var React16 = __toESM(require("react"), 1);
2524
3039
  var echarts13 = __toESM(require("echarts/core"), 1);
2525
3040
  var import_charts11 = require("echarts/charts");
2526
- var import_components11 = require("echarts/components");
2527
- var import_renderers11 = require("echarts/renderers");
2528
- var import_charts_core14 = require("@classic-homes/charts-core");
2529
- var import_jsx_runtime16 = require("react/jsx-runtime");
2530
- echarts13.use([import_charts11.TreemapChart, import_components11.TooltipComponent, import_components11.TitleComponent, import_renderers11.CanvasRenderer]);
3041
+ var import_components12 = require("echarts/components");
3042
+ var import_renderers12 = require("echarts/renderers");
3043
+ var import_charts_core16 = require("@classic-homes/charts-core");
3044
+ var import_jsx_runtime17 = require("react/jsx-runtime");
3045
+ echarts13.use([import_charts11.TreemapChart, import_components12.TooltipComponent, import_components12.TitleComponent, import_renderers12.CanvasRenderer]);
2531
3046
  var TreemapChart = React16.forwardRef(
2532
3047
  ({
2533
3048
  title,
@@ -2535,6 +3050,8 @@ var TreemapChart = React16.forwardRef(
2535
3050
  data,
2536
3051
  levels,
2537
3052
  height = 400,
3053
+ minHeight,
3054
+ maxHeight,
2538
3055
  loading,
2539
3056
  error,
2540
3057
  emptyMessage,
@@ -2542,36 +3059,48 @@ var TreemapChart = React16.forwardRef(
2542
3059
  animation = true,
2543
3060
  showTooltip = true,
2544
3061
  labelFormatter,
3062
+ valueFormat,
3063
+ locale,
2545
3064
  tooltipFormatter,
2546
3065
  tooltipValueFormatter,
2547
3066
  option: optionOverride,
3067
+ onReady,
3068
+ events,
3069
+ showDataTable,
3070
+ exportable,
3071
+ patterns,
2548
3072
  onClick,
2549
3073
  class: className,
2550
3074
  ...props
2551
3075
  }, ref) => {
2552
3076
  const isEmpty = !data?.length;
2553
3077
  const currentTheme = useChartTheme(theme);
2554
- const chartColors = (0, import_charts_core14.getChartColors)(currentTheme);
3078
+ const chartColors = (0, import_charts_core16.getChartColors)(currentTheme);
3079
+ const format = React16.useMemo(
3080
+ () => (0, import_charts_core16.resolveValueFormatter)(valueFormat, locale),
3081
+ [valueFormat, locale]
3082
+ );
3083
+ const valueFormatter = tooltipValueFormatter ?? format;
2555
3084
  const option = React16.useMemo(() => {
2556
3085
  if (isEmpty) return {};
2557
3086
  const toNode = (node) => ({
2558
3087
  ...node,
2559
3088
  children: node.children?.map(toNode),
2560
- label: (0, import_charts_core14.pointLabel)(node.label, labelFormatter)
3089
+ label: (0, import_charts_core16.pointLabel)(node.label, labelFormatter)
2561
3090
  });
2562
- return (0, import_charts_core14.mergeChartOption)(
3091
+ return (0, import_charts_core16.mergeChartOption)(
2563
3092
  {
2564
- tooltip: (0, import_charts_core14.buildTooltip)(
3093
+ tooltip: (0, import_charts_core16.buildTooltip)(
2565
3094
  {
2566
3095
  formatter: (params) => {
2567
3096
  const p = params;
2568
- return `${(0, import_charts_core14.escapeHtml)(p.name)}: ${(0, import_charts_core14.escapeHtml)((0, import_charts_core14.formatTooltipValue)(p.value, tooltipValueFormatter))}`;
3097
+ return `${(0, import_charts_core16.escapeHtml)(p.name)}: ${(0, import_charts_core16.escapeHtml)((0, import_charts_core16.formatTooltipValue)(p.value, valueFormatter))}`;
2569
3098
  }
2570
3099
  },
2571
3100
  {
2572
3101
  show: showTooltip,
2573
3102
  formatter: tooltipFormatter,
2574
- valueFormatter: tooltipValueFormatter
3103
+ valueFormatter
2575
3104
  }
2576
3105
  ),
2577
3106
  series: [
@@ -2606,10 +3135,10 @@ var TreemapChart = React16.forwardRef(
2606
3135
  colorSaturation: [0.3, 0.5]
2607
3136
  }
2608
3137
  ],
2609
- label: (0, import_charts_core14.buildDataLabel)({ show: true, formatter: "{b}" }, void 0, {
3138
+ label: (0, import_charts_core16.buildDataLabel)({ show: true, formatter: "{b}" }, void 0, {
2610
3139
  show: true,
2611
3140
  formatter: labelFormatter,
2612
- getLabel: (0, import_charts_core14.nameLabelLookup)(data)
3141
+ getLabel: (0, import_charts_core16.nameLabelLookup)(data)
2613
3142
  }),
2614
3143
  upperLabel: {
2615
3144
  show: true,
@@ -2631,20 +3160,19 @@ var TreemapChart = React16.forwardRef(
2631
3160
  chartColors,
2632
3161
  labelFormatter,
2633
3162
  tooltipFormatter,
2634
- tooltipValueFormatter,
3163
+ valueFormatter,
2635
3164
  optionOverride
2636
3165
  ]);
2637
- const latest = useLatestRef({ onClick });
2638
- const { containerRef } = useChart({
3166
+ const { containerRef, exportImage } = useChart({
2639
3167
  option,
2640
- theme: currentTheme === import_charts_core14.THEME_DARK ? "dark" : "light",
3168
+ theme: currentTheme === import_charts_core16.THEME_DARK ? "dark" : "light",
2641
3169
  animation,
2642
- onReady: (chart) => {
2643
- chart.on("click", (params) => {
2644
- const { onClick: onClick2 } = latest.current;
2645
- if (!onClick2) return;
3170
+ patterns,
3171
+ events: chartEvents(events, {
3172
+ click: onClick && ((params) => {
3173
+ if (!onClick) return;
2646
3174
  const treePathInfo = params.treePathInfo || [];
2647
- onClick2({
3175
+ onClick({
2648
3176
  type: params.type || "click",
2649
3177
  componentType: params.componentType || "series",
2650
3178
  name: params.name || "",
@@ -2652,24 +3180,32 @@ var TreemapChart = React16.forwardRef(
2652
3180
  path: treePathInfo.map((item) => item.name || ""),
2653
3181
  depth: treePathInfo.length - 1
2654
3182
  });
2655
- });
2656
- }
3183
+ })
3184
+ }),
3185
+ onCreated: onReady
2657
3186
  });
2658
3187
  const accessibilityDescription = description || (!isEmpty ? `${title}. Treemap chart showing hierarchical data.` : void 0);
2659
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3188
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2660
3189
  ChartContainer,
2661
3190
  {
2662
3191
  ref,
2663
3192
  title,
2664
3193
  description: accessibilityDescription,
2665
3194
  height,
3195
+ minHeight,
3196
+ maxHeight,
2666
3197
  loading,
2667
3198
  error,
2668
3199
  empty: isEmpty,
2669
3200
  emptyMessage,
2670
3201
  className: cn(className),
3202
+ dataTable: isEmpty ? void 0 : (0, import_charts_core16.treemapTable)(data),
3203
+ showDataTable,
3204
+ format,
3205
+ exportable,
3206
+ exportImage,
2671
3207
  ...props,
2672
- children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref: containerRef, className: "h-full w-full" })
3208
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { ref: containerRef, className: "h-full w-full" })
2673
3209
  }
2674
3210
  );
2675
3211
  }
@@ -2680,18 +3216,18 @@ TreemapChart.displayName = "TreemapChart";
2680
3216
  var React17 = __toESM(require("react"), 1);
2681
3217
  var echarts14 = __toESM(require("echarts/core"), 1);
2682
3218
  var import_charts12 = require("echarts/charts");
2683
- var import_components12 = require("echarts/components");
2684
- var import_renderers12 = require("echarts/renderers");
2685
- var import_charts_core15 = require("@classic-homes/charts-core");
2686
- var import_jsx_runtime17 = require("react/jsx-runtime");
3219
+ var import_components13 = require("echarts/components");
3220
+ var import_renderers13 = require("echarts/renderers");
3221
+ var import_charts_core17 = require("@classic-homes/charts-core");
3222
+ var import_jsx_runtime18 = require("react/jsx-runtime");
2687
3223
  echarts14.use([
2688
3224
  import_charts12.CandlestickChart,
2689
3225
  import_charts12.BarChart,
2690
- import_components12.GridComponent,
2691
- import_components12.TooltipComponent,
2692
- import_components12.TitleComponent,
2693
- import_components12.DataZoomComponent,
2694
- import_renderers12.CanvasRenderer
3226
+ import_components13.GridComponent,
3227
+ import_components13.TooltipComponent,
3228
+ import_components13.TitleComponent,
3229
+ import_components13.DataZoomComponent,
3230
+ import_renderers13.CanvasRenderer
2695
3231
  ]);
2696
3232
  var CandlestickChart = React17.forwardRef(
2697
3233
  ({
@@ -2699,6 +3235,8 @@ var CandlestickChart = React17.forwardRef(
2699
3235
  description,
2700
3236
  data,
2701
3237
  height = 400,
3238
+ minHeight,
3239
+ maxHeight,
2702
3240
  loading,
2703
3241
  error,
2704
3242
  emptyMessage,
@@ -2706,18 +3244,31 @@ var CandlestickChart = React17.forwardRef(
2706
3244
  animation = true,
2707
3245
  showTooltip = true,
2708
3246
  showVolume = false,
3247
+ zoomStart = 80,
2709
3248
  xAxisConfig,
2710
3249
  yAxisConfig,
3250
+ valueFormat,
3251
+ locale,
2711
3252
  tooltipFormatter,
2712
3253
  tooltipValueFormatter,
2713
3254
  option: optionOverride,
3255
+ onReady,
3256
+ events,
3257
+ showDataTable,
3258
+ exportable,
3259
+ patterns,
2714
3260
  onClick,
2715
3261
  class: className,
2716
3262
  ...props
2717
3263
  }, ref) => {
2718
3264
  const isEmpty = !data?.dates?.length || !data?.data?.length;
2719
3265
  const currentTheme = useChartTheme(theme);
2720
- const chartColors = (0, import_charts_core15.getChartColors)(currentTheme);
3266
+ const chartColors = (0, import_charts_core17.getChartColors)(currentTheme);
3267
+ const format = React17.useMemo(
3268
+ () => (0, import_charts_core17.resolveValueFormatter)(valueFormat, locale),
3269
+ [valueFormat, locale]
3270
+ );
3271
+ const valueFormatter = tooltipValueFormatter ?? format;
2721
3272
  const option = React17.useMemo(() => {
2722
3273
  if (isEmpty) return {};
2723
3274
  const candlestickData = data.data.map((item) => [item.open, item.close, item.low, item.high]);
@@ -2745,7 +3296,7 @@ var CandlestickChart = React17.forwardRef(
2745
3296
  }
2746
3297
  ];
2747
3298
  const xAxisArr = [
2748
- (0, import_charts_core15.buildAxis)(
3299
+ (0, import_charts_core17.buildAxis)(
2749
3300
  {
2750
3301
  type: "category",
2751
3302
  data: data.dates,
@@ -2759,7 +3310,7 @@ var CandlestickChart = React17.forwardRef(
2759
3310
  )
2760
3311
  ];
2761
3312
  const yAxisArr = [
2762
- (0, import_charts_core15.buildAxis)(
3313
+ (0, import_charts_core17.buildAxis)(
2763
3314
  {
2764
3315
  scale: true,
2765
3316
  splitArea: {
@@ -2808,9 +3359,9 @@ var CandlestickChart = React17.forwardRef(
2808
3359
  }
2809
3360
  });
2810
3361
  }
2811
- return (0, import_charts_core15.mergeChartOption)(
3362
+ return (0, import_charts_core17.mergeChartOption)(
2812
3363
  {
2813
- tooltip: (0, import_charts_core15.buildTooltip)(
3364
+ tooltip: (0, import_charts_core17.buildTooltip)(
2814
3365
  {
2815
3366
  trigger: "axis",
2816
3367
  axisPointer: {
@@ -2820,7 +3371,7 @@ var CandlestickChart = React17.forwardRef(
2820
3371
  {
2821
3372
  show: showTooltip,
2822
3373
  formatter: tooltipFormatter,
2823
- valueFormatter: tooltipValueFormatter
3374
+ valueFormatter
2824
3375
  }
2825
3376
  ),
2826
3377
  grid: gridArr,
@@ -2829,14 +3380,14 @@ var CandlestickChart = React17.forwardRef(
2829
3380
  dataZoom: [
2830
3381
  {
2831
3382
  type: "inside",
2832
- start: 80,
3383
+ start: zoomStart,
2833
3384
  end: 100
2834
3385
  },
2835
3386
  {
2836
3387
  show: true,
2837
3388
  type: "slider",
2838
3389
  top: "90%",
2839
- start: 80,
3390
+ start: zoomStart,
2840
3391
  end: 100
2841
3392
  }
2842
3393
  ],
@@ -2849,54 +3400,62 @@ var CandlestickChart = React17.forwardRef(
2849
3400
  isEmpty,
2850
3401
  showTooltip,
2851
3402
  showVolume,
3403
+ zoomStart,
2852
3404
  title,
2853
3405
  chartColors,
2854
3406
  xAxisConfig,
2855
3407
  yAxisConfig,
2856
3408
  tooltipFormatter,
2857
- tooltipValueFormatter,
3409
+ valueFormatter,
2858
3410
  optionOverride
2859
3411
  ]);
2860
- const latest = useLatestRef({ onClick, data });
2861
- const { containerRef } = useChart({
3412
+ const { containerRef, exportImage } = useChart({
2862
3413
  option,
2863
- theme: currentTheme === import_charts_core15.THEME_DARK ? "dark" : "light",
3414
+ theme: currentTheme === import_charts_core17.THEME_DARK ? "dark" : "light",
2864
3415
  animation,
2865
- onReady: (chart) => {
2866
- chart.on("click", (params) => {
2867
- const { onClick: onClick2, data: data2 } = latest.current;
2868
- if (!onClick2) return;
3416
+ patterns,
3417
+ events: chartEvents(events, {
3418
+ click: onClick && ((params) => {
3419
+ if (!onClick) return;
2869
3420
  const dataIndex = params.dataIndex || 0;
2870
- const item = data2.data[dataIndex];
3421
+ const item = data.data[dataIndex];
2871
3422
  if (!item) return;
2872
- onClick2({
3423
+ onClick({
2873
3424
  type: params.type || "click",
2874
3425
  componentType: params.componentType || "series",
2875
- date: data2.dates[dataIndex],
3426
+ date: data.dates[dataIndex],
2876
3427
  open: item.open,
2877
3428
  close: item.close,
2878
3429
  high: item.high,
2879
3430
  low: item.low,
2880
- volume: data2.volume?.[dataIndex]
3431
+ volume: data.volume?.[dataIndex]
2881
3432
  });
2882
- });
2883
- }
3433
+ })
3434
+ }),
3435
+ onCreated: onReady
2884
3436
  });
2885
3437
  const accessibilityDescription = description || (!isEmpty ? `${title}. Candlestick chart with ${data.dates.length} data points.` : void 0);
2886
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3438
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2887
3439
  ChartContainer,
2888
3440
  {
2889
3441
  ref,
2890
3442
  title,
2891
3443
  description: accessibilityDescription,
2892
3444
  height,
3445
+ minHeight,
3446
+ maxHeight,
2893
3447
  loading,
2894
3448
  error,
2895
3449
  empty: isEmpty,
2896
3450
  emptyMessage,
2897
3451
  className: cn(className),
3452
+ dataTable: isEmpty ? void 0 : (0, import_charts_core17.candlestickTable)(data),
3453
+ showDataTable,
3454
+ format,
3455
+ exportable,
3456
+ exportImage,
2898
3457
  ...props,
2899
- children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { ref: containerRef, className: "h-full w-full" })
3458
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { ref: containerRef, className: "h-full w-full" })
2900
3459
  }
2901
3460
  );
2902
3461
  }
@@ -2907,17 +3466,19 @@ CandlestickChart.displayName = "CandlestickChart";
2907
3466
  var React18 = __toESM(require("react"), 1);
2908
3467
  var echarts15 = __toESM(require("echarts/core"), 1);
2909
3468
  var import_charts13 = require("echarts/charts");
2910
- var import_components13 = require("echarts/components");
2911
- var import_renderers13 = require("echarts/renderers");
2912
- var import_charts_core16 = require("@classic-homes/charts-core");
2913
- var import_jsx_runtime18 = require("react/jsx-runtime");
2914
- echarts15.use([import_charts13.SankeyChart, import_components13.TooltipComponent, import_components13.TitleComponent, import_renderers13.CanvasRenderer]);
3469
+ var import_components14 = require("echarts/components");
3470
+ var import_renderers14 = require("echarts/renderers");
3471
+ var import_charts_core18 = require("@classic-homes/charts-core");
3472
+ var import_jsx_runtime19 = require("react/jsx-runtime");
3473
+ echarts15.use([import_charts13.SankeyChart, import_components14.TooltipComponent, import_components14.TitleComponent, import_renderers14.CanvasRenderer]);
2915
3474
  var SankeyChart = React18.forwardRef(
2916
3475
  ({
2917
3476
  title,
2918
3477
  description,
2919
3478
  data,
2920
3479
  height = 400,
3480
+ minHeight,
3481
+ maxHeight,
2921
3482
  loading,
2922
3483
  error,
2923
3484
  emptyMessage,
@@ -2926,19 +3487,31 @@ var SankeyChart = React18.forwardRef(
2926
3487
  showTooltip = true,
2927
3488
  orient = "horizontal",
2928
3489
  labelFormatter,
3490
+ valueFormat,
3491
+ locale,
2929
3492
  tooltipFormatter,
2930
3493
  tooltipValueFormatter,
2931
3494
  option: optionOverride,
3495
+ onReady,
3496
+ events,
3497
+ showDataTable,
3498
+ exportable,
3499
+ patterns,
2932
3500
  onClick,
2933
3501
  class: className,
2934
3502
  ...props
2935
3503
  }, ref) => {
2936
3504
  const isEmpty = !data?.nodes?.length || !data?.links?.length;
3505
+ const format = React18.useMemo(
3506
+ () => (0, import_charts_core18.resolveValueFormatter)(valueFormat, locale),
3507
+ [valueFormat, locale]
3508
+ );
3509
+ const valueFormatter = tooltipValueFormatter ?? format;
2937
3510
  const option = React18.useMemo(() => {
2938
3511
  if (isEmpty) return {};
2939
- return (0, import_charts_core16.mergeChartOption)(
3512
+ return (0, import_charts_core18.mergeChartOption)(
2940
3513
  {
2941
- tooltip: (0, import_charts_core16.buildTooltip)(
3514
+ tooltip: (0, import_charts_core18.buildTooltip)(
2942
3515
  {
2943
3516
  trigger: "item",
2944
3517
  triggerOn: "mousemove"
@@ -2946,7 +3519,7 @@ var SankeyChart = React18.forwardRef(
2946
3519
  {
2947
3520
  show: showTooltip,
2948
3521
  formatter: tooltipFormatter,
2949
- valueFormatter: tooltipValueFormatter
3522
+ valueFormatter
2950
3523
  }
2951
3524
  ),
2952
3525
  series: [
@@ -2959,7 +3532,7 @@ var SankeyChart = React18.forwardRef(
2959
3532
  data: data.nodes.map((node) => ({
2960
3533
  name: node.name,
2961
3534
  itemStyle: node.color ? { color: node.color } : void 0,
2962
- label: (0, import_charts_core16.pointLabel)(node.label, labelFormatter)
3535
+ label: (0, import_charts_core18.pointLabel)(node.label, labelFormatter)
2963
3536
  })),
2964
3537
  links: data.links.map((link) => ({
2965
3538
  source: link.source,
@@ -2970,12 +3543,12 @@ var SankeyChart = React18.forwardRef(
2970
3543
  color: "gradient",
2971
3544
  curveness: 0.5
2972
3545
  },
2973
- label: (0, import_charts_core16.buildDataLabel)(
3546
+ label: (0, import_charts_core18.buildDataLabel)(
2974
3547
  {
2975
3548
  position: orient === "horizontal" ? "right" : "bottom"
2976
3549
  },
2977
3550
  void 0,
2978
- { show: true, formatter: labelFormatter, getLabel: (0, import_charts_core16.nameLabelLookup)(data.nodes) }
3551
+ { show: true, formatter: labelFormatter, getLabel: (0, import_charts_core18.nameLabelLookup)(data.nodes) }
2979
3552
  )
2980
3553
  }
2981
3554
  ]
@@ -2989,20 +3562,19 @@ var SankeyChart = React18.forwardRef(
2989
3562
  orient,
2990
3563
  labelFormatter,
2991
3564
  tooltipFormatter,
2992
- tooltipValueFormatter,
3565
+ valueFormatter,
2993
3566
  optionOverride
2994
3567
  ]);
2995
- const latest = useLatestRef({ onClick });
2996
- const { containerRef } = useChart({
3568
+ const { containerRef, exportImage } = useChart({
2997
3569
  option,
2998
3570
  theme,
2999
3571
  animation,
3000
- onReady: (chart) => {
3001
- chart.on("click", (params) => {
3002
- const { onClick: onClick2 } = latest.current;
3003
- if (!onClick2) return;
3572
+ patterns,
3573
+ events: chartEvents(events, {
3574
+ click: onClick && ((params) => {
3575
+ if (!onClick) return;
3004
3576
  const isEdge = params.dataType === "edge";
3005
- onClick2({
3577
+ onClick({
3006
3578
  type: params.type || "click",
3007
3579
  componentType: params.componentType || "series",
3008
3580
  dataType: isEdge ? "edge" : "node",
@@ -3011,24 +3583,32 @@ var SankeyChart = React18.forwardRef(
3011
3583
  source: isEdge ? params.data?.source : void 0,
3012
3584
  target: isEdge ? params.data?.target : void 0
3013
3585
  });
3014
- });
3015
- }
3586
+ })
3587
+ }),
3588
+ onCreated: onReady
3016
3589
  });
3017
3590
  const accessibilityDescription = description || (!isEmpty ? `${title}. Sankey diagram with ${data.nodes.length} nodes and ${data.links.length} links.` : void 0);
3018
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3591
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3019
3592
  ChartContainer,
3020
3593
  {
3021
3594
  ref,
3022
3595
  title,
3023
3596
  description: accessibilityDescription,
3024
3597
  height,
3598
+ minHeight,
3599
+ maxHeight,
3025
3600
  loading,
3026
3601
  error,
3027
3602
  empty: isEmpty,
3028
3603
  emptyMessage,
3029
3604
  className: cn(className),
3605
+ dataTable: isEmpty ? void 0 : (0, import_charts_core18.sankeyTable)(data),
3606
+ showDataTable,
3607
+ format,
3608
+ exportable,
3609
+ exportImage,
3030
3610
  ...props,
3031
- children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { ref: containerRef, className: "h-full w-full" })
3611
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { ref: containerRef, className: "h-full w-full" })
3032
3612
  }
3033
3613
  );
3034
3614
  }
@@ -3040,6 +3620,7 @@ SankeyChart.displayName = "SankeyChart";
3040
3620
  BarChart,
3041
3621
  CandlestickChart,
3042
3622
  ChartContainer,
3623
+ ChartDataTable,
3043
3624
  ChartEmpty,
3044
3625
  ChartError,
3045
3626
  ChartLegend,
@@ -3055,7 +3636,9 @@ SankeyChart.displayName = "SankeyChart";
3055
3636
  ScatterChart,
3056
3637
  TreemapChart,
3057
3638
  cn,
3639
+ exportChartImage,
3058
3640
  registerClassicThemes,
3641
+ registerEchartsModules,
3059
3642
  useChart,
3060
3643
  useChartLegend,
3061
3644
  useChartResize,