@classic-homes/charts-react 0.2.2 → 0.4.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,55 @@ var BarChart = React7.forwardRef(
826
1107
  orientation = "vertical",
827
1108
  stacked = false,
828
1109
  showValues = false,
1110
+ showTotal = false,
1111
+ valueFormat,
1112
+ locale,
829
1113
  labelFormatter,
830
1114
  xAxisConfig,
831
1115
  yAxisConfig,
1116
+ referenceLines,
1117
+ referenceBands,
1118
+ dataZoom,
832
1119
  tooltipFormatter,
833
1120
  tooltipValueFormatter,
834
1121
  legend: legendConfig,
835
1122
  renderLegend,
836
1123
  onLegendChange,
837
1124
  option: optionOverride,
1125
+ onReady,
1126
+ events,
1127
+ showDataTable,
1128
+ exportable,
1129
+ patterns,
838
1130
  onClick,
1131
+ onHover,
839
1132
  class: className,
840
1133
  ...props
841
1134
  }, ref) => {
842
1135
  const isEmpty = !data?.categories?.length || !data?.series?.length || data.series.every((s) => !s.data?.length);
843
1136
  const isHorizontal = orientation === "horizontal";
1137
+ const isPercent = stacked === "percent";
844
1138
  const currentTheme = useChartTheme(theme);
1139
+ const chartColors = (0, import_charts_core7.getChartColors)(currentTheme);
845
1140
  const legend = useChartLegend({
846
1141
  names: data?.series?.map((s) => s.name) ?? [],
847
1142
  colors: data?.series?.map((s) => s.color) ?? [],
848
- palette: (0, import_charts_core5.getChartColors)(currentTheme).series,
1143
+ palette: chartColors.series,
849
1144
  config: legendConfig,
850
1145
  title,
851
1146
  onLegendChange
852
1147
  });
853
1148
  const customLegend = renderLegend !== void 0;
1149
+ const builtInLegend = showLegend && !customLegend;
854
1150
  const option = React7.useMemo(() => {
855
1151
  if (isEmpty) return {};
1152
+ const formatters = (0, import_charts_core7.chartFormatters)({
1153
+ valueFormat: isPercent ? "percentValue" : valueFormat,
1154
+ locale,
1155
+ tooltipValueFormatter,
1156
+ labelFormatter
1157
+ });
1158
+ const plotted = isPercent ? (0, import_charts_core7.toPercentStack)(data.series) : data.series;
856
1159
  const categoryAxis = {
857
1160
  type: "category",
858
1161
  data: data.categories,
@@ -864,21 +1167,57 @@ var BarChart = React7.forwardRef(
864
1167
  };
865
1168
  const valueAxis = {
866
1169
  type: "value",
1170
+ ...isPercent && { max: 100 },
867
1171
  splitLine: {
868
1172
  show: showGrid
869
1173
  }
870
1174
  };
871
- const getLabel = (0, import_charts_core5.seriesLabelLookup)(data.series);
872
- return (0, import_charts_core5.mergeChartOption)(
1175
+ const getLabel = (0, import_charts_core7.seriesLabelLookup)(data.series);
1176
+ const labelPosition = isHorizontal ? "right" : "top";
1177
+ const zoomAxis = isHorizontal ? "y" : "x";
1178
+ const legendBottom = builtInLegend && (legendConfig?.position ?? "bottom") === "bottom";
1179
+ const series = data.series.map((source, index) => ({
1180
+ name: source.name,
1181
+ type: "bar",
1182
+ data: (0, import_charts_core7.withPointLabels)(plotted[index].data, source.labels, formatters.label, {
1183
+ position: labelPosition
1184
+ }),
1185
+ stack: stacked ? "Total" : void 0,
1186
+ itemStyle: source.color ? { color: source.color } : void 0,
1187
+ label: (0, import_charts_core7.buildDataLabel)({ show: true, position: labelPosition }, void 0, {
1188
+ show: showValues,
1189
+ formatter: formatters.label,
1190
+ getLabel
1191
+ }),
1192
+ emphasis: {
1193
+ focus: "series"
1194
+ }
1195
+ }));
1196
+ const format2 = (0, import_charts_core7.resolveValueFormatter)(valueFormat, locale);
1197
+ const stackedSeries = data.series.map((s) => ({ data: s.data }));
1198
+ const totalSeries = showTotal ? (0, import_charts_core7.buildStackTotalSeries)(data.categories, stackedSeries, {
1199
+ stacked,
1200
+ position: labelPosition,
1201
+ format: format2
1202
+ }) : [];
1203
+ const endLabels = !isHorizontal ? [] : totalSeries.length ? [...(0, import_charts_core7.stackTotals)(stackedSeries, stacked).values()].flat().map((t) => (0, import_charts_core7.formatValue)(t, format2)) : showValues ? plotted.flatMap((s) => s.data.map((value) => (0, import_charts_core7.formatValue)(value, formatters.format))) : [];
1204
+ return (0, import_charts_core7.mergeChartOption)(
873
1205
  {
874
1206
  grid: {
875
1207
  left: "3%",
876
1208
  right: "4%",
877
1209
  bottom: "3%",
878
1210
  containLabel: true,
879
- ...(0, import_charts_core5.gridInset)(legendConfig, showLegend && !customLegend, xAxisConfig, yAxisConfig)
1211
+ ...(0, import_charts_core7.withZoomInset)(
1212
+ (0, import_charts_core7.withEndLabelInset)(
1213
+ (0, import_charts_core7.gridInset)(legendConfig, builtInLegend, xAxisConfig, yAxisConfig),
1214
+ endLabels
1215
+ ),
1216
+ dataZoom,
1217
+ zoomAxis
1218
+ )
880
1219
  },
881
- tooltip: (0, import_charts_core5.buildTooltip)(
1220
+ tooltip: (0, import_charts_core7.buildTooltip)(
882
1221
  {
883
1222
  trigger: "axis",
884
1223
  axisPointer: {
@@ -888,37 +1227,31 @@ var BarChart = React7.forwardRef(
888
1227
  {
889
1228
  show: showTooltip,
890
1229
  formatter: tooltipFormatter,
891
- valueFormatter: tooltipValueFormatter,
1230
+ valueFormatter: formatters.tooltip,
892
1231
  getLabel
893
1232
  }
894
1233
  ),
895
- legend: (0, import_charts_core5.buildLegend)(
1234
+ legend: (0, import_charts_core7.buildLegend)(
896
1235
  data.series.map((s) => s.name),
897
1236
  legendConfig,
898
1237
  { show: showLegend, custom: customLegend }
899
1238
  ),
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
- }))
1239
+ dataZoom: (0, import_charts_core7.buildDataZoom)(dataZoom, zoomAxis, legendBottom ? 36 : 0),
1240
+ xAxis: (0, import_charts_core7.buildAxis)(
1241
+ isHorizontal ? valueAxis : categoryAxis,
1242
+ isHorizontal ? formatters.axis(xAxisConfig) : xAxisConfig
1243
+ ),
1244
+ yAxis: (0, import_charts_core7.buildAxis)(
1245
+ isHorizontal ? categoryAxis : valueAxis,
1246
+ isHorizontal ? yAxisConfig : formatters.axis(yAxisConfig)
1247
+ ),
1248
+ series: (0, import_charts_core7.withReferenceMarks)([...series, ...totalSeries], referenceLines, referenceBands, {
1249
+ valueAxis: isHorizontal ? "x" : "y",
1250
+ inverse: isHorizontal,
1251
+ format: formatters.format,
1252
+ color: chartColors.reference,
1253
+ bandColor: chartColors.referenceBand
1254
+ })
922
1255
  },
923
1256
  optionOverride
924
1257
  );
@@ -929,48 +1262,55 @@ var BarChart = React7.forwardRef(
929
1262
  showLegend,
930
1263
  showGrid,
931
1264
  isHorizontal,
1265
+ isPercent,
932
1266
  stacked,
933
1267
  showValues,
1268
+ showTotal,
1269
+ valueFormat,
1270
+ locale,
934
1271
  labelFormatter,
935
1272
  xAxisConfig,
936
1273
  yAxisConfig,
1274
+ referenceLines,
1275
+ referenceBands,
1276
+ dataZoom,
937
1277
  tooltipFormatter,
938
1278
  tooltipValueFormatter,
939
1279
  legendConfig,
940
1280
  customLegend,
1281
+ builtInLegend,
1282
+ chartColors,
941
1283
  optionOverride
942
1284
  ]);
943
- const latest = useLatestRef({ onClick });
944
- const { containerRef } = useChart({
1285
+ const { containerRef, exportImage } = useChart({
945
1286
  option,
946
1287
  theme,
947
1288
  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
- }
1289
+ patterns,
1290
+ events: chartEvents(events, {
1291
+ click: onClick && ((params) => onClick(toDataPointParams(params, "click"))),
1292
+ mouseover: onHover && ((params) => onHover(toDataPointParams(params, "mouseover")))
1293
+ }),
1294
+ onReady: legend.attach,
1295
+ onCreated: onReady
965
1296
  });
966
- const accessibilityDescription = description || (!isEmpty ? (0, import_charts_core5.generateBarChartDescription)(title, data) : void 0);
967
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1297
+ const format = (0, import_charts_core7.resolveValueFormatter)(valueFormat, locale);
1298
+ const accessibilityDescription = description || (!isEmpty ? (0, import_charts_core7.generateBarChartDescription)(title, data, format) : void 0);
1299
+ const resolvedHeight = isHorizontal ? (0, import_charts_core7.resolveChartHeight)(height, data?.categories?.length ?? 0, {
1300
+ rowHeight,
1301
+ minHeight,
1302
+ maxHeight,
1303
+ chrome: 56 + (builtInLegend ? 36 : 0) + (dataZoom ? 36 : 0)
1304
+ }) : height === "auto" ? 400 : height;
1305
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
968
1306
  ChartContainer,
969
1307
  {
970
1308
  ref,
971
1309
  title,
972
1310
  description: accessibilityDescription,
973
- height,
1311
+ height: resolvedHeight,
1312
+ minHeight,
1313
+ maxHeight,
974
1314
  loading,
975
1315
  error,
976
1316
  empty: isEmpty,
@@ -978,8 +1318,13 @@ var BarChart = React7.forwardRef(
978
1318
  className: cn(className),
979
1319
  legend: !isEmpty && renderLegend ? renderLegend(legend.renderProps) : void 0,
980
1320
  legendPosition: legendConfig?.position,
1321
+ dataTable: isEmpty ? void 0 : (0, import_charts_core7.categoryTable)(data),
1322
+ showDataTable,
1323
+ format,
1324
+ exportable,
1325
+ exportImage,
981
1326
  ...props,
982
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { ref: containerRef, className: "h-full w-full" })
1327
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { ref: containerRef, className: "h-full w-full" })
983
1328
  }
984
1329
  );
985
1330
  }
@@ -990,17 +1335,19 @@ BarChart.displayName = "BarChart";
990
1335
  var React8 = __toESM(require("react"), 1);
991
1336
  var echarts5 = __toESM(require("echarts/core"), 1);
992
1337
  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]);
1338
+ var import_components4 = require("echarts/components");
1339
+ var import_renderers4 = require("echarts/renderers");
1340
+ var import_charts_core8 = require("@classic-homes/charts-core");
1341
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1342
+ echarts5.use([import_charts3.PieChart, import_components4.TooltipComponent, import_components4.LegendComponent, import_components4.TitleComponent, import_renderers4.CanvasRenderer]);
998
1343
  var PieChart = React8.forwardRef(
999
1344
  ({
1000
1345
  title,
1001
1346
  description,
1002
1347
  data,
1003
1348
  height = 400,
1349
+ minHeight,
1350
+ maxHeight,
1004
1351
  loading,
1005
1352
  error,
1006
1353
  emptyMessage,
@@ -1011,6 +1358,8 @@ var PieChart = React8.forwardRef(
1011
1358
  showLabels = true,
1012
1359
  labelPosition = "outside",
1013
1360
  innerRadius = 0,
1361
+ valueFormat,
1362
+ locale,
1014
1363
  labelFormatter,
1015
1364
  tooltipFormatter,
1016
1365
  tooltipValueFormatter,
@@ -1018,6 +1367,11 @@ var PieChart = React8.forwardRef(
1018
1367
  renderLegend,
1019
1368
  onLegendChange,
1020
1369
  option: optionOverride,
1370
+ onReady,
1371
+ events,
1372
+ showDataTable,
1373
+ exportable,
1374
+ patterns,
1021
1375
  onClick,
1022
1376
  class: className,
1023
1377
  ...props
@@ -1027,31 +1381,36 @@ var PieChart = React8.forwardRef(
1027
1381
  const legend = useChartLegend({
1028
1382
  names: data?.map((d) => d.name) ?? [],
1029
1383
  colors: data?.map((d) => d.color) ?? [],
1030
- palette: (0, import_charts_core6.getChartColors)(currentTheme).series,
1384
+ palette: (0, import_charts_core8.getChartColors)(currentTheme).series,
1031
1385
  config: legendConfig,
1032
1386
  title,
1033
1387
  onLegendChange
1034
1388
  });
1035
1389
  const customLegend = renderLegend !== void 0;
1390
+ const format = React8.useMemo(
1391
+ () => (0, import_charts_core8.resolveValueFormatter)(valueFormat, locale),
1392
+ [valueFormat, locale]
1393
+ );
1394
+ const tooltipValues = tooltipValueFormatter ?? format;
1036
1395
  const option = React8.useMemo(() => {
1037
1396
  if (isEmpty) return {};
1038
- const valueFormatter = tooltipFormatter === void 0 ? tooltipValueFormatter : void 0;
1397
+ const valueFormatter = tooltipFormatter === void 0 ? tooltipValues : void 0;
1039
1398
  const tooltipBase = {
1040
1399
  trigger: "item",
1041
1400
  formatter: valueFormatter ? (params) => {
1042
1401
  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}%)`;
1402
+ 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
1403
  } : "{a} <br/>{b}: {c} ({d}%)"
1045
1404
  };
1046
- return (0, import_charts_core6.mergeChartOption)(
1405
+ return (0, import_charts_core8.mergeChartOption)(
1047
1406
  {
1048
- tooltip: (0, import_charts_core6.buildTooltip)(tooltipBase, {
1407
+ tooltip: (0, import_charts_core8.buildTooltip)(tooltipBase, {
1049
1408
  show: showTooltip,
1050
1409
  formatter: tooltipFormatter,
1051
- valueFormatter: tooltipValueFormatter,
1052
- getLabel: (0, import_charts_core6.itemLabelLookup)(data)
1410
+ valueFormatter: tooltipValues,
1411
+ getLabel: (0, import_charts_core8.itemLabelLookup)(data)
1053
1412
  }),
1054
- legend: (0, import_charts_core6.buildLegend)(
1413
+ legend: (0, import_charts_core8.buildLegend)(
1055
1414
  data.map((d) => d.name),
1056
1415
  legendConfig,
1057
1416
  { show: showLegend, custom: customLegend, defaults: { orient: "horizontal" } }
@@ -1061,21 +1420,21 @@ var PieChart = React8.forwardRef(
1061
1420
  name: title,
1062
1421
  type: "pie",
1063
1422
  radius: innerRadius ? [innerRadius, "70%"] : "70%",
1064
- center: (0, import_charts_core6.legendCenter)(legendConfig, showLegend && !customLegend, ["50%", "45%"]),
1423
+ center: (0, import_charts_core8.legendCenter)(legendConfig, showLegend && !customLegend, ["50%", "45%"]),
1065
1424
  data: data.map((item) => ({
1066
1425
  name: item.name,
1067
1426
  value: item.value,
1068
1427
  itemStyle: item.color ? { color: item.color } : void 0,
1069
- label: (0, import_charts_core6.pointLabel)(item.label, labelFormatter, { position: labelPosition })
1428
+ label: (0, import_charts_core8.pointLabel)(item.label, labelFormatter, { position: labelPosition })
1070
1429
  })),
1071
- label: (0, import_charts_core6.buildDataLabel)(
1430
+ label: (0, import_charts_core8.buildDataLabel)(
1072
1431
  {
1073
1432
  show: true,
1074
1433
  position: labelPosition,
1075
1434
  formatter: labelPosition === "inside" ? "{d}%" : "{b}: {d}%"
1076
1435
  },
1077
1436
  { show: false },
1078
- { show: showLabels, formatter: labelFormatter, getLabel: (0, import_charts_core6.itemLabelLookup)(data) }
1437
+ { show: showLabels, formatter: labelFormatter, getLabel: (0, import_charts_core8.itemLabelLookup)(data) }
1079
1438
  ),
1080
1439
  emphasis: {
1081
1440
  itemStyle: {
@@ -1100,40 +1459,32 @@ var PieChart = React8.forwardRef(
1100
1459
  title,
1101
1460
  labelFormatter,
1102
1461
  tooltipFormatter,
1103
- tooltipValueFormatter,
1462
+ tooltipValues,
1104
1463
  legendConfig,
1105
1464
  customLegend,
1106
1465
  optionOverride
1107
1466
  ]);
1108
- const latest = useLatestRef({ onClick });
1109
- const { containerRef } = useChart({
1467
+ const { containerRef, exportImage } = useChart({
1110
1468
  option,
1111
1469
  theme,
1112
1470
  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
- }
1471
+ patterns,
1472
+ events: chartEvents(events, {
1473
+ click: onClick && ((params) => onClick(toSliceParams(params, "click")))
1474
+ }),
1475
+ onReady: legend.attach,
1476
+ onCreated: onReady
1128
1477
  });
1129
- const accessibilityDescription = description || (!isEmpty ? (0, import_charts_core6.generatePieChartDescription)(title, data, false) : void 0);
1130
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1478
+ const accessibilityDescription = description || (!isEmpty ? (0, import_charts_core8.generatePieChartDescription)(title, data, false) : void 0);
1479
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1131
1480
  ChartContainer,
1132
1481
  {
1133
1482
  ref,
1134
1483
  title,
1135
1484
  description: accessibilityDescription,
1136
1485
  height,
1486
+ minHeight,
1487
+ maxHeight,
1137
1488
  loading,
1138
1489
  error,
1139
1490
  empty: isEmpty,
@@ -1141,8 +1492,13 @@ var PieChart = React8.forwardRef(
1141
1492
  className: cn(className),
1142
1493
  legend: !isEmpty && renderLegend ? renderLegend(legend.renderProps) : void 0,
1143
1494
  legendPosition: legendConfig?.position,
1495
+ dataTable: isEmpty ? void 0 : (0, import_charts_core8.sliceTable)(data),
1496
+ showDataTable,
1497
+ format,
1498
+ exportable,
1499
+ exportImage,
1144
1500
  ...props,
1145
- children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { ref: containerRef, className: "h-full w-full" })
1501
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { ref: containerRef, className: "h-full w-full" })
1146
1502
  }
1147
1503
  );
1148
1504
  }
@@ -1153,17 +1509,17 @@ PieChart.displayName = "PieChart";
1153
1509
  var React9 = __toESM(require("react"), 1);
1154
1510
  var echarts6 = __toESM(require("echarts/core"), 1);
1155
1511
  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");
1512
+ var import_components5 = require("echarts/components");
1513
+ var import_renderers5 = require("echarts/renderers");
1514
+ var import_charts_core9 = require("@classic-homes/charts-core");
1515
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1160
1516
  echarts6.use([
1161
1517
  import_charts4.LineChart,
1162
- import_components4.GridComponent,
1163
- import_components4.TooltipComponent,
1164
- import_components4.LegendComponent,
1165
- import_components4.TitleComponent,
1166
- import_renderers4.CanvasRenderer
1518
+ import_components5.GridComponent,
1519
+ import_components5.TooltipComponent,
1520
+ import_components5.LegendComponent,
1521
+ import_components5.TitleComponent,
1522
+ import_renderers5.CanvasRenderer
1167
1523
  ]);
1168
1524
  var AreaChart = React9.forwardRef(
1169
1525
  ({
@@ -1171,6 +1527,8 @@ var AreaChart = React9.forwardRef(
1171
1527
  description,
1172
1528
  data,
1173
1529
  height = 400,
1530
+ minHeight,
1531
+ maxHeight,
1174
1532
  loading,
1175
1533
  error,
1176
1534
  emptyMessage,
@@ -1181,24 +1539,37 @@ var AreaChart = React9.forwardRef(
1181
1539
  showGrid = true,
1182
1540
  smooth = false,
1183
1541
  stacked = false,
1542
+ connectNulls = false,
1184
1543
  gradient = true,
1185
1544
  showLabels = false,
1545
+ valueFormat,
1546
+ locale,
1186
1547
  labelFormatter,
1187
1548
  xAxisConfig,
1188
1549
  yAxisConfig,
1550
+ referenceLines,
1551
+ referenceBands,
1552
+ dataZoom,
1189
1553
  tooltipFormatter,
1190
1554
  tooltipValueFormatter,
1191
1555
  legend: legendConfig,
1192
1556
  renderLegend,
1193
1557
  onLegendChange,
1194
1558
  option: optionOverride,
1559
+ onReady,
1560
+ events,
1561
+ showDataTable,
1562
+ exportable,
1563
+ patterns,
1195
1564
  onClick,
1565
+ onHover,
1196
1566
  class: className,
1197
1567
  ...props
1198
1568
  }, ref) => {
1199
1569
  const isEmpty = !data?.categories?.length || !data?.series?.length || data.series.every((s) => !s.data?.length);
1570
+ const isPercent = stacked === "percent";
1200
1571
  const currentTheme = useChartTheme(theme);
1201
- const chartColors = (0, import_charts_core7.getChartColors)(currentTheme);
1572
+ const chartColors = (0, import_charts_core9.getChartColors)(currentTheme);
1202
1573
  const legend = useChartLegend({
1203
1574
  names: data?.series?.map((s) => s.name) ?? [],
1204
1575
  colors: data?.series?.map((s) => s.color) ?? [],
@@ -1208,20 +1579,63 @@ var AreaChart = React9.forwardRef(
1208
1579
  onLegendChange
1209
1580
  });
1210
1581
  const customLegend = renderLegend !== void 0;
1582
+ const builtInLegend = showLegend && !customLegend;
1211
1583
  const option = React9.useMemo(() => {
1212
1584
  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)(
1585
+ const formatters = (0, import_charts_core9.chartFormatters)({
1586
+ valueFormat: isPercent ? "percentValue" : valueFormat,
1587
+ locale,
1588
+ tooltipValueFormatter,
1589
+ labelFormatter
1590
+ });
1591
+ const plotted = isPercent ? (0, import_charts_core9.toPercentStack)(data.series) : data.series;
1592
+ const getLabel = (0, import_charts_core9.seriesLabelLookup)(data.series);
1593
+ const showSymbol = showLabels || (0, import_charts_core9.hasPointLabels)(data.series);
1594
+ const legendBottom = builtInLegend && (legendConfig?.position ?? "bottom") === "bottom";
1595
+ const series = data.series.map((source, index) => {
1596
+ const base = source.color || chartColors.series[index % chartColors.series.length];
1597
+ return {
1598
+ name: source.name,
1599
+ type: "line",
1600
+ data: (0, import_charts_core9.withPointLabels)(plotted[index].data, source.labels, formatters.label, {
1601
+ position: "top"
1602
+ }),
1603
+ smooth,
1604
+ connectNulls,
1605
+ stack: stacked ? "Total" : void 0,
1606
+ areaStyle: gradient ? {
1607
+ opacity: 0.8,
1608
+ color: new echarts6.graphic.LinearGradient(0, 0, 0, 1, [
1609
+ { offset: 0, color: (0, import_charts_core9.colorWithAlpha)(base, 0.8) },
1610
+ { offset: 1, color: (0, import_charts_core9.colorWithAlpha)(base, 0.1) }
1611
+ ])
1612
+ } : { opacity: 0.5 },
1613
+ itemStyle: source.color ? { color: source.color } : void 0,
1614
+ label: (0, import_charts_core9.buildDataLabel)({ show: true, position: "top" }, void 0, {
1615
+ show: showLabels,
1616
+ formatter: formatters.label,
1617
+ getLabel
1618
+ }),
1619
+ emphasis: {
1620
+ focus: "series"
1621
+ },
1622
+ showSymbol
1623
+ };
1624
+ });
1625
+ return (0, import_charts_core9.mergeChartOption)(
1216
1626
  {
1217
1627
  grid: {
1218
1628
  left: "3%",
1219
1629
  right: "4%",
1220
1630
  bottom: "3%",
1221
1631
  containLabel: true,
1222
- ...(0, import_charts_core7.gridInset)(legendConfig, showLegend && !customLegend, xAxisConfig, yAxisConfig)
1632
+ ...(0, import_charts_core9.withZoomInset)(
1633
+ (0, import_charts_core9.gridInset)(legendConfig, builtInLegend, xAxisConfig, yAxisConfig),
1634
+ dataZoom,
1635
+ "x"
1636
+ )
1223
1637
  },
1224
- tooltip: (0, import_charts_core7.buildTooltip)(
1638
+ tooltip: (0, import_charts_core9.buildTooltip)(
1225
1639
  {
1226
1640
  trigger: "axis",
1227
1641
  axisPointer: {
@@ -1234,16 +1648,17 @@ var AreaChart = React9.forwardRef(
1234
1648
  {
1235
1649
  show: showTooltip,
1236
1650
  formatter: tooltipFormatter,
1237
- valueFormatter: tooltipValueFormatter,
1651
+ valueFormatter: formatters.tooltip,
1238
1652
  getLabel
1239
1653
  }
1240
1654
  ),
1241
- legend: (0, import_charts_core7.buildLegend)(
1655
+ legend: (0, import_charts_core9.buildLegend)(
1242
1656
  data.series.map((s) => s.name),
1243
1657
  legendConfig,
1244
1658
  { show: showLegend, custom: customLegend }
1245
1659
  ),
1246
- xAxis: (0, import_charts_core7.buildAxis)(
1660
+ dataZoom: (0, import_charts_core9.buildDataZoom)(dataZoom, "x", legendBottom ? 36 : 0),
1661
+ xAxis: (0, import_charts_core9.buildAxis)(
1247
1662
  {
1248
1663
  type: "category",
1249
1664
  boundaryGap: false,
@@ -1251,43 +1666,21 @@ var AreaChart = React9.forwardRef(
1251
1666
  },
1252
1667
  xAxisConfig
1253
1668
  ),
1254
- yAxis: (0, import_charts_core7.buildAxis)(
1669
+ yAxis: (0, import_charts_core9.buildAxis)(
1255
1670
  {
1256
1671
  type: "value",
1672
+ ...isPercent && { max: 100 },
1257
1673
  splitLine: {
1258
1674
  show: showGrid
1259
1675
  }
1260
1676
  },
1261
- yAxisConfig
1677
+ formatters.axis(yAxisConfig)
1262
1678
  ),
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
- };
1679
+ series: (0, import_charts_core9.withReferenceMarks)(series, referenceLines, referenceBands, {
1680
+ valueAxis: "y",
1681
+ format: formatters.format,
1682
+ color: chartColors.reference,
1683
+ bandColor: chartColors.referenceBand
1291
1684
  })
1292
1685
  },
1293
1686
  optionOverride
@@ -1300,49 +1693,49 @@ var AreaChart = React9.forwardRef(
1300
1693
  showGrid,
1301
1694
  smooth,
1302
1695
  stacked,
1696
+ isPercent,
1697
+ connectNulls,
1303
1698
  gradient,
1304
1699
  chartColors,
1305
1700
  showLabels,
1701
+ valueFormat,
1702
+ locale,
1306
1703
  labelFormatter,
1307
1704
  xAxisConfig,
1308
1705
  yAxisConfig,
1706
+ referenceLines,
1707
+ referenceBands,
1708
+ dataZoom,
1309
1709
  tooltipFormatter,
1310
1710
  tooltipValueFormatter,
1311
1711
  legendConfig,
1312
1712
  customLegend,
1713
+ builtInLegend,
1313
1714
  optionOverride
1314
1715
  ]);
1315
- const latest = useLatestRef({ onClick });
1316
- const { containerRef } = useChart({
1716
+ const { containerRef, exportImage } = useChart({
1317
1717
  option,
1318
- theme: currentTheme === import_charts_core7.THEME_DARK ? "dark" : "light",
1718
+ theme: currentTheme === import_charts_core9.THEME_DARK ? "dark" : "light",
1319
1719
  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
- }
1720
+ patterns,
1721
+ events: chartEvents(events, {
1722
+ click: onClick && ((params) => onClick(toDataPointParams(params, "click"))),
1723
+ mouseover: onHover && ((params) => onHover(toDataPointParams(params, "mouseover")))
1724
+ }),
1725
+ onReady: legend.attach,
1726
+ onCreated: onReady
1337
1727
  });
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)(
1728
+ const format = (0, import_charts_core9.resolveValueFormatter)(valueFormat, locale);
1729
+ const accessibilityDescription = description || (!isEmpty ? (0, import_charts_core9.generateAreaChartDescription)(title, data, format) : void 0);
1730
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1340
1731
  ChartContainer,
1341
1732
  {
1342
1733
  ref,
1343
1734
  title,
1344
1735
  description: accessibilityDescription,
1345
1736
  height,
1737
+ minHeight,
1738
+ maxHeight,
1346
1739
  loading,
1347
1740
  error,
1348
1741
  empty: isEmpty,
@@ -1350,8 +1743,13 @@ var AreaChart = React9.forwardRef(
1350
1743
  className: cn(className),
1351
1744
  legend: !isEmpty && renderLegend ? renderLegend(legend.renderProps) : void 0,
1352
1745
  legendPosition: legendConfig?.position,
1746
+ dataTable: isEmpty ? void 0 : (0, import_charts_core9.categoryTable)(data),
1747
+ showDataTable,
1748
+ format,
1749
+ exportable,
1750
+ exportImage,
1353
1751
  ...props,
1354
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { ref: containerRef, className: "h-full w-full" })
1752
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { ref: containerRef, className: "h-full w-full" })
1355
1753
  }
1356
1754
  );
1357
1755
  }
@@ -1362,19 +1760,19 @@ AreaChart.displayName = "AreaChart";
1362
1760
  var React10 = __toESM(require("react"), 1);
1363
1761
  var echarts7 = __toESM(require("echarts/core"), 1);
1364
1762
  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");
1763
+ var import_components6 = require("echarts/components");
1764
+ var import_renderers6 = require("echarts/renderers");
1765
+ var import_charts_core10 = require("@classic-homes/charts-core");
1766
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1369
1767
  echarts7.use([
1370
1768
  import_charts5.ScatterChart,
1371
1769
  // Trend lines are line series
1372
1770
  import_charts5.LineChart,
1373
- import_components5.GridComponent,
1374
- import_components5.TooltipComponent,
1375
- import_components5.LegendComponent,
1376
- import_components5.TitleComponent,
1377
- import_renderers5.CanvasRenderer
1771
+ import_components6.GridComponent,
1772
+ import_components6.TooltipComponent,
1773
+ import_components6.LegendComponent,
1774
+ import_components6.TitleComponent,
1775
+ import_renderers6.CanvasRenderer
1378
1776
  ]);
1379
1777
  var ScatterChart = React10.forwardRef(
1380
1778
  ({
@@ -1382,6 +1780,8 @@ var ScatterChart = React10.forwardRef(
1382
1780
  description,
1383
1781
  data,
1384
1782
  height = 400,
1783
+ minHeight,
1784
+ maxHeight,
1385
1785
  loading,
1386
1786
  error,
1387
1787
  emptyMessage,
@@ -1393,25 +1793,36 @@ var ScatterChart = React10.forwardRef(
1393
1793
  showTrendLine = false,
1394
1794
  symbolSize = 10,
1395
1795
  showLabels = false,
1796
+ valueFormat,
1797
+ locale,
1396
1798
  labelFormatter,
1397
1799
  xAxisConfig,
1398
1800
  yAxisConfig,
1801
+ referenceLines,
1802
+ referenceBands,
1399
1803
  tooltipFormatter,
1400
1804
  tooltipValueFormatter,
1401
1805
  legend: legendConfig,
1402
1806
  renderLegend,
1403
1807
  onLegendChange,
1404
1808
  option: optionOverride,
1809
+ onReady,
1810
+ events,
1811
+ showDataTable,
1812
+ exportable,
1813
+ patterns,
1405
1814
  onClick,
1815
+ onHover,
1406
1816
  class: className,
1407
1817
  ...props
1408
1818
  }, ref) => {
1409
1819
  const isEmpty = !data?.series?.length || data.series.every((s) => !s.data?.length);
1410
1820
  const currentTheme = useChartTheme(theme);
1821
+ const chartColors = (0, import_charts_core10.getChartColors)(currentTheme);
1411
1822
  const legend = useChartLegend({
1412
1823
  names: data?.series?.map((s) => s.name) ?? [],
1413
1824
  colors: data?.series?.map((s) => s.color) ?? [],
1414
- palette: (0, import_charts_core8.getChartColors)(currentTheme).series,
1825
+ palette: chartColors.series,
1415
1826
  config: legendConfig,
1416
1827
  title,
1417
1828
  onLegendChange
@@ -1419,16 +1830,22 @@ var ScatterChart = React10.forwardRef(
1419
1830
  const customLegend = renderLegend !== void 0;
1420
1831
  const option = React10.useMemo(() => {
1421
1832
  if (isEmpty) return {};
1422
- const getLabel = (0, import_charts_core8.seriesLabelLookup)(data.series);
1833
+ const formatters = (0, import_charts_core10.chartFormatters)({
1834
+ valueFormat,
1835
+ locale,
1836
+ tooltipValueFormatter,
1837
+ labelFormatter
1838
+ });
1839
+ const getLabel = (0, import_charts_core10.seriesLabelLookup)(data.series);
1423
1840
  const series = data.series.map((s) => ({
1424
1841
  name: s.name,
1425
1842
  type: "scatter",
1426
- data: (0, import_charts_core8.withPointLabels)(s.data, s.labels, labelFormatter, { position: "top" }),
1843
+ data: (0, import_charts_core10.withPointLabels)(s.data, s.labels, formatters.label, { position: "top" }),
1427
1844
  symbolSize: typeof symbolSize === "function" ? symbolSize : symbolSize,
1428
1845
  itemStyle: s.color ? { color: s.color } : void 0,
1429
- label: (0, import_charts_core8.buildDataLabel)({ show: true, position: "top" }, void 0, {
1846
+ label: (0, import_charts_core10.buildDataLabel)({ show: true, position: "top" }, void 0, {
1430
1847
  show: showLabels,
1431
- formatter: labelFormatter,
1848
+ formatter: formatters.label,
1432
1849
  getLabel
1433
1850
  }),
1434
1851
  emphasis: {
@@ -1478,39 +1895,39 @@ var ScatterChart = React10.forwardRef(
1478
1895
  });
1479
1896
  });
1480
1897
  }
1481
- return (0, import_charts_core8.mergeChartOption)(
1898
+ return (0, import_charts_core10.mergeChartOption)(
1482
1899
  {
1483
1900
  grid: {
1484
1901
  left: "3%",
1485
1902
  right: "4%",
1486
1903
  bottom: "3%",
1487
1904
  containLabel: true,
1488
- ...(0, import_charts_core8.gridInset)(legendConfig, showLegend && !customLegend, xAxisConfig, yAxisConfig)
1905
+ ...(0, import_charts_core10.gridInset)(legendConfig, showLegend && !customLegend, xAxisConfig, yAxisConfig)
1489
1906
  },
1490
- tooltip: (0, import_charts_core8.buildTooltip)(
1907
+ tooltip: (0, import_charts_core10.buildTooltip)(
1491
1908
  {
1492
1909
  trigger: "item",
1493
1910
  formatter: (params) => {
1494
1911
  const p = params;
1495
1912
  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)}`;
1913
+ const x = (0, import_charts_core10.formatTooltipValue)(p.value[0], formatters.tooltip);
1914
+ const y = (0, import_charts_core10.formatTooltipValue)(p.value[1], formatters.tooltip);
1915
+ 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
1916
  }
1500
1917
  },
1501
1918
  {
1502
1919
  show: showTooltip,
1503
1920
  formatter: tooltipFormatter,
1504
- valueFormatter: tooltipValueFormatter,
1921
+ valueFormatter: formatters.tooltip,
1505
1922
  getLabel
1506
1923
  }
1507
1924
  ),
1508
- legend: (0, import_charts_core8.buildLegend)(
1925
+ legend: (0, import_charts_core10.buildLegend)(
1509
1926
  data.series.map((s) => s.name),
1510
1927
  legendConfig,
1511
1928
  { show: showLegend, custom: customLegend }
1512
1929
  ),
1513
- xAxis: (0, import_charts_core8.buildAxis)(
1930
+ xAxis: (0, import_charts_core10.buildAxis)(
1514
1931
  {
1515
1932
  type: "value",
1516
1933
  splitLine: {
@@ -1519,16 +1936,26 @@ var ScatterChart = React10.forwardRef(
1519
1936
  },
1520
1937
  xAxisConfig
1521
1938
  ),
1522
- yAxis: (0, import_charts_core8.buildAxis)(
1939
+ yAxis: (0, import_charts_core10.buildAxis)(
1523
1940
  {
1524
1941
  type: "value",
1525
1942
  splitLine: {
1526
1943
  show: showGrid
1527
1944
  }
1528
1945
  },
1529
- yAxisConfig
1946
+ formatters.axis(yAxisConfig)
1530
1947
  ),
1531
- series
1948
+ series: (0, import_charts_core10.withReferenceMarks)(
1949
+ series,
1950
+ referenceLines,
1951
+ referenceBands,
1952
+ {
1953
+ valueAxis: "y",
1954
+ format: formatters.format,
1955
+ color: chartColors.reference,
1956
+ bandColor: chartColors.referenceBand
1957
+ }
1958
+ )
1532
1959
  },
1533
1960
  optionOverride
1534
1961
  );
@@ -1541,46 +1968,42 @@ var ScatterChart = React10.forwardRef(
1541
1968
  showTrendLine,
1542
1969
  symbolSize,
1543
1970
  showLabels,
1971
+ valueFormat,
1972
+ locale,
1544
1973
  labelFormatter,
1545
1974
  xAxisConfig,
1546
1975
  yAxisConfig,
1976
+ referenceLines,
1977
+ referenceBands,
1978
+ chartColors,
1547
1979
  tooltipFormatter,
1548
1980
  tooltipValueFormatter,
1549
1981
  legendConfig,
1550
1982
  customLegend,
1551
1983
  optionOverride
1552
1984
  ]);
1553
- const latest = useLatestRef({ onClick });
1554
- const { containerRef } = useChart({
1985
+ const { containerRef, exportImage } = useChart({
1555
1986
  option,
1556
1987
  theme,
1557
1988
  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
- }
1989
+ patterns,
1990
+ events: chartEvents(events, {
1991
+ click: onClick && ((params) => onClick(toDataPointParams(params, "click"))),
1992
+ mouseover: onHover && ((params) => onHover(toDataPointParams(params, "mouseover")))
1993
+ }),
1994
+ onReady: legend.attach,
1995
+ onCreated: onReady
1575
1996
  });
1576
- const accessibilityDescription = description || (!isEmpty ? (0, import_charts_core8.generateScatterChartDescription)(title, data) : void 0);
1577
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1997
+ const accessibilityDescription = description || (!isEmpty ? (0, import_charts_core10.generateScatterChartDescription)(title, data) : void 0);
1998
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1578
1999
  ChartContainer,
1579
2000
  {
1580
2001
  ref,
1581
2002
  title,
1582
2003
  description: accessibilityDescription,
1583
2004
  height,
2005
+ minHeight,
2006
+ maxHeight,
1584
2007
  loading,
1585
2008
  error,
1586
2009
  empty: isEmpty,
@@ -1588,8 +2011,13 @@ var ScatterChart = React10.forwardRef(
1588
2011
  className: cn(className),
1589
2012
  legend: !isEmpty && renderLegend ? renderLegend(legend.renderProps) : void 0,
1590
2013
  legendPosition: legendConfig?.position,
2014
+ dataTable: isEmpty ? void 0 : (0, import_charts_core10.scatterTable)(data, xAxisConfig?.name, yAxisConfig?.name),
2015
+ showDataTable,
2016
+ format: (0, import_charts_core10.resolveValueFormatter)(valueFormat, locale),
2017
+ exportable,
2018
+ exportImage,
1591
2019
  ...props,
1592
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { ref: containerRef, className: "h-full w-full" })
2020
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { ref: containerRef, className: "h-full w-full" })
1593
2021
  }
1594
2022
  );
1595
2023
  }
@@ -1600,17 +2028,19 @@ ScatterChart.displayName = "ScatterChart";
1600
2028
  var React11 = __toESM(require("react"), 1);
1601
2029
  var echarts8 = __toESM(require("echarts/core"), 1);
1602
2030
  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]);
2031
+ var import_components7 = require("echarts/components");
2032
+ var import_renderers7 = require("echarts/renderers");
2033
+ var import_charts_core11 = require("@classic-homes/charts-core");
2034
+ var import_jsx_runtime12 = require("react/jsx-runtime");
2035
+ echarts8.use([import_charts6.PieChart, import_components7.TooltipComponent, import_components7.LegendComponent, import_components7.TitleComponent, import_renderers7.CanvasRenderer]);
1608
2036
  var DonutChart = React11.forwardRef(
1609
2037
  ({
1610
2038
  title,
1611
2039
  description,
1612
2040
  data,
1613
2041
  height = 400,
2042
+ minHeight,
2043
+ maxHeight,
1614
2044
  loading,
1615
2045
  error,
1616
2046
  emptyMessage,
@@ -1623,6 +2053,8 @@ var DonutChart = React11.forwardRef(
1623
2053
  innerRadius = "50%",
1624
2054
  centerLabel,
1625
2055
  centerValue,
2056
+ valueFormat,
2057
+ locale,
1626
2058
  labelFormatter,
1627
2059
  tooltipFormatter,
1628
2060
  tooltipValueFormatter,
@@ -1630,13 +2062,18 @@ var DonutChart = React11.forwardRef(
1630
2062
  renderLegend,
1631
2063
  onLegendChange,
1632
2064
  option: optionOverride,
2065
+ onReady,
2066
+ events,
2067
+ showDataTable,
2068
+ exportable,
2069
+ patterns,
1633
2070
  onClick,
1634
2071
  class: className,
1635
2072
  ...props
1636
2073
  }, ref) => {
1637
2074
  const isEmpty = !data?.length;
1638
2075
  const currentTheme = useChartTheme(theme);
1639
- const chartColors = (0, import_charts_core9.getChartColors)(currentTheme);
2076
+ const chartColors = (0, import_charts_core11.getChartColors)(currentTheme);
1640
2077
  const legend = useChartLegend({
1641
2078
  names: data?.map((d) => d.name) ?? [],
1642
2079
  colors: data?.map((d) => d.color) ?? [],
@@ -1646,13 +2083,18 @@ var DonutChart = React11.forwardRef(
1646
2083
  onLegendChange
1647
2084
  });
1648
2085
  const customLegend = renderLegend !== void 0;
2086
+ const format = React11.useMemo(
2087
+ () => (0, import_charts_core11.resolveValueFormatter)(valueFormat, locale),
2088
+ [valueFormat, locale]
2089
+ );
2090
+ const tooltipValues = tooltipValueFormatter ?? format;
1649
2091
  const option = React11.useMemo(() => {
1650
2092
  if (isEmpty) return {};
1651
- const pieCenter = (0, import_charts_core9.legendCenter)(legendConfig, showLegend && !customLegend, ["50%", "45%"]);
2093
+ const pieCenter = (0, import_charts_core11.legendCenter)(legendConfig, showLegend && !customLegend, ["50%", "45%"]);
1652
2094
  const graphicElements = [];
1653
2095
  if (centerLabel || centerValue) {
1654
2096
  graphicElements.push(
1655
- (0, import_charts_core9.anchorCenterGraphic)(
2097
+ (0, import_charts_core11.anchorCenterGraphic)(
1656
2098
  {
1657
2099
  type: "group",
1658
2100
  left: "center",
@@ -1692,23 +2134,23 @@ var DonutChart = React11.forwardRef(
1692
2134
  )
1693
2135
  );
1694
2136
  }
1695
- const valueFormatter = tooltipFormatter === void 0 ? tooltipValueFormatter : void 0;
2137
+ const valueFormatter = tooltipFormatter === void 0 ? tooltipValues : void 0;
1696
2138
  const tooltipBase = {
1697
2139
  trigger: "item",
1698
2140
  formatter: valueFormatter ? (params) => {
1699
2141
  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}%)`;
2142
+ 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
2143
  } : "{a} <br/>{b}: {c} ({d}%)"
1702
2144
  };
1703
- return (0, import_charts_core9.mergeChartOption)(
2145
+ return (0, import_charts_core11.mergeChartOption)(
1704
2146
  {
1705
- tooltip: (0, import_charts_core9.buildTooltip)(tooltipBase, {
2147
+ tooltip: (0, import_charts_core11.buildTooltip)(tooltipBase, {
1706
2148
  show: showTooltip,
1707
2149
  formatter: tooltipFormatter,
1708
- valueFormatter: tooltipValueFormatter,
1709
- getLabel: (0, import_charts_core9.itemLabelLookup)(data)
2150
+ valueFormatter: tooltipValues,
2151
+ getLabel: (0, import_charts_core11.itemLabelLookup)(data)
1710
2152
  }),
1711
- legend: (0, import_charts_core9.buildLegend)(
2153
+ legend: (0, import_charts_core11.buildLegend)(
1712
2154
  data.map((d) => d.name),
1713
2155
  legendConfig,
1714
2156
  { show: showLegend, custom: customLegend, defaults: { orient: "horizontal" } }
@@ -1725,16 +2167,16 @@ var DonutChart = React11.forwardRef(
1725
2167
  name: item.name,
1726
2168
  value: item.value,
1727
2169
  itemStyle: item.color ? { color: item.color } : void 0,
1728
- label: (0, import_charts_core9.pointLabel)(item.label, labelFormatter, { position: labelPosition })
2170
+ label: (0, import_charts_core11.pointLabel)(item.label, labelFormatter, { position: labelPosition })
1729
2171
  })),
1730
- label: (0, import_charts_core9.buildDataLabel)(
2172
+ label: (0, import_charts_core11.buildDataLabel)(
1731
2173
  {
1732
2174
  show: true,
1733
2175
  position: labelPosition,
1734
2176
  formatter: labelPosition === "inside" ? "{d}%" : "{b}: {d}%"
1735
2177
  },
1736
2178
  { show: false },
1737
- { show: showLabels, formatter: labelFormatter, getLabel: (0, import_charts_core9.itemLabelLookup)(data) }
2179
+ { show: showLabels, formatter: labelFormatter, getLabel: (0, import_charts_core11.itemLabelLookup)(data) }
1738
2180
  ),
1739
2181
  labelLine: {
1740
2182
  show: showLabels && labelPosition === "outside"
@@ -1765,40 +2207,32 @@ var DonutChart = React11.forwardRef(
1765
2207
  chartColors,
1766
2208
  labelFormatter,
1767
2209
  tooltipFormatter,
1768
- tooltipValueFormatter,
2210
+ tooltipValues,
1769
2211
  legendConfig,
1770
2212
  customLegend,
1771
2213
  optionOverride
1772
2214
  ]);
1773
- const latest = useLatestRef({ onClick });
1774
- const { containerRef } = useChart({
2215
+ const { containerRef, exportImage } = useChart({
1775
2216
  option,
1776
- theme: currentTheme === import_charts_core9.THEME_DARK ? "dark" : "light",
2217
+ theme: currentTheme === import_charts_core11.THEME_DARK ? "dark" : "light",
1777
2218
  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
- }
2219
+ patterns,
2220
+ events: chartEvents(events, {
2221
+ click: onClick && ((params) => onClick(toSliceParams(params, "click")))
2222
+ }),
2223
+ onReady: legend.attach,
2224
+ onCreated: onReady
1793
2225
  });
1794
- const accessibilityDescription = description || (!isEmpty ? (0, import_charts_core9.generatePieChartDescription)(title, data, true) : void 0);
1795
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2226
+ const accessibilityDescription = description || (!isEmpty ? (0, import_charts_core11.generatePieChartDescription)(title, data, true) : void 0);
2227
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1796
2228
  ChartContainer,
1797
2229
  {
1798
2230
  ref,
1799
2231
  title,
1800
2232
  description: accessibilityDescription,
1801
2233
  height,
2234
+ minHeight,
2235
+ maxHeight,
1802
2236
  loading,
1803
2237
  error,
1804
2238
  empty: isEmpty,
@@ -1806,8 +2240,13 @@ var DonutChart = React11.forwardRef(
1806
2240
  className: cn(className),
1807
2241
  legend: !isEmpty && renderLegend ? renderLegend(legend.renderProps) : void 0,
1808
2242
  legendPosition: legendConfig?.position,
2243
+ dataTable: isEmpty ? void 0 : (0, import_charts_core11.sliceTable)(data),
2244
+ showDataTable,
2245
+ format,
2246
+ exportable,
2247
+ exportImage,
1809
2248
  ...props,
1810
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { ref: containerRef, className: "h-full w-full" })
2249
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { ref: containerRef, className: "h-full w-full" })
1811
2250
  }
1812
2251
  );
1813
2252
  }
@@ -1818,17 +2257,17 @@ DonutChart.displayName = "DonutChart";
1818
2257
  var React12 = __toESM(require("react"), 1);
1819
2258
  var echarts9 = __toESM(require("echarts/core"), 1);
1820
2259
  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");
2260
+ var import_components8 = require("echarts/components");
2261
+ var import_renderers8 = require("echarts/renderers");
2262
+ var import_charts_core12 = require("@classic-homes/charts-core");
2263
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1825
2264
  echarts9.use([
1826
2265
  import_charts7.RadarChart,
1827
- import_components7.TooltipComponent,
1828
- import_components7.LegendComponent,
1829
- import_components7.TitleComponent,
1830
- import_components7.RadarComponent,
1831
- import_renderers7.CanvasRenderer
2266
+ import_components8.TooltipComponent,
2267
+ import_components8.LegendComponent,
2268
+ import_components8.TitleComponent,
2269
+ import_components8.RadarComponent,
2270
+ import_renderers8.CanvasRenderer
1832
2271
  ]);
1833
2272
  var RadarChart = React12.forwardRef(
1834
2273
  ({
@@ -1837,6 +2276,8 @@ var RadarChart = React12.forwardRef(
1837
2276
  data,
1838
2277
  indicators,
1839
2278
  height = 400,
2279
+ minHeight,
2280
+ maxHeight,
1840
2281
  loading,
1841
2282
  error,
1842
2283
  emptyMessage,
@@ -1846,6 +2287,8 @@ var RadarChart = React12.forwardRef(
1846
2287
  showTooltip = true,
1847
2288
  shape = "polygon",
1848
2289
  showLabels = false,
2290
+ valueFormat,
2291
+ locale,
1849
2292
  labelFormatter,
1850
2293
  tooltipFormatter,
1851
2294
  tooltipValueFormatter,
@@ -1853,6 +2296,11 @@ var RadarChart = React12.forwardRef(
1853
2296
  renderLegend,
1854
2297
  onLegendChange,
1855
2298
  option: optionOverride,
2299
+ onReady,
2300
+ events,
2301
+ showDataTable,
2302
+ exportable,
2303
+ patterns,
1856
2304
  onClick,
1857
2305
  class: className,
1858
2306
  ...props
@@ -1862,27 +2310,32 @@ var RadarChart = React12.forwardRef(
1862
2310
  const legend = useChartLegend({
1863
2311
  names: data?.series?.map((s) => s.name) ?? [],
1864
2312
  colors: data?.series?.map((s) => s.color) ?? [],
1865
- palette: (0, import_charts_core10.getChartColors)(currentTheme).series,
2313
+ palette: (0, import_charts_core12.getChartColors)(currentTheme).series,
1866
2314
  config: legendConfig,
1867
2315
  title,
1868
2316
  onLegendChange
1869
2317
  });
1870
2318
  const customLegend = renderLegend !== void 0;
2319
+ const format = React12.useMemo(
2320
+ () => (0, import_charts_core12.resolveValueFormatter)(valueFormat, locale),
2321
+ [valueFormat, locale]
2322
+ );
2323
+ const valueFormatter = tooltipValueFormatter ?? format;
1871
2324
  const option = React12.useMemo(() => {
1872
2325
  if (isEmpty) return {};
1873
- return (0, import_charts_core10.mergeChartOption)(
2326
+ return (0, import_charts_core12.mergeChartOption)(
1874
2327
  {
1875
- tooltip: (0, import_charts_core10.buildTooltip)(
2328
+ tooltip: (0, import_charts_core12.buildTooltip)(
1876
2329
  {
1877
2330
  trigger: "item"
1878
2331
  },
1879
2332
  {
1880
2333
  show: showTooltip,
1881
2334
  formatter: tooltipFormatter,
1882
- valueFormatter: tooltipValueFormatter
2335
+ valueFormatter
1883
2336
  }
1884
2337
  ),
1885
- legend: (0, import_charts_core10.buildLegend)(
2338
+ legend: (0, import_charts_core12.buildLegend)(
1886
2339
  data.series.map((s) => s.name),
1887
2340
  legendConfig,
1888
2341
  { show: showLegend, custom: customLegend }
@@ -1894,12 +2347,12 @@ var RadarChart = React12.forwardRef(
1894
2347
  min: ind.min
1895
2348
  })),
1896
2349
  shape,
1897
- center: (0, import_charts_core10.legendCenter)(legendConfig, showLegend && !customLegend, ["50%", "50%"])
2350
+ center: (0, import_charts_core12.legendCenter)(legendConfig, showLegend && !customLegend, ["50%", "50%"])
1898
2351
  },
1899
2352
  series: [
1900
2353
  {
1901
2354
  type: "radar",
1902
- label: (0, import_charts_core10.buildDataLabel)({ show: true }, void 0, {
2355
+ label: (0, import_charts_core12.buildDataLabel)({ show: true }, void 0, {
1903
2356
  show: showLabels,
1904
2357
  formatter: labelFormatter
1905
2358
  }),
@@ -1926,22 +2379,20 @@ var RadarChart = React12.forwardRef(
1926
2379
  showLabels,
1927
2380
  labelFormatter,
1928
2381
  tooltipFormatter,
1929
- tooltipValueFormatter,
2382
+ valueFormatter,
1930
2383
  legendConfig,
1931
2384
  customLegend,
1932
2385
  optionOverride
1933
2386
  ]);
1934
- const latest = useLatestRef({ onClick });
1935
- const { containerRef } = useChart({
2387
+ const { containerRef, exportImage } = useChart({
1936
2388
  option,
1937
2389
  theme,
1938
2390
  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({
2391
+ patterns,
2392
+ events: chartEvents(events, {
2393
+ click: onClick && ((params) => {
2394
+ if (!onClick) return;
2395
+ onClick({
1945
2396
  type: params.type || "click",
1946
2397
  componentType: params.componentType || "series",
1947
2398
  seriesIndex: params.seriesIndex,
@@ -1951,17 +2402,21 @@ var RadarChart = React12.forwardRef(
1951
2402
  value: params.value,
1952
2403
  color: params.color
1953
2404
  });
1954
- });
1955
- }
2405
+ })
2406
+ }),
2407
+ onReady: legend.attach,
2408
+ onCreated: onReady
1956
2409
  });
1957
2410
  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)(
2411
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1959
2412
  ChartContainer,
1960
2413
  {
1961
2414
  ref,
1962
2415
  title,
1963
2416
  description: accessibilityDescription,
1964
2417
  height,
2418
+ minHeight,
2419
+ maxHeight,
1965
2420
  loading,
1966
2421
  error,
1967
2422
  empty: isEmpty,
@@ -1969,8 +2424,13 @@ var RadarChart = React12.forwardRef(
1969
2424
  className: cn(className),
1970
2425
  legend: !isEmpty && renderLegend ? renderLegend(legend.renderProps) : void 0,
1971
2426
  legendPosition: legendConfig?.position,
2427
+ dataTable: isEmpty ? void 0 : (0, import_charts_core12.radarTable)(data, indicators),
2428
+ showDataTable,
2429
+ format,
2430
+ exportable,
2431
+ exportImage,
1972
2432
  ...props,
1973
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { ref: containerRef, className: "h-full w-full" })
2433
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { ref: containerRef, className: "h-full w-full" })
1974
2434
  }
1975
2435
  );
1976
2436
  }
@@ -1981,16 +2441,16 @@ RadarChart.displayName = "RadarChart";
1981
2441
  var React13 = __toESM(require("react"), 1);
1982
2442
  var echarts10 = __toESM(require("echarts/core"), 1);
1983
2443
  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");
2444
+ var import_components9 = require("echarts/components");
2445
+ var import_renderers9 = require("echarts/renderers");
2446
+ var import_charts_core13 = require("@classic-homes/charts-core");
2447
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1988
2448
  echarts10.use([
1989
2449
  import_charts8.FunnelChart,
1990
- import_components8.TooltipComponent,
1991
- import_components8.LegendComponent,
1992
- import_components8.TitleComponent,
1993
- import_renderers8.CanvasRenderer
2450
+ import_components9.TooltipComponent,
2451
+ import_components9.LegendComponent,
2452
+ import_components9.TitleComponent,
2453
+ import_renderers9.CanvasRenderer
1994
2454
  ]);
1995
2455
  var FunnelChart = React13.forwardRef(
1996
2456
  ({
@@ -1998,6 +2458,8 @@ var FunnelChart = React13.forwardRef(
1998
2458
  description,
1999
2459
  data,
2000
2460
  height = 400,
2461
+ minHeight,
2462
+ maxHeight,
2001
2463
  loading,
2002
2464
  error,
2003
2465
  emptyMessage,
@@ -2008,6 +2470,8 @@ var FunnelChart = React13.forwardRef(
2008
2470
  sort = "descending",
2009
2471
  orientation = "vertical",
2010
2472
  showLabels = true,
2473
+ valueFormat,
2474
+ locale,
2011
2475
  labelFormatter,
2012
2476
  tooltipFormatter,
2013
2477
  tooltipValueFormatter,
@@ -2015,6 +2479,11 @@ var FunnelChart = React13.forwardRef(
2015
2479
  renderLegend,
2016
2480
  onLegendChange,
2017
2481
  option: optionOverride,
2482
+ onReady,
2483
+ events,
2484
+ showDataTable,
2485
+ exportable,
2486
+ patterns,
2018
2487
  onClick,
2019
2488
  class: className,
2020
2489
  ...props
@@ -2024,32 +2493,37 @@ var FunnelChart = React13.forwardRef(
2024
2493
  const legend = useChartLegend({
2025
2494
  names: data?.map((d) => d.name) ?? [],
2026
2495
  colors: data?.map((d) => d.color) ?? [],
2027
- palette: (0, import_charts_core11.getChartColors)(currentTheme).series,
2496
+ palette: (0, import_charts_core13.getChartColors)(currentTheme).series,
2028
2497
  config: legendConfig,
2029
2498
  title,
2030
2499
  onLegendChange
2031
2500
  });
2032
2501
  const customLegend = renderLegend !== void 0;
2502
+ const format = React13.useMemo(
2503
+ () => (0, import_charts_core13.resolveValueFormatter)(valueFormat, locale),
2504
+ [valueFormat, locale]
2505
+ );
2506
+ const valueFormatter = tooltipValueFormatter ?? format;
2033
2507
  const option = React13.useMemo(() => {
2034
2508
  if (isEmpty) return {};
2035
- const getLabel = (0, import_charts_core11.itemLabelLookup)(data);
2036
- const valueFormatter = tooltipFormatter === void 0 ? tooltipValueFormatter : void 0;
2509
+ const getLabel = (0, import_charts_core13.itemLabelLookup)(data);
2510
+ const templateFormatter = tooltipFormatter === void 0 ? valueFormatter : void 0;
2037
2511
  const tooltipBase = {
2038
2512
  trigger: "item",
2039
- formatter: valueFormatter ? (params) => {
2513
+ formatter: templateFormatter ? (params) => {
2040
2514
  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))}`;
2515
+ 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
2516
  } : "{a} <br/>{b}: {c}"
2043
2517
  };
2044
- return (0, import_charts_core11.mergeChartOption)(
2518
+ return (0, import_charts_core13.mergeChartOption)(
2045
2519
  {
2046
- tooltip: (0, import_charts_core11.buildTooltip)(tooltipBase, {
2520
+ tooltip: (0, import_charts_core13.buildTooltip)(tooltipBase, {
2047
2521
  show: showTooltip,
2048
2522
  formatter: tooltipFormatter,
2049
- valueFormatter: tooltipValueFormatter,
2523
+ valueFormatter,
2050
2524
  getLabel
2051
2525
  }),
2052
- legend: (0, import_charts_core11.buildLegend)(
2526
+ legend: (0, import_charts_core13.buildLegend)(
2053
2527
  data.map((d) => d.name),
2054
2528
  legendConfig,
2055
2529
  { show: showLegend, custom: customLegend }
@@ -2070,7 +2544,7 @@ var FunnelChart = React13.forwardRef(
2070
2544
  sort,
2071
2545
  orient: orientation,
2072
2546
  gap: 2,
2073
- label: (0, import_charts_core11.buildDataLabel)(
2547
+ label: (0, import_charts_core13.buildDataLabel)(
2074
2548
  {
2075
2549
  show: true,
2076
2550
  position: "inside",
@@ -2091,7 +2565,7 @@ var FunnelChart = React13.forwardRef(
2091
2565
  name: item.name,
2092
2566
  value: item.value,
2093
2567
  itemStyle: item.color ? { color: item.color } : void 0,
2094
- label: (0, import_charts_core11.pointLabel)(item.label, labelFormatter, { position: "inside" })
2568
+ label: (0, import_charts_core13.pointLabel)(item.label, labelFormatter, { position: "inside" })
2095
2569
  }))
2096
2570
  }
2097
2571
  ]
@@ -2109,39 +2583,41 @@ var FunnelChart = React13.forwardRef(
2109
2583
  title,
2110
2584
  labelFormatter,
2111
2585
  tooltipFormatter,
2112
- tooltipValueFormatter,
2586
+ valueFormatter,
2113
2587
  legendConfig,
2114
2588
  customLegend,
2115
2589
  optionOverride
2116
2590
  ]);
2117
- const latest = useLatestRef({ onClick });
2118
- const { containerRef } = useChart({
2591
+ const { containerRef, exportImage } = useChart({
2119
2592
  option,
2120
2593
  theme,
2121
2594
  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({
2595
+ patterns,
2596
+ events: chartEvents(events, {
2597
+ click: onClick && ((params) => {
2598
+ if (!onClick) return;
2599
+ onClick({
2128
2600
  type: params.type || "click",
2129
2601
  componentType: params.componentType || "series",
2130
2602
  name: params.name || "",
2131
2603
  value: params.value,
2132
2604
  color: params.color
2133
2605
  });
2134
- });
2135
- }
2606
+ })
2607
+ }),
2608
+ onReady: legend.attach,
2609
+ onCreated: onReady
2136
2610
  });
2137
2611
  const accessibilityDescription = description || (!isEmpty ? `${title}. Funnel chart with ${data.length} stages.` : void 0);
2138
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2612
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2139
2613
  ChartContainer,
2140
2614
  {
2141
2615
  ref,
2142
2616
  title,
2143
2617
  description: accessibilityDescription,
2144
2618
  height,
2619
+ minHeight,
2620
+ maxHeight,
2145
2621
  loading,
2146
2622
  error,
2147
2623
  empty: isEmpty,
@@ -2149,8 +2625,13 @@ var FunnelChart = React13.forwardRef(
2149
2625
  className: cn(className),
2150
2626
  legend: !isEmpty && renderLegend ? renderLegend(legend.renderProps) : void 0,
2151
2627
  legendPosition: legendConfig?.position,
2628
+ dataTable: isEmpty ? void 0 : (0, import_charts_core13.sliceTable)(data, "Stage"),
2629
+ showDataTable,
2630
+ format,
2631
+ exportable,
2632
+ exportImage,
2152
2633
  ...props,
2153
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { ref: containerRef, className: "h-full w-full" })
2634
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { ref: containerRef, className: "h-full w-full" })
2154
2635
  }
2155
2636
  );
2156
2637
  }
@@ -2161,11 +2642,11 @@ FunnelChart.displayName = "FunnelChart";
2161
2642
  var React14 = __toESM(require("react"), 1);
2162
2643
  var echarts11 = __toESM(require("echarts/core"), 1);
2163
2644
  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]);
2645
+ var import_components10 = require("echarts/components");
2646
+ var import_renderers10 = require("echarts/renderers");
2647
+ var import_charts_core14 = require("@classic-homes/charts-core");
2648
+ var import_jsx_runtime15 = require("react/jsx-runtime");
2649
+ echarts11.use([import_charts9.GaugeChart, import_components10.TitleComponent, import_components10.TooltipComponent, import_renderers10.CanvasRenderer]);
2169
2650
  var GaugeChart = React14.forwardRef(
2170
2651
  ({
2171
2652
  title,
@@ -2174,6 +2655,8 @@ var GaugeChart = React14.forwardRef(
2174
2655
  min = 0,
2175
2656
  max = 100,
2176
2657
  height = 400,
2658
+ minHeight,
2659
+ maxHeight,
2177
2660
  loading,
2178
2661
  error,
2179
2662
  emptyMessage,
@@ -2181,23 +2664,35 @@ var GaugeChart = React14.forwardRef(
2181
2664
  animation = true,
2182
2665
  splitNumber = 10,
2183
2666
  showProgress = true,
2184
- formatValue,
2667
+ formatValue: formatValue2,
2185
2668
  showTooltip = true,
2669
+ valueFormat,
2670
+ locale,
2186
2671
  tooltipFormatter,
2187
2672
  tooltipValueFormatter,
2188
2673
  option: optionOverride,
2674
+ onReady,
2675
+ events,
2676
+ showDataTable,
2677
+ exportable,
2678
+ patterns,
2189
2679
  onClick,
2190
2680
  class: className,
2191
2681
  ...props
2192
2682
  }, ref) => {
2193
2683
  const currentTheme = useChartTheme(theme);
2194
- const chartColors = (0, import_charts_core12.getChartColors)(currentTheme);
2684
+ const chartColors = (0, import_charts_core14.getChartColors)(currentTheme);
2195
2685
  const reducedMotion = useReducedMotion();
2686
+ const format = React14.useMemo(
2687
+ () => (0, import_charts_core14.resolveValueFormatter)(valueFormat, locale),
2688
+ [valueFormat, locale]
2689
+ );
2690
+ const valueFormatter = formatValue2 ?? format;
2196
2691
  const option = React14.useMemo(() => {
2197
- return (0, import_charts_core12.mergeChartOption)(
2692
+ return (0, import_charts_core14.mergeChartOption)(
2198
2693
  {
2199
2694
  // No tooltip by default; one appears once its content is customised
2200
- tooltip: tooltipFormatter || tooltipValueFormatter ? (0, import_charts_core12.buildTooltip)(
2695
+ tooltip: tooltipFormatter || tooltipValueFormatter ? (0, import_charts_core14.buildTooltip)(
2201
2696
  { trigger: "item" },
2202
2697
  {
2203
2698
  show: showTooltip,
@@ -2264,7 +2759,7 @@ var GaugeChart = React14.forwardRef(
2264
2759
  fontSize: 28,
2265
2760
  fontWeight: "bold",
2266
2761
  offsetCenter: [0, "40%"],
2267
- formatter: formatValue || "{value}"
2762
+ formatter: valueFormatter || "{value}"
2268
2763
  },
2269
2764
  data: [
2270
2765
  {
@@ -2283,7 +2778,7 @@ var GaugeChart = React14.forwardRef(
2283
2778
  max,
2284
2779
  splitNumber,
2285
2780
  showProgress,
2286
- formatValue,
2781
+ valueFormatter,
2287
2782
  title,
2288
2783
  animation,
2289
2784
  reducedMotion,
@@ -2293,16 +2788,15 @@ var GaugeChart = React14.forwardRef(
2293
2788
  tooltipValueFormatter,
2294
2789
  optionOverride
2295
2790
  ]);
2296
- const latest = useLatestRef({ onClick });
2297
- const { containerRef } = useChart({
2791
+ const { containerRef, exportImage } = useChart({
2298
2792
  option,
2299
- theme: currentTheme === import_charts_core12.THEME_DARK ? "dark" : "light",
2793
+ theme: currentTheme === import_charts_core14.THEME_DARK ? "dark" : "light",
2300
2794
  animation,
2301
- onReady: (chart) => {
2302
- chart.on("click", (params) => {
2303
- const { onClick: onClick2 } = latest.current;
2304
- if (!onClick2) return;
2305
- onClick2({
2795
+ patterns,
2796
+ events: chartEvents(events, {
2797
+ click: onClick && ((params) => {
2798
+ if (!onClick) return;
2799
+ onClick({
2306
2800
  type: params.type || "click",
2307
2801
  componentType: params.componentType || "series",
2308
2802
  seriesIndex: params.seriesIndex,
@@ -2312,23 +2806,35 @@ var GaugeChart = React14.forwardRef(
2312
2806
  value: params.value,
2313
2807
  color: params.color
2314
2808
  });
2315
- });
2316
- }
2809
+ })
2810
+ }),
2811
+ onCreated: onReady
2317
2812
  });
2318
- const accessibilityDescription = description || `${title}. Gauge showing value ${value} on scale from ${min} to ${max}.`;
2319
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2813
+ const show = (n) => valueFormatter ? valueFormatter(n) : String(n);
2814
+ const accessibilityDescription = description || `${title}. Gauge showing value ${show(value)} on scale from ${show(min)} to ${show(max)}.`;
2815
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2320
2816
  ChartContainer,
2321
2817
  {
2322
2818
  ref,
2323
2819
  title,
2324
2820
  description: accessibilityDescription,
2325
2821
  height,
2822
+ minHeight,
2823
+ maxHeight,
2326
2824
  loading,
2327
2825
  error,
2328
2826
  emptyMessage,
2329
2827
  className: cn(className),
2828
+ dataTable: {
2829
+ headers: ["Metric", "Value", "Minimum", "Maximum"],
2830
+ rows: [[title, value, min, max]]
2831
+ },
2832
+ showDataTable,
2833
+ format,
2834
+ exportable,
2835
+ exportImage,
2330
2836
  ...props,
2331
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { ref: containerRef, className: "h-full w-full" })
2837
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { ref: containerRef, className: "h-full w-full" })
2332
2838
  }
2333
2839
  );
2334
2840
  }
@@ -2339,17 +2845,17 @@ GaugeChart.displayName = "GaugeChart";
2339
2845
  var React15 = __toESM(require("react"), 1);
2340
2846
  var echarts12 = __toESM(require("echarts/core"), 1);
2341
2847
  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");
2848
+ var import_components11 = require("echarts/components");
2849
+ var import_renderers11 = require("echarts/renderers");
2850
+ var import_charts_core15 = require("@classic-homes/charts-core");
2851
+ var import_jsx_runtime16 = require("react/jsx-runtime");
2346
2852
  echarts12.use([
2347
2853
  import_charts10.HeatmapChart,
2348
- import_components10.GridComponent,
2349
- import_components10.TooltipComponent,
2350
- import_components10.TitleComponent,
2351
- import_components10.VisualMapComponent,
2352
- import_renderers10.CanvasRenderer
2854
+ import_components11.GridComponent,
2855
+ import_components11.TooltipComponent,
2856
+ import_components11.TitleComponent,
2857
+ import_components11.VisualMapComponent,
2858
+ import_renderers11.CanvasRenderer
2353
2859
  ]);
2354
2860
  var HeatmapChart = React15.forwardRef(
2355
2861
  ({
@@ -2359,6 +2865,8 @@ var HeatmapChart = React15.forwardRef(
2359
2865
  xAxis,
2360
2866
  yAxis,
2361
2867
  height = 400,
2868
+ minHeight,
2869
+ maxHeight,
2362
2870
  loading,
2363
2871
  error,
2364
2872
  emptyMessage,
@@ -2369,9 +2877,16 @@ var HeatmapChart = React15.forwardRef(
2369
2877
  labelFormatter,
2370
2878
  xAxisConfig,
2371
2879
  yAxisConfig,
2880
+ valueFormat,
2881
+ locale,
2372
2882
  tooltipFormatter,
2373
2883
  tooltipValueFormatter,
2374
2884
  option: optionOverride,
2885
+ onReady,
2886
+ events,
2887
+ showDataTable,
2888
+ exportable,
2889
+ patterns,
2375
2890
  onClick,
2376
2891
  class: className,
2377
2892
  ...props
@@ -2385,24 +2900,29 @@ var HeatmapChart = React15.forwardRef(
2385
2900
  }
2386
2901
  const minValue = data?.min ?? dataMin;
2387
2902
  const maxValue = data?.max ?? dataMax;
2903
+ const format = React15.useMemo(
2904
+ () => (0, import_charts_core15.resolveValueFormatter)(valueFormat, locale),
2905
+ [valueFormat, locale]
2906
+ );
2907
+ const valueFormatter = tooltipValueFormatter ?? format;
2388
2908
  const option = React15.useMemo(() => {
2389
2909
  if (isEmpty) return {};
2390
- return (0, import_charts_core13.mergeChartOption)(
2910
+ return (0, import_charts_core15.mergeChartOption)(
2391
2911
  {
2392
- tooltip: (0, import_charts_core13.buildTooltip)(
2912
+ tooltip: (0, import_charts_core15.buildTooltip)(
2393
2913
  {
2394
2914
  position: "top",
2395
2915
  formatter: (params) => {
2396
2916
  const p = params;
2397
2917
  if (!p.value) return "";
2398
2918
  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))}`;
2919
+ 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
2920
  }
2401
2921
  },
2402
2922
  {
2403
2923
  show: showTooltip,
2404
2924
  formatter: tooltipFormatter,
2405
- valueFormatter: tooltipValueFormatter
2925
+ valueFormatter
2406
2926
  }
2407
2927
  ),
2408
2928
  grid: {
@@ -2411,7 +2931,7 @@ var HeatmapChart = React15.forwardRef(
2411
2931
  bottom: "3%",
2412
2932
  containLabel: true
2413
2933
  },
2414
- xAxis: (0, import_charts_core13.buildAxis)(
2934
+ xAxis: (0, import_charts_core15.buildAxis)(
2415
2935
  {
2416
2936
  type: "category",
2417
2937
  data: xAxis,
@@ -2421,7 +2941,7 @@ var HeatmapChart = React15.forwardRef(
2421
2941
  },
2422
2942
  xAxisConfig
2423
2943
  ),
2424
- yAxis: (0, import_charts_core13.buildAxis)(
2944
+ yAxis: (0, import_charts_core15.buildAxis)(
2425
2945
  {
2426
2946
  type: "category",
2427
2947
  data: yAxis,
@@ -2437,14 +2957,15 @@ var HeatmapChart = React15.forwardRef(
2437
2957
  calculable: true,
2438
2958
  orient: "vertical",
2439
2959
  right: "0%",
2440
- top: "center"
2960
+ top: "center",
2961
+ formatter: valueFormatter ? (value) => valueFormatter(value) : void 0
2441
2962
  },
2442
2963
  series: [
2443
2964
  {
2444
2965
  name: title,
2445
2966
  type: "heatmap",
2446
2967
  data: data.data,
2447
- label: (0, import_charts_core13.buildDataLabel)({ show: true }, void 0, {
2968
+ label: (0, import_charts_core15.buildDataLabel)({ show: true }, void 0, {
2448
2969
  show: showValues,
2449
2970
  formatter: labelFormatter
2450
2971
  }),
@@ -2473,46 +2994,53 @@ var HeatmapChart = React15.forwardRef(
2473
2994
  xAxisConfig,
2474
2995
  yAxisConfig,
2475
2996
  tooltipFormatter,
2476
- tooltipValueFormatter,
2997
+ valueFormatter,
2477
2998
  optionOverride
2478
2999
  ]);
2479
- const latest = useLatestRef({ onClick, xAxis, yAxis });
2480
- const { containerRef } = useChart({
3000
+ const { containerRef, exportImage } = useChart({
2481
3001
  option,
2482
3002
  theme,
2483
3003
  animation,
2484
- onReady: (chart) => {
2485
- chart.on("click", (params) => {
2486
- const { onClick: onClick2, xAxis: xAxis2, yAxis: yAxis2 } = latest.current;
2487
- if (!onClick2) return;
3004
+ patterns,
3005
+ events: chartEvents(events, {
3006
+ click: onClick && ((params) => {
3007
+ if (!onClick) return;
2488
3008
  const [xIdx, yIdx, value] = params.value || [0, 0, 0];
2489
- onClick2({
3009
+ onClick({
2490
3010
  type: params.type || "click",
2491
3011
  componentType: params.componentType || "series",
2492
3012
  xIndex: xIdx,
2493
3013
  yIndex: yIdx,
2494
- xLabel: xAxis2[xIdx],
2495
- yLabel: yAxis2[yIdx],
3014
+ xLabel: xAxis[xIdx],
3015
+ yLabel: yAxis[yIdx],
2496
3016
  value
2497
3017
  });
2498
- });
2499
- }
3018
+ })
3019
+ }),
3020
+ onCreated: onReady
2500
3021
  });
2501
3022
  const accessibilityDescription = description || (!isEmpty ? `${title}. Heatmap with ${xAxis.length} columns and ${yAxis.length} rows.` : void 0);
2502
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3023
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2503
3024
  ChartContainer,
2504
3025
  {
2505
3026
  ref,
2506
3027
  title,
2507
3028
  description: accessibilityDescription,
2508
3029
  height,
3030
+ minHeight,
3031
+ maxHeight,
2509
3032
  loading,
2510
3033
  error,
2511
3034
  empty: isEmpty,
2512
3035
  emptyMessage,
2513
3036
  className: cn(className),
3037
+ dataTable: isEmpty ? void 0 : (0, import_charts_core15.heatmapTable)(data, xAxis, yAxis),
3038
+ showDataTable,
3039
+ format,
3040
+ exportable,
3041
+ exportImage,
2514
3042
  ...props,
2515
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { ref: containerRef, className: "h-full w-full" })
3043
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref: containerRef, className: "h-full w-full" })
2516
3044
  }
2517
3045
  );
2518
3046
  }
@@ -2523,11 +3051,11 @@ HeatmapChart.displayName = "HeatmapChart";
2523
3051
  var React16 = __toESM(require("react"), 1);
2524
3052
  var echarts13 = __toESM(require("echarts/core"), 1);
2525
3053
  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]);
3054
+ var import_components12 = require("echarts/components");
3055
+ var import_renderers12 = require("echarts/renderers");
3056
+ var import_charts_core16 = require("@classic-homes/charts-core");
3057
+ var import_jsx_runtime17 = require("react/jsx-runtime");
3058
+ echarts13.use([import_charts11.TreemapChart, import_components12.TooltipComponent, import_components12.TitleComponent, import_renderers12.CanvasRenderer]);
2531
3059
  var TreemapChart = React16.forwardRef(
2532
3060
  ({
2533
3061
  title,
@@ -2535,6 +3063,8 @@ var TreemapChart = React16.forwardRef(
2535
3063
  data,
2536
3064
  levels,
2537
3065
  height = 400,
3066
+ minHeight,
3067
+ maxHeight,
2538
3068
  loading,
2539
3069
  error,
2540
3070
  emptyMessage,
@@ -2542,36 +3072,48 @@ var TreemapChart = React16.forwardRef(
2542
3072
  animation = true,
2543
3073
  showTooltip = true,
2544
3074
  labelFormatter,
3075
+ valueFormat,
3076
+ locale,
2545
3077
  tooltipFormatter,
2546
3078
  tooltipValueFormatter,
2547
3079
  option: optionOverride,
3080
+ onReady,
3081
+ events,
3082
+ showDataTable,
3083
+ exportable,
3084
+ patterns,
2548
3085
  onClick,
2549
3086
  class: className,
2550
3087
  ...props
2551
3088
  }, ref) => {
2552
3089
  const isEmpty = !data?.length;
2553
3090
  const currentTheme = useChartTheme(theme);
2554
- const chartColors = (0, import_charts_core14.getChartColors)(currentTheme);
3091
+ const chartColors = (0, import_charts_core16.getChartColors)(currentTheme);
3092
+ const format = React16.useMemo(
3093
+ () => (0, import_charts_core16.resolveValueFormatter)(valueFormat, locale),
3094
+ [valueFormat, locale]
3095
+ );
3096
+ const valueFormatter = tooltipValueFormatter ?? format;
2555
3097
  const option = React16.useMemo(() => {
2556
3098
  if (isEmpty) return {};
2557
3099
  const toNode = (node) => ({
2558
3100
  ...node,
2559
3101
  children: node.children?.map(toNode),
2560
- label: (0, import_charts_core14.pointLabel)(node.label, labelFormatter)
3102
+ label: (0, import_charts_core16.pointLabel)(node.label, labelFormatter)
2561
3103
  });
2562
- return (0, import_charts_core14.mergeChartOption)(
3104
+ return (0, import_charts_core16.mergeChartOption)(
2563
3105
  {
2564
- tooltip: (0, import_charts_core14.buildTooltip)(
3106
+ tooltip: (0, import_charts_core16.buildTooltip)(
2565
3107
  {
2566
3108
  formatter: (params) => {
2567
3109
  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))}`;
3110
+ return `${(0, import_charts_core16.escapeHtml)(p.name)}: ${(0, import_charts_core16.escapeHtml)((0, import_charts_core16.formatTooltipValue)(p.value, valueFormatter))}`;
2569
3111
  }
2570
3112
  },
2571
3113
  {
2572
3114
  show: showTooltip,
2573
3115
  formatter: tooltipFormatter,
2574
- valueFormatter: tooltipValueFormatter
3116
+ valueFormatter
2575
3117
  }
2576
3118
  ),
2577
3119
  series: [
@@ -2606,10 +3148,10 @@ var TreemapChart = React16.forwardRef(
2606
3148
  colorSaturation: [0.3, 0.5]
2607
3149
  }
2608
3150
  ],
2609
- label: (0, import_charts_core14.buildDataLabel)({ show: true, formatter: "{b}" }, void 0, {
3151
+ label: (0, import_charts_core16.buildDataLabel)({ show: true, formatter: "{b}" }, void 0, {
2610
3152
  show: true,
2611
3153
  formatter: labelFormatter,
2612
- getLabel: (0, import_charts_core14.nameLabelLookup)(data)
3154
+ getLabel: (0, import_charts_core16.nameLabelLookup)(data)
2613
3155
  }),
2614
3156
  upperLabel: {
2615
3157
  show: true,
@@ -2631,20 +3173,19 @@ var TreemapChart = React16.forwardRef(
2631
3173
  chartColors,
2632
3174
  labelFormatter,
2633
3175
  tooltipFormatter,
2634
- tooltipValueFormatter,
3176
+ valueFormatter,
2635
3177
  optionOverride
2636
3178
  ]);
2637
- const latest = useLatestRef({ onClick });
2638
- const { containerRef } = useChart({
3179
+ const { containerRef, exportImage } = useChart({
2639
3180
  option,
2640
- theme: currentTheme === import_charts_core14.THEME_DARK ? "dark" : "light",
3181
+ theme: currentTheme === import_charts_core16.THEME_DARK ? "dark" : "light",
2641
3182
  animation,
2642
- onReady: (chart) => {
2643
- chart.on("click", (params) => {
2644
- const { onClick: onClick2 } = latest.current;
2645
- if (!onClick2) return;
3183
+ patterns,
3184
+ events: chartEvents(events, {
3185
+ click: onClick && ((params) => {
3186
+ if (!onClick) return;
2646
3187
  const treePathInfo = params.treePathInfo || [];
2647
- onClick2({
3188
+ onClick({
2648
3189
  type: params.type || "click",
2649
3190
  componentType: params.componentType || "series",
2650
3191
  name: params.name || "",
@@ -2652,24 +3193,32 @@ var TreemapChart = React16.forwardRef(
2652
3193
  path: treePathInfo.map((item) => item.name || ""),
2653
3194
  depth: treePathInfo.length - 1
2654
3195
  });
2655
- });
2656
- }
3196
+ })
3197
+ }),
3198
+ onCreated: onReady
2657
3199
  });
2658
3200
  const accessibilityDescription = description || (!isEmpty ? `${title}. Treemap chart showing hierarchical data.` : void 0);
2659
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3201
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2660
3202
  ChartContainer,
2661
3203
  {
2662
3204
  ref,
2663
3205
  title,
2664
3206
  description: accessibilityDescription,
2665
3207
  height,
3208
+ minHeight,
3209
+ maxHeight,
2666
3210
  loading,
2667
3211
  error,
2668
3212
  empty: isEmpty,
2669
3213
  emptyMessage,
2670
3214
  className: cn(className),
3215
+ dataTable: isEmpty ? void 0 : (0, import_charts_core16.treemapTable)(data),
3216
+ showDataTable,
3217
+ format,
3218
+ exportable,
3219
+ exportImage,
2671
3220
  ...props,
2672
- children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref: containerRef, className: "h-full w-full" })
3221
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { ref: containerRef, className: "h-full w-full" })
2673
3222
  }
2674
3223
  );
2675
3224
  }
@@ -2680,18 +3229,18 @@ TreemapChart.displayName = "TreemapChart";
2680
3229
  var React17 = __toESM(require("react"), 1);
2681
3230
  var echarts14 = __toESM(require("echarts/core"), 1);
2682
3231
  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");
3232
+ var import_components13 = require("echarts/components");
3233
+ var import_renderers13 = require("echarts/renderers");
3234
+ var import_charts_core17 = require("@classic-homes/charts-core");
3235
+ var import_jsx_runtime18 = require("react/jsx-runtime");
2687
3236
  echarts14.use([
2688
3237
  import_charts12.CandlestickChart,
2689
3238
  import_charts12.BarChart,
2690
- import_components12.GridComponent,
2691
- import_components12.TooltipComponent,
2692
- import_components12.TitleComponent,
2693
- import_components12.DataZoomComponent,
2694
- import_renderers12.CanvasRenderer
3239
+ import_components13.GridComponent,
3240
+ import_components13.TooltipComponent,
3241
+ import_components13.TitleComponent,
3242
+ import_components13.DataZoomComponent,
3243
+ import_renderers13.CanvasRenderer
2695
3244
  ]);
2696
3245
  var CandlestickChart = React17.forwardRef(
2697
3246
  ({
@@ -2699,6 +3248,8 @@ var CandlestickChart = React17.forwardRef(
2699
3248
  description,
2700
3249
  data,
2701
3250
  height = 400,
3251
+ minHeight,
3252
+ maxHeight,
2702
3253
  loading,
2703
3254
  error,
2704
3255
  emptyMessage,
@@ -2706,18 +3257,31 @@ var CandlestickChart = React17.forwardRef(
2706
3257
  animation = true,
2707
3258
  showTooltip = true,
2708
3259
  showVolume = false,
3260
+ zoomStart = 80,
2709
3261
  xAxisConfig,
2710
3262
  yAxisConfig,
3263
+ valueFormat,
3264
+ locale,
2711
3265
  tooltipFormatter,
2712
3266
  tooltipValueFormatter,
2713
3267
  option: optionOverride,
3268
+ onReady,
3269
+ events,
3270
+ showDataTable,
3271
+ exportable,
3272
+ patterns,
2714
3273
  onClick,
2715
3274
  class: className,
2716
3275
  ...props
2717
3276
  }, ref) => {
2718
3277
  const isEmpty = !data?.dates?.length || !data?.data?.length;
2719
3278
  const currentTheme = useChartTheme(theme);
2720
- const chartColors = (0, import_charts_core15.getChartColors)(currentTheme);
3279
+ const chartColors = (0, import_charts_core17.getChartColors)(currentTheme);
3280
+ const format = React17.useMemo(
3281
+ () => (0, import_charts_core17.resolveValueFormatter)(valueFormat, locale),
3282
+ [valueFormat, locale]
3283
+ );
3284
+ const valueFormatter = tooltipValueFormatter ?? format;
2721
3285
  const option = React17.useMemo(() => {
2722
3286
  if (isEmpty) return {};
2723
3287
  const candlestickData = data.data.map((item) => [item.open, item.close, item.low, item.high]);
@@ -2745,7 +3309,7 @@ var CandlestickChart = React17.forwardRef(
2745
3309
  }
2746
3310
  ];
2747
3311
  const xAxisArr = [
2748
- (0, import_charts_core15.buildAxis)(
3312
+ (0, import_charts_core17.buildAxis)(
2749
3313
  {
2750
3314
  type: "category",
2751
3315
  data: data.dates,
@@ -2759,7 +3323,7 @@ var CandlestickChart = React17.forwardRef(
2759
3323
  )
2760
3324
  ];
2761
3325
  const yAxisArr = [
2762
- (0, import_charts_core15.buildAxis)(
3326
+ (0, import_charts_core17.buildAxis)(
2763
3327
  {
2764
3328
  scale: true,
2765
3329
  splitArea: {
@@ -2808,9 +3372,9 @@ var CandlestickChart = React17.forwardRef(
2808
3372
  }
2809
3373
  });
2810
3374
  }
2811
- return (0, import_charts_core15.mergeChartOption)(
3375
+ return (0, import_charts_core17.mergeChartOption)(
2812
3376
  {
2813
- tooltip: (0, import_charts_core15.buildTooltip)(
3377
+ tooltip: (0, import_charts_core17.buildTooltip)(
2814
3378
  {
2815
3379
  trigger: "axis",
2816
3380
  axisPointer: {
@@ -2820,7 +3384,7 @@ var CandlestickChart = React17.forwardRef(
2820
3384
  {
2821
3385
  show: showTooltip,
2822
3386
  formatter: tooltipFormatter,
2823
- valueFormatter: tooltipValueFormatter
3387
+ valueFormatter
2824
3388
  }
2825
3389
  ),
2826
3390
  grid: gridArr,
@@ -2829,14 +3393,14 @@ var CandlestickChart = React17.forwardRef(
2829
3393
  dataZoom: [
2830
3394
  {
2831
3395
  type: "inside",
2832
- start: 80,
3396
+ start: zoomStart,
2833
3397
  end: 100
2834
3398
  },
2835
3399
  {
2836
3400
  show: true,
2837
3401
  type: "slider",
2838
3402
  top: "90%",
2839
- start: 80,
3403
+ start: zoomStart,
2840
3404
  end: 100
2841
3405
  }
2842
3406
  ],
@@ -2849,54 +3413,62 @@ var CandlestickChart = React17.forwardRef(
2849
3413
  isEmpty,
2850
3414
  showTooltip,
2851
3415
  showVolume,
3416
+ zoomStart,
2852
3417
  title,
2853
3418
  chartColors,
2854
3419
  xAxisConfig,
2855
3420
  yAxisConfig,
2856
3421
  tooltipFormatter,
2857
- tooltipValueFormatter,
3422
+ valueFormatter,
2858
3423
  optionOverride
2859
3424
  ]);
2860
- const latest = useLatestRef({ onClick, data });
2861
- const { containerRef } = useChart({
3425
+ const { containerRef, exportImage } = useChart({
2862
3426
  option,
2863
- theme: currentTheme === import_charts_core15.THEME_DARK ? "dark" : "light",
3427
+ theme: currentTheme === import_charts_core17.THEME_DARK ? "dark" : "light",
2864
3428
  animation,
2865
- onReady: (chart) => {
2866
- chart.on("click", (params) => {
2867
- const { onClick: onClick2, data: data2 } = latest.current;
2868
- if (!onClick2) return;
3429
+ patterns,
3430
+ events: chartEvents(events, {
3431
+ click: onClick && ((params) => {
3432
+ if (!onClick) return;
2869
3433
  const dataIndex = params.dataIndex || 0;
2870
- const item = data2.data[dataIndex];
3434
+ const item = data.data[dataIndex];
2871
3435
  if (!item) return;
2872
- onClick2({
3436
+ onClick({
2873
3437
  type: params.type || "click",
2874
3438
  componentType: params.componentType || "series",
2875
- date: data2.dates[dataIndex],
3439
+ date: data.dates[dataIndex],
2876
3440
  open: item.open,
2877
3441
  close: item.close,
2878
3442
  high: item.high,
2879
3443
  low: item.low,
2880
- volume: data2.volume?.[dataIndex]
3444
+ volume: data.volume?.[dataIndex]
2881
3445
  });
2882
- });
2883
- }
3446
+ })
3447
+ }),
3448
+ onCreated: onReady
2884
3449
  });
2885
3450
  const accessibilityDescription = description || (!isEmpty ? `${title}. Candlestick chart with ${data.dates.length} data points.` : void 0);
2886
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3451
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2887
3452
  ChartContainer,
2888
3453
  {
2889
3454
  ref,
2890
3455
  title,
2891
3456
  description: accessibilityDescription,
2892
3457
  height,
3458
+ minHeight,
3459
+ maxHeight,
2893
3460
  loading,
2894
3461
  error,
2895
3462
  empty: isEmpty,
2896
3463
  emptyMessage,
2897
3464
  className: cn(className),
3465
+ dataTable: isEmpty ? void 0 : (0, import_charts_core17.candlestickTable)(data),
3466
+ showDataTable,
3467
+ format,
3468
+ exportable,
3469
+ exportImage,
2898
3470
  ...props,
2899
- children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { ref: containerRef, className: "h-full w-full" })
3471
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { ref: containerRef, className: "h-full w-full" })
2900
3472
  }
2901
3473
  );
2902
3474
  }
@@ -2907,17 +3479,19 @@ CandlestickChart.displayName = "CandlestickChart";
2907
3479
  var React18 = __toESM(require("react"), 1);
2908
3480
  var echarts15 = __toESM(require("echarts/core"), 1);
2909
3481
  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]);
3482
+ var import_components14 = require("echarts/components");
3483
+ var import_renderers14 = require("echarts/renderers");
3484
+ var import_charts_core18 = require("@classic-homes/charts-core");
3485
+ var import_jsx_runtime19 = require("react/jsx-runtime");
3486
+ echarts15.use([import_charts13.SankeyChart, import_components14.TooltipComponent, import_components14.TitleComponent, import_renderers14.CanvasRenderer]);
2915
3487
  var SankeyChart = React18.forwardRef(
2916
3488
  ({
2917
3489
  title,
2918
3490
  description,
2919
3491
  data,
2920
3492
  height = 400,
3493
+ minHeight,
3494
+ maxHeight,
2921
3495
  loading,
2922
3496
  error,
2923
3497
  emptyMessage,
@@ -2926,19 +3500,31 @@ var SankeyChart = React18.forwardRef(
2926
3500
  showTooltip = true,
2927
3501
  orient = "horizontal",
2928
3502
  labelFormatter,
3503
+ valueFormat,
3504
+ locale,
2929
3505
  tooltipFormatter,
2930
3506
  tooltipValueFormatter,
2931
3507
  option: optionOverride,
3508
+ onReady,
3509
+ events,
3510
+ showDataTable,
3511
+ exportable,
3512
+ patterns,
2932
3513
  onClick,
2933
3514
  class: className,
2934
3515
  ...props
2935
3516
  }, ref) => {
2936
3517
  const isEmpty = !data?.nodes?.length || !data?.links?.length;
3518
+ const format = React18.useMemo(
3519
+ () => (0, import_charts_core18.resolveValueFormatter)(valueFormat, locale),
3520
+ [valueFormat, locale]
3521
+ );
3522
+ const valueFormatter = tooltipValueFormatter ?? format;
2937
3523
  const option = React18.useMemo(() => {
2938
3524
  if (isEmpty) return {};
2939
- return (0, import_charts_core16.mergeChartOption)(
3525
+ return (0, import_charts_core18.mergeChartOption)(
2940
3526
  {
2941
- tooltip: (0, import_charts_core16.buildTooltip)(
3527
+ tooltip: (0, import_charts_core18.buildTooltip)(
2942
3528
  {
2943
3529
  trigger: "item",
2944
3530
  triggerOn: "mousemove"
@@ -2946,7 +3532,7 @@ var SankeyChart = React18.forwardRef(
2946
3532
  {
2947
3533
  show: showTooltip,
2948
3534
  formatter: tooltipFormatter,
2949
- valueFormatter: tooltipValueFormatter
3535
+ valueFormatter
2950
3536
  }
2951
3537
  ),
2952
3538
  series: [
@@ -2959,7 +3545,7 @@ var SankeyChart = React18.forwardRef(
2959
3545
  data: data.nodes.map((node) => ({
2960
3546
  name: node.name,
2961
3547
  itemStyle: node.color ? { color: node.color } : void 0,
2962
- label: (0, import_charts_core16.pointLabel)(node.label, labelFormatter)
3548
+ label: (0, import_charts_core18.pointLabel)(node.label, labelFormatter)
2963
3549
  })),
2964
3550
  links: data.links.map((link) => ({
2965
3551
  source: link.source,
@@ -2970,12 +3556,12 @@ var SankeyChart = React18.forwardRef(
2970
3556
  color: "gradient",
2971
3557
  curveness: 0.5
2972
3558
  },
2973
- label: (0, import_charts_core16.buildDataLabel)(
3559
+ label: (0, import_charts_core18.buildDataLabel)(
2974
3560
  {
2975
3561
  position: orient === "horizontal" ? "right" : "bottom"
2976
3562
  },
2977
3563
  void 0,
2978
- { show: true, formatter: labelFormatter, getLabel: (0, import_charts_core16.nameLabelLookup)(data.nodes) }
3564
+ { show: true, formatter: labelFormatter, getLabel: (0, import_charts_core18.nameLabelLookup)(data.nodes) }
2979
3565
  )
2980
3566
  }
2981
3567
  ]
@@ -2989,20 +3575,19 @@ var SankeyChart = React18.forwardRef(
2989
3575
  orient,
2990
3576
  labelFormatter,
2991
3577
  tooltipFormatter,
2992
- tooltipValueFormatter,
3578
+ valueFormatter,
2993
3579
  optionOverride
2994
3580
  ]);
2995
- const latest = useLatestRef({ onClick });
2996
- const { containerRef } = useChart({
3581
+ const { containerRef, exportImage } = useChart({
2997
3582
  option,
2998
3583
  theme,
2999
3584
  animation,
3000
- onReady: (chart) => {
3001
- chart.on("click", (params) => {
3002
- const { onClick: onClick2 } = latest.current;
3003
- if (!onClick2) return;
3585
+ patterns,
3586
+ events: chartEvents(events, {
3587
+ click: onClick && ((params) => {
3588
+ if (!onClick) return;
3004
3589
  const isEdge = params.dataType === "edge";
3005
- onClick2({
3590
+ onClick({
3006
3591
  type: params.type || "click",
3007
3592
  componentType: params.componentType || "series",
3008
3593
  dataType: isEdge ? "edge" : "node",
@@ -3011,24 +3596,32 @@ var SankeyChart = React18.forwardRef(
3011
3596
  source: isEdge ? params.data?.source : void 0,
3012
3597
  target: isEdge ? params.data?.target : void 0
3013
3598
  });
3014
- });
3015
- }
3599
+ })
3600
+ }),
3601
+ onCreated: onReady
3016
3602
  });
3017
3603
  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)(
3604
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3019
3605
  ChartContainer,
3020
3606
  {
3021
3607
  ref,
3022
3608
  title,
3023
3609
  description: accessibilityDescription,
3024
3610
  height,
3611
+ minHeight,
3612
+ maxHeight,
3025
3613
  loading,
3026
3614
  error,
3027
3615
  empty: isEmpty,
3028
3616
  emptyMessage,
3029
3617
  className: cn(className),
3618
+ dataTable: isEmpty ? void 0 : (0, import_charts_core18.sankeyTable)(data),
3619
+ showDataTable,
3620
+ format,
3621
+ exportable,
3622
+ exportImage,
3030
3623
  ...props,
3031
- children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { ref: containerRef, className: "h-full w-full" })
3624
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { ref: containerRef, className: "h-full w-full" })
3032
3625
  }
3033
3626
  );
3034
3627
  }
@@ -3040,6 +3633,7 @@ SankeyChart.displayName = "SankeyChart";
3040
3633
  BarChart,
3041
3634
  CandlestickChart,
3042
3635
  ChartContainer,
3636
+ ChartDataTable,
3043
3637
  ChartEmpty,
3044
3638
  ChartError,
3045
3639
  ChartLegend,
@@ -3055,7 +3649,9 @@ SankeyChart.displayName = "SankeyChart";
3055
3649
  ScatterChart,
3056
3650
  TreemapChart,
3057
3651
  cn,
3652
+ exportChartImage,
3058
3653
  registerClassicThemes,
3654
+ registerEchartsModules,
3059
3655
  useChart,
3060
3656
  useChartLegend,
3061
3657
  useChartResize,