csv-charts-ai 1.11.0 → 1.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -343,13 +343,15 @@ useEffect(() => {
343
343
 
344
344
  ## React Components (`csv-charts-ai/charts`)
345
345
 
346
- Chart components are available as a **separate entry point** so projects that only need AI/parsing don't pull in React, Recharts, or Lucide.
346
+ Chart components are available as a **separate entry point** so projects that only need AI/parsing don't pull in React or Recharts.
347
347
 
348
348
  ```bash
349
349
  # Optional peer dependencies — only needed if you import from csv-charts-ai/charts
350
- pnpm add react recharts lucide-react
350
+ pnpm add react recharts
351
351
  ```
352
352
 
353
+ Icons are **built-in** (SVG, zero dependency). To use your own icon library, see [Custom Icons](#custom-icons) below.
354
+
353
355
  ### Display Charts
354
356
 
355
357
  ```tsx
@@ -409,6 +411,23 @@ You can also pass `className` to any component to add classes alongside the buil
409
411
  <ChartDisplay data={data} charts={charts} className="my-extra-class" />
410
412
  ```
411
413
 
414
+ ### Custom Icons
415
+
416
+ Chart toolbar icons are built-in as minimal SVGs (zero dependency). To use your own icon library (lucide-react, heroicons, phosphor, etc.), wrap your charts with `ChartIconProvider`:
417
+
418
+ ```tsx
419
+ import { ChartDisplay, ChartIconProvider } from "csv-charts-ai/charts";
420
+ import { RefreshCw, Download, ArrowUp, ArrowDown, RotateCcw, TrendingUp, Filter, Image } from "lucide-react";
421
+
422
+ const icons = { RefreshCw, Download, SortAsc: ArrowUp, SortDesc: ArrowDown, RotateCcw, TrendingUp, Filter, ImageIcon: Image };
423
+
424
+ <ChartIconProvider icons={icons}>
425
+ <ChartDisplay data={data} charts={charts} />
426
+ </ChartIconProvider>
427
+ ```
428
+
429
+ You only need to override the icons you want to change — the rest fall back to the built-in SVGs.
430
+
412
431
  ### Headless Usage (No React)
413
432
 
414
433
  The core entry point (`csv-charts-ai`) works without React — use it in Node.js scripts, APIs, or CLI tools:
@@ -439,7 +458,9 @@ console.log(result.summary.keyInsights);
439
458
  | `SingleChart` | Individual chart with toolbar (sort, zoom, trendline, CSV/PNG export) |
440
459
  | `ChartToolbar` | Standalone toolbar component |
441
460
  | `ChartThemeProvider` | React context for chart theming |
461
+ | `ChartIconProvider` | React context for pluggable icons (default: built-in SVGs) |
442
462
  | `defaultDarkTheme` / `defaultLightTheme` | Built-in themes |
463
+ | `defaultIcons` | Built-in SVG icon set |
443
464
 
444
465
  ## AI Functions Reference
445
466
 
package/dist/charts.d.ts CHANGED
@@ -36,7 +36,7 @@ interface SingleChartProps {
36
36
  /** When true, removes all built-in Tailwind classes from toolbar and metadata tags */
37
37
  unstyled?: boolean;
38
38
  }
39
- declare function SingleChart({ data, chart, onRegenerate, className, unstyled }: SingleChartProps): react_jsx_runtime.JSX.Element;
39
+ declare function SingleChart({ data, chart, onRegenerate, className, unstyled, }: SingleChartProps): react_jsx_runtime.JSX.Element;
40
40
 
41
41
  interface ChartToolbarProps {
42
42
  chartType: ChartType;
package/dist/charts.js CHANGED
@@ -93,8 +93,8 @@ import { createContext as createContext2, useContext as useContext2 } from "reac
93
93
  import { jsx as jsx2, jsxs } from "react/jsx-runtime";
94
94
  var svgProps = {
95
95
  xmlns: "http://www.w3.org/2000/svg",
96
- width: 24,
97
- height: 24,
96
+ width: "1em",
97
+ height: "1em",
98
98
  viewBox: "0 0 24 24",
99
99
  fill: "none",
100
100
  stroke: "currentColor",
@@ -381,122 +381,148 @@ function ChartToolbar({
381
381
  const supportsTrendline = chartType === "bar" || chartType === "line" || chartType === "area";
382
382
  const cls = (defaultCls) => unstyled ? "" : defaultCls;
383
383
  const activeCls = (active, activeCls2, inactiveCls) => unstyled ? "" : `flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm transition-colors ${active ? activeCls2 : inactiveCls}`;
384
- return /* @__PURE__ */ jsxs2("div", { className: unstyled ? className ?? "" : `mb-4 flex flex-wrap items-center gap-2 rounded-xl border border-white/10 bg-white/5 p-3 ${className ?? ""}`.trim(), children: [
385
- /* @__PURE__ */ jsxs2(
386
- "button",
387
- {
388
- onClick: onToggleSort,
389
- className: activeCls(
390
- sortOrder !== "none",
391
- "border border-violet-500/30 bg-violet-500/20 text-violet-400",
392
- "bg-white/5 text-gray-400 hover:bg-white/10 hover:text-white"
393
- ),
394
- title: "Sort by value",
395
- children: [
396
- sortOrder === "asc" ? /* @__PURE__ */ jsx3(icons.SortAsc, { className: "h-4 w-4" }) : sortOrder === "desc" ? /* @__PURE__ */ jsx3(icons.SortDesc, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx3(icons.SortDesc, { className: cls("h-4 w-4 opacity-50") }),
397
- "Sort"
398
- ]
399
- }
400
- ),
401
- /* @__PURE__ */ jsxs2("div", { className: cls("flex items-center gap-2"), children: [
402
- /* @__PURE__ */ jsx3(icons.Filter, { className: cls("h-4 w-4 text-gray-400"), "aria-hidden": "true" }),
403
- /* @__PURE__ */ jsxs2(
404
- "select",
405
- {
406
- value: limitResults,
407
- onChange: (e) => onLimitChange(Number(e.target.value)),
408
- "aria-label": "Limit number of results",
409
- className: cls("rounded-lg border border-white/10 bg-white/5 px-2 py-1.5 text-sm text-gray-300 focus:border-violet-500/50 focus:outline-none"),
410
- children: [
411
- /* @__PURE__ */ jsx3("option", { value: 10, children: "Top 10" }),
412
- /* @__PURE__ */ jsx3("option", { value: 20, children: "Top 20" }),
413
- /* @__PURE__ */ jsx3("option", { value: 50, children: "Top 50" }),
414
- /* @__PURE__ */ jsx3("option", { value: 100, children: "Top 100" }),
415
- /* @__PURE__ */ jsx3("option", { value: 999999, children: "All" })
416
- ]
417
- }
418
- )
419
- ] }),
420
- supportsBrush && /* @__PURE__ */ jsxs2(
421
- "button",
422
- {
423
- onClick: onToggleBrush,
424
- className: activeCls(
425
- showBrush,
426
- "border border-cyan-500/30 bg-cyan-500/20 text-cyan-400",
427
- "bg-white/5 text-gray-400 hover:bg-white/10 hover:text-white"
428
- ),
429
- title: "Enable zoom/brush",
430
- children: [
431
- /* @__PURE__ */ jsx3(icons.RotateCcw, { className: "h-4 w-4" }),
432
- "Zoom"
433
- ]
434
- }
435
- ),
436
- supportsTrendline && /* @__PURE__ */ jsxs2(
437
- "button",
438
- {
439
- onClick: onToggleTrendline,
440
- className: activeCls(
441
- showTrendline,
442
- "border border-emerald-500/30 bg-emerald-500/20 text-emerald-400",
443
- "bg-white/5 text-gray-400 hover:bg-white/10 hover:text-white"
384
+ return /* @__PURE__ */ jsxs2(
385
+ "div",
386
+ {
387
+ className: unstyled ? className ?? "" : `mb-4 flex flex-wrap items-center gap-2 rounded-xl border border-white/10 bg-white/5 p-3 ${className ?? ""}`.trim(),
388
+ children: [
389
+ /* @__PURE__ */ jsxs2(
390
+ "button",
391
+ {
392
+ onClick: onToggleSort,
393
+ className: activeCls(
394
+ sortOrder !== "none",
395
+ "border border-violet-500/30 bg-violet-500/20 text-violet-400",
396
+ "bg-white/5 text-gray-400 hover:bg-white/10 hover:text-white"
397
+ ),
398
+ title: "Sort by value",
399
+ children: [
400
+ sortOrder === "asc" ? /* @__PURE__ */ jsx3(icons.SortAsc, { className: "h-4 w-4" }) : sortOrder === "desc" ? /* @__PURE__ */ jsx3(icons.SortDesc, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx3(icons.SortDesc, { className: cls("h-4 w-4 opacity-50") }),
401
+ "Sort"
402
+ ]
403
+ }
444
404
  ),
445
- title: "Show average line",
446
- children: [
447
- /* @__PURE__ */ jsx3(icons.TrendingUp, { className: "h-4 w-4" }),
448
- "Average"
449
- ]
450
- }
451
- ),
452
- /* @__PURE__ */ jsx3("div", { className: cls("flex-1") }),
453
- /* @__PURE__ */ jsxs2(
454
- "button",
455
- {
456
- onClick: onExportPNG,
457
- className: cls("flex items-center gap-1.5 rounded-lg bg-white/5 px-3 py-1.5 text-sm text-gray-400 transition-colors hover:bg-white/10 hover:text-white"),
458
- title: "Export chart as PNG image",
459
- children: [
460
- /* @__PURE__ */ jsx3(icons.ImageIcon, { className: "h-4 w-4" }),
461
- "PNG"
462
- ]
463
- }
464
- ),
465
- /* @__PURE__ */ jsxs2(
466
- "button",
467
- {
468
- onClick: onExportCSV,
469
- className: cls("flex items-center gap-1.5 rounded-lg bg-white/5 px-3 py-1.5 text-sm text-gray-400 transition-colors hover:bg-white/10 hover:text-white"),
470
- title: "Export chart data as CSV",
471
- children: [
472
- /* @__PURE__ */ jsx3(icons.Download, { className: "h-4 w-4" }),
473
- "CSV"
474
- ]
475
- }
476
- ),
477
- hasRegenerate && /* @__PURE__ */ jsxs2(
478
- "button",
479
- {
480
- onClick: onRegenerate,
481
- disabled: isRegenerating,
482
- className: cls("flex items-center gap-1.5 rounded-lg bg-violet-500/20 px-3 py-1.5 text-sm text-violet-400 transition-colors hover:bg-violet-500/30 disabled:opacity-50"),
483
- children: [
405
+ /* @__PURE__ */ jsxs2("div", { className: cls("flex items-center gap-2"), children: [
484
406
  /* @__PURE__ */ jsx3(
485
- icons.RefreshCw,
407
+ icons.Filter,
486
408
  {
487
- className: `h-4 w-4 ${isRegenerating ? "animate-spin" : ""}`
409
+ className: cls("h-4 w-4 text-gray-400"),
410
+ "aria-hidden": "true"
488
411
  }
489
412
  ),
490
- isRegenerating ? "..." : "Regenerate"
491
- ]
492
- }
493
- )
494
- ] });
413
+ /* @__PURE__ */ jsxs2(
414
+ "select",
415
+ {
416
+ value: limitResults,
417
+ onChange: (e) => onLimitChange(Number(e.target.value)),
418
+ "aria-label": "Limit number of results",
419
+ className: cls(
420
+ "rounded-lg border border-white/10 bg-white/5 px-2 py-1.5 text-sm text-gray-300 focus:border-violet-500/50 focus:outline-none"
421
+ ),
422
+ children: [
423
+ /* @__PURE__ */ jsx3("option", { value: 10, children: "Top 10" }),
424
+ /* @__PURE__ */ jsx3("option", { value: 20, children: "Top 20" }),
425
+ /* @__PURE__ */ jsx3("option", { value: 50, children: "Top 50" }),
426
+ /* @__PURE__ */ jsx3("option", { value: 100, children: "Top 100" }),
427
+ /* @__PURE__ */ jsx3("option", { value: 999999, children: "All" })
428
+ ]
429
+ }
430
+ )
431
+ ] }),
432
+ supportsBrush && /* @__PURE__ */ jsxs2(
433
+ "button",
434
+ {
435
+ onClick: onToggleBrush,
436
+ className: activeCls(
437
+ showBrush,
438
+ "border border-cyan-500/30 bg-cyan-500/20 text-cyan-400",
439
+ "bg-white/5 text-gray-400 hover:bg-white/10 hover:text-white"
440
+ ),
441
+ title: "Enable zoom/brush",
442
+ children: [
443
+ /* @__PURE__ */ jsx3(icons.RotateCcw, { className: "h-4 w-4" }),
444
+ "Zoom"
445
+ ]
446
+ }
447
+ ),
448
+ supportsTrendline && /* @__PURE__ */ jsxs2(
449
+ "button",
450
+ {
451
+ onClick: onToggleTrendline,
452
+ className: activeCls(
453
+ showTrendline,
454
+ "border border-emerald-500/30 bg-emerald-500/20 text-emerald-400",
455
+ "bg-white/5 text-gray-400 hover:bg-white/10 hover:text-white"
456
+ ),
457
+ title: "Show average line",
458
+ children: [
459
+ /* @__PURE__ */ jsx3(icons.TrendingUp, { className: "h-4 w-4" }),
460
+ "Average"
461
+ ]
462
+ }
463
+ ),
464
+ /* @__PURE__ */ jsx3("div", { className: cls("flex-1") }),
465
+ /* @__PURE__ */ jsxs2(
466
+ "button",
467
+ {
468
+ onClick: onExportPNG,
469
+ className: cls(
470
+ "flex items-center gap-1.5 rounded-lg bg-white/5 px-3 py-1.5 text-sm text-gray-400 transition-colors hover:bg-white/10 hover:text-white"
471
+ ),
472
+ title: "Export chart as PNG image",
473
+ children: [
474
+ /* @__PURE__ */ jsx3(icons.ImageIcon, { className: "h-4 w-4" }),
475
+ "PNG"
476
+ ]
477
+ }
478
+ ),
479
+ /* @__PURE__ */ jsxs2(
480
+ "button",
481
+ {
482
+ onClick: onExportCSV,
483
+ className: cls(
484
+ "flex items-center gap-1.5 rounded-lg bg-white/5 px-3 py-1.5 text-sm text-gray-400 transition-colors hover:bg-white/10 hover:text-white"
485
+ ),
486
+ title: "Export chart data as CSV",
487
+ children: [
488
+ /* @__PURE__ */ jsx3(icons.Download, { className: "h-4 w-4" }),
489
+ "CSV"
490
+ ]
491
+ }
492
+ ),
493
+ hasRegenerate && /* @__PURE__ */ jsxs2(
494
+ "button",
495
+ {
496
+ onClick: onRegenerate,
497
+ disabled: isRegenerating,
498
+ className: cls(
499
+ "flex items-center gap-1.5 rounded-lg bg-violet-500/20 px-3 py-1.5 text-sm text-violet-400 transition-colors hover:bg-violet-500/30 disabled:opacity-50"
500
+ ),
501
+ children: [
502
+ /* @__PURE__ */ jsx3(
503
+ icons.RefreshCw,
504
+ {
505
+ className: `h-4 w-4 ${isRegenerating ? "animate-spin" : ""}`
506
+ }
507
+ ),
508
+ isRegenerating ? "..." : "Regenerate"
509
+ ]
510
+ }
511
+ )
512
+ ]
513
+ }
514
+ );
495
515
  }
496
516
 
497
517
  // src/SingleChart.tsx
498
518
  import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
499
- function SingleChart({ data, chart, onRegenerate, className, unstyled = false }) {
519
+ function SingleChart({
520
+ data,
521
+ chart,
522
+ onRegenerate,
523
+ className,
524
+ unstyled = false
525
+ }) {
500
526
  const theme = useChartTheme();
501
527
  const icons = useChartIcons();
502
528
  const chartContainerRef = useRef(null);
@@ -556,10 +582,7 @@ ${rows}`;
556
582
  const svgElement = container.querySelector("svg");
557
583
  if (!svgElement) return;
558
584
  const svgClone = svgElement.cloneNode(true);
559
- svgClone.setAttribute(
560
- "xmlns",
561
- "http://www.w3.org/2000/svg"
562
- );
585
+ svgClone.setAttribute("xmlns", "http://www.w3.org/2000/svg");
563
586
  const rect = svgElement.getBoundingClientRect();
564
587
  svgClone.setAttribute("width", String(rect.width));
565
588
  svgClone.setAttribute("height", String(rect.height));
@@ -751,13 +774,21 @@ ${rows}`;
751
774
  /* @__PURE__ */ jsx4(Tooltip, { contentStyle: tooltipStyle }),
752
775
  /* @__PURE__ */ jsx4(Legend, {}),
753
776
  trendlineComponent,
754
- /* @__PURE__ */ jsx4(Bar, { dataKey: yKey, fill: theme.accentPrimary, radius: [4, 4, 0, 0], children: chartData.map((_, index) => /* @__PURE__ */ jsx4(
755
- Cell,
777
+ /* @__PURE__ */ jsx4(
778
+ Bar,
756
779
  {
757
- fill: theme.colors[index % theme.colors.length]
758
- },
759
- `cell-${index}`
760
- )) }),
780
+ dataKey: yKey,
781
+ fill: theme.accentPrimary,
782
+ radius: [4, 4, 0, 0],
783
+ children: chartData.map((_, index) => /* @__PURE__ */ jsx4(
784
+ Cell,
785
+ {
786
+ fill: theme.colors[index % theme.colors.length]
787
+ },
788
+ `cell-${index}`
789
+ ))
790
+ }
791
+ ),
761
792
  brushComponent
762
793
  ] });
763
794
  case "line":
@@ -824,21 +855,8 @@ ${rows}`;
824
855
  case "scatter":
825
856
  return /* @__PURE__ */ jsxs3(ScatterChart, { ...commonProps, children: [
826
857
  /* @__PURE__ */ jsx4(CartesianGrid, { strokeDasharray: "3 3", stroke: theme.gridStroke }),
827
- /* @__PURE__ */ jsx4(
828
- XAxis,
829
- {
830
- type: "category",
831
- ...xAxisProps
832
- }
833
- ),
834
- /* @__PURE__ */ jsx4(
835
- YAxis,
836
- {
837
- type: "number",
838
- dataKey: yKey,
839
- ...yAxisProps
840
- }
841
- ),
858
+ /* @__PURE__ */ jsx4(XAxis, { type: "category", ...xAxisProps }),
859
+ /* @__PURE__ */ jsx4(YAxis, { type: "number", dataKey: yKey, ...yAxisProps }),
842
860
  /* @__PURE__ */ jsx4(
843
861
  Tooltip,
844
862
  {
@@ -879,32 +897,38 @@ ${rows}`;
879
897
  }
880
898
  };
881
899
  if (processedData.length === 0) {
882
- return /* @__PURE__ */ jsx4("div", { className: unstyled ? className ?? "" : `flex h-[300px] flex-col items-center justify-center gap-4 text-gray-400 ${className ?? ""}`.trim(), children: /* @__PURE__ */ jsxs3("div", { className: unstyled ? "" : "text-center", children: [
883
- /* @__PURE__ */ jsx4("p", { className: unstyled ? "" : "mb-1 font-medium text-red-400", children: "Unable to generate this chart" }),
884
- /* @__PURE__ */ jsxs3("p", { className: unstyled ? "" : "mb-4 text-sm text-gray-500", children: [
885
- "Columns: ",
886
- chart.xAxis,
887
- ", ",
888
- chart.yAxis
889
- ] }),
890
- onRegenerate && /* @__PURE__ */ jsxs3(
891
- "button",
892
- {
893
- onClick: handleRegenerate,
894
- disabled: isRegenerating,
895
- className: unstyled ? "" : "flex items-center gap-2 rounded-lg bg-violet-600 px-4 py-2 text-sm text-white transition-colors hover:bg-violet-500 disabled:opacity-50",
896
- children: [
897
- /* @__PURE__ */ jsx4(
898
- icons.RefreshCw,
899
- {
900
- className: `h-4 w-4 ${isRegenerating ? "animate-spin" : ""}`
901
- }
902
- ),
903
- isRegenerating ? "Regenerating..." : "Regenerate with AI"
904
- ]
905
- }
906
- )
907
- ] }) });
900
+ return /* @__PURE__ */ jsx4(
901
+ "div",
902
+ {
903
+ className: unstyled ? className ?? "" : `flex h-[300px] flex-col items-center justify-center gap-4 text-gray-400 ${className ?? ""}`.trim(),
904
+ children: /* @__PURE__ */ jsxs3("div", { className: unstyled ? "" : "text-center", children: [
905
+ /* @__PURE__ */ jsx4("p", { className: unstyled ? "" : "mb-1 font-medium text-red-400", children: "Unable to generate this chart" }),
906
+ /* @__PURE__ */ jsxs3("p", { className: unstyled ? "" : "mb-4 text-sm text-gray-500", children: [
907
+ "Columns: ",
908
+ chart.xAxis,
909
+ ", ",
910
+ chart.yAxis
911
+ ] }),
912
+ onRegenerate && /* @__PURE__ */ jsxs3(
913
+ "button",
914
+ {
915
+ onClick: handleRegenerate,
916
+ disabled: isRegenerating,
917
+ className: unstyled ? "" : "flex items-center gap-2 rounded-lg bg-violet-600 px-4 py-2 text-sm text-white transition-colors hover:bg-violet-500 disabled:opacity-50",
918
+ children: [
919
+ /* @__PURE__ */ jsx4(
920
+ icons.RefreshCw,
921
+ {
922
+ className: `h-4 w-4 ${isRegenerating ? "animate-spin" : ""}`
923
+ }
924
+ ),
925
+ isRegenerating ? "Regenerating..." : "Regenerate with AI"
926
+ ]
927
+ }
928
+ )
929
+ ] })
930
+ }
931
+ );
908
932
  }
909
933
  return /* @__PURE__ */ jsxs3("div", { className, children: [
910
934
  /* @__PURE__ */ jsx4(
@@ -927,45 +951,89 @@ ${rows}`;
927
951
  unstyled
928
952
  }
929
953
  ),
930
- /* @__PURE__ */ jsx4("div", { className: unstyled ? "" : "h-[450px] w-full", style: unstyled ? { height: 450, width: "100%" } : void 0, ref: chartContainerRef, children: /* @__PURE__ */ jsx4(
931
- ResponsiveContainer,
954
+ /* @__PURE__ */ jsx4(
955
+ "div",
932
956
  {
933
- width: "100%",
934
- height: "100%",
935
- children: renderChartContent(
936
- chart.type,
937
- processedData,
938
- xColName,
939
- isMultiSeries ? "" : yColName,
940
- showBrush,
941
- showTrendline,
942
- average
957
+ className: unstyled ? "" : "h-[450px] w-full",
958
+ style: unstyled ? { height: 450, width: "100%" } : void 0,
959
+ ref: chartContainerRef,
960
+ children: /* @__PURE__ */ jsx4(
961
+ ResponsiveContainer,
962
+ {
963
+ width: "100%",
964
+ height: "100%",
965
+ children: renderChartContent(
966
+ chart.type,
967
+ processedData,
968
+ xColName,
969
+ isMultiSeries ? "" : yColName,
970
+ showBrush,
971
+ showTrendline,
972
+ average
973
+ )
974
+ },
975
+ `chart-${chart.id}-${showBrush ? "brush" : "no-brush"}`
943
976
  )
944
- },
945
- `chart-${chart.id}-${showBrush ? "brush" : "no-brush"}`
946
- ) }),
977
+ }
978
+ ),
947
979
  /* @__PURE__ */ jsxs3("div", { className: unstyled ? "" : "mt-4 flex flex-wrap gap-2", children: [
948
- /* @__PURE__ */ jsxs3("span", { className: unstyled ? "" : "rounded bg-white/10 px-2 py-0.5 text-xs text-gray-400", children: [
949
- "X: ",
950
- chart.xAxis
951
- ] }),
952
- /* @__PURE__ */ jsxs3("span", { className: unstyled ? "" : "rounded bg-white/10 px-2 py-0.5 text-xs text-gray-400", children: [
953
- "Y: ",
954
- chart.yAxis
955
- ] }),
956
- chart.groupBy && /* @__PURE__ */ jsxs3("span", { className: unstyled ? "" : "rounded bg-cyan-500/20 px-2 py-0.5 text-xs text-cyan-300", children: [
957
- "Group: ",
958
- chart.groupBy
959
- ] }),
960
- chart.aggregation && chart.aggregation !== "none" && /* @__PURE__ */ jsx4("span", { className: unstyled ? "" : "rounded bg-violet-500/20 px-2 py-0.5 text-xs text-violet-300", children: chart.aggregation }),
961
- /* @__PURE__ */ jsxs3("span", { className: unstyled ? "" : "rounded bg-white/10 px-2 py-0.5 text-xs text-gray-400", children: [
962
- processedData.length,
963
- " items"
964
- ] }),
965
- isMultiSeries && /* @__PURE__ */ jsxs3("span", { className: unstyled ? "" : "rounded bg-emerald-500/20 px-2 py-0.5 text-xs text-emerald-300", children: [
966
- seriesKeys.length,
967
- " series"
968
- ] })
980
+ /* @__PURE__ */ jsxs3(
981
+ "span",
982
+ {
983
+ className: unstyled ? "" : "rounded bg-white/10 px-2 py-0.5 text-xs text-gray-400",
984
+ children: [
985
+ "X: ",
986
+ chart.xAxis
987
+ ]
988
+ }
989
+ ),
990
+ /* @__PURE__ */ jsxs3(
991
+ "span",
992
+ {
993
+ className: unstyled ? "" : "rounded bg-white/10 px-2 py-0.5 text-xs text-gray-400",
994
+ children: [
995
+ "Y: ",
996
+ chart.yAxis
997
+ ]
998
+ }
999
+ ),
1000
+ chart.groupBy && /* @__PURE__ */ jsxs3(
1001
+ "span",
1002
+ {
1003
+ className: unstyled ? "" : "rounded bg-cyan-500/20 px-2 py-0.5 text-xs text-cyan-300",
1004
+ children: [
1005
+ "Group: ",
1006
+ chart.groupBy
1007
+ ]
1008
+ }
1009
+ ),
1010
+ chart.aggregation && chart.aggregation !== "none" && /* @__PURE__ */ jsx4(
1011
+ "span",
1012
+ {
1013
+ className: unstyled ? "" : "rounded bg-violet-500/20 px-2 py-0.5 text-xs text-violet-300",
1014
+ children: chart.aggregation
1015
+ }
1016
+ ),
1017
+ /* @__PURE__ */ jsxs3(
1018
+ "span",
1019
+ {
1020
+ className: unstyled ? "" : "rounded bg-white/10 px-2 py-0.5 text-xs text-gray-400",
1021
+ children: [
1022
+ processedData.length,
1023
+ " items"
1024
+ ]
1025
+ }
1026
+ ),
1027
+ isMultiSeries && /* @__PURE__ */ jsxs3(
1028
+ "span",
1029
+ {
1030
+ className: unstyled ? "" : "rounded bg-emerald-500/20 px-2 py-0.5 text-xs text-emerald-300",
1031
+ children: [
1032
+ seriesKeys.length,
1033
+ " series"
1034
+ ]
1035
+ }
1036
+ )
969
1037
  ] })
970
1038
  ] });
971
1039
  }
@@ -996,27 +1064,19 @@ function ChartDisplay({
996
1064
  const titleCls = unstyled ? titleClassName ?? "" : `mb-2 bg-linear-to-r from-violet-400 to-fuchsia-400 bg-clip-text text-xl font-bold text-transparent ${titleClassName ?? ""}`.trim();
997
1065
  const descCls = unstyled ? descriptionClassName ?? "" : `mb-4 text-gray-400 ${descriptionClassName ?? ""}`.trim();
998
1066
  const innerCls = unstyled ? "" : "p-6";
999
- return /* @__PURE__ */ jsx5(ChartThemeProvider, { theme, children: /* @__PURE__ */ jsx5("div", { className: containerCls, children: charts.map((chart) => /* @__PURE__ */ jsx5(
1000
- CardWrapper,
1001
- {
1002
- title: chart.title,
1003
- className: cardCls,
1004
- children: /* @__PURE__ */ jsxs4("div", { className: innerCls, children: [
1005
- /* @__PURE__ */ jsx5("h3", { className: titleCls, children: chart.title }),
1006
- /* @__PURE__ */ jsx5("p", { className: descCls, children: chart.description }),
1007
- /* @__PURE__ */ jsx5(
1008
- SingleChart,
1009
- {
1010
- data,
1011
- chart,
1012
- onRegenerate,
1013
- unstyled
1014
- }
1015
- )
1016
- ] })
1017
- },
1018
- chart.id
1019
- )) }) });
1067
+ return /* @__PURE__ */ jsx5(ChartThemeProvider, { theme, children: /* @__PURE__ */ jsx5("div", { className: containerCls, children: charts.map((chart) => /* @__PURE__ */ jsx5(CardWrapper, { title: chart.title, className: cardCls, children: /* @__PURE__ */ jsxs4("div", { className: innerCls, children: [
1068
+ /* @__PURE__ */ jsx5("h3", { className: titleCls, children: chart.title }),
1069
+ /* @__PURE__ */ jsx5("p", { className: descCls, children: chart.description }),
1070
+ /* @__PURE__ */ jsx5(
1071
+ SingleChart,
1072
+ {
1073
+ data,
1074
+ chart,
1075
+ onRegenerate,
1076
+ unstyled
1077
+ }
1078
+ )
1079
+ ] }) }, chart.id)) }) });
1020
1080
  }
1021
1081
 
1022
1082
  // src/constants.ts