@anuma/sdk 11.0.0 → 11.1.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.
@@ -36371,6 +36371,12 @@ function cx(...classes) {
36371
36371
  return classes.filter(Boolean).join(" ");
36372
36372
  }
36373
36373
  var THEMES = { light: "", dark: ".dark" };
36374
+ var SAFE_CSS_KEY = /^[\w-]+$/;
36375
+ var SAFE_CSS_COLOR = /^(?:#(?:[0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})|[a-z]+|(?:rgba?|hsla?|hwb|lab|lch|oklab|oklch)\([\w\s.,%/+-]*\)|var\(--[\w-]+\))$/i;
36376
+ function isSafeCssColor(value) {
36377
+ if (typeof value !== "string" || !SAFE_CSS_COLOR.test(value)) return false;
36378
+ return typeof CSS === "undefined" || typeof CSS.supports !== "function" || CSS.supports("color", value);
36379
+ }
36374
36380
  var ChartContext = React2.createContext(null);
36375
36381
  function useChart() {
36376
36382
  const context = React2.useContext(ChartContext);
@@ -36380,7 +36386,9 @@ function useChart() {
36380
36386
  return context;
36381
36387
  }
36382
36388
  function ChartStyle({ id: id2, config }) {
36383
- const colorConfig = Object.entries(config).filter(([, cfg]) => cfg.theme || cfg.color);
36389
+ const colorConfig = Object.entries(config).filter(
36390
+ ([key3, cfg]) => SAFE_CSS_KEY.test(key3) && (cfg.theme || cfg.color)
36391
+ );
36384
36392
  if (!colorConfig.length) return null;
36385
36393
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
36386
36394
  "style",
@@ -36391,7 +36399,7 @@ function ChartStyle({ id: id2, config }) {
36391
36399
  ${prefix} [data-chart=${id2}] {
36392
36400
  ${colorConfig.map(([key3, itemConfig]) => {
36393
36401
  const color = itemConfig.theme?.[theme] || itemConfig.color;
36394
- return color ? ` --color-${key3}: ${color};` : null;
36402
+ return isSafeCssColor(color) ? ` --color-${key3}: ${color};` : null;
36395
36403
  }).join("\n")}
36396
36404
  }
36397
36405
  `
@@ -36440,7 +36448,8 @@ function ChartTooltipContent({
36440
36448
  formatter,
36441
36449
  color,
36442
36450
  nameKey,
36443
- labelKey
36451
+ labelKey,
36452
+ valueFormatter
36444
36453
  }) {
36445
36454
  const { config } = useChart();
36446
36455
  const tooltipLabel = React2.useMemo(() => {
@@ -36507,7 +36516,7 @@ function ChartTooltipContent({
36507
36516
  nestLabel ? tooltipLabel : null,
36508
36517
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-muted-foreground", children: itemConfig?.label || item.name })
36509
36518
  ] }),
36510
- item.value && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-foreground font-mono font-medium tabular-nums", children: item.value.toLocaleString() })
36519
+ item.value !== void 0 && item.value !== null && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-foreground font-medium tabular-nums", children: valueFormatter && typeof item.value === "number" ? valueFormatter(item.value) : item.value.toLocaleString() })
36511
36520
  ]
36512
36521
  }
36513
36522
  )
@@ -36553,7 +36562,7 @@ function ChartLegendContent({
36553
36562
  style: { backgroundColor: item.color }
36554
36563
  }
36555
36564
  ),
36556
- itemConfig?.label
36565
+ itemConfig?.label ?? cellText(item.value)
36557
36566
  ]
36558
36567
  },
36559
36568
  String(item.value)
@@ -36580,86 +36589,417 @@ var DEFAULT_COLORS = [
36580
36589
  "var(--chart-4)",
36581
36590
  "var(--chart-5)"
36582
36591
  ];
36592
+ var SURFACE = "var(--chart-surface)";
36593
+ var DOT_LIMIT = 12;
36594
+ var MAX_TICKS = 8;
36595
+ var MINUS = "\u2212";
36596
+ function paletteColor(index) {
36597
+ return index < DEFAULT_COLORS.length ? DEFAULT_COLORS[index] : `hsl(${Math.round(index * 137.508 % 360)} 65% 55%)`;
36598
+ }
36599
+ function cellText(value) {
36600
+ return typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? String(value) : "";
36601
+ }
36602
+ var VISUALLY_HIDDEN = {
36603
+ position: "absolute",
36604
+ width: 1,
36605
+ height: 1,
36606
+ padding: 0,
36607
+ margin: -1,
36608
+ overflow: "hidden",
36609
+ clip: "rect(0, 0, 0, 0)",
36610
+ whiteSpace: "nowrap",
36611
+ border: 0
36612
+ };
36613
+ function tickDigits(ticks) {
36614
+ if (!ticks || ticks.length < 2) return 3;
36615
+ const step = ticks[1] - ticks[0];
36616
+ const magnitude = Math.max(...ticks.map(Math.abs));
36617
+ if (step <= 0 || magnitude === 0) return 3;
36618
+ const needed = Math.floor(Math.log10(magnitude)) - Math.floor(Math.log10(step)) + 1;
36619
+ return Math.min(21, Math.max(3, needed));
36620
+ }
36621
+ function keepSmall(options) {
36622
+ const small = new Intl.NumberFormat(void 0, { ...options, maximumSignificantDigits: 3 });
36623
+ const regular = new Intl.NumberFormat(void 0, { ...options, maximumFractionDigits: 2 });
36624
+ return (n, format) => format(n !== 0 && Math.abs(n) < 1 ? small : regular, n);
36625
+ }
36626
+ function buildFormatters(format, currency, ticks) {
36627
+ const digits = tickDigits(ticks);
36628
+ if (format === "currency") {
36629
+ const money = (options) => new Intl.NumberFormat(void 0, {
36630
+ style: "currency",
36631
+ currency: currency ?? "USD",
36632
+ ...options
36633
+ });
36634
+ const compact2 = money({ notation: "compact", maximumSignificantDigits: 3 });
36635
+ const tick2 = money({ notation: "compact", maximumSignificantDigits: digits });
36636
+ const small2 = money({ maximumSignificantDigits: 4 });
36637
+ const cents = money({ minimumFractionDigits: 2, maximumFractionDigits: 2 });
36638
+ const value2 = (n) => Math.abs(n) >= 1e6 ? compact2.format(n) : n !== 0 && Math.abs(n) < 1 ? small2.format(n) : cents.format(n);
36639
+ return { tick: (n) => tick2.format(n), value: value2, change: (d) => value2(Math.abs(d)) };
36640
+ }
36641
+ if (format === "percent") {
36642
+ const percent = keepSmall({ style: "percent" });
36643
+ const points = keepSmall({});
36644
+ const tick2 = new Intl.NumberFormat(void 0, {
36645
+ style: "percent",
36646
+ maximumSignificantDigits: digits
36647
+ });
36648
+ return {
36649
+ tick: (n) => tick2.format(n / 100),
36650
+ value: (n) => percent(n, (formatter) => formatter.format(n / 100)),
36651
+ change: (d) => `${points(Math.abs(d), (formatter, n) => formatter.format(n))} pts`
36652
+ };
36653
+ }
36654
+ const tick = new Intl.NumberFormat(void 0, {
36655
+ notation: "compact",
36656
+ maximumSignificantDigits: digits
36657
+ });
36658
+ const compact = new Intl.NumberFormat(void 0, {
36659
+ notation: "compact",
36660
+ maximumSignificantDigits: 3
36661
+ });
36662
+ const small = new Intl.NumberFormat(void 0, { maximumSignificantDigits: 4 });
36663
+ const plain2 = new Intl.NumberFormat(void 0, { maximumFractionDigits: 2 });
36664
+ const value = (n) => Math.abs(n) >= 1e6 ? compact.format(n) : n !== 0 && Math.abs(n) < 1 ? small.format(n) : plain2.format(n);
36665
+ return { tick: (n) => tick.format(n), value, change: (d) => value(Math.abs(d)) };
36666
+ }
36667
+ function seriesValues(points, keys) {
36668
+ return points.flatMap(
36669
+ (point) => keys.map((key3) => point[key3]).filter((v) => typeof v === "number")
36670
+ );
36671
+ }
36672
+ function niceStep(rough) {
36673
+ const exponent = Math.floor(Math.log10(rough));
36674
+ const base = 10 ** exponent;
36675
+ const fraction = rough / base;
36676
+ const nice = fraction <= 1 ? 1 : fraction <= 2 ? 2 : fraction <= 2.5 ? 2.5 : fraction <= 5 ? 5 : 10;
36677
+ return nice * base;
36678
+ }
36679
+ function niceTicks(values) {
36680
+ if (values.length === 0) return void 0;
36681
+ const min = Math.min(...values);
36682
+ const max = Math.max(...values);
36683
+ const span = max - min || Math.abs(max) * 0.02 || 1;
36684
+ const low = min - span * 0.1;
36685
+ const high = max + span * 0.1;
36686
+ const step = niceStep((high - low) / 3);
36687
+ const start = min >= 0 ? Math.max(0, Math.floor(low / step) * step) : Math.floor(low / step) * step;
36688
+ const ticks = [];
36689
+ for (let index = 0; index <= MAX_TICKS; index++) {
36690
+ const tick = Number((start + index * step).toPrecision(15));
36691
+ if (ticks.length > 0 && tick <= ticks[ticks.length - 1]) break;
36692
+ ticks.push(tick);
36693
+ if (tick >= high) break;
36694
+ }
36695
+ return ticks.length >= 2 ? ticks : void 0;
36696
+ }
36583
36697
  function buildChartConfig(dataKeys, colors) {
36584
36698
  const config = {};
36585
36699
  dataKeys.forEach((key3, i) => {
36700
+ const custom = colors?.[key3];
36586
36701
  config[key3] = {
36587
36702
  label: key3.charAt(0).toUpperCase() + key3.slice(1),
36588
- color: colors?.[key3] || DEFAULT_COLORS[i % DEFAULT_COLORS.length]
36703
+ color: isSafeCssColor(custom) ? custom : paletteColor(i)
36589
36704
  };
36590
36705
  });
36591
36706
  return config;
36592
36707
  }
36708
+ function lastValueIndex(points, key3) {
36709
+ for (let index = points.length - 1; index >= 0; index--) {
36710
+ if (typeof points[index][key3] === "number") return index;
36711
+ }
36712
+ return -1;
36713
+ }
36714
+ function usePrefersReducedMotion() {
36715
+ const [reduced, setReduced] = React2.useState(false);
36716
+ React2.useEffect(() => {
36717
+ if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
36718
+ const query = window.matchMedia("(prefers-reduced-motion: reduce)");
36719
+ setReduced(query.matches);
36720
+ const onChange = (event) => setReduced(event.matches);
36721
+ query.addEventListener?.("change", onChange);
36722
+ return () => query.removeEventListener?.("change", onChange);
36723
+ }, []);
36724
+ return reduced;
36725
+ }
36726
+ function buildTrend(values, format, formatters) {
36727
+ if (values.length < 2) return void 0;
36728
+ const first = values[0];
36729
+ const last = values[values.length - 1];
36730
+ const difference = last - first;
36731
+ const direction = difference > 0 ? "up" : difference < 0 ? "down" : "flat";
36732
+ const sign = direction === "up" ? "+" : direction === "down" ? MINUS : "";
36733
+ const percent = format !== "percent" && first !== 0 ? ` (${sign}${new Intl.NumberFormat(void 0, { maximumFractionDigits: 2 }).format(
36734
+ Math.abs(difference / Math.abs(first) * 100)
36735
+ )}%)` : "";
36736
+ return {
36737
+ value: formatters.value(last),
36738
+ change: `${sign}${formatters.change(difference)}${percent}`,
36739
+ direction
36740
+ };
36741
+ }
36742
+ var TREND_CLASS = {
36743
+ up: "text-emerald-600 dark:text-emerald-400",
36744
+ down: "text-red-600 dark:text-red-400",
36745
+ flat: "text-muted-foreground"
36746
+ };
36747
+ var TREND_ARROW = { up: "\u25B2", down: "\u25BC", flat: "" };
36748
+ function ChartHeader({
36749
+ title,
36750
+ trend,
36751
+ range
36752
+ }) {
36753
+ if (!trend) {
36754
+ return title ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "mb-3 text-sm font-medium", children: title }) : null;
36755
+ }
36756
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "mb-3", "data-testid": "chart-header", children: [
36757
+ title && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-sm text-muted-foreground", children: title }),
36758
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "mt-0.5 text-2xl font-semibold tracking-tight text-foreground", children: trend.value }),
36759
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "mt-0.5 flex flex-wrap items-center gap-x-1.5 text-xs", children: [
36760
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: cx("font-medium", TREND_CLASS[trend.direction]), children: [
36761
+ TREND_ARROW[trend.direction] && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { "aria-hidden": "true", className: "mr-1 text-[0.6rem]", children: TREND_ARROW[trend.direction] }),
36762
+ trend.change
36763
+ ] }),
36764
+ range && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-muted-foreground", children: range })
36765
+ ] })
36766
+ ] });
36767
+ }
36593
36768
  function ChartCard({ data }) {
36594
36769
  const containerRef = React2.useRef(null);
36595
36770
  const [ready, setReady] = React2.useState(false);
36771
+ const gradientId = `chart-fill-${React2.useId().replace(/:/g, "")}`;
36772
+ const reducedMotion = usePrefersReducedMotion();
36596
36773
  React2.useEffect(() => {
36597
36774
  const frame = requestAnimationFrame(() => setReady(true));
36598
36775
  return () => cancelAnimationFrame(frame);
36599
36776
  }, []);
36600
36777
  if ("error" in data) {
36601
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "my-4 max-w-lg", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "rounded-xl bg-sidebar dark:bg-card px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-sm text-muted-foreground", children: data.error }) }) });
36778
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "my-4 max-w-lg", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "rounded-xl bg-sidebar dark:bg-card px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-sm text-muted-foreground", children: "Couldn't display this chart." }) }) });
36602
36779
  }
36603
- const { chartType, title, data: chartData, dataKeys, xAxisKey, colors } = data;
36780
+ const {
36781
+ chartType,
36782
+ title,
36783
+ data: chartData,
36784
+ dataKeys,
36785
+ xAxisKey,
36786
+ colors,
36787
+ valueFormat,
36788
+ currency
36789
+ } = data;
36604
36790
  const chartConfig = buildChartConfig(dataKeys, colors);
36605
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "my-4 max-w-lg", ref: containerRef, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rounded-xl bg-sidebar dark:bg-card px-5 py-4", children: [
36606
- title && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-sm font-medium mb-3", children: title }),
36607
- ready ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartContainer, { config: chartConfig, className: "aspect-auto h-[250px] w-full", children: chartType === "bar" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_recharts.BarChart, { data: chartData, children: [
36608
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.CartesianGrid, { vertical: false }),
36609
- xAxisKey && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.XAxis, { dataKey: xAxisKey, tickLine: false, axisLine: false, tickMargin: 8 }),
36610
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.YAxis, { tickLine: false, axisLine: false }),
36611
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTooltip, { content: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTooltipContent, {}) }),
36612
- dataKeys.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegend, { content: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegendContent, {}) }),
36613
- dataKeys.map((key3) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.Bar, { dataKey: key3, fill: `var(--color-${key3})`, radius: 4 }, key3))
36614
- ] }) : chartType === "line" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_recharts.LineChart, { data: chartData, children: [
36615
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.CartesianGrid, { vertical: false }),
36616
- xAxisKey && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.XAxis, { dataKey: xAxisKey, tickLine: false, axisLine: false, tickMargin: 8 }),
36617
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.YAxis, { tickLine: false, axisLine: false }),
36618
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTooltip, { content: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTooltipContent, {}) }),
36619
- dataKeys.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegend, { content: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegendContent, {}) }),
36620
- dataKeys.map((key3) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
36621
- import_recharts.Line,
36622
- {
36623
- dataKey: key3,
36624
- stroke: `var(--color-${key3})`,
36625
- strokeWidth: 2,
36626
- dot: false
36627
- },
36628
- key3
36629
- ))
36630
- ] }) : chartType === "area" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_recharts.AreaChart, { data: chartData, children: [
36631
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.CartesianGrid, { vertical: false }),
36632
- xAxisKey && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.XAxis, { dataKey: xAxisKey, tickLine: false, axisLine: false, tickMargin: 8 }),
36633
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.YAxis, { tickLine: false, axisLine: false }),
36634
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTooltip, { content: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTooltipContent, {}) }),
36635
- dataKeys.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegend, { content: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegendContent, {}) }),
36636
- dataKeys.map((key3) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
36637
- import_recharts.Area,
36638
- {
36639
- dataKey: key3,
36640
- fill: `var(--color-${key3})`,
36641
- stroke: `var(--color-${key3})`,
36642
- fillOpacity: 0.3
36643
- },
36644
- key3
36645
- ))
36646
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_recharts.PieChart, { children: [
36647
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTooltip, { content: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTooltipContent, {}) }),
36648
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
36649
- import_recharts.Pie,
36791
+ const seriesColor = (key3) => chartConfig[key3]?.color;
36792
+ const isTrendChart = chartType === "line" || chartType === "area";
36793
+ const plottedKeys = chartType === "pie" ? dataKeys.slice(0, 1) : dataKeys;
36794
+ const values = seriesValues(chartData, plottedKeys);
36795
+ const yTicks = isTrendChart ? niceTicks(values) : void 0;
36796
+ const yDomain = yTicks ? [yTicks[0], yTicks[yTicks.length - 1]] : void 0;
36797
+ const formatters = buildFormatters(valueFormat, currency, yTicks);
36798
+ const trend = isTrendChart && dataKeys.length === 1 ? buildTrend(values, valueFormat, formatters) : void 0;
36799
+ const trendRows = trend ? chartData.filter((point) => typeof point[dataKeys[0]] === "number") : [];
36800
+ const range = trend && xAxisKey ? [trendRows[0], trendRows[trendRows.length - 1]].map((point) => cellText(point[xAxisKey])).filter(Boolean).join(" \u2013 ") : void 0;
36801
+ const headerTitle = title ?? (trend ? chartConfig[dataKeys[0]]?.label : void 0);
36802
+ const tickSamples = [...yDomain ?? [], ...values].map((value) => formatters.tick(value));
36803
+ const longestTick = tickSamples.reduce((max, label) => Math.max(max, label.length), 0);
36804
+ const animate = !reducedMotion;
36805
+ const showDots = chartData.length <= DOT_LIMIT;
36806
+ const curve = showDots ? "linear" : "monotone";
36807
+ const hasNegative = values.some((value) => value < 0);
36808
+ const margin = { top: 8, right: 8, bottom: 0, left: 0 };
36809
+ const xAxis = xAxisKey && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
36810
+ import_recharts.XAxis,
36811
+ {
36812
+ dataKey: xAxisKey,
36813
+ tickLine: false,
36814
+ axisLine: false,
36815
+ tickMargin: 8,
36816
+ minTickGap: 16,
36817
+ interval: "preserveStartEnd",
36818
+ padding: isTrendChart ? { left: 12, right: 12 } : void 0
36819
+ }
36820
+ );
36821
+ const yAxis = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
36822
+ import_recharts.YAxis,
36823
+ {
36824
+ tickLine: false,
36825
+ axisLine: false,
36826
+ tickCount: yTicks ? void 0 : 4,
36827
+ ticks: yTicks,
36828
+ tickMargin: 4,
36829
+ tickFormatter: formatters.tick,
36830
+ domain: yDomain,
36831
+ allowDataOverflow: false,
36832
+ width: Math.min(120, Math.max(36, longestTick * 7 + 12))
36833
+ }
36834
+ );
36835
+ const tooltip = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
36836
+ ChartTooltip,
36837
+ {
36838
+ cursor: chartType === "bar" ? { fill: "var(--muted)", opacity: 0.5 } : { stroke: "var(--border)", strokeWidth: 1 },
36839
+ content: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
36840
+ ChartTooltipContent,
36650
36841
  {
36651
- data: chartData,
36652
- dataKey: dataKeys[0],
36653
- nameKey: xAxisKey || "name",
36654
- cx: "50%",
36655
- cy: "50%",
36656
- outerRadius: 80,
36657
- children: chartData.map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.Cell, { fill: DEFAULT_COLORS[index % DEFAULT_COLORS.length] }, index))
36842
+ indicator: chartType === "bar" ? "dot" : "line",
36843
+ valueFormatter: formatters.value
36658
36844
  }
36659
- ),
36660
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegend, { content: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegendContent, { nameKey: xAxisKey || "name" }) })
36661
- ] }) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "h-[250px] w-full" })
36662
- ] }) });
36845
+ )
36846
+ }
36847
+ );
36848
+ const legend = dataKeys.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegend, { content: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegendContent, {}) });
36849
+ const marker = (key3, r) => ({
36850
+ r,
36851
+ fill: seriesColor(key3),
36852
+ stroke: SURFACE,
36853
+ strokeWidth: 2
36854
+ });
36855
+ const lineDot = (key3) => showDots ? marker(key3, 4) : (props) => props.index === lastValueIndex(chartData, key3) && typeof props.cx === "number" && typeof props.cy === "number" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: props.cx, cy: props.cy, ...marker(key3, 4) }, `end-${key3}`) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("g", {}, `dot-${key3}-${props.index}`);
36856
+ const labelKey = chartType === "pie" ? xAxisKey || "name" : xAxisKey;
36857
+ const tableColumns = labelKey ? [labelKey, ...plottedKeys] : plottedKeys;
36858
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
36859
+ "div",
36860
+ {
36861
+ className: "my-4 max-w-lg",
36862
+ ref: containerRef,
36863
+ role: "figure",
36864
+ "aria-label": [title, `${chartType} chart`].filter(Boolean).join(", "),
36865
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rounded-xl bg-sidebar dark:bg-card px-5 py-4 [--chart-surface:var(--sidebar)] dark:[--chart-surface:var(--card)]", children: [
36866
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartHeader, { title: headerTitle, trend, range }),
36867
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("table", { style: VISUALLY_HIDDEN, children: [
36868
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("tr", { children: tableColumns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("th", { scope: "col", children: column }, column)) }) }),
36869
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("tbody", { children: chartData.map((point, row) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("tr", { children: tableColumns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { children: cellText(point[column]) }, column)) }, row)) })
36870
+ ] }),
36871
+ ready ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
36872
+ ChartContainer,
36873
+ {
36874
+ config: chartConfig,
36875
+ className: "aspect-auto h-[220px] w-full",
36876
+ "aria-hidden": "true",
36877
+ children: chartType === "bar" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_recharts.BarChart, { data: chartData, margin, barGap: 2, barCategoryGap: "24%", children: [
36878
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.CartesianGrid, { vertical: false }),
36879
+ xAxis,
36880
+ yAxis,
36881
+ tooltip,
36882
+ legend,
36883
+ dataKeys.map((key3) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
36884
+ import_recharts.Bar,
36885
+ {
36886
+ dataKey: key3,
36887
+ fill: seriesColor(key3),
36888
+ maxBarSize: 24,
36889
+ radius: hasNegative ? 2 : [4, 4, 0, 0],
36890
+ isAnimationActive: animate
36891
+ },
36892
+ key3
36893
+ ))
36894
+ ] }) : chartType === "line" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_recharts.LineChart, { data: chartData, margin, children: [
36895
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.CartesianGrid, { vertical: false }),
36896
+ xAxis,
36897
+ yAxis,
36898
+ tooltip,
36899
+ legend,
36900
+ dataKeys.map((key3) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
36901
+ import_recharts.Line,
36902
+ {
36903
+ type: curve,
36904
+ dataKey: key3,
36905
+ stroke: seriesColor(key3),
36906
+ strokeWidth: 2,
36907
+ strokeLinecap: "round",
36908
+ strokeLinejoin: "round",
36909
+ dot: lineDot(key3),
36910
+ activeDot: marker(key3, 5),
36911
+ isAnimationActive: animate,
36912
+ animationDuration: 600
36913
+ },
36914
+ key3
36915
+ ))
36916
+ ] }) : chartType === "area" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_recharts.AreaChart, { data: chartData, margin, children: [
36917
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("defs", { children: dataKeys.map((key3, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
36918
+ "linearGradient",
36919
+ {
36920
+ id: `${gradientId}-${index}`,
36921
+ x1: "0",
36922
+ y1: "0",
36923
+ x2: "0",
36924
+ y2: "1",
36925
+ children: [
36926
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("stop", { offset: "0%", stopColor: seriesColor(key3), stopOpacity: 0.24 }),
36927
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("stop", { offset: "100%", stopColor: seriesColor(key3), stopOpacity: 0 })
36928
+ ]
36929
+ },
36930
+ key3
36931
+ )) }),
36932
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.CartesianGrid, { vertical: false }),
36933
+ xAxis,
36934
+ yAxis,
36935
+ tooltip,
36936
+ legend,
36937
+ dataKeys.map((key3, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
36938
+ import_recharts.Area,
36939
+ {
36940
+ type: curve,
36941
+ dataKey: key3,
36942
+ stroke: seriesColor(key3),
36943
+ strokeWidth: 2,
36944
+ fill: `url(#${gradientId}-${index})`,
36945
+ dot: lineDot(key3),
36946
+ activeDot: marker(key3, 5),
36947
+ baseValue: "dataMin",
36948
+ isAnimationActive: animate,
36949
+ animationDuration: 600
36950
+ },
36951
+ key3
36952
+ ))
36953
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_recharts.PieChart, { margin, children: [
36954
+ tooltip,
36955
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
36956
+ import_recharts.Pie,
36957
+ {
36958
+ data: chartData,
36959
+ dataKey: dataKeys[0],
36960
+ nameKey: xAxisKey || "name",
36961
+ cx: "50%",
36962
+ cy: "50%",
36963
+ innerRadius: "58%",
36964
+ outerRadius: "86%",
36965
+ paddingAngle: chartData.length > 1 ? 1 : 0,
36966
+ stroke: SURFACE,
36967
+ strokeWidth: 2,
36968
+ isAnimationActive: animate,
36969
+ children: [
36970
+ chartData.map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_recharts.Cell, { fill: paletteColor(index) }, index)),
36971
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
36972
+ import_recharts.Label,
36973
+ {
36974
+ position: "center",
36975
+ content: ({ viewBox }) => {
36976
+ const box = viewBox;
36977
+ if (box?.cx === void 0 || box.cy === void 0) return null;
36978
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("text", { x: box.cx, y: box.cy, textAnchor: "middle", dominantBaseline: "middle", children: [
36979
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
36980
+ "tspan",
36981
+ {
36982
+ x: box.cx,
36983
+ y: box.cy - 6,
36984
+ className: "fill-foreground text-lg font-semibold",
36985
+ children: formatters.value(values.reduce((sum, value) => sum + value, 0))
36986
+ }
36987
+ ),
36988
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("tspan", { x: box.cx, y: box.cy + 14, className: "fill-muted-foreground", children: "Total" })
36989
+ ] });
36990
+ }
36991
+ }
36992
+ )
36993
+ ]
36994
+ }
36995
+ ),
36996
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegend, { content: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartLegendContent, { nameKey: xAxisKey || "name" }) })
36997
+ ] })
36998
+ }
36999
+ ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "h-[220px] w-full" })
37000
+ ] })
37001
+ }
37002
+ );
36663
37003
  }
36664
37004
 
36665
37005
  // src/react/LoggerProvider.tsx
@@ -14419,6 +14419,7 @@ declare function renderAnumaTree(node: AnumaNode): React.ReactElement | null;
14419
14419
  declare function renderAnumaJsx(jsx: string): React.ReactElement | null;
14420
14420
 
14421
14421
  type ChartDataPoint = Record<string, string | number>;
14422
+ type ChartValueFormat = "number" | "currency" | "percent";
14422
14423
  type DisplayChartResult = {
14423
14424
  chartType: "bar" | "line" | "area" | "pie";
14424
14425
  title?: string;
@@ -14426,6 +14427,8 @@ type DisplayChartResult = {
14426
14427
  dataKeys: string[];
14427
14428
  xAxisKey?: string;
14428
14429
  colors?: Record<string, string>;
14430
+ valueFormat?: ChartValueFormat;
14431
+ currency?: string;
14429
14432
  } | {
14430
14433
  error: string;
14431
14434
  };
@@ -14455,12 +14458,13 @@ declare function ChartContainer({ id, className, children, config, ...props }: R
14455
14458
  children: React.ComponentProps<typeof RechartsPrimitive.ResponsiveContainer>["children"];
14456
14459
  }): react_jsx_runtime.JSX.Element;
14457
14460
  declare const ChartTooltip: typeof RechartsPrimitive.Tooltip;
14458
- declare function ChartTooltipContent({ active, payload, className, indicator, hideLabel, hideIndicator, label, labelFormatter, labelClassName, formatter, color, nameKey, labelKey, }: React.ComponentProps<typeof RechartsPrimitive.Tooltip> & React.ComponentProps<"div"> & {
14461
+ declare function ChartTooltipContent({ active, payload, className, indicator, hideLabel, hideIndicator, label, labelFormatter, labelClassName, formatter, color, nameKey, labelKey, valueFormatter, }: React.ComponentProps<typeof RechartsPrimitive.Tooltip> & React.ComponentProps<"div"> & {
14459
14462
  hideLabel?: boolean;
14460
14463
  hideIndicator?: boolean;
14461
14464
  indicator?: "line" | "dot" | "dashed";
14462
14465
  nameKey?: string;
14463
14466
  labelKey?: string;
14467
+ valueFormatter?: (value: number) => string;
14464
14468
  }): react_jsx_runtime.JSX.Element | null;
14465
14469
  declare const ChartLegend: typeof RechartsPrimitive.Legend;
14466
14470
  declare function ChartLegendContent({ className, hideIcon, payload, verticalAlign, nameKey, }: React.ComponentProps<"div"> & Pick<RechartsPrimitive.LegendProps, "payload" | "verticalAlign"> & {
@@ -14419,6 +14419,7 @@ declare function renderAnumaTree(node: AnumaNode): React.ReactElement | null;
14419
14419
  declare function renderAnumaJsx(jsx: string): React.ReactElement | null;
14420
14420
 
14421
14421
  type ChartDataPoint = Record<string, string | number>;
14422
+ type ChartValueFormat = "number" | "currency" | "percent";
14422
14423
  type DisplayChartResult = {
14423
14424
  chartType: "bar" | "line" | "area" | "pie";
14424
14425
  title?: string;
@@ -14426,6 +14427,8 @@ type DisplayChartResult = {
14426
14427
  dataKeys: string[];
14427
14428
  xAxisKey?: string;
14428
14429
  colors?: Record<string, string>;
14430
+ valueFormat?: ChartValueFormat;
14431
+ currency?: string;
14429
14432
  } | {
14430
14433
  error: string;
14431
14434
  };
@@ -14455,12 +14458,13 @@ declare function ChartContainer({ id, className, children, config, ...props }: R
14455
14458
  children: React.ComponentProps<typeof RechartsPrimitive.ResponsiveContainer>["children"];
14456
14459
  }): react_jsx_runtime.JSX.Element;
14457
14460
  declare const ChartTooltip: typeof RechartsPrimitive.Tooltip;
14458
- declare function ChartTooltipContent({ active, payload, className, indicator, hideLabel, hideIndicator, label, labelFormatter, labelClassName, formatter, color, nameKey, labelKey, }: React.ComponentProps<typeof RechartsPrimitive.Tooltip> & React.ComponentProps<"div"> & {
14461
+ declare function ChartTooltipContent({ active, payload, className, indicator, hideLabel, hideIndicator, label, labelFormatter, labelClassName, formatter, color, nameKey, labelKey, valueFormatter, }: React.ComponentProps<typeof RechartsPrimitive.Tooltip> & React.ComponentProps<"div"> & {
14459
14462
  hideLabel?: boolean;
14460
14463
  hideIndicator?: boolean;
14461
14464
  indicator?: "line" | "dot" | "dashed";
14462
14465
  nameKey?: string;
14463
14466
  labelKey?: string;
14467
+ valueFormatter?: (value: number) => string;
14464
14468
  }): react_jsx_runtime.JSX.Element | null;
14465
14469
  declare const ChartLegend: typeof RechartsPrimitive.Legend;
14466
14470
  declare function ChartLegendContent({ className, hideIcon, payload, verticalAlign, nameKey, }: React.ComponentProps<"div"> & Pick<RechartsPrimitive.LegendProps, "payload" | "verticalAlign"> & {