@burdenoff/microfe-bigconsole 2026.613.3 → 2026.613.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/bigconsole/components/widgets/WidgetRegistry.js +55 -1
  2. package/dist/bigconsole/components/widgets/WidgetRegistry.js.map +1 -1
  3. package/dist/bigconsole/components/widgets/chart/ChartWidget.js +123 -91
  4. package/dist/bigconsole/components/widgets/chart/ChartWidget.js.map +1 -1
  5. package/dist/bigconsole/components/widgets/chart/charts/AreaChart.js +40 -35
  6. package/dist/bigconsole/components/widgets/chart/charts/AreaChart.js.map +1 -1
  7. package/dist/bigconsole/components/widgets/chart/charts/BarChart.js +30 -25
  8. package/dist/bigconsole/components/widgets/chart/charts/BarChart.js.map +1 -1
  9. package/dist/bigconsole/components/widgets/chart/charts/ComboChart.js +139 -0
  10. package/dist/bigconsole/components/widgets/chart/charts/ComboChart.js.map +1 -0
  11. package/dist/bigconsole/components/widgets/chart/charts/LineChart.js +35 -30
  12. package/dist/bigconsole/components/widgets/chart/charts/LineChart.js.map +1 -1
  13. package/dist/bigconsole/components/widgets/chart/charts/ScatterChart.js +128 -0
  14. package/dist/bigconsole/components/widgets/chart/charts/ScatterChart.js.map +1 -0
  15. package/dist/bigconsole/components/widgets/chart/charts/WaterfallChart.js +111 -0
  16. package/dist/bigconsole/components/widgets/chart/charts/WaterfallChart.js.map +1 -0
  17. package/dist/bigconsole/components/widgets/chart/charts/index.js +4 -0
  18. package/dist/bigconsole/components/widgets/chart/charts/referenceElements.js +49 -0
  19. package/dist/bigconsole/components/widgets/chart/charts/referenceElements.js.map +1 -0
  20. package/dist/bigconsole/components/widgets/kpi-comparison/KPIComparisonWidget.js +72 -68
  21. package/dist/bigconsole/components/widgets/kpi-comparison/KPIComparisonWidget.js.map +1 -1
  22. package/dist/bigconsole/components/widgets/map-widget/MapWidget.js +74 -24
  23. package/dist/bigconsole/components/widgets/map-widget/MapWidget.js.map +1 -1
  24. package/dist/bigconsole/components/widgets/metric-card/MetricCardWidget.js +87 -86
  25. package/dist/bigconsole/components/widgets/metric-card/MetricCardWidget.js.map +1 -1
  26. package/dist/bigconsole/components/widgets/table/TableCell.js +55 -26
  27. package/dist/bigconsole/components/widgets/table/TableCell.js.map +1 -1
  28. package/dist/bigconsole/components/widgets/table/TableHeader.js +25 -18
  29. package/dist/bigconsole/components/widgets/table/TableHeader.js.map +1 -1
  30. package/dist/bigconsole/components/widgets/table/TableWidget.js +255 -107
  31. package/dist/bigconsole/components/widgets/table/TableWidget.js.map +1 -1
  32. package/dist/bigconsole/components/widgets/utils/conditionalFormat.js +91 -0
  33. package/dist/bigconsole/components/widgets/utils/conditionalFormat.js.map +1 -0
  34. package/dist/bigconsole/hooks/index.js +1 -0
  35. package/dist/bigconsole/hooks/useDashboardImageExport.js +1 -0
  36. package/dist/bigconsole/utils/widgetTypeMapping.js +1 -0
  37. package/dist/bigconsole/utils/widgetTypeMapping.js.map +1 -1
  38. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"LineChart.js","names":[],"sources":["../../../../../../src/bigconsole/components/widgets/chart/charts/LineChart.tsx"],"sourcesContent":["/**\n * LineChart Component\n *\n * Line chart using Recharts.\n */\n\nimport { type FC, memo, useMemo } from 'react';\nimport {\n LineChart as RechartsLineChart,\n Line,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n ResponsiveContainer,\n Legend,\n} from 'recharts';\nimport { ChartTooltip } from '../ChartTooltip';\nimport type { ChartConfig, ChartData } from './types';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface LineChartProps {\n /** Chart data */\n data: ChartData[];\n /** Chart configuration */\n config: ChartConfig;\n /** Series to hide */\n hiddenSeries?: string[];\n /** Click handler for data points */\n onDataClick?: (data: ChartData, index: number) => void;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst DEFAULT_COLORS = [\n 'var(--color-chart-1)',\n 'var(--color-chart-2)',\n 'var(--color-chart-3)',\n 'var(--color-chart-4)',\n 'var(--color-chart-5)',\n];\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const LineChart: FC<LineChartProps> = memo(function LineChart({\n data = [],\n config,\n hiddenSeries = [],\n onDataClick,\n}) {\n // Extract data keys (series)\n const dataKeys = useMemo(() => {\n if (!data?.length) return [];\n const keys = Object.keys(data[0]).filter((key) => key !== config.xAxisKey && typeof data[0][key] === 'number');\n return keys;\n }, [data, config.xAxisKey]);\n\n // Format value\n const formatValue = (value: number | string): string => {\n if (typeof value !== 'number') return String(value);\n return new Intl.NumberFormat('en-US', {\n notation: value >= 10000 ? 'compact' : 'standard',\n maximumFractionDigits: 2,\n }).format(value);\n };\n\n if (!data?.length) {\n return null;\n }\n\n return (\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsLineChart\n data={data}\n margin={{ top: 10, right: 10, left: 0, bottom: 0 }}\n onClick={(e) => {\n if (e?.activePayload?.[0] && onDataClick) {\n onDataClick(e.activePayload[0].payload, e.activeTooltipIndex || 0);\n }\n }}\n >\n {config.showGrid !== false && (\n <CartesianGrid strokeDasharray=\"3 3\" stroke=\"var(--color-border-default)\" opacity={0.5} />\n )}\n\n <XAxis\n dataKey={config.xAxisKey || 'name'}\n tick={{ fill: 'var(--color-text-secondary)', fontSize: 12 }}\n tickLine={{ stroke: 'var(--color-border-default)' }}\n axisLine={{ stroke: 'var(--color-border-default)' }}\n label={\n config.xAxisLabel\n ? {\n value: config.xAxisLabel,\n position: 'insideBottom',\n offset: -5,\n fill: 'var(--color-text-secondary)',\n }\n : undefined\n }\n />\n\n <YAxis\n tick={{ fill: 'var(--color-text-secondary)', fontSize: 12 }}\n tickLine={{ stroke: 'var(--color-border-default)' }}\n axisLine={{ stroke: 'var(--color-border-default)' }}\n tickFormatter={formatValue}\n label={\n config.yAxisLabel\n ? {\n value: config.yAxisLabel,\n angle: -90,\n position: 'insideLeft',\n fill: 'var(--color-text-secondary)',\n }\n : undefined\n }\n />\n\n <Tooltip\n content={<ChartTooltip valueFormatter={formatValue} />}\n cursor={{ stroke: 'var(--color-border-default)' }}\n />\n\n {config.showLegend !== false && (\n <Legend\n wrapperStyle={{ paddingTop: 20 }}\n formatter={(value) => <span style={{ color: 'var(--color-text-primary)' }}>{value}</span>}\n />\n )}\n\n {dataKeys.map((key, index) => (\n <Line\n key={key}\n type={config.curveType || 'monotone'}\n dataKey={key}\n name={config.seriesNames?.[key] || key}\n stroke={config.colors?.[index] || DEFAULT_COLORS[index % DEFAULT_COLORS.length]}\n strokeWidth={2}\n dot={config.showDots !== false}\n activeDot={{ r: 6 }}\n hide={hiddenSeries.includes(key)}\n connectNulls\n />\n ))}\n </RechartsLineChart>\n </ResponsiveContainer>\n );\n});\n\nexport default LineChart;\n"],"mappings":";;;;;AAuCA,IAAM,IAAiB;CACrB;CACA;CACA;CACA;CACA;CACD,EAMY,IAAgC,EAAK,SAAmB,EACnE,UAAO,EAAE,EACT,WACA,kBAAe,EAAE,EACjB,kBACC;CAED,IAAM,IAAW,QACV,GAAM,SACE,OAAO,KAAK,EAAK,GAAG,CAAC,QAAQ,MAAQ,MAAQ,EAAO,YAAY,OAAO,EAAK,GAAG,MAAS,SAAS,GADpF,EAAE,EAG3B,CAAC,GAAM,EAAO,SAAS,CAAC,EAGrB,KAAe,MACf,OAAO,KAAU,WACd,IAAI,KAAK,aAAa,SAAS;EACpC,UAAU,KAAS,MAAQ,YAAY;EACvC,uBAAuB;EACxB,CAAC,CAAC,OAAO,EAAM,GAJsB,OAAO,EAAM;AAWrD,QAJK,GAAM,SAKT,kBAAC,GAAD;EAAqB,OAAM;EAAO,QAAO;YACvC,kBAAC,GAAD;GACQ;GACN,QAAQ;IAAE,KAAK;IAAI,OAAO;IAAI,MAAM;IAAG,QAAQ;IAAG;GAClD,UAAU,MAAM;AACd,IAAI,GAAG,gBAAgB,MAAM,KAC3B,EAAY,EAAE,cAAc,GAAG,SAAS,EAAE,sBAAsB,EAAE;;aALxE;IASG,EAAO,aAAa,MACnB,kBAAC,GAAD;KAAe,iBAAgB;KAAM,QAAO;KAA8B,SAAS;KAAO,CAAA;IAG5F,kBAAC,GAAD;KACE,SAAS,EAAO,YAAY;KAC5B,MAAM;MAAE,MAAM;MAA+B,UAAU;MAAI;KAC3D,UAAU,EAAE,QAAQ,+BAA+B;KACnD,UAAU,EAAE,QAAQ,+BAA+B;KACnD,OACE,EAAO,aACH;MACE,OAAO,EAAO;MACd,UAAU;MACV,QAAQ;MACR,MAAM;MACP,GACD,KAAA;KAEN,CAAA;IAEF,kBAAC,GAAD;KACE,MAAM;MAAE,MAAM;MAA+B,UAAU;MAAI;KAC3D,UAAU,EAAE,QAAQ,+BAA+B;KACnD,UAAU,EAAE,QAAQ,+BAA+B;KACnD,eAAe;KACf,OACE,EAAO,aACH;MACE,OAAO,EAAO;MACd,OAAO;MACP,UAAU;MACV,MAAM;MACP,GACD,KAAA;KAEN,CAAA;IAEF,kBAAC,GAAD;KACE,SAAS,kBAAC,GAAD,EAAc,gBAAgB,GAAe,CAAA;KACtD,QAAQ,EAAE,QAAQ,+BAA+B;KACjD,CAAA;IAED,EAAO,eAAe,MACrB,kBAAC,GAAD;KACE,cAAc,EAAE,YAAY,IAAI;KAChC,YAAY,MAAU,kBAAC,QAAD;MAAM,OAAO,EAAE,OAAO,6BAA6B;gBAAG;MAAa,CAAA;KACzF,CAAA;IAGH,EAAS,KAAK,GAAK,MAClB,kBAAC,GAAD;KAEE,MAAM,EAAO,aAAa;KAC1B,SAAS;KACT,MAAM,EAAO,cAAc,MAAQ;KACnC,QAAQ,EAAO,SAAS,MAAU,EAAe,IAAQ,EAAe;KACxE,aAAa;KACb,KAAK,EAAO,aAAa;KACzB,WAAW,EAAE,GAAG,GAAG;KACnB,MAAM,EAAa,SAAS,EAAI;KAChC,cAAA;KACA,EAVK,EAUL,CACF;IACgB;;EACA,CAAA,GA/Ef;EAiFT"}
1
+ {"version":3,"file":"LineChart.js","names":[],"sources":["../../../../../../src/bigconsole/components/widgets/chart/charts/LineChart.tsx"],"sourcesContent":["/**\n * LineChart Component\n *\n * Line chart using Recharts.\n */\n\nimport { type FC, memo, useMemo } from 'react';\nimport {\n LineChart as RechartsLineChart,\n Line,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n ResponsiveContainer,\n Legend,\n} from 'recharts';\nimport { ChartTooltip } from '../ChartTooltip';\nimport type { ChartConfig, ChartData } from './types';\nimport { buildReferenceElements } from './referenceElements';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface LineChartProps {\n /** Chart data */\n data: ChartData[];\n /** Chart configuration */\n config: ChartConfig;\n /** Series to hide */\n hiddenSeries?: string[];\n /** Click handler for data points */\n onDataClick?: (data: ChartData, index: number) => void;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst DEFAULT_COLORS = [\n 'var(--color-chart-1)',\n 'var(--color-chart-2)',\n 'var(--color-chart-3)',\n 'var(--color-chart-4)',\n 'var(--color-chart-5)',\n];\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const LineChart: FC<LineChartProps> = memo(function LineChart({\n data = [],\n config,\n hiddenSeries = [],\n onDataClick,\n}) {\n // Extract data keys (series)\n const dataKeys = useMemo(() => {\n if (!data?.length) return [];\n const keys = Object.keys(data[0]).filter((key) => key !== config.xAxisKey && typeof data[0][key] === 'number');\n return keys;\n }, [data, config.xAxisKey]);\n\n // Format value\n const formatValue = (value: number | string): string => {\n if (typeof value !== 'number') return String(value);\n return new Intl.NumberFormat('en-US', {\n notation: value >= 10000 ? 'compact' : 'standard',\n maximumFractionDigits: 2,\n }).format(value);\n };\n\n if (!data?.length) {\n return null;\n }\n\n return (\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsLineChart\n data={data}\n margin={{ top: 10, right: 10, left: 0, bottom: 0 }}\n onClick={(e) => {\n if (e?.activePayload?.[0] && onDataClick) {\n onDataClick(e.activePayload[0].payload, e.activeTooltipIndex || 0);\n }\n }}\n >\n {config.showGrid !== false && (\n <CartesianGrid strokeDasharray=\"3 3\" stroke=\"var(--color-border-default)\" opacity={0.5} />\n )}\n\n <XAxis\n dataKey={config.xAxisKey || 'name'}\n tick={{ fill: 'var(--color-text-secondary)', fontSize: 12 }}\n tickLine={{ stroke: 'var(--color-border-default)' }}\n axisLine={{ stroke: 'var(--color-border-default)' }}\n label={\n config.xAxisLabel\n ? {\n value: config.xAxisLabel,\n position: 'insideBottom',\n offset: -5,\n fill: 'var(--color-text-secondary)',\n }\n : undefined\n }\n />\n\n <YAxis\n tick={{ fill: 'var(--color-text-secondary)', fontSize: 12 }}\n tickLine={{ stroke: 'var(--color-border-default)' }}\n axisLine={{ stroke: 'var(--color-border-default)' }}\n tickFormatter={formatValue}\n scale={config.logScale ? 'log' : 'auto'}\n domain={config.logScale ? ['auto', 'auto'] : undefined}\n allowDataOverflow={config.logScale || undefined}\n label={\n config.yAxisLabel\n ? {\n value: config.yAxisLabel,\n angle: -90,\n position: 'insideLeft',\n fill: 'var(--color-text-secondary)',\n }\n : undefined\n }\n />\n\n <Tooltip\n content={<ChartTooltip valueFormatter={formatValue} />}\n cursor={{ stroke: 'var(--color-border-default)' }}\n />\n\n {config.showLegend !== false && (\n <Legend\n wrapperStyle={{ paddingTop: 20 }}\n formatter={(value) => <span style={{ color: 'var(--color-text-primary)' }}>{value}</span>}\n />\n )}\n\n {buildReferenceElements(config.referenceLines)}\n\n {dataKeys.map((key, index) => (\n <Line\n key={key}\n type={config.curveType || 'monotone'}\n dataKey={key}\n name={config.seriesNames?.[key] || key}\n stroke={config.colors?.[index] || DEFAULT_COLORS[index % DEFAULT_COLORS.length]}\n strokeWidth={2}\n dot={config.showDots !== false}\n activeDot={{ r: 6 }}\n hide={hiddenSeries.includes(key)}\n connectNulls\n />\n ))}\n </RechartsLineChart>\n </ResponsiveContainer>\n );\n});\n\nexport default LineChart;\n"],"mappings":";;;;;;AAwCA,IAAM,IAAiB;CACrB;CACA;CACA;CACA;CACA;CACD,EAMY,IAAgC,EAAK,SAAmB,EACnE,UAAO,EAAE,EACT,WACA,kBAAe,EAAE,EACjB,kBACC;CAED,IAAM,IAAW,QACV,GAAM,SACE,OAAO,KAAK,EAAK,GAAG,CAAC,QAAQ,MAAQ,MAAQ,EAAO,YAAY,OAAO,EAAK,GAAG,MAAS,SAAS,GADpF,EAAE,EAG3B,CAAC,GAAM,EAAO,SAAS,CAAC,EAGrB,KAAe,MACf,OAAO,KAAU,WACd,IAAI,KAAK,aAAa,SAAS;EACpC,UAAU,KAAS,MAAQ,YAAY;EACvC,uBAAuB;EACxB,CAAC,CAAC,OAAO,EAAM,GAJsB,OAAO,EAAM;AAWrD,QAJK,GAAM,SAKT,kBAAC,GAAD;EAAqB,OAAM;EAAO,QAAO;YACvC,kBAAC,GAAD;GACQ;GACN,QAAQ;IAAE,KAAK;IAAI,OAAO;IAAI,MAAM;IAAG,QAAQ;IAAG;GAClD,UAAU,MAAM;AACd,IAAI,GAAG,gBAAgB,MAAM,KAC3B,EAAY,EAAE,cAAc,GAAG,SAAS,EAAE,sBAAsB,EAAE;;aALxE;IASG,EAAO,aAAa,MACnB,kBAAC,GAAD;KAAe,iBAAgB;KAAM,QAAO;KAA8B,SAAS;KAAO,CAAA;IAG5F,kBAAC,GAAD;KACE,SAAS,EAAO,YAAY;KAC5B,MAAM;MAAE,MAAM;MAA+B,UAAU;MAAI;KAC3D,UAAU,EAAE,QAAQ,+BAA+B;KACnD,UAAU,EAAE,QAAQ,+BAA+B;KACnD,OACE,EAAO,aACH;MACE,OAAO,EAAO;MACd,UAAU;MACV,QAAQ;MACR,MAAM;MACP,GACD,KAAA;KAEN,CAAA;IAEF,kBAAC,GAAD;KACE,MAAM;MAAE,MAAM;MAA+B,UAAU;MAAI;KAC3D,UAAU,EAAE,QAAQ,+BAA+B;KACnD,UAAU,EAAE,QAAQ,+BAA+B;KACnD,eAAe;KACf,OAAO,EAAO,WAAW,QAAQ;KACjC,QAAQ,EAAO,WAAW,CAAC,QAAQ,OAAO,GAAG,KAAA;KAC7C,mBAAmB,EAAO,YAAY,KAAA;KACtC,OACE,EAAO,aACH;MACE,OAAO,EAAO;MACd,OAAO;MACP,UAAU;MACV,MAAM;MACP,GACD,KAAA;KAEN,CAAA;IAEF,kBAAC,GAAD;KACE,SAAS,kBAAC,GAAD,EAAc,gBAAgB,GAAe,CAAA;KACtD,QAAQ,EAAE,QAAQ,+BAA+B;KACjD,CAAA;IAED,EAAO,eAAe,MACrB,kBAAC,GAAD;KACE,cAAc,EAAE,YAAY,IAAI;KAChC,YAAY,MAAU,kBAAC,QAAD;MAAM,OAAO,EAAE,OAAO,6BAA6B;gBAAG;MAAa,CAAA;KACzF,CAAA;IAGH,EAAuB,EAAO,eAAe;IAE7C,EAAS,KAAK,GAAK,MAClB,kBAAC,GAAD;KAEE,MAAM,EAAO,aAAa;KAC1B,SAAS;KACT,MAAM,EAAO,cAAc,MAAQ;KACnC,QAAQ,EAAO,SAAS,MAAU,EAAe,IAAQ,EAAe;KACxE,aAAa;KACb,KAAK,EAAO,aAAa;KACzB,WAAW,EAAE,GAAG,GAAG;KACnB,MAAM,EAAa,SAAS,EAAI;KAChC,cAAA;KACA,EAVK,EAUL,CACF;IACgB;;EACA,CAAA,GApFf;EAsFT"}
@@ -0,0 +1,128 @@
1
+ import e from "../ChartTooltip.js";
2
+ import { buildReferenceElements as t } from "./referenceElements.js";
3
+ import { memo as n, useMemo as r } from "react";
4
+ import { jsx as i, jsxs as a } from "react/jsx-runtime";
5
+ import { CartesianGrid as o, Legend as s, ResponsiveContainer as c, Scatter as l, ScatterChart as u, Tooltip as d, XAxis as f, YAxis as p, ZAxis as m } from "recharts";
6
+ //#region src/bigconsole/components/widgets/chart/charts/ScatterChart.tsx
7
+ var h = [
8
+ "var(--color-chart-1)",
9
+ "var(--color-chart-2)",
10
+ "var(--color-chart-3)",
11
+ "var(--color-chart-4)",
12
+ "var(--color-chart-5)"
13
+ ], g = n(function({ data: n = [], config: g, onDataClick: _ }) {
14
+ let { xKey: v, yKey: y } = r(() => {
15
+ if (g.xField && g.yField) return {
16
+ xKey: g.xField,
17
+ yKey: g.yField
18
+ };
19
+ let e = n.length ? Object.keys(n[0]).filter((e) => typeof n[0][e] == "number") : [];
20
+ return {
21
+ xKey: g.xField || e[0] || "x",
22
+ yKey: g.yField || e[1] || "y"
23
+ };
24
+ }, [
25
+ g.xField,
26
+ g.yField,
27
+ n
28
+ ]), b = g.sizeField, x = g.colorField, S = r(() => {
29
+ if (!x) return [{
30
+ name: g.seriesNames?.[y] || y,
31
+ points: n
32
+ }];
33
+ let e = /* @__PURE__ */ new Map();
34
+ for (let t of n) {
35
+ let n = String(t[x] ?? "—");
36
+ e.has(n) || e.set(n, []), e.get(n).push(t);
37
+ }
38
+ return Array.from(e.entries()).map(([e, t]) => ({
39
+ name: e,
40
+ points: t
41
+ }));
42
+ }, [
43
+ n,
44
+ x,
45
+ y,
46
+ g.seriesNames
47
+ ]), C = (e) => typeof e == "number" ? new Intl.NumberFormat("en-US", {
48
+ notation: Math.abs(e) >= 1e4 ? "compact" : "standard",
49
+ maximumFractionDigits: 2
50
+ }).format(e) : String(e);
51
+ return n?.length ? /* @__PURE__ */ i(c, {
52
+ width: "100%",
53
+ height: "100%",
54
+ children: /* @__PURE__ */ a(u, {
55
+ margin: {
56
+ top: 10,
57
+ right: 10,
58
+ left: 0,
59
+ bottom: 0
60
+ },
61
+ children: [
62
+ g.showGrid !== !1 && /* @__PURE__ */ i(o, {
63
+ strokeDasharray: "3 3",
64
+ stroke: "var(--color-border-default)",
65
+ opacity: .5
66
+ }),
67
+ /* @__PURE__ */ i(f, {
68
+ type: "number",
69
+ dataKey: v,
70
+ name: g.xAxisLabel || v,
71
+ tick: {
72
+ fill: "var(--color-text-secondary)",
73
+ fontSize: 12
74
+ },
75
+ tickLine: { stroke: "var(--color-border-default)" },
76
+ axisLine: { stroke: "var(--color-border-default)" },
77
+ tickFormatter: C,
78
+ scale: g.logScale ? "log" : "auto",
79
+ domain: g.logScale ? ["auto", "auto"] : void 0
80
+ }),
81
+ /* @__PURE__ */ i(p, {
82
+ type: "number",
83
+ dataKey: y,
84
+ name: g.yAxisLabel || y,
85
+ tick: {
86
+ fill: "var(--color-text-secondary)",
87
+ fontSize: 12
88
+ },
89
+ tickLine: { stroke: "var(--color-border-default)" },
90
+ axisLine: { stroke: "var(--color-border-default)" },
91
+ tickFormatter: C,
92
+ scale: g.logScale ? "log" : "auto",
93
+ domain: g.logScale ? ["auto", "auto"] : void 0
94
+ }),
95
+ b && /* @__PURE__ */ i(m, {
96
+ type: "number",
97
+ dataKey: b,
98
+ range: [40, 400],
99
+ name: b
100
+ }),
101
+ /* @__PURE__ */ i(d, {
102
+ content: /* @__PURE__ */ i(e, { valueFormatter: C }),
103
+ cursor: {
104
+ strokeDasharray: "3 3",
105
+ stroke: "var(--color-border-default)"
106
+ }
107
+ }),
108
+ S.length > 1 && g.showLegend !== !1 && /* @__PURE__ */ i(s, { formatter: (e) => /* @__PURE__ */ i("span", {
109
+ style: { color: "var(--color-text-primary)" },
110
+ children: e
111
+ }) }),
112
+ t(g.referenceLines),
113
+ S.map((e, t) => /* @__PURE__ */ i(l, {
114
+ name: e.name,
115
+ data: e.points,
116
+ fill: g.colors?.[t] || h[t % h.length],
117
+ onClick: (e) => {
118
+ _ && e?.payload && _(e.payload, 0);
119
+ }
120
+ }, e.name))
121
+ ]
122
+ })
123
+ }) : null;
124
+ });
125
+ //#endregion
126
+ export { g as default };
127
+
128
+ //# sourceMappingURL=ScatterChart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScatterChart.js","names":[],"sources":["../../../../../../src/bigconsole/components/widgets/chart/charts/ScatterChart.tsx"],"sourcesContent":["/**\n * ScatterChart Component\n *\n * Scatter / bubble chart using Recharts `ScatterChart`. Plots `xField` vs\n * `yField`; an optional `sizeField` drives bubble radius (ZAxis) and an\n * optional `colorField` splits points into colored groups.\n */\n\nimport { type FC, memo, useMemo } from 'react';\nimport {\n ScatterChart as RechartsScatterChart,\n Scatter,\n XAxis,\n YAxis,\n ZAxis,\n CartesianGrid,\n Tooltip,\n ResponsiveContainer,\n Legend,\n} from 'recharts';\nimport { ChartTooltip } from '../ChartTooltip';\nimport type { ChartConfig, ChartData } from './types';\nimport { buildReferenceElements } from './referenceElements';\n\nexport interface ScatterChartProps {\n data: ChartData[];\n config: ChartConfig;\n hiddenSeries?: string[];\n onDataClick?: (data: ChartData, index: number) => void;\n}\n\nconst DEFAULT_COLORS = [\n 'var(--color-chart-1)',\n 'var(--color-chart-2)',\n 'var(--color-chart-3)',\n 'var(--color-chart-4)',\n 'var(--color-chart-5)',\n];\n\nexport const ScatterChart: FC<ScatterChartProps> = memo(function ScatterChart({ data = [], config, onDataClick }) {\n // Resolve axis fields, falling back to the first two numeric fields.\n const { xKey, yKey } = useMemo(() => {\n if (config.xField && config.yField) return { xKey: config.xField, yKey: config.yField };\n const numeric = data.length ? Object.keys(data[0]).filter((k) => typeof data[0][k] === 'number') : [];\n return { xKey: config.xField || numeric[0] || 'x', yKey: config.yField || numeric[1] || 'y' };\n }, [config.xField, config.yField, data]);\n\n const sizeKey = config.sizeField;\n const colorKey = config.colorField;\n\n // Group points by colorField (single group when absent).\n const groups = useMemo(() => {\n if (!colorKey) return [{ name: config.seriesNames?.[yKey] || yKey, points: data }];\n const map = new Map<string, ChartData[]>();\n for (const row of data) {\n const key = String(row[colorKey] ?? '—');\n if (!map.has(key)) map.set(key, []);\n map.get(key)!.push(row);\n }\n return Array.from(map.entries()).map(([name, points]) => ({ name, points }));\n }, [data, colorKey, yKey, config.seriesNames]);\n\n const formatValue = (value: number | string): string => {\n if (typeof value !== 'number') return String(value);\n return new Intl.NumberFormat('en-US', {\n notation: Math.abs(value) >= 10000 ? 'compact' : 'standard',\n maximumFractionDigits: 2,\n }).format(value);\n };\n\n if (!data?.length) return null;\n\n return (\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsScatterChart margin={{ top: 10, right: 10, left: 0, bottom: 0 }}>\n {config.showGrid !== false && (\n <CartesianGrid strokeDasharray=\"3 3\" stroke=\"var(--color-border-default)\" opacity={0.5} />\n )}\n <XAxis\n type=\"number\"\n dataKey={xKey}\n name={config.xAxisLabel || xKey}\n tick={{ fill: 'var(--color-text-secondary)', fontSize: 12 }}\n tickLine={{ stroke: 'var(--color-border-default)' }}\n axisLine={{ stroke: 'var(--color-border-default)' }}\n tickFormatter={formatValue}\n scale={config.logScale ? 'log' : 'auto'}\n domain={config.logScale ? ['auto', 'auto'] : undefined}\n />\n <YAxis\n type=\"number\"\n dataKey={yKey}\n name={config.yAxisLabel || yKey}\n tick={{ fill: 'var(--color-text-secondary)', fontSize: 12 }}\n tickLine={{ stroke: 'var(--color-border-default)' }}\n axisLine={{ stroke: 'var(--color-border-default)' }}\n tickFormatter={formatValue}\n scale={config.logScale ? 'log' : 'auto'}\n domain={config.logScale ? ['auto', 'auto'] : undefined}\n />\n {sizeKey && <ZAxis type=\"number\" dataKey={sizeKey} range={[40, 400]} name={sizeKey} />}\n <Tooltip\n content={<ChartTooltip valueFormatter={formatValue} />}\n cursor={{ strokeDasharray: '3 3', stroke: 'var(--color-border-default)' }}\n />\n {groups.length > 1 && config.showLegend !== false && (\n <Legend formatter={(value) => <span style={{ color: 'var(--color-text-primary)' }}>{value}</span>} />\n )}\n {buildReferenceElements(config.referenceLines)}\n {groups.map((g, i) => (\n <Scatter\n key={g.name}\n name={g.name}\n data={g.points}\n fill={config.colors?.[i] || DEFAULT_COLORS[i % DEFAULT_COLORS.length]}\n onClick={(point) => {\n if (onDataClick && point?.payload) onDataClick(point.payload as ChartData, 0);\n }}\n />\n ))}\n </RechartsScatterChart>\n </ResponsiveContainer>\n );\n});\n\nexport default ScatterChart;\n"],"mappings":"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"}
@@ -0,0 +1,111 @@
1
+ import e from "../ChartTooltip.js";
2
+ import { buildReferenceElements as t } from "./referenceElements.js";
3
+ import { memo as n, useMemo as r } from "react";
4
+ import { jsx as i, jsxs as a } from "react/jsx-runtime";
5
+ import { Bar as o, BarChart as s, CartesianGrid as c, Cell as l, ResponsiveContainer as u, Tooltip as d, XAxis as f, YAxis as p } from "recharts";
6
+ //#region src/bigconsole/components/widgets/chart/charts/WaterfallChart.tsx
7
+ var m = "var(--color-status-success)", h = "var(--color-status-error)", g = "var(--color-chart-1)", _ = n(function({ data: n = [], config: _, onDataClick: v }) {
8
+ let y = _.labelField || _.xAxisKey || "name", b = _.valueField || "value", x = r(() => {
9
+ if (!n.length) return [];
10
+ let e = 0, t = n.map((t) => {
11
+ let n = typeof t[b] == "number" ? t[b] : Number(t[b]) || 0, r = n >= 0 ? e : e + n;
12
+ return e += n, {
13
+ name: String(t[y] ?? ""),
14
+ base: r,
15
+ delta: Math.abs(n),
16
+ cumulative: e,
17
+ isTotal: !1,
18
+ sign: n >= 0 ? "up" : "down"
19
+ };
20
+ });
21
+ return _.showTotal && t.push({
22
+ name: _.totalLabel || "Total",
23
+ base: 0,
24
+ delta: e,
25
+ cumulative: e,
26
+ isTotal: !0,
27
+ sign: "total"
28
+ }), t;
29
+ }, [
30
+ n,
31
+ y,
32
+ b,
33
+ _.showTotal,
34
+ _.totalLabel
35
+ ]), S = (e) => typeof e == "number" ? new Intl.NumberFormat("en-US", {
36
+ notation: Math.abs(e) >= 1e4 ? "compact" : "standard",
37
+ maximumFractionDigits: 2
38
+ }).format(e) : String(e);
39
+ return x.length ? /* @__PURE__ */ i(u, {
40
+ width: "100%",
41
+ height: "100%",
42
+ children: /* @__PURE__ */ a(s, {
43
+ data: x,
44
+ margin: {
45
+ top: 10,
46
+ right: 10,
47
+ left: 0,
48
+ bottom: 0
49
+ },
50
+ onClick: (e) => {
51
+ e?.activePayload?.[0] && v && v(e.activePayload[0].payload, e.activeTooltipIndex || 0);
52
+ },
53
+ children: [
54
+ _.showGrid !== !1 && /* @__PURE__ */ i(c, {
55
+ strokeDasharray: "3 3",
56
+ stroke: "var(--color-border-default)",
57
+ opacity: .5,
58
+ vertical: !1
59
+ }),
60
+ /* @__PURE__ */ i(f, {
61
+ dataKey: "name",
62
+ tick: {
63
+ fill: "var(--color-text-secondary)",
64
+ fontSize: 12
65
+ },
66
+ tickLine: { stroke: "var(--color-border-default)" },
67
+ axisLine: { stroke: "var(--color-border-default)" }
68
+ }),
69
+ /* @__PURE__ */ i(p, {
70
+ tick: {
71
+ fill: "var(--color-text-secondary)",
72
+ fontSize: 12
73
+ },
74
+ tickLine: { stroke: "var(--color-border-default)" },
75
+ axisLine: { stroke: "var(--color-border-default)" },
76
+ tickFormatter: S
77
+ }),
78
+ /* @__PURE__ */ i(d, {
79
+ content: /* @__PURE__ */ i(e, { valueFormatter: S }),
80
+ cursor: {
81
+ fill: "var(--color-bg-muted)",
82
+ opacity: .5
83
+ }
84
+ }),
85
+ t(_.referenceLines),
86
+ /* @__PURE__ */ i(o, {
87
+ dataKey: "base",
88
+ stackId: "wf",
89
+ fill: "transparent",
90
+ isAnimationActive: !1
91
+ }),
92
+ /* @__PURE__ */ i(o, {
93
+ dataKey: "delta",
94
+ stackId: "wf",
95
+ radius: [
96
+ 4,
97
+ 4,
98
+ 0,
99
+ 0
100
+ ],
101
+ name: "Change",
102
+ children: x.map((e, t) => /* @__PURE__ */ i(l, { fill: e.sign === "total" ? g : e.sign === "up" ? m : h }, t))
103
+ })
104
+ ]
105
+ })
106
+ }) : null;
107
+ });
108
+ //#endregion
109
+ export { _ as default };
110
+
111
+ //# sourceMappingURL=WaterfallChart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WaterfallChart.js","names":[],"sources":["../../../../../../src/bigconsole/components/widgets/chart/charts/WaterfallChart.tsx"],"sourcesContent":["/**\n * WaterfallChart Component\n *\n * Bridge / waterfall chart (budget-vs-actual, P&L) using a Recharts stacked\n * BarChart: a transparent \"base\" bar floats each visible delta bar to its\n * running cumulative position. Positive steps render success-toned, negative\n * steps danger-toned, and an optional final bar shows the cumulative total.\n */\n\nimport { type FC, memo, useMemo } from 'react';\nimport {\n BarChart as RechartsBarChart,\n Bar,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n ResponsiveContainer,\n Cell,\n} from 'recharts';\nimport { ChartTooltip } from '../ChartTooltip';\nimport type { ChartConfig, ChartData } from './types';\nimport { buildReferenceElements } from './referenceElements';\n\nexport interface WaterfallChartProps {\n data: ChartData[];\n config: ChartConfig;\n hiddenSeries?: string[];\n onDataClick?: (data: ChartData, index: number) => void;\n}\n\ninterface WaterfallRow {\n name: string;\n base: number;\n delta: number;\n cumulative: number;\n isTotal: boolean;\n sign: 'up' | 'down' | 'total';\n}\n\nconst COLOR_UP = 'var(--color-status-success)';\nconst COLOR_DOWN = 'var(--color-status-error)';\nconst COLOR_TOTAL = 'var(--color-chart-1)';\n\nexport const WaterfallChart: FC<WaterfallChartProps> = memo(function WaterfallChart({\n data = [],\n config,\n onDataClick,\n}) {\n const labelKey = config.labelField || config.xAxisKey || 'name';\n const valueKey = config.valueField || 'value';\n\n const rows: WaterfallRow[] = useMemo(() => {\n if (!data.length) return [];\n let cumulative = 0;\n const out: WaterfallRow[] = data.map((d) => {\n const delta = typeof d[valueKey] === 'number' ? (d[valueKey] as number) : Number(d[valueKey]) || 0;\n const base = delta >= 0 ? cumulative : cumulative + delta;\n cumulative += delta;\n return {\n name: String(d[labelKey] ?? ''),\n base,\n delta: Math.abs(delta),\n cumulative,\n isTotal: false,\n sign: delta >= 0 ? 'up' : 'down',\n };\n });\n if (config.showTotal) {\n out.push({\n name: config.totalLabel || 'Total',\n base: 0,\n delta: cumulative,\n cumulative,\n isTotal: true,\n sign: 'total',\n });\n }\n return out;\n }, [data, labelKey, valueKey, config.showTotal, config.totalLabel]);\n\n const formatValue = (value: number | string): string => {\n if (typeof value !== 'number') return String(value);\n return new Intl.NumberFormat('en-US', {\n notation: Math.abs(value) >= 10000 ? 'compact' : 'standard',\n maximumFractionDigits: 2,\n }).format(value);\n };\n\n if (!rows.length) return null;\n\n return (\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsBarChart\n data={rows}\n margin={{ top: 10, right: 10, left: 0, bottom: 0 }}\n onClick={(e) => {\n if (e?.activePayload?.[0] && onDataClick) {\n onDataClick(e.activePayload[0].payload, e.activeTooltipIndex || 0);\n }\n }}\n >\n {config.showGrid !== false && (\n <CartesianGrid strokeDasharray=\"3 3\" stroke=\"var(--color-border-default)\" opacity={0.5} vertical={false} />\n )}\n <XAxis\n dataKey=\"name\"\n tick={{ fill: 'var(--color-text-secondary)', fontSize: 12 }}\n tickLine={{ stroke: 'var(--color-border-default)' }}\n axisLine={{ stroke: 'var(--color-border-default)' }}\n />\n <YAxis\n tick={{ fill: 'var(--color-text-secondary)', fontSize: 12 }}\n tickLine={{ stroke: 'var(--color-border-default)' }}\n axisLine={{ stroke: 'var(--color-border-default)' }}\n tickFormatter={formatValue}\n />\n <Tooltip\n content={<ChartTooltip valueFormatter={formatValue} />}\n cursor={{ fill: 'var(--color-bg-muted)', opacity: 0.5 }}\n />\n {buildReferenceElements(config.referenceLines)}\n {/* Transparent floating base */}\n <Bar dataKey=\"base\" stackId=\"wf\" fill=\"transparent\" isAnimationActive={false} />\n {/* Visible delta, colored by direction */}\n <Bar dataKey=\"delta\" stackId=\"wf\" radius={[4, 4, 0, 0]} name=\"Change\">\n {rows.map((r, i) => (\n <Cell key={i} fill={r.sign === 'total' ? COLOR_TOTAL : r.sign === 'up' ? COLOR_UP : COLOR_DOWN} />\n ))}\n </Bar>\n </RechartsBarChart>\n </ResponsiveContainer>\n );\n});\n\nexport default WaterfallChart;\n"],"mappings":";;;;;;AAwCA,IAAM,IAAW,+BACX,IAAa,6BACb,IAAc,wBAEP,IAA0C,EAAK,SAAwB,EAClF,UAAO,EAAE,EACT,WACA,kBACC;CACD,IAAM,IAAW,EAAO,cAAc,EAAO,YAAY,QACnD,IAAW,EAAO,cAAc,SAEhC,IAAuB,QAAc;AACzC,MAAI,CAAC,EAAK,OAAQ,QAAO,EAAE;EAC3B,IAAI,IAAa,GACX,IAAsB,EAAK,KAAK,MAAM;GAC1C,IAAM,IAAQ,OAAO,EAAE,MAAc,WAAY,EAAE,KAAuB,OAAO,EAAE,GAAU,IAAI,GAC3F,IAAO,KAAS,IAAI,IAAa,IAAa;AAEpD,UADA,KAAc,GACP;IACL,MAAM,OAAO,EAAE,MAAa,GAAG;IAC/B;IACA,OAAO,KAAK,IAAI,EAAM;IACtB;IACA,SAAS;IACT,MAAM,KAAS,IAAI,OAAO;IAC3B;IACD;AAWF,SAVI,EAAO,aACT,EAAI,KAAK;GACP,MAAM,EAAO,cAAc;GAC3B,MAAM;GACN,OAAO;GACP;GACA,SAAS;GACT,MAAM;GACP,CAAC,EAEG;IACN;EAAC;EAAM;EAAU;EAAU,EAAO;EAAW,EAAO;EAAW,CAAC,EAE7D,KAAe,MACf,OAAO,KAAU,WACd,IAAI,KAAK,aAAa,SAAS;EACpC,UAAU,KAAK,IAAI,EAAM,IAAI,MAAQ,YAAY;EACjD,uBAAuB;EACxB,CAAC,CAAC,OAAO,EAAM,GAJsB,OAAO,EAAM;AASrD,QAFK,EAAK,SAGR,kBAAC,GAAD;EAAqB,OAAM;EAAO,QAAO;YACvC,kBAAC,GAAD;GACE,MAAM;GACN,QAAQ;IAAE,KAAK;IAAI,OAAO;IAAI,MAAM;IAAG,QAAQ;IAAG;GAClD,UAAU,MAAM;AACd,IAAI,GAAG,gBAAgB,MAAM,KAC3B,EAAY,EAAE,cAAc,GAAG,SAAS,EAAE,sBAAsB,EAAE;;aALxE;IASG,EAAO,aAAa,MACnB,kBAAC,GAAD;KAAe,iBAAgB;KAAM,QAAO;KAA8B,SAAS;KAAK,UAAU;KAAS,CAAA;IAE7G,kBAAC,GAAD;KACE,SAAQ;KACR,MAAM;MAAE,MAAM;MAA+B,UAAU;MAAI;KAC3D,UAAU,EAAE,QAAQ,+BAA+B;KACnD,UAAU,EAAE,QAAQ,+BAA+B;KACnD,CAAA;IACF,kBAAC,GAAD;KACE,MAAM;MAAE,MAAM;MAA+B,UAAU;MAAI;KAC3D,UAAU,EAAE,QAAQ,+BAA+B;KACnD,UAAU,EAAE,QAAQ,+BAA+B;KACnD,eAAe;KACf,CAAA;IACF,kBAAC,GAAD;KACE,SAAS,kBAAC,GAAD,EAAc,gBAAgB,GAAe,CAAA;KACtD,QAAQ;MAAE,MAAM;MAAyB,SAAS;MAAK;KACvD,CAAA;IACD,EAAuB,EAAO,eAAe;IAE9C,kBAAC,GAAD;KAAK,SAAQ;KAAO,SAAQ;KAAK,MAAK;KAAc,mBAAmB;KAAS,CAAA;IAEhF,kBAAC,GAAD;KAAK,SAAQ;KAAQ,SAAQ;KAAK,QAAQ;MAAC;MAAG;MAAG;MAAG;MAAE;KAAE,MAAK;eAC1D,EAAK,KAAK,GAAG,MACZ,kBAAC,GAAD,EAAc,MAAM,EAAE,SAAS,UAAU,IAAc,EAAE,SAAS,OAAO,IAAW,GAAc,EAAvF,EAAuF,CAClG;KACE,CAAA;IACW;;EACC,CAAA,GA1CC;EA4CzB"}
@@ -1,5 +1,9 @@
1
+ import "./referenceElements.js";
1
2
  import "./LineChart.js";
2
3
  import "./BarChart.js";
3
4
  import "./AreaChart.js";
4
5
  import "./PieChart.js";
5
6
  import "./FunnelChart.js";
7
+ import "./ComboChart.js";
8
+ import "./WaterfallChart.js";
9
+ import "./ScatterChart.js";
@@ -0,0 +1,49 @@
1
+ import { intentToCssVar as e } from "../../utils/conditionalFormat.js";
2
+ import { jsx as t } from "react/jsx-runtime";
3
+ import { ReferenceArea as n, ReferenceLine as r } from "recharts";
4
+ //#region src/bigconsole/components/widgets/chart/charts/referenceElements.tsx
5
+ function i(i, a) {
6
+ return i?.length ? i.map((i, o) => {
7
+ let s = e(i.color ?? "danger"), c = (i.axis ?? "y") === "y", l = a?.yAxisId;
8
+ if (i.value2 != null) {
9
+ let e = Math.min(i.value, i.value2), r = Math.max(i.value, i.value2);
10
+ return /* @__PURE__ */ t(n, {
11
+ ...c ? {
12
+ y1: e,
13
+ y2: r
14
+ } : {
15
+ x1: e,
16
+ x2: r
17
+ },
18
+ ...l == null ? {} : { yAxisId: l },
19
+ fill: s,
20
+ fillOpacity: .1,
21
+ stroke: s,
22
+ strokeOpacity: .3,
23
+ label: i.label ? {
24
+ value: i.label,
25
+ fill: s,
26
+ fontSize: 11,
27
+ position: "insideTopLeft"
28
+ } : void 0
29
+ }, `ref-band-${o}`);
30
+ }
31
+ return /* @__PURE__ */ t(r, {
32
+ ...c ? { y: i.value } : { x: i.value },
33
+ ...l == null ? {} : { yAxisId: l },
34
+ stroke: s,
35
+ strokeWidth: 1.5,
36
+ strokeDasharray: i.dashed === !1 ? void 0 : "6 4",
37
+ label: i.label ? {
38
+ value: i.label,
39
+ fill: s,
40
+ fontSize: 11,
41
+ position: "right"
42
+ } : void 0
43
+ }, `ref-line-${o}`);
44
+ }) : [];
45
+ }
46
+ //#endregion
47
+ export { i as buildReferenceElements };
48
+
49
+ //# sourceMappingURL=referenceElements.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"referenceElements.js","names":[],"sources":["../../../../../../src/bigconsole/components/widgets/chart/charts/referenceElements.tsx"],"sourcesContent":["/**\n * Reference / threshold line & band helpers (Recharts).\n *\n * Builds `ReferenceLine` / `ReferenceArea` elements from a widget's\n * `config.referenceLines`. Colors are resolved from semantic intents so\n * targets / control limits / SLAs stay theme-aware.\n */\n\nimport { ReferenceLine, ReferenceArea } from 'recharts';\nimport type { ReactElement } from 'react';\nimport { intentToCssVar, type SemanticIntent } from '../../utils/conditionalFormat';\n\nexport interface ReferenceLineConfig {\n axis?: 'x' | 'y';\n value: number;\n value2?: number;\n label?: string;\n color?: SemanticIntent;\n dashed?: boolean;\n}\n\n/**\n * Build reference line/band elements for a cartesian chart.\n * `yAxisIds` lets dual-axis charts target the correct axis (defaults to none).\n */\nexport function buildReferenceElements(\n referenceLines: ReferenceLineConfig[] | undefined,\n opts?: { yAxisId?: string | number }\n): ReactElement[] {\n if (!referenceLines?.length) return [];\n\n return referenceLines.map((ref, index) => {\n const color = intentToCssVar(ref.color ?? 'danger');\n const onY = (ref.axis ?? 'y') === 'y';\n const yAxisId = opts?.yAxisId;\n\n // Band (shaded area) when a second bound is supplied.\n if (ref.value2 != null) {\n const lo = Math.min(ref.value, ref.value2);\n const hi = Math.max(ref.value, ref.value2);\n return (\n <ReferenceArea\n key={`ref-band-${index}`}\n {...(onY ? { y1: lo, y2: hi } : { x1: lo, x2: hi })}\n {...(yAxisId != null ? { yAxisId } : {})}\n fill={color}\n fillOpacity={0.1}\n stroke={color}\n strokeOpacity={0.3}\n label={ref.label ? { value: ref.label, fill: color, fontSize: 11, position: 'insideTopLeft' } : undefined}\n />\n );\n }\n\n return (\n <ReferenceLine\n key={`ref-line-${index}`}\n {...(onY ? { y: ref.value } : { x: ref.value })}\n {...(yAxisId != null ? { yAxisId } : {})}\n stroke={color}\n strokeWidth={1.5}\n strokeDasharray={ref.dashed === false ? undefined : '6 4'}\n label={ref.label ? { value: ref.label, fill: color, fontSize: 11, position: 'right' } : undefined}\n />\n );\n });\n}\n"],"mappings":";;;;AAyBA,SAAgB,EACd,GACA,GACgB;AAGhB,QAFK,GAAgB,SAEd,EAAe,KAAK,GAAK,MAAU;EACxC,IAAM,IAAQ,EAAe,EAAI,SAAS,SAAS,EAC7C,KAAO,EAAI,QAAQ,SAAS,KAC5B,IAAU,GAAM;AAGtB,MAAI,EAAI,UAAU,MAAM;GACtB,IAAM,IAAK,KAAK,IAAI,EAAI,OAAO,EAAI,OAAO,EACpC,IAAK,KAAK,IAAI,EAAI,OAAO,EAAI,OAAO;AAC1C,UACE,kBAAC,GAAD;IAEE,GAAK,IAAM;KAAE,IAAI;KAAI,IAAI;KAAI,GAAG;KAAE,IAAI;KAAI,IAAI;KAAI;IAClD,GAAK,KAAW,OAAqB,EAAE,GAAhB,EAAE,YAAS;IAClC,MAAM;IACN,aAAa;IACb,QAAQ;IACR,eAAe;IACf,OAAO,EAAI,QAAQ;KAAE,OAAO,EAAI;KAAO,MAAM;KAAO,UAAU;KAAI,UAAU;KAAiB,GAAG,KAAA;IAChG,EARK,YAAY,IAQjB;;AAIN,SACE,kBAAC,GAAD;GAEE,GAAK,IAAM,EAAE,GAAG,EAAI,OAAO,GAAG,EAAE,GAAG,EAAI,OAAO;GAC9C,GAAK,KAAW,OAAqB,EAAE,GAAhB,EAAE,YAAS;GAClC,QAAQ;GACR,aAAa;GACb,iBAAiB,EAAI,WAAW,KAAQ,KAAA,IAAY;GACpD,OAAO,EAAI,QAAQ;IAAE,OAAO,EAAI;IAAO,MAAM;IAAO,UAAU;IAAI,UAAU;IAAS,GAAG,KAAA;GACxF,EAPK,YAAY,IAOjB;GAEJ,GApCkC,EAAE"}
@@ -1,7 +1,8 @@
1
- import { memo as e } from "react";
2
- import { jsx as t, jsxs as n } from "react/jsx-runtime";
1
+ import { conditionalStyleToClassName as e, resolveConditionalStyle as t } from "../utils/conditionalFormat.js";
2
+ import { memo as n } from "react";
3
+ import { jsx as r, jsxs as i } from "react/jsx-runtime";
3
4
  //#region src/bigconsole/components/widgets/kpi-comparison/KPIComparisonWidget.tsx
4
- function r(e, t) {
5
+ function a(e, t) {
5
6
  return t === "$" ? new Intl.NumberFormat("en-US", {
6
7
  style: "currency",
7
8
  currency: "USD",
@@ -12,21 +13,21 @@ function r(e, t) {
12
13
  maximumFractionDigits: 1
13
14
  }).format(e);
14
15
  }
15
- function i(e, t) {
16
+ function o(e, t) {
16
17
  return !e || e === "stable" ? "text-text-secondary" : e === "up" && (t ?? 0) >= 0 ? "text-state-success" : e === "down" && (t ?? 0) < 0 ? "text-state-error" : "text-text-secondary";
17
18
  }
18
- function a(e) {
19
+ function s(e) {
19
20
  return e === "up" ? "↑" : e === "down" ? "↓" : "→";
20
21
  }
21
- var o = e(function({ widget: e, data: o, onClick: s, onDrilldown: c }) {
22
- let l = !!e.drilldown?.enabled, u = e.config, d = [], f = u?.valueField || u?.value_field || "value", p = u?.labelField || u?.label_field || "label", m = (e) => Object.entries(e).filter(([, e]) => typeof e == "number").map(([e, t]) => ({
22
+ var c = n(function({ widget: n, data: c, onClick: l, onDrilldown: u }) {
23
+ let d = !!n.drilldown?.enabled, f = n.config, p = f?.conditionalRules, m = [], h = f?.valueField || f?.value_field || "value", g = f?.labelField || f?.label_field || "label", _ = (e) => Object.entries(e).filter(([, e]) => typeof e == "number").map(([e, t]) => ({
23
24
  id: e,
24
25
  label: e.replace(/([A-Z])/g, " $1").replace(/^./, (e) => e.toUpperCase()),
25
26
  value: t,
26
27
  unit: e.toLowerCase().includes("sales") || e.toLowerCase().includes("revenue") || e.toLowerCase().includes("value") ? "$" : void 0
27
- })), h = (e, t) => {
28
+ })), v = (e, t) => {
28
29
  let n = [
29
- f,
30
+ h,
30
31
  "value",
31
32
  "revenue",
32
33
  "amount",
@@ -51,7 +52,7 @@ var o = e(function({ widget: e, data: o, onClick: s, onDrilldown: c }) {
51
52
  }
52
53
  if (r === null) return null;
53
54
  let i = [
54
- p,
55
+ g,
55
56
  "label",
56
57
  "name",
57
58
  "title",
@@ -68,24 +69,24 @@ var o = e(function({ widget: e, data: o, onClick: s, onDrilldown: c }) {
68
69
  id: `kpi-${t}`,
69
70
  label: a,
70
71
  value: r,
71
- unit: f.toLowerCase().includes("revenue") || f.toLowerCase().includes("sales") ? "$" : void 0,
72
+ unit: h.toLowerCase().includes("revenue") || h.toLowerCase().includes("sales") ? "$" : void 0,
72
73
  trend: s,
73
74
  trendValue: typeof o == "number" ? o : void 0
74
75
  };
75
76
  };
76
- if (o?.kpis && Array.isArray(o.kpis)) d = o.kpis;
77
- else if (Array.isArray(o) && o.length > 0) {
78
- for (let e = 0; e < Math.min(o.length, 4); e++) {
79
- let t = o[e];
77
+ if (c?.kpis && Array.isArray(c.kpis)) m = c.kpis;
78
+ else if (Array.isArray(c) && c.length > 0) {
79
+ for (let e = 0; e < Math.min(c.length, 4); e++) {
80
+ let t = c[e];
80
81
  if (t && typeof t == "object") {
81
- let n = h(t, e);
82
- n && d.push(n);
82
+ let n = v(t, e);
83
+ n && m.push(n);
83
84
  }
84
85
  }
85
- if (d.length === 0 && o.length > 0) {
86
- let e = o[0];
87
- d = Object.entries(e).filter(([, e]) => typeof e == "number").slice(0, 4).map(([e]) => {
88
- let t = o.reduce((t, n) => {
86
+ if (m.length === 0 && c.length > 0) {
87
+ let e = c[0];
88
+ m = Object.entries(e).filter(([, e]) => typeof e == "number").slice(0, 4).map(([e]) => {
89
+ let t = c.reduce((t, n) => {
89
90
  let r = n[e];
90
91
  return t + (typeof r == "number" ? r : 0);
91
92
  }, 0);
@@ -97,92 +98,95 @@ var o = e(function({ widget: e, data: o, onClick: s, onDrilldown: c }) {
97
98
  };
98
99
  });
99
100
  }
100
- } else if (typeof o == "number" || typeof o == "string") {
101
- let t = typeof o == "string" ? parseFloat(o) : o;
102
- isNaN(t) || (d = [{
101
+ } else if (typeof c == "number" || typeof c == "string") {
102
+ let e = typeof c == "string" ? parseFloat(c) : c;
103
+ isNaN(e) || (m = [{
103
104
  id: "primary",
104
- label: (u?.subtitle || e.title || "Value").trim(),
105
- value: t,
106
- unit: u?.format === "currency" ? "$" : u?.format === "percent" ? "%" : void 0
105
+ label: (f?.subtitle || n.title || "Value").trim(),
106
+ value: e,
107
+ unit: f?.format === "currency" ? "$" : f?.format === "percent" ? "%" : void 0
107
108
  }]);
108
- } else if (o && typeof o == "object" && !Array.isArray(o)) {
109
- let e = o;
110
- "summary" in e && e.summary && typeof e.summary == "object" && (d = m(e.summary)), d.length === 0 && (d = m(e));
109
+ } else if (c && typeof c == "object" && !Array.isArray(c)) {
110
+ let e = c;
111
+ "summary" in e && e.summary && typeof e.summary == "object" && (m = _(e.summary)), m.length === 0 && (m = _(e));
111
112
  }
112
- return d.length ? /* @__PURE__ */ t("div", {
113
+ return m.length ? /* @__PURE__ */ r("div", {
113
114
  className: "h-full p-4 overflow-auto",
114
- children: /* @__PURE__ */ t("div", {
115
+ children: /* @__PURE__ */ r("div", {
115
116
  className: "grid grid-cols-2 gap-3",
116
- children: d.map((e) => /* @__PURE__ */ n("div", {
117
+ children: m.map((n) => /* @__PURE__ */ i("div", {
117
118
  className: `
118
119
  p-3 rounded-lg border border-border-default bg-bg-muted/30
119
- ${s || l ? "cursor-pointer hover:border-action-primary-bg transition-colors" : ""}
120
+ ${l || d ? "cursor-pointer hover:border-action-primary-bg transition-colors" : ""}
120
121
  `,
121
122
  onClick: () => {
122
- l && c && c({
123
- kpiId: e.id,
124
- kpiLabel: e.label,
125
- kpiValue: e.value,
126
- kpiUnit: e.unit,
127
- kpiTrend: e.trend,
128
- kpiTrendValue: e.trendValue,
129
- kpiTarget: e.target,
130
- kpiPreviousValue: e.previousValue
131
- }), s?.(e);
123
+ d && u && u({
124
+ kpiId: n.id,
125
+ kpiLabel: n.label,
126
+ kpiValue: n.value,
127
+ kpiUnit: n.unit,
128
+ kpiTrend: n.trend,
129
+ kpiTrendValue: n.trendValue,
130
+ kpiTarget: n.target,
131
+ kpiPreviousValue: n.previousValue
132
+ }), l?.(n);
132
133
  },
133
134
  children: [
134
- /* @__PURE__ */ t("p", {
135
+ /* @__PURE__ */ r("p", {
135
136
  className: "text-xs text-text-secondary truncate mb-1",
136
- children: e.label
137
+ children: n.label
137
138
  }),
138
- /* @__PURE__ */ t("p", {
139
- className: "text-xl font-semibold text-text-primary",
140
- children: r(e.value, e.unit)
139
+ /* @__PURE__ */ r("p", {
140
+ className: `text-xl font-semibold ${e(t(n.value, p, {
141
+ [n.label]: n.value,
142
+ value: n.value
143
+ })) || "text-text-primary"}`,
144
+ children: a(n.value, n.unit)
141
145
  }),
142
- e.trendValue !== void 0 && /* @__PURE__ */ n("div", {
143
- className: `flex items-center gap-1 mt-1 text-xs ${i(e.trend, e.trendValue)}`,
144
- children: [/* @__PURE__ */ t("span", { children: a(e.trend) }), /* @__PURE__ */ n("span", { children: [
145
- e.trendValue >= 0 ? "+" : "",
146
- e.trendValue.toFixed(1),
146
+ n.trendValue !== void 0 && /* @__PURE__ */ i("div", {
147
+ className: `flex items-center gap-1 mt-1 text-xs ${o(n.trend, n.trendValue)}`,
148
+ children: [/* @__PURE__ */ r("span", { children: s(n.trend) }), /* @__PURE__ */ i("span", { children: [
149
+ n.trendValue >= 0 ? "+" : "",
150
+ n.trendValue.toFixed(1),
147
151
  "%"
148
152
  ] })]
149
153
  }),
150
- e.target !== void 0 && /* @__PURE__ */ n("div", {
154
+ n.target !== void 0 && /* @__PURE__ */ i("div", {
151
155
  className: "mt-2",
152
- children: [/* @__PURE__ */ n("div", {
156
+ children: [/* @__PURE__ */ i("div", {
153
157
  className: "flex justify-between text-[10px] text-text-tertiary mb-0.5",
154
- children: [/* @__PURE__ */ t("span", { children: "vs target" }), /* @__PURE__ */ n("span", { children: [(e.value / e.target * 100).toFixed(0), "%"] })]
155
- }), /* @__PURE__ */ t("div", {
158
+ children: [/* @__PURE__ */ r("span", { children: "vs target" }), /* @__PURE__ */ i("span", { children: [(n.value / n.target * 100).toFixed(0), "%"] })]
159
+ }), /* @__PURE__ */ r("div", {
156
160
  className: "h-1 bg-bg-muted rounded-full overflow-hidden",
157
- children: /* @__PURE__ */ t("div", {
158
- className: `h-full rounded-full ${e.value >= e.target ? "bg-state-success" : "bg-action-primary-bg"}`,
159
- style: { width: `${Math.min(e.value / e.target * 100, 100)}%` }
161
+ children: /* @__PURE__ */ r("div", {
162
+ className: `h-full rounded-full ${n.value >= n.target ? "bg-state-success" : "bg-action-primary-bg"}`,
163
+ style: { width: `${Math.min(n.value / n.target * 100, 100)}%` }
160
164
  })
161
165
  })]
162
166
  })
163
167
  ]
164
- }, e.id))
168
+ }, n.id))
165
169
  })
166
- }) : /* @__PURE__ */ t("div", {
170
+ }) : /* @__PURE__ */ r("div", {
167
171
  className: "flex items-center justify-center h-full text-text-secondary text-sm",
168
- children: /* @__PURE__ */ n("div", {
172
+ children: /* @__PURE__ */ i("div", {
169
173
  className: "text-center",
170
- children: [/* @__PURE__ */ t("svg", {
174
+ children: [/* @__PURE__ */ r("svg", {
171
175
  className: "w-12 h-12 mx-auto mb-2 text-text-tertiary",
172
176
  fill: "none",
173
177
  stroke: "currentColor",
174
178
  viewBox: "0 0 24 24",
175
- children: /* @__PURE__ */ t("path", {
179
+ children: /* @__PURE__ */ r("path", {
176
180
  strokeLinecap: "round",
177
181
  strokeLinejoin: "round",
178
182
  strokeWidth: 1.5,
179
183
  d: "M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"
180
184
  })
181
- }), /* @__PURE__ */ t("p", { children: "No KPI data" })]
185
+ }), /* @__PURE__ */ r("p", { children: "No KPI data" })]
182
186
  })
183
187
  });
184
188
  });
185
189
  //#endregion
186
- export { o as default };
190
+ export { c as default };
187
191
 
188
192
  //# sourceMappingURL=KPIComparisonWidget.js.map