drizzle-cube 0.4.21 → 0.4.22

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 (86) hide show
  1. package/dist/client/charts.js +12 -12
  2. package/dist/client/chunks/{RetentionCombinedChart-CLq89aOJ.js → RetentionCombinedChart-BK3NPsHP.js} +2 -2
  3. package/dist/client/chunks/{RetentionCombinedChart-CLq89aOJ.js.map → RetentionCombinedChart-BK3NPsHP.js.map} +1 -1
  4. package/dist/client/chunks/{analysis-builder-3z9fHE2F.js → analysis-builder-DVrv9Q4n.js} +9 -9
  5. package/dist/client/chunks/{analysis-builder-3z9fHE2F.js.map → analysis-builder-DVrv9Q4n.js.map} +1 -1
  6. package/dist/client/chunks/{analysis-builder-shared-Da-vlQa_.js → analysis-builder-shared-CrENEvEk.js} +6 -6
  7. package/dist/client/chunks/{analysis-builder-shared-Da-vlQa_.js.map → analysis-builder-shared-CrENEvEk.js.map} +1 -1
  8. package/dist/client/chunks/{chart-activity-grid-CPGcTSuh.js → chart-activity-grid-OG6he4YS.js} +2 -2
  9. package/dist/client/chunks/{chart-activity-grid-CPGcTSuh.js.map → chart-activity-grid-OG6he4YS.js.map} +1 -1
  10. package/dist/client/chunks/{chart-area-ByJQ7NZd.js → chart-area-TawAd2k9.js} +3 -3
  11. package/dist/client/chunks/{chart-area-ByJQ7NZd.js.map → chart-area-TawAd2k9.js.map} +1 -1
  12. package/dist/client/chunks/{chart-bar-dj14frMt.js → chart-bar-D3vtCNQG.js} +2 -2
  13. package/dist/client/chunks/{chart-bar-dj14frMt.js.map → chart-bar-D3vtCNQG.js.map} +1 -1
  14. package/dist/client/chunks/{chart-box-plot-ZatBpatq.js → chart-box-plot-BXwN2rO5.js} +2 -2
  15. package/dist/client/chunks/{chart-box-plot-ZatBpatq.js.map → chart-box-plot-BXwN2rO5.js.map} +1 -1
  16. package/dist/client/chunks/{chart-bubble-CemotLx-.js → chart-bubble-ZfNe8t5k.js} +2 -2
  17. package/dist/client/chunks/{chart-bubble-CemotLx-.js.map → chart-bubble-ZfNe8t5k.js.map} +1 -1
  18. package/dist/client/chunks/{chart-candlestick-BIR4uGGt.js → chart-candlestick-DmF3haFu.js} +2 -2
  19. package/dist/client/chunks/{chart-candlestick-BIR4uGGt.js.map → chart-candlestick-DmF3haFu.js.map} +1 -1
  20. package/dist/client/chunks/{chart-data-table-BsAjHe7o.js → chart-data-table-DJZPkArt.js} +4 -4
  21. package/dist/client/chunks/{chart-data-table-BsAjHe7o.js.map → chart-data-table-DJZPkArt.js.map} +1 -1
  22. package/dist/client/chunks/{chart-funnel-dofnhD24.js → chart-funnel-CE9x0Io9.js} +2 -2
  23. package/dist/client/chunks/{chart-funnel-dofnhD24.js.map → chart-funnel-CE9x0Io9.js.map} +1 -1
  24. package/dist/client/chunks/{chart-gauge-CKJJ8m3b.js → chart-gauge-Djs5FWxB.js} +2 -2
  25. package/dist/client/chunks/{chart-gauge-CKJJ8m3b.js.map → chart-gauge-Djs5FWxB.js.map} +1 -1
  26. package/dist/client/chunks/{chart-heat-map-BVuPUKHT.js → chart-heat-map-CqtMkdxd.js} +2 -2
  27. package/dist/client/chunks/{chart-heat-map-BVuPUKHT.js.map → chart-heat-map-CqtMkdxd.js.map} +1 -1
  28. package/dist/client/chunks/{chart-kpi-delta-DUD3f8vL.js → chart-kpi-delta-DEzA74cL.js} +4 -4
  29. package/dist/client/chunks/{chart-kpi-delta-DUD3f8vL.js.map → chart-kpi-delta-DEzA74cL.js.map} +1 -1
  30. package/dist/client/chunks/{chart-kpi-number-iJh-PzsM.js → chart-kpi-number-Bab-BZtX.js} +3 -3
  31. package/dist/client/chunks/{chart-kpi-number-iJh-PzsM.js.map → chart-kpi-number-Bab-BZtX.js.map} +1 -1
  32. package/dist/client/chunks/{chart-kpi-text-x6pV9v9Q.js → chart-kpi-text-BkTgckDJ.js} +3 -3
  33. package/dist/client/chunks/{chart-kpi-text-x6pV9v9Q.js.map → chart-kpi-text-BkTgckDJ.js.map} +1 -1
  34. package/dist/client/chunks/{chart-line-DzyZkugh.js → chart-line-DhM-Hvu0.js} +3 -3
  35. package/dist/client/chunks/{chart-line-DzyZkugh.js.map → chart-line-DhM-Hvu0.js.map} +1 -1
  36. package/dist/client/chunks/{chart-measure-profile-C2IkBG3V.js → chart-measure-profile-4vQxFm69.js} +3 -3
  37. package/dist/client/chunks/{chart-measure-profile-C2IkBG3V.js.map → chart-measure-profile-4vQxFm69.js.map} +1 -1
  38. package/dist/client/chunks/{chart-pie-akbfRfb9.js → chart-pie-B86KRcHI.js} +2 -2
  39. package/dist/client/chunks/{chart-pie-akbfRfb9.js.map → chart-pie-B86KRcHI.js.map} +1 -1
  40. package/dist/client/chunks/{chart-radar-BaN-Kjww.js → chart-radar-BhDBmJRh.js} +2 -2
  41. package/dist/client/chunks/{chart-radar-BaN-Kjww.js.map → chart-radar-BhDBmJRh.js.map} +1 -1
  42. package/dist/client/chunks/{chart-radial-bar-DpptEL3s.js → chart-radial-bar-Brugya8X.js} +2 -2
  43. package/dist/client/chunks/{chart-radial-bar-DpptEL3s.js.map → chart-radial-bar-Brugya8X.js.map} +1 -1
  44. package/dist/client/chunks/{chart-sankey-CG-3hHmX.js → chart-sankey-D2L8ympI.js} +2 -2
  45. package/dist/client/chunks/{chart-sankey-CG-3hHmX.js.map → chart-sankey-D2L8ympI.js.map} +1 -1
  46. package/dist/client/chunks/{chart-scatter-l_yTVxF3.js → chart-scatter-CAkbBDkK.js} +2 -2
  47. package/dist/client/chunks/{chart-scatter-l_yTVxF3.js.map → chart-scatter-CAkbBDkK.js.map} +1 -1
  48. package/dist/client/chunks/{chart-sunburst-KhDcKhmZ.js → chart-sunburst-DaxJ-cob.js} +2 -2
  49. package/dist/client/chunks/{chart-sunburst-KhDcKhmZ.js.map → chart-sunburst-DaxJ-cob.js.map} +1 -1
  50. package/dist/client/chunks/{chart-tree-map-CBbiaBXV.js → chart-tree-map-CrDJAvZU.js} +2 -2
  51. package/dist/client/chunks/{chart-tree-map-CBbiaBXV.js.map → chart-tree-map-CrDJAvZU.js.map} +1 -1
  52. package/dist/client/chunks/{chart-waterfall-CX3vx_lI.js → chart-waterfall-BBwSfEKT.js} +3 -3
  53. package/dist/client/chunks/{chart-waterfall-CX3vx_lI.js.map → chart-waterfall-BBwSfEKT.js.map} +1 -1
  54. package/dist/client/chunks/{charts-core-CU9u_HtL.js → charts-core-B4Rbfdcn.js} +2 -2
  55. package/dist/client/chunks/{charts-core-CU9u_HtL.js.map → charts-core-B4Rbfdcn.js.map} +1 -1
  56. package/dist/client/chunks/{charts-loader-B3tt5oKG.js → charts-loader-DbrwgvCK.js} +25 -25
  57. package/dist/client/chunks/{charts-loader-B3tt5oKG.js.map → charts-loader-DbrwgvCK.js.map} +1 -1
  58. package/dist/client/chunks/{components-CMGGxqOB.js → components-GzooQM5J.js} +9 -9
  59. package/dist/client/chunks/{components-CMGGxqOB.js.map → components-GzooQM5J.js.map} +1 -1
  60. package/dist/client/chunks/{core-D_8mkGpQ.js → core-Y9e-sNfb.js} +2 -2
  61. package/dist/client/chunks/{core-D_8mkGpQ.js.map → core-Y9e-sNfb.js.map} +1 -1
  62. package/dist/client/chunks/{icons-M7shurcH.js → icons-DFJw-2HU.js} +6 -6
  63. package/dist/client/chunks/{icons-M7shurcH.js.map → icons-DFJw-2HU.js.map} +1 -1
  64. package/dist/client/chunks/{providers-CgxXm6Ll.js → providers-CCw8Kjlc.js} +2 -2
  65. package/dist/client/chunks/{providers-CgxXm6Ll.js.map → providers-CCw8Kjlc.js.map} +1 -1
  66. package/dist/client/chunks/{syntaxHighlighting-BQfjio-i.js → syntaxHighlighting-DAMSW_A6.js} +2 -2
  67. package/dist/client/chunks/{syntaxHighlighting-BQfjio-i.js.map → syntaxHighlighting-DAMSW_A6.js.map} +1 -1
  68. package/dist/client/chunks/{useDirtyStateTracking-Cu1HSjmo.js → useDirtyStateTracking-CjhwBXRw.js} +20 -20
  69. package/dist/client/chunks/{useDirtyStateTracking-Cu1HSjmo.js.map → useDirtyStateTracking-CjhwBXRw.js.map} +1 -1
  70. package/dist/client/chunks/useExplainAI-IiW55BaQ.js +182 -0
  71. package/dist/client/chunks/useExplainAI-IiW55BaQ.js.map +1 -0
  72. package/dist/client/chunks/{vendor-AVsJ2ni0.js → vendor-B2EH3V58.js} +7 -7
  73. package/dist/client/chunks/{vendor-AVsJ2ni0.js.map → vendor-B2EH3V58.js.map} +1 -1
  74. package/dist/client/components.js +1 -1
  75. package/dist/client/hooks/useNotebookLayout.d.ts +8 -0
  76. package/dist/client/hooks.d.ts +2 -0
  77. package/dist/client/hooks.js +51 -190
  78. package/dist/client/hooks.js.map +1 -1
  79. package/dist/client/icons.js +1 -1
  80. package/dist/client/index.js +871 -742
  81. package/dist/client/index.js.map +1 -1
  82. package/dist/client/providers.js +1 -1
  83. package/dist/client/styles.css +1 -1
  84. package/dist/client/utils.js +7 -7
  85. package/dist/client-bundle-stats.html +1 -1
  86. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"chart-radar-BaN-Kjww.js","sources":["../../../src/client/components/charts/RadarChart.tsx"],"sourcesContent":["import React, { useState } from 'react'\nimport { RadarChart as RechartsRadarChart, PolarGrid, PolarAngleAxis, PolarRadiusAxis, Radar, Legend } from 'recharts'\nimport ChartContainer from './ChartContainer'\nimport ChartTooltip from './ChartTooltip'\nimport { CHART_COLORS } from '../../utils/chartConstants'\nimport { transformChartDataWithSeries, formatTimeValue, getFieldGranularity, formatAxisValue } from '../../utils/chartUtils'\nimport type { ChartProps } from '../../types'\n\nconst RadarChart = React.memo(function RadarChart({ \n data, \n chartConfig,\n displayConfig = {},\n queryObject,\n height = \"100%\",\n colorPalette\n}: ChartProps) {\n const [hoveredLegend, setHoveredLegend] = useState<string | null>(null)\n \n try {\n const safeDisplayConfig = {\n showLegend: displayConfig?.showLegend ?? true,\n showTooltip: displayConfig?.showTooltip ?? true,\n showGrid: displayConfig?.showGrid ?? true,\n leftYAxisFormat: displayConfig?.leftYAxisFormat\n }\n\n if (!data || data.length === 0) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">No data available</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">No data points to display in radar chart</div>\n </div>\n </div>\n )\n }\n\n let radarData: any[]\n let seriesKeys: string[] = []\n\n if (chartConfig?.xAxis && chartConfig?.yAxis) {\n // New format - use chart config\n const xAxisField = Array.isArray(chartConfig.xAxis) ? chartConfig.xAxis[0] : chartConfig.xAxis // Subject/category field\n const yAxisFields = Array.isArray(chartConfig.yAxis) ? chartConfig.yAxis : [chartConfig.yAxis] // Value fields\n const seriesFields = chartConfig.series || []\n\n // Use shared function to transform data and handle series\n const { data: chartData, seriesKeys: transformedSeriesKeys } = transformChartDataWithSeries(\n data, \n xAxisField, \n yAxisFields, \n queryObject,\n seriesFields\n )\n \n radarData = chartData\n seriesKeys = transformedSeriesKeys\n } else {\n // Legacy format or auto-detection - try to find suitable fields\n const firstRow = data[0]\n const keys = Object.keys(firstRow)\n \n // Try to find subject/category field\n const subjectField = keys.find(key => \n typeof firstRow[key] === 'string' ||\n key.toLowerCase().includes('subject') ||\n key.toLowerCase().includes('name') ||\n key.toLowerCase().includes('category')\n ) || keys[0]\n\n // Find numeric fields for values\n const valueFields = keys.filter(key => \n typeof firstRow[key] === 'number' && key !== subjectField\n )\n\n if (valueFields.length === 0) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-warning\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">Configuration Error</div>\n <div className=\"dc:text-xs\">No numeric fields found for radar chart values</div>\n </div>\n </div>\n )\n }\n\n // Transform data for radar chart\n if (subjectField) {\n // Use subject field for radar categories\n const granularity = getFieldGranularity(queryObject, subjectField)\n radarData = data.map(item => {\n const transformedItem: any = {\n name: formatTimeValue(item[subjectField], granularity) || String(item[subjectField]) || 'Unknown'\n }\n \n valueFields.forEach(field => {\n const displayName = field.split('.').pop() || field\n transformedItem[displayName] = typeof item[field] === 'string' \n ? parseFloat(item[field]) \n : (item[field] || 0)\n })\n \n return transformedItem\n })\n \n seriesKeys = valueFields.map(field => field.split('.').pop() || field)\n } else {\n // Fallback - use first value field only\n radarData = data.map(item => ({\n name: String(item[keys[0]] || 'Unknown'),\n value: typeof item[valueFields[0]] === 'string' \n ? parseFloat(item[valueFields[0]]) \n : (item[valueFields[0]] || 0)\n }))\n seriesKeys = ['value']\n }\n }\n \n // Validate transformed data\n if (!radarData || radarData.length === 0) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">No valid data</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">No valid data points for radar chart after transformation</div>\n </div>\n </div>\n )\n }\n\n return (\n <ChartContainer height={height}>\n <RechartsRadarChart data={radarData} margin={{ top: 20, right: 80, bottom: 20, left: 80 }} accessibilityLayer={false}>\n {safeDisplayConfig.showGrid && (\n <PolarGrid />\n )}\n <PolarAngleAxis\n dataKey=\"name\"\n tick={{ fontSize: 12 }}\n className=\"text-dc-text-muted\"\n />\n <PolarRadiusAxis\n tick={{ fontSize: 10 }}\n className=\"text-dc-text-muted\"\n tickFormatter={safeDisplayConfig.leftYAxisFormat\n ? (value: any) => formatAxisValue(value, safeDisplayConfig.leftYAxisFormat)\n : undefined\n }\n />\n {safeDisplayConfig.showTooltip && (\n <ChartTooltip\n formatter={safeDisplayConfig.leftYAxisFormat\n ? (value: any, name: string) => [formatAxisValue(value, safeDisplayConfig.leftYAxisFormat), name]\n : undefined\n }\n />\n )}\n {(safeDisplayConfig.showLegend && seriesKeys.length > 1) && (\n <Legend \n wrapperStyle={{ fontSize: '12px', paddingTop: '10px' }}\n iconType=\"rect\"\n iconSize={8}\n layout=\"horizontal\"\n align=\"center\"\n verticalAlign=\"bottom\"\n onMouseEnter={(o) => setHoveredLegend(String(o.dataKey || ''))}\n onMouseLeave={() => setHoveredLegend(null)}\n />\n )}\n {seriesKeys.map((seriesKey, index) => (\n <Radar\n key={seriesKey}\n name={seriesKey}\n dataKey={seriesKey}\n stroke={(colorPalette?.colors && colorPalette.colors[index % colorPalette.colors.length]) || CHART_COLORS[index % CHART_COLORS.length]}\n fill={(colorPalette?.colors && colorPalette.colors[index % colorPalette.colors.length]) || CHART_COLORS[index % CHART_COLORS.length]}\n fillOpacity={hoveredLegend ? (hoveredLegend === seriesKey ? 0.6 : 0.1) : 0.3}\n strokeOpacity={hoveredLegend ? (hoveredLegend === seriesKey ? 1 : 0.3) : 1}\n strokeWidth={2}\n />\n ))}\n </RechartsRadarChart>\n </ChartContainer>\n )\n } catch (error) {\n // 'RadarChart rendering error\n return (\n <div className=\"dc:flex dc:flex-col dc:items-center dc:justify-center dc:w-full text-dc-error dc:p-4\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">Radar Chart Error</div>\n <div className=\"dc:text-xs dc:mb-2\">{error instanceof Error ? error.message : 'Unknown rendering error'}</div>\n <div className=\"dc:text-xs text-dc-text-muted\">Check the data and configuration</div>\n </div>\n </div>\n )\n }\n})\n\nexport default RadarChart"],"names":["RadarChart","React","data","chartConfig","displayConfig","queryObject","height","colorPalette","hoveredLegend","setHoveredLegend","useState","safeDisplayConfig","jsx","jsxs","radarData","seriesKeys","xAxisField","yAxisFields","seriesFields","chartData","transformedSeriesKeys","transformChartDataWithSeries","firstRow","keys","subjectField","key","valueFields","granularity","getFieldGranularity","item","transformedItem","formatTimeValue","field","displayName","ChartContainer","RechartsRadarChart","PolarGrid","PolarAngleAxis","PolarRadiusAxis","value","formatAxisValue","ChartTooltip","name","Legend","o","seriesKey","index","Radar","CHART_COLORS","error"],"mappings":"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"}
1
+ {"version":3,"file":"chart-radar-BhDBmJRh.js","sources":["../../../src/client/components/charts/RadarChart.tsx"],"sourcesContent":["import React, { useState } from 'react'\nimport { RadarChart as RechartsRadarChart, PolarGrid, PolarAngleAxis, PolarRadiusAxis, Radar, Legend } from 'recharts'\nimport ChartContainer from './ChartContainer'\nimport ChartTooltip from './ChartTooltip'\nimport { CHART_COLORS } from '../../utils/chartConstants'\nimport { transformChartDataWithSeries, formatTimeValue, getFieldGranularity, formatAxisValue } from '../../utils/chartUtils'\nimport type { ChartProps } from '../../types'\n\nconst RadarChart = React.memo(function RadarChart({ \n data, \n chartConfig,\n displayConfig = {},\n queryObject,\n height = \"100%\",\n colorPalette\n}: ChartProps) {\n const [hoveredLegend, setHoveredLegend] = useState<string | null>(null)\n \n try {\n const safeDisplayConfig = {\n showLegend: displayConfig?.showLegend ?? true,\n showTooltip: displayConfig?.showTooltip ?? true,\n showGrid: displayConfig?.showGrid ?? true,\n leftYAxisFormat: displayConfig?.leftYAxisFormat\n }\n\n if (!data || data.length === 0) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">No data available</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">No data points to display in radar chart</div>\n </div>\n </div>\n )\n }\n\n let radarData: any[]\n let seriesKeys: string[] = []\n\n if (chartConfig?.xAxis && chartConfig?.yAxis) {\n // New format - use chart config\n const xAxisField = Array.isArray(chartConfig.xAxis) ? chartConfig.xAxis[0] : chartConfig.xAxis // Subject/category field\n const yAxisFields = Array.isArray(chartConfig.yAxis) ? chartConfig.yAxis : [chartConfig.yAxis] // Value fields\n const seriesFields = chartConfig.series || []\n\n // Use shared function to transform data and handle series\n const { data: chartData, seriesKeys: transformedSeriesKeys } = transformChartDataWithSeries(\n data, \n xAxisField, \n yAxisFields, \n queryObject,\n seriesFields\n )\n \n radarData = chartData\n seriesKeys = transformedSeriesKeys\n } else {\n // Legacy format or auto-detection - try to find suitable fields\n const firstRow = data[0]\n const keys = Object.keys(firstRow)\n \n // Try to find subject/category field\n const subjectField = keys.find(key => \n typeof firstRow[key] === 'string' ||\n key.toLowerCase().includes('subject') ||\n key.toLowerCase().includes('name') ||\n key.toLowerCase().includes('category')\n ) || keys[0]\n\n // Find numeric fields for values\n const valueFields = keys.filter(key => \n typeof firstRow[key] === 'number' && key !== subjectField\n )\n\n if (valueFields.length === 0) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-warning\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">Configuration Error</div>\n <div className=\"dc:text-xs\">No numeric fields found for radar chart values</div>\n </div>\n </div>\n )\n }\n\n // Transform data for radar chart\n if (subjectField) {\n // Use subject field for radar categories\n const granularity = getFieldGranularity(queryObject, subjectField)\n radarData = data.map(item => {\n const transformedItem: any = {\n name: formatTimeValue(item[subjectField], granularity) || String(item[subjectField]) || 'Unknown'\n }\n \n valueFields.forEach(field => {\n const displayName = field.split('.').pop() || field\n transformedItem[displayName] = typeof item[field] === 'string' \n ? parseFloat(item[field]) \n : (item[field] || 0)\n })\n \n return transformedItem\n })\n \n seriesKeys = valueFields.map(field => field.split('.').pop() || field)\n } else {\n // Fallback - use first value field only\n radarData = data.map(item => ({\n name: String(item[keys[0]] || 'Unknown'),\n value: typeof item[valueFields[0]] === 'string' \n ? parseFloat(item[valueFields[0]]) \n : (item[valueFields[0]] || 0)\n }))\n seriesKeys = ['value']\n }\n }\n \n // Validate transformed data\n if (!radarData || radarData.length === 0) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">No valid data</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">No valid data points for radar chart after transformation</div>\n </div>\n </div>\n )\n }\n\n return (\n <ChartContainer height={height}>\n <RechartsRadarChart data={radarData} margin={{ top: 20, right: 80, bottom: 20, left: 80 }} accessibilityLayer={false}>\n {safeDisplayConfig.showGrid && (\n <PolarGrid />\n )}\n <PolarAngleAxis\n dataKey=\"name\"\n tick={{ fontSize: 12 }}\n className=\"text-dc-text-muted\"\n />\n <PolarRadiusAxis\n tick={{ fontSize: 10 }}\n className=\"text-dc-text-muted\"\n tickFormatter={safeDisplayConfig.leftYAxisFormat\n ? (value: any) => formatAxisValue(value, safeDisplayConfig.leftYAxisFormat)\n : undefined\n }\n />\n {safeDisplayConfig.showTooltip && (\n <ChartTooltip\n formatter={safeDisplayConfig.leftYAxisFormat\n ? (value: any, name: string) => [formatAxisValue(value, safeDisplayConfig.leftYAxisFormat), name]\n : undefined\n }\n />\n )}\n {(safeDisplayConfig.showLegend && seriesKeys.length > 1) && (\n <Legend \n wrapperStyle={{ fontSize: '12px', paddingTop: '10px' }}\n iconType=\"rect\"\n iconSize={8}\n layout=\"horizontal\"\n align=\"center\"\n verticalAlign=\"bottom\"\n onMouseEnter={(o) => setHoveredLegend(String(o.dataKey || ''))}\n onMouseLeave={() => setHoveredLegend(null)}\n />\n )}\n {seriesKeys.map((seriesKey, index) => (\n <Radar\n key={seriesKey}\n name={seriesKey}\n dataKey={seriesKey}\n stroke={(colorPalette?.colors && colorPalette.colors[index % colorPalette.colors.length]) || CHART_COLORS[index % CHART_COLORS.length]}\n fill={(colorPalette?.colors && colorPalette.colors[index % colorPalette.colors.length]) || CHART_COLORS[index % CHART_COLORS.length]}\n fillOpacity={hoveredLegend ? (hoveredLegend === seriesKey ? 0.6 : 0.1) : 0.3}\n strokeOpacity={hoveredLegend ? (hoveredLegend === seriesKey ? 1 : 0.3) : 1}\n strokeWidth={2}\n />\n ))}\n </RechartsRadarChart>\n </ChartContainer>\n )\n } catch (error) {\n // 'RadarChart rendering error\n return (\n <div className=\"dc:flex dc:flex-col dc:items-center dc:justify-center dc:w-full text-dc-error dc:p-4\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">Radar Chart Error</div>\n <div className=\"dc:text-xs dc:mb-2\">{error instanceof Error ? error.message : 'Unknown rendering error'}</div>\n <div className=\"dc:text-xs text-dc-text-muted\">Check the data and configuration</div>\n </div>\n </div>\n )\n }\n})\n\nexport default RadarChart"],"names":["RadarChart","React","data","chartConfig","displayConfig","queryObject","height","colorPalette","hoveredLegend","setHoveredLegend","useState","safeDisplayConfig","jsx","jsxs","radarData","seriesKeys","xAxisField","yAxisFields","seriesFields","chartData","transformedSeriesKeys","transformChartDataWithSeries","firstRow","keys","subjectField","key","valueFields","granularity","getFieldGranularity","item","transformedItem","formatTimeValue","field","displayName","ChartContainer","RechartsRadarChart","PolarGrid","PolarAngleAxis","PolarRadiusAxis","value","formatAxisValue","ChartTooltip","name","Legend","o","seriesKey","index","Radar","CHART_COLORS","error"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { jsx as t, jsxs as m } from "react/jsx-runtime";
2
2
  import N, { useState as g } from "react";
3
3
  import { RadialBarChart as w, Legend as F, RadialBar as R, Cell as L } from "recharts";
4
- import { g as S, c as u, d as C, a as T, b as j, f as A } from "./charts-core-CU9u_HtL.js";
4
+ import { g as S, c as u, d as C, a as T, b as j, f as A } from "./charts-core-B4Rbfdcn.js";
5
5
  const _ = N.memo(function({
6
6
  data: o,
7
7
  chartConfig: d,
@@ -116,4 +116,4 @@ const _ = N.memo(function({
116
116
  export {
117
117
  _ as default
118
118
  };
119
- //# sourceMappingURL=chart-radial-bar-DpptEL3s.js.map
119
+ //# sourceMappingURL=chart-radial-bar-Brugya8X.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chart-radial-bar-DpptEL3s.js","sources":["../../../src/client/components/charts/RadialBarChart.tsx"],"sourcesContent":["import React, { useState } from 'react'\nimport { RadialBarChart as RechartsRadialBarChart, RadialBar, Legend, Cell } from 'recharts'\nimport ChartContainer from './ChartContainer'\nimport ChartTooltip from './ChartTooltip'\nimport { CHART_COLORS } from '../../utils/chartConstants'\nimport { formatTimeValue, getFieldGranularity, formatAxisValue } from '../../utils/chartUtils'\nimport type { ChartProps } from '../../types'\n\nconst RadialBarChart = React.memo(function RadialBarChart({ \n data, \n chartConfig,\n displayConfig = {},\n queryObject,\n height = \"100%\",\n colorPalette\n}: ChartProps) {\n const [hoveredLegend, setHoveredLegend] = useState<string | null>(null)\n \n try {\n const safeDisplayConfig = {\n showLegend: displayConfig?.showLegend ?? true,\n showTooltip: displayConfig?.showTooltip ?? true,\n leftYAxisFormat: displayConfig?.leftYAxisFormat\n }\n\n if (!data || data.length === 0) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">No data available</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">No data points to display in radial bar chart</div>\n </div>\n </div>\n )\n }\n\n let radialData: Array<{name: string, value: number, fill?: string}>\n\n if (chartConfig?.xAxis && chartConfig?.yAxis) {\n // New format - use chart config\n const xAxisField = Array.isArray(chartConfig.xAxis) ? chartConfig.xAxis[0] : chartConfig.xAxis // Name/category field\n const yAxisField = Array.isArray(chartConfig.yAxis) ? chartConfig.yAxis[0] : chartConfig.yAxis // Value field\n\n const granularity = getFieldGranularity(queryObject, xAxisField)\n radialData = data.map((item, index) => ({\n name: formatTimeValue(item[xAxisField], granularity) || String(item[xAxisField]) || 'Unknown',\n value: typeof item[yAxisField] === 'string' \n ? parseFloat(item[yAxisField]) \n : (item[yAxisField] || 0),\n fill: (colorPalette?.colors && colorPalette.colors[index % colorPalette.colors.length]) || CHART_COLORS[index % CHART_COLORS.length]\n }))\n } else {\n // Legacy format or auto-detection\n const firstRow = data[0]\n const keys = Object.keys(firstRow)\n \n // Try to find name/label field\n const nameField = keys.find(key => \n typeof firstRow[key] === 'string' ||\n key.toLowerCase().includes('name') ||\n key.toLowerCase().includes('label') ||\n key.toLowerCase().includes('category')\n ) || keys[0]\n\n // Find a numeric field for values\n const valueField = keys.find(key => \n typeof firstRow[key] === 'number' && key !== nameField\n ) || keys[1]\n\n if (!valueField) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-warning\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">Configuration Error</div>\n <div className=\"dc:text-xs\">No numeric field found for radial bar chart values</div>\n </div>\n </div>\n )\n }\n\n // Transform data for radial bar chart\n radialData = data.map((item, index) => {\n let name = item[nameField]\n // Handle boolean values with better labels\n if (typeof name === 'boolean') {\n name = name ? 'Active' : 'Inactive'\n } else if (name === 'true' || name === 'false') {\n name = name === 'true' ? 'Active' : 'Inactive'\n } else {\n name = String(name)\n }\n return {\n name,\n value: typeof item[valueField] === 'string' \n ? parseFloat(item[valueField]) \n : (item[valueField] || 0),\n fill: (colorPalette?.colors && colorPalette.colors[index % colorPalette.colors.length]) || CHART_COLORS[index % CHART_COLORS.length]\n }\n })\n }\n\n // Filter out zero/null values\n radialData = radialData.filter(item => item.value != null && item.value !== 0)\n \n if (radialData.length === 0) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">No valid data</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">No valid data points for radial bar chart after transformation</div>\n </div>\n </div>\n )\n }\n\n return (\n <ChartContainer height={height}>\n <RechartsRadialBarChart\n data={radialData}\n innerRadius=\"10%\"\n outerRadius=\"80%\"\n margin={{ top: 20, right: 30, bottom: 20, left: 30 }}\n accessibilityLayer={false}\n >\n {safeDisplayConfig.showTooltip && (\n <ChartTooltip\n formatter={safeDisplayConfig.leftYAxisFormat\n ? (value: any, name: string) => [formatAxisValue(value, safeDisplayConfig.leftYAxisFormat), name]\n : undefined\n }\n />\n )}\n {safeDisplayConfig.showLegend && (\n <Legend \n wrapperStyle={{ fontSize: '12px', paddingTop: '10px' }}\n iconType=\"circle\"\n iconSize={8}\n layout=\"horizontal\"\n align=\"center\"\n verticalAlign=\"bottom\"\n onMouseEnter={(o) => setHoveredLegend(String(o.value || ''))}\n onMouseLeave={() => setHoveredLegend(null)}\n />\n )}\n <RadialBar\n dataKey=\"value\"\n cornerRadius={4}\n label={{\n position: 'insideStart',\n fill: '#fff',\n fontSize: 12,\n formatter: safeDisplayConfig.leftYAxisFormat\n ? (value: any) => formatAxisValue(value, safeDisplayConfig.leftYAxisFormat)\n : undefined\n }}\n >\n {radialData.map((entry, index) => (\n <Cell \n key={`cell-${index}`} \n fill={entry.fill}\n fillOpacity={hoveredLegend ? (hoveredLegend === entry.name ? 1 : 0.3) : 1}\n />\n ))}\n </RadialBar>\n </RechartsRadialBarChart>\n </ChartContainer>\n )\n } catch (error) {\n // 'RadialBarChart rendering error\n return (\n <div className=\"dc:flex dc:flex-col dc:items-center dc:justify-center dc:w-full text-dc-error dc:p-4\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">Radial Bar Chart Error</div>\n <div className=\"dc:text-xs dc:mb-2\">{error instanceof Error ? error.message : 'Unknown rendering error'}</div>\n <div className=\"dc:text-xs text-dc-text-muted\">Check the data and configuration</div>\n </div>\n </div>\n )\n }\n})\n\nexport default RadialBarChart"],"names":["RadialBarChart","React","data","chartConfig","displayConfig","queryObject","height","colorPalette","hoveredLegend","setHoveredLegend","useState","safeDisplayConfig","jsx","jsxs","radialData","xAxisField","yAxisField","granularity","getFieldGranularity","item","index","formatTimeValue","CHART_COLORS","firstRow","keys","nameField","key","valueField","name","ChartContainer","RechartsRadialBarChart","ChartTooltip","value","formatAxisValue","Legend","o","RadialBar","entry","Cell","error"],"mappings":"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"}
1
+ {"version":3,"file":"chart-radial-bar-Brugya8X.js","sources":["../../../src/client/components/charts/RadialBarChart.tsx"],"sourcesContent":["import React, { useState } from 'react'\nimport { RadialBarChart as RechartsRadialBarChart, RadialBar, Legend, Cell } from 'recharts'\nimport ChartContainer from './ChartContainer'\nimport ChartTooltip from './ChartTooltip'\nimport { CHART_COLORS } from '../../utils/chartConstants'\nimport { formatTimeValue, getFieldGranularity, formatAxisValue } from '../../utils/chartUtils'\nimport type { ChartProps } from '../../types'\n\nconst RadialBarChart = React.memo(function RadialBarChart({ \n data, \n chartConfig,\n displayConfig = {},\n queryObject,\n height = \"100%\",\n colorPalette\n}: ChartProps) {\n const [hoveredLegend, setHoveredLegend] = useState<string | null>(null)\n \n try {\n const safeDisplayConfig = {\n showLegend: displayConfig?.showLegend ?? true,\n showTooltip: displayConfig?.showTooltip ?? true,\n leftYAxisFormat: displayConfig?.leftYAxisFormat\n }\n\n if (!data || data.length === 0) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">No data available</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">No data points to display in radial bar chart</div>\n </div>\n </div>\n )\n }\n\n let radialData: Array<{name: string, value: number, fill?: string}>\n\n if (chartConfig?.xAxis && chartConfig?.yAxis) {\n // New format - use chart config\n const xAxisField = Array.isArray(chartConfig.xAxis) ? chartConfig.xAxis[0] : chartConfig.xAxis // Name/category field\n const yAxisField = Array.isArray(chartConfig.yAxis) ? chartConfig.yAxis[0] : chartConfig.yAxis // Value field\n\n const granularity = getFieldGranularity(queryObject, xAxisField)\n radialData = data.map((item, index) => ({\n name: formatTimeValue(item[xAxisField], granularity) || String(item[xAxisField]) || 'Unknown',\n value: typeof item[yAxisField] === 'string' \n ? parseFloat(item[yAxisField]) \n : (item[yAxisField] || 0),\n fill: (colorPalette?.colors && colorPalette.colors[index % colorPalette.colors.length]) || CHART_COLORS[index % CHART_COLORS.length]\n }))\n } else {\n // Legacy format or auto-detection\n const firstRow = data[0]\n const keys = Object.keys(firstRow)\n \n // Try to find name/label field\n const nameField = keys.find(key => \n typeof firstRow[key] === 'string' ||\n key.toLowerCase().includes('name') ||\n key.toLowerCase().includes('label') ||\n key.toLowerCase().includes('category')\n ) || keys[0]\n\n // Find a numeric field for values\n const valueField = keys.find(key => \n typeof firstRow[key] === 'number' && key !== nameField\n ) || keys[1]\n\n if (!valueField) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-warning\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">Configuration Error</div>\n <div className=\"dc:text-xs\">No numeric field found for radial bar chart values</div>\n </div>\n </div>\n )\n }\n\n // Transform data for radial bar chart\n radialData = data.map((item, index) => {\n let name = item[nameField]\n // Handle boolean values with better labels\n if (typeof name === 'boolean') {\n name = name ? 'Active' : 'Inactive'\n } else if (name === 'true' || name === 'false') {\n name = name === 'true' ? 'Active' : 'Inactive'\n } else {\n name = String(name)\n }\n return {\n name,\n value: typeof item[valueField] === 'string' \n ? parseFloat(item[valueField]) \n : (item[valueField] || 0),\n fill: (colorPalette?.colors && colorPalette.colors[index % colorPalette.colors.length]) || CHART_COLORS[index % CHART_COLORS.length]\n }\n })\n }\n\n // Filter out zero/null values\n radialData = radialData.filter(item => item.value != null && item.value !== 0)\n \n if (radialData.length === 0) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">No valid data</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">No valid data points for radial bar chart after transformation</div>\n </div>\n </div>\n )\n }\n\n return (\n <ChartContainer height={height}>\n <RechartsRadialBarChart\n data={radialData}\n innerRadius=\"10%\"\n outerRadius=\"80%\"\n margin={{ top: 20, right: 30, bottom: 20, left: 30 }}\n accessibilityLayer={false}\n >\n {safeDisplayConfig.showTooltip && (\n <ChartTooltip\n formatter={safeDisplayConfig.leftYAxisFormat\n ? (value: any, name: string) => [formatAxisValue(value, safeDisplayConfig.leftYAxisFormat), name]\n : undefined\n }\n />\n )}\n {safeDisplayConfig.showLegend && (\n <Legend \n wrapperStyle={{ fontSize: '12px', paddingTop: '10px' }}\n iconType=\"circle\"\n iconSize={8}\n layout=\"horizontal\"\n align=\"center\"\n verticalAlign=\"bottom\"\n onMouseEnter={(o) => setHoveredLegend(String(o.value || ''))}\n onMouseLeave={() => setHoveredLegend(null)}\n />\n )}\n <RadialBar\n dataKey=\"value\"\n cornerRadius={4}\n label={{\n position: 'insideStart',\n fill: '#fff',\n fontSize: 12,\n formatter: safeDisplayConfig.leftYAxisFormat\n ? (value: any) => formatAxisValue(value, safeDisplayConfig.leftYAxisFormat)\n : undefined\n }}\n >\n {radialData.map((entry, index) => (\n <Cell \n key={`cell-${index}`} \n fill={entry.fill}\n fillOpacity={hoveredLegend ? (hoveredLegend === entry.name ? 1 : 0.3) : 1}\n />\n ))}\n </RadialBar>\n </RechartsRadialBarChart>\n </ChartContainer>\n )\n } catch (error) {\n // 'RadialBarChart rendering error\n return (\n <div className=\"dc:flex dc:flex-col dc:items-center dc:justify-center dc:w-full text-dc-error dc:p-4\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">Radial Bar Chart Error</div>\n <div className=\"dc:text-xs dc:mb-2\">{error instanceof Error ? error.message : 'Unknown rendering error'}</div>\n <div className=\"dc:text-xs text-dc-text-muted\">Check the data and configuration</div>\n </div>\n </div>\n )\n }\n})\n\nexport default RadialBarChart"],"names":["RadialBarChart","React","data","chartConfig","displayConfig","queryObject","height","colorPalette","hoveredLegend","setHoveredLegend","useState","safeDisplayConfig","jsx","jsxs","radialData","xAxisField","yAxisField","granularity","getFieldGranularity","item","index","formatTimeValue","CHART_COLORS","firstRow","keys","nameField","key","valueField","name","ChartContainer","RechartsRadialBarChart","ChartTooltip","value","formatAxisValue","Legend","o","RadialBar","entry","Cell","error"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { jsx as c, jsxs as s } from "react/jsx-runtime";
2
2
  import L, { useRef as R, useState as E, useEffect as O, useMemo as N } from "react";
3
3
  import { ResponsiveContainer as F, Sankey as W, Tooltip as A } from "recharts";
4
- import { c as j } from "./charts-core-CU9u_HtL.js";
4
+ import { c as j } from "./charts-core-B4Rbfdcn.js";
5
5
  import { i as p } from "./flow-utils-CjQZG5qq.js";
6
6
  const g = {
7
7
  before: "#F97316",
@@ -186,4 +186,4 @@ const K = L.memo(function({
186
186
  export {
187
187
  K as default
188
188
  };
189
- //# sourceMappingURL=chart-sankey-CG-3hHmX.js.map
189
+ //# sourceMappingURL=chart-sankey-D2L8ympI.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chart-sankey-CG-3hHmX.js","sources":["../../../src/client/components/charts/SankeyChart.tsx"],"sourcesContent":["/**\n * SankeyChart Component\n *\n * Visualizes flow data using Sankey diagrams showing paths between states.\n * Works with data from flow queries which provide nodes and links.\n *\n * The chart displays:\n * - Nodes representing events at different layers (before, start, after)\n * - Links showing the flow of entities between adjacent nodes\n * - Values indicating count of entities following each path\n */\n\nimport React, { useMemo, useRef, useState, useEffect } from 'react'\nimport { Sankey, Tooltip, ResponsiveContainer } from 'recharts'\nimport { CHART_COLORS } from '../../utils/chartConstants'\nimport type { ChartProps } from '../../types'\nimport type { FlowChartData } from '../../types/flow'\nimport { isSankeyData } from '../../types/flow'\n\n/**\n * Color palette for Sankey nodes based on layer\n */\nconst SANKEY_COLORS = {\n before: '#F97316', // orange-500 - for steps before\n start: '#3B82F6', // blue-500 - for starting step\n after: '#10B981', // emerald-500 - for steps after\n}\n\n/**\n * Get color for a node based on its layer\n */\nfunction getNodeColor(layer: number, colorPalette?: string[]): string {\n if (colorPalette && colorPalette.length > 0) {\n // Use palette colors cycling through\n const absLayer = Math.abs(layer)\n return colorPalette[absLayer % colorPalette.length]\n }\n\n if (layer < 0) return SANKEY_COLORS.before\n if (layer === 0) return SANKEY_COLORS.start\n return SANKEY_COLORS.after\n}\n\n/**\n * Transform FlowChartData to Recharts Sankey format\n */\nfunction transformToRechartsFormat(\n data: FlowChartData,\n colorPalette?: string[]\n): {\n nodes: Array<{ name: string; fill: string; layer: number; value?: number }>\n links: Array<{ source: number; target: number; value: number }>\n} | null {\n if (!data.nodes || data.nodes.length === 0) return null\n\n // Create node index map for link resolution\n const nodeIndexMap = new Map<string, number>()\n data.nodes.forEach((node, index) => {\n nodeIndexMap.set(node.id, index)\n })\n\n // Transform nodes\n const nodes = data.nodes.map((node) => ({\n name: node.name,\n fill: getNodeColor(node.layer, colorPalette),\n layer: node.layer,\n value: node.value,\n }))\n\n // Transform links - resolve string IDs to numeric indices\n const links = data.links\n .map((link) => {\n const sourceIndex = nodeIndexMap.get(link.source)\n const targetIndex = nodeIndexMap.get(link.target)\n\n if (sourceIndex === undefined || targetIndex === undefined) {\n console.warn(`Sankey: Could not resolve link ${link.source} -> ${link.target}`)\n return null\n }\n\n return {\n source: sourceIndex,\n target: targetIndex,\n value: link.value,\n }\n })\n .filter((link): link is { source: number; target: number; value: number } => link !== null)\n\n return { nodes, links }\n}\n\n/**\n * Extract FlowChartData from various data formats\n */\nfunction extractFlowData(data: unknown[]): FlowChartData | null {\n if (!data || data.length === 0) return null\n\n // If first element is already FlowChartData (server returns as single-row array)\n if (isSankeyData(data[0])) {\n return data[0] as FlowChartData\n }\n\n // If data itself is FlowChartData shape\n if (isSankeyData(data)) {\n return data as unknown as FlowChartData\n }\n\n // Check if data is an array with nodes and links at top level\n const asAny = data as unknown as Record<string, unknown>\n if (asAny.nodes && asAny.links) {\n return asAny as unknown as FlowChartData\n }\n\n return null\n}\n\n/**\n * Custom node renderer for Sankey chart\n * Displays the node rectangle with label and value\n */\nfunction SankeyNode({\n x,\n y,\n width,\n height,\n payload,\n containerWidth,\n showLabels = true,\n}: {\n x: number\n y: number\n width: number\n height: number\n payload: { name: string; value?: number; fill: string }\n containerWidth: number\n showLabels?: boolean\n}) {\n // Determine if label should be on the left or right based on position\n const isRightSide = x > containerWidth / 2\n const labelX = isRightSide ? x - 6 : x + width + 6\n const textAnchor = isRightSide ? 'end' : 'start'\n\n return (\n <g>\n {/* Node rectangle */}\n <rect\n x={x}\n y={y}\n width={width}\n height={height}\n fill={payload.fill}\n rx={2}\n ry={2}\n />\n {/* Node label - only shown if showLabels is true */}\n {showLabels && (\n <text\n x={labelX}\n y={y + height / 2}\n textAnchor={textAnchor}\n dominantBaseline=\"middle\"\n className=\"dc:text-xs dc:fill-dc-text\"\n style={{ fontSize: 11 }}\n >\n {payload.name}\n {payload.value !== undefined && (\n <tspan className=\"dc:fill-dc-text-secondary\" dx={4}>\n ({payload.value.toLocaleString()})\n </tspan>\n )}\n </text>\n )}\n </g>\n )\n}\n\n/**\n * Custom tooltip for Sankey chart\n */\nfunction SankeyTooltip({ active, payload }: {\n active?: boolean\n payload?: Array<{ payload: { name: string; value: number; source?: { name: string }; target?: { name: string } } }>\n}) {\n if (!active || !payload || payload.length === 0) return null\n\n const data = payload[0].payload\n\n // Check if this is a link (has source/target) or a node\n if (data.source && data.target) {\n return (\n <div className=\"bg-dc-surface dc:border border-dc-border dc:rounded-md dc:px-3 dc:py-2 dc:shadow-lg dc:text-sm\">\n <div className=\"dc:font-medium text-dc-text\">\n {data.source.name} → {data.target.name}\n </div>\n <div className=\"text-dc-text-secondary dc:mt-1\">\n <span className=\"dc:font-medium\">{data.value.toLocaleString()}</span> entities\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"bg-dc-surface dc:border border-dc-border dc:rounded-md dc:px-3 dc:py-2 dc:shadow-lg dc:text-sm\">\n <div className=\"dc:font-medium text-dc-text\">{data.name}</div>\n {data.value !== undefined && (\n <div className=\"text-dc-text-secondary dc:mt-1\">\n <span className=\"dc:font-medium\">{data.value.toLocaleString()}</span> entities\n </div>\n )}\n </div>\n )\n}\n\n/**\n * SankeyChart Component\n *\n * Renders a Sankey diagram visualization from FlowChartData.\n * Shows flow paths with nodes at each layer and links between them.\n */\nconst SankeyChart = React.memo(function SankeyChart({\n data,\n height = '100%',\n colorPalette,\n displayConfig,\n}: ChartProps) {\n // Track container width for label positioning\n const containerRef = useRef<HTMLDivElement>(null)\n const [containerWidth, setContainerWidth] = useState(800)\n\n useEffect(() => {\n const updateWidth = () => {\n if (containerRef.current) {\n setContainerWidth(containerRef.current.offsetWidth)\n }\n }\n updateWidth()\n window.addEventListener('resize', updateWidth)\n return () => window.removeEventListener('resize', updateWidth)\n }, [])\n\n // Get display config options\n // Use custom properties from displayConfig if available, otherwise use defaults\n const displayConfigAny = displayConfig as Record<string, unknown> | undefined\n const linkOpacity = parseFloat(String(displayConfigAny?.linkOpacity || '0.5'))\n const nodeWidth = (displayConfigAny?.nodeWidth as number) ?? 10\n const nodePadding = (displayConfigAny?.nodePadding as number) ?? 50\n const showNodeLabels = displayConfigAny?.showNodeLabels !== false // Default true\n\n // Extract and transform data\n const flowData = useMemo(() => {\n const extracted = extractFlowData(data || [])\n if (!extracted) return null\n\n return transformToRechartsFormat(extracted, colorPalette?.colors || CHART_COLORS)\n }, [data, colorPalette])\n\n // Calculate summary stats\n const summaryStats = useMemo(() => {\n const extracted = extractFlowData(data || [])\n if (!extracted) return null\n\n const totalEntities = extracted.nodes\n .filter((n) => n.layer === 0)\n .reduce((sum, n) => sum + (n.value || 0), 0)\n\n const totalPaths = extracted.links.reduce((sum, l) => sum + l.value, 0)\n\n return {\n nodeCount: extracted.nodes.length,\n linkCount: extracted.links.length,\n totalEntities,\n totalPaths,\n }\n }, [data])\n\n // Handle no data\n if (!data || data.length === 0 || !flowData || flowData.nodes.length === 0) {\n return (\n <div\n className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-text-muted\"\n style={{ height }}\n >\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">No flow data</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">\n Configure a flow analysis with a starting step and event dimension\n </div>\n </div>\n </div>\n )\n }\n\n return (\n <div ref={containerRef} className=\"dc:relative dc:w-full dc:h-full dc:flex dc:flex-col\" style={{ height }}>\n {/* Sankey Diagram */}\n <div className=\"dc:flex-1 dc:min-h-0\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <Sankey\n data={flowData}\n nodeWidth={nodeWidth}\n nodePadding={nodePadding}\n margin={{ top: 20, right: 20, bottom: 20, left: 20 }}\n link={{\n stroke: 'var(--dc-border)',\n strokeOpacity: linkOpacity,\n }}\n node={(props: any) => (\n <SankeyNode {...props} containerWidth={containerWidth} showLabels={showNodeLabels} />\n )}\n >\n <Tooltip content={<SankeyTooltip />} />\n </Sankey>\n </ResponsiveContainer>\n </div>\n\n {/* Summary Footer */}\n {!(displayConfigAny?.hideSummaryFooter) && summaryStats && (\n <div className=\"dc:flex-shrink-0 dc:px-4 dc:py-2 dc:border-t border-dc-border bg-dc-surface-secondary\">\n <div className=\"dc:flex dc:items-center dc:justify-between dc:text-sm\">\n <div className=\"text-dc-text-muted\">\n <span className=\"dc:font-medium\">{summaryStats.nodeCount}</span> events\n </div>\n <div className=\"text-dc-text\">\n <span className=\"text-dc-text-muted\">Paths:</span>{' '}\n <span className=\"dc:font-medium\">{summaryStats.linkCount}</span>\n </div>\n <div className=\"text-dc-text-muted\">\n <span className=\"dc:font-medium\">{summaryStats.totalEntities.toLocaleString()}</span> starting entities\n </div>\n </div>\n </div>\n )}\n </div>\n )\n})\n\nexport default SankeyChart\n"],"names":["SANKEY_COLORS","getNodeColor","layer","colorPalette","absLayer","transformToRechartsFormat","data","nodeIndexMap","node","index","nodes","links","link","sourceIndex","targetIndex","extractFlowData","isSankeyData","asAny","SankeyNode","x","y","width","height","payload","containerWidth","showLabels","isRightSide","labelX","textAnchor","jsx","jsxs","SankeyTooltip","active","SankeyChart","React","displayConfig","containerRef","useRef","setContainerWidth","useState","useEffect","updateWidth","displayConfigAny","linkOpacity","nodeWidth","nodePadding","showNodeLabels","flowData","useMemo","extracted","CHART_COLORS","summaryStats","totalEntities","n","sum","totalPaths","l","ResponsiveContainer","Sankey","props","Tooltip"],"mappings":"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"}
1
+ {"version":3,"file":"chart-sankey-D2L8ympI.js","sources":["../../../src/client/components/charts/SankeyChart.tsx"],"sourcesContent":["/**\n * SankeyChart Component\n *\n * Visualizes flow data using Sankey diagrams showing paths between states.\n * Works with data from flow queries which provide nodes and links.\n *\n * The chart displays:\n * - Nodes representing events at different layers (before, start, after)\n * - Links showing the flow of entities between adjacent nodes\n * - Values indicating count of entities following each path\n */\n\nimport React, { useMemo, useRef, useState, useEffect } from 'react'\nimport { Sankey, Tooltip, ResponsiveContainer } from 'recharts'\nimport { CHART_COLORS } from '../../utils/chartConstants'\nimport type { ChartProps } from '../../types'\nimport type { FlowChartData } from '../../types/flow'\nimport { isSankeyData } from '../../types/flow'\n\n/**\n * Color palette for Sankey nodes based on layer\n */\nconst SANKEY_COLORS = {\n before: '#F97316', // orange-500 - for steps before\n start: '#3B82F6', // blue-500 - for starting step\n after: '#10B981', // emerald-500 - for steps after\n}\n\n/**\n * Get color for a node based on its layer\n */\nfunction getNodeColor(layer: number, colorPalette?: string[]): string {\n if (colorPalette && colorPalette.length > 0) {\n // Use palette colors cycling through\n const absLayer = Math.abs(layer)\n return colorPalette[absLayer % colorPalette.length]\n }\n\n if (layer < 0) return SANKEY_COLORS.before\n if (layer === 0) return SANKEY_COLORS.start\n return SANKEY_COLORS.after\n}\n\n/**\n * Transform FlowChartData to Recharts Sankey format\n */\nfunction transformToRechartsFormat(\n data: FlowChartData,\n colorPalette?: string[]\n): {\n nodes: Array<{ name: string; fill: string; layer: number; value?: number }>\n links: Array<{ source: number; target: number; value: number }>\n} | null {\n if (!data.nodes || data.nodes.length === 0) return null\n\n // Create node index map for link resolution\n const nodeIndexMap = new Map<string, number>()\n data.nodes.forEach((node, index) => {\n nodeIndexMap.set(node.id, index)\n })\n\n // Transform nodes\n const nodes = data.nodes.map((node) => ({\n name: node.name,\n fill: getNodeColor(node.layer, colorPalette),\n layer: node.layer,\n value: node.value,\n }))\n\n // Transform links - resolve string IDs to numeric indices\n const links = data.links\n .map((link) => {\n const sourceIndex = nodeIndexMap.get(link.source)\n const targetIndex = nodeIndexMap.get(link.target)\n\n if (sourceIndex === undefined || targetIndex === undefined) {\n console.warn(`Sankey: Could not resolve link ${link.source} -> ${link.target}`)\n return null\n }\n\n return {\n source: sourceIndex,\n target: targetIndex,\n value: link.value,\n }\n })\n .filter((link): link is { source: number; target: number; value: number } => link !== null)\n\n return { nodes, links }\n}\n\n/**\n * Extract FlowChartData from various data formats\n */\nfunction extractFlowData(data: unknown[]): FlowChartData | null {\n if (!data || data.length === 0) return null\n\n // If first element is already FlowChartData (server returns as single-row array)\n if (isSankeyData(data[0])) {\n return data[0] as FlowChartData\n }\n\n // If data itself is FlowChartData shape\n if (isSankeyData(data)) {\n return data as unknown as FlowChartData\n }\n\n // Check if data is an array with nodes and links at top level\n const asAny = data as unknown as Record<string, unknown>\n if (asAny.nodes && asAny.links) {\n return asAny as unknown as FlowChartData\n }\n\n return null\n}\n\n/**\n * Custom node renderer for Sankey chart\n * Displays the node rectangle with label and value\n */\nfunction SankeyNode({\n x,\n y,\n width,\n height,\n payload,\n containerWidth,\n showLabels = true,\n}: {\n x: number\n y: number\n width: number\n height: number\n payload: { name: string; value?: number; fill: string }\n containerWidth: number\n showLabels?: boolean\n}) {\n // Determine if label should be on the left or right based on position\n const isRightSide = x > containerWidth / 2\n const labelX = isRightSide ? x - 6 : x + width + 6\n const textAnchor = isRightSide ? 'end' : 'start'\n\n return (\n <g>\n {/* Node rectangle */}\n <rect\n x={x}\n y={y}\n width={width}\n height={height}\n fill={payload.fill}\n rx={2}\n ry={2}\n />\n {/* Node label - only shown if showLabels is true */}\n {showLabels && (\n <text\n x={labelX}\n y={y + height / 2}\n textAnchor={textAnchor}\n dominantBaseline=\"middle\"\n className=\"dc:text-xs dc:fill-dc-text\"\n style={{ fontSize: 11 }}\n >\n {payload.name}\n {payload.value !== undefined && (\n <tspan className=\"dc:fill-dc-text-secondary\" dx={4}>\n ({payload.value.toLocaleString()})\n </tspan>\n )}\n </text>\n )}\n </g>\n )\n}\n\n/**\n * Custom tooltip for Sankey chart\n */\nfunction SankeyTooltip({ active, payload }: {\n active?: boolean\n payload?: Array<{ payload: { name: string; value: number; source?: { name: string }; target?: { name: string } } }>\n}) {\n if (!active || !payload || payload.length === 0) return null\n\n const data = payload[0].payload\n\n // Check if this is a link (has source/target) or a node\n if (data.source && data.target) {\n return (\n <div className=\"bg-dc-surface dc:border border-dc-border dc:rounded-md dc:px-3 dc:py-2 dc:shadow-lg dc:text-sm\">\n <div className=\"dc:font-medium text-dc-text\">\n {data.source.name} → {data.target.name}\n </div>\n <div className=\"text-dc-text-secondary dc:mt-1\">\n <span className=\"dc:font-medium\">{data.value.toLocaleString()}</span> entities\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"bg-dc-surface dc:border border-dc-border dc:rounded-md dc:px-3 dc:py-2 dc:shadow-lg dc:text-sm\">\n <div className=\"dc:font-medium text-dc-text\">{data.name}</div>\n {data.value !== undefined && (\n <div className=\"text-dc-text-secondary dc:mt-1\">\n <span className=\"dc:font-medium\">{data.value.toLocaleString()}</span> entities\n </div>\n )}\n </div>\n )\n}\n\n/**\n * SankeyChart Component\n *\n * Renders a Sankey diagram visualization from FlowChartData.\n * Shows flow paths with nodes at each layer and links between them.\n */\nconst SankeyChart = React.memo(function SankeyChart({\n data,\n height = '100%',\n colorPalette,\n displayConfig,\n}: ChartProps) {\n // Track container width for label positioning\n const containerRef = useRef<HTMLDivElement>(null)\n const [containerWidth, setContainerWidth] = useState(800)\n\n useEffect(() => {\n const updateWidth = () => {\n if (containerRef.current) {\n setContainerWidth(containerRef.current.offsetWidth)\n }\n }\n updateWidth()\n window.addEventListener('resize', updateWidth)\n return () => window.removeEventListener('resize', updateWidth)\n }, [])\n\n // Get display config options\n // Use custom properties from displayConfig if available, otherwise use defaults\n const displayConfigAny = displayConfig as Record<string, unknown> | undefined\n const linkOpacity = parseFloat(String(displayConfigAny?.linkOpacity || '0.5'))\n const nodeWidth = (displayConfigAny?.nodeWidth as number) ?? 10\n const nodePadding = (displayConfigAny?.nodePadding as number) ?? 50\n const showNodeLabels = displayConfigAny?.showNodeLabels !== false // Default true\n\n // Extract and transform data\n const flowData = useMemo(() => {\n const extracted = extractFlowData(data || [])\n if (!extracted) return null\n\n return transformToRechartsFormat(extracted, colorPalette?.colors || CHART_COLORS)\n }, [data, colorPalette])\n\n // Calculate summary stats\n const summaryStats = useMemo(() => {\n const extracted = extractFlowData(data || [])\n if (!extracted) return null\n\n const totalEntities = extracted.nodes\n .filter((n) => n.layer === 0)\n .reduce((sum, n) => sum + (n.value || 0), 0)\n\n const totalPaths = extracted.links.reduce((sum, l) => sum + l.value, 0)\n\n return {\n nodeCount: extracted.nodes.length,\n linkCount: extracted.links.length,\n totalEntities,\n totalPaths,\n }\n }, [data])\n\n // Handle no data\n if (!data || data.length === 0 || !flowData || flowData.nodes.length === 0) {\n return (\n <div\n className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-text-muted\"\n style={{ height }}\n >\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">No flow data</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">\n Configure a flow analysis with a starting step and event dimension\n </div>\n </div>\n </div>\n )\n }\n\n return (\n <div ref={containerRef} className=\"dc:relative dc:w-full dc:h-full dc:flex dc:flex-col\" style={{ height }}>\n {/* Sankey Diagram */}\n <div className=\"dc:flex-1 dc:min-h-0\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <Sankey\n data={flowData}\n nodeWidth={nodeWidth}\n nodePadding={nodePadding}\n margin={{ top: 20, right: 20, bottom: 20, left: 20 }}\n link={{\n stroke: 'var(--dc-border)',\n strokeOpacity: linkOpacity,\n }}\n node={(props: any) => (\n <SankeyNode {...props} containerWidth={containerWidth} showLabels={showNodeLabels} />\n )}\n >\n <Tooltip content={<SankeyTooltip />} />\n </Sankey>\n </ResponsiveContainer>\n </div>\n\n {/* Summary Footer */}\n {!(displayConfigAny?.hideSummaryFooter) && summaryStats && (\n <div className=\"dc:flex-shrink-0 dc:px-4 dc:py-2 dc:border-t border-dc-border bg-dc-surface-secondary\">\n <div className=\"dc:flex dc:items-center dc:justify-between dc:text-sm\">\n <div className=\"text-dc-text-muted\">\n <span className=\"dc:font-medium\">{summaryStats.nodeCount}</span> events\n </div>\n <div className=\"text-dc-text\">\n <span className=\"text-dc-text-muted\">Paths:</span>{' '}\n <span className=\"dc:font-medium\">{summaryStats.linkCount}</span>\n </div>\n <div className=\"text-dc-text-muted\">\n <span className=\"dc:font-medium\">{summaryStats.totalEntities.toLocaleString()}</span> starting entities\n </div>\n </div>\n </div>\n )}\n </div>\n )\n})\n\nexport default SankeyChart\n"],"names":["SANKEY_COLORS","getNodeColor","layer","colorPalette","absLayer","transformToRechartsFormat","data","nodeIndexMap","node","index","nodes","links","link","sourceIndex","targetIndex","extractFlowData","isSankeyData","asAny","SankeyNode","x","y","width","height","payload","containerWidth","showLabels","isRightSide","labelX","textAnchor","jsx","jsxs","SankeyTooltip","active","SankeyChart","React","displayConfig","containerRef","useRef","setContainerWidth","useState","useEffect","updateWidth","displayConfigAny","linkOpacity","nodeWidth","nodePadding","showNodeLabels","flowData","useMemo","extracted","CHART_COLORS","summaryStats","totalEntities","n","sum","totalPaths","l","ResponsiveContainer","Sankey","props","Tooltip"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { jsx as e, jsxs as c } from "react/jsx-runtime";
2
2
  import O, { useState as Y } from "react";
3
3
  import { ScatterChart as B, CartesianGrid as C, XAxis as U, YAxis as W, Tooltip as $, Legend as J, Scatter as z } from "recharts";
4
- import { u as Q, g as V, d as F, e as I, i as _, C as Z, a as q, f as k, c as D } from "./charts-core-CU9u_HtL.js";
4
+ import { u as Q, g as V, d as F, e as I, i as _, C as Z, a as q, f as k, c as D } from "./charts-core-B4Rbfdcn.js";
5
5
  const ne = O.memo(function({
6
6
  data: g,
7
7
  chartConfig: i,
@@ -199,4 +199,4 @@ const ne = O.memo(function({
199
199
  export {
200
200
  ne as default
201
201
  };
202
- //# sourceMappingURL=chart-scatter-l_yTVxF3.js.map
202
+ //# sourceMappingURL=chart-scatter-CAkbBDkK.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chart-scatter-l_yTVxF3.js","sources":["../../../src/client/components/charts/ScatterChart.tsx"],"sourcesContent":["import React, { useState } from 'react'\nimport { ScatterChart as RechartsScatterChart, Scatter, XAxis, YAxis, CartesianGrid, Legend, Tooltip } from 'recharts'\nimport ChartContainer from './ChartContainer'\nimport { CHART_COLORS, CHART_MARGINS } from '../../utils/chartConstants'\nimport { formatTimeValue, getFieldGranularity, parseNumericValue, isValidNumericValue, formatAxisValue } from '../../utils/chartUtils'\nimport { useCubeFieldLabel } from '../../hooks/useCubeFieldLabel'\nimport type { ChartProps } from '../../types'\n\nconst ScatterChart = React.memo(function ScatterChart({ \n data, \n chartConfig, \n displayConfig = {},\n queryObject,\n height = \"100%\",\n colorPalette\n}: ChartProps) {\n const [hoveredLegend, setHoveredLegend] = useState<string | null>(null)\n // Use specialized hook to avoid re-renders from unrelated context changes\n const getFieldLabel = useCubeFieldLabel()\n \n try {\n const safeDisplayConfig = {\n showLegend: displayConfig?.showLegend ?? true,\n showGrid: displayConfig?.showGrid ?? true,\n showTooltip: displayConfig?.showTooltip ?? true\n }\n\n // Extract axis format configs\n // For scatter charts, xAxis uses xAxisFormat, yAxis uses leftYAxisFormat\n const xAxisFormat = displayConfig?.xAxisFormat\n const yAxisFormat = displayConfig?.leftYAxisFormat\n\n if (!data || data.length === 0) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">No data available</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">No data points to display in scatter chart</div>\n </div>\n </div>\n )\n }\n\n // Validate chartConfig - support both legacy and new formats\n let xAxisField: string\n let yAxisField: string\n let seriesFields: string[] = []\n \n if (chartConfig?.xAxis && chartConfig?.yAxis) {\n // New format - handle both string and array values\n xAxisField = Array.isArray(chartConfig.xAxis) ? chartConfig.xAxis[0] : chartConfig.xAxis\n yAxisField = Array.isArray(chartConfig.yAxis) ? chartConfig.yAxis[0] : chartConfig.yAxis\n // Normalize series to array\n const seriesConfig = chartConfig.series\n seriesFields = seriesConfig ? (Array.isArray(seriesConfig) ? seriesConfig : [seriesConfig]) : []\n } else if (chartConfig?.x && chartConfig?.y) {\n // Legacy format (adapt for scatter chart)\n xAxisField = chartConfig.x\n yAxisField = Array.isArray(chartConfig.y) ? chartConfig.y[0] : chartConfig.y\n } else {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-warning\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">Configuration Error</div>\n <div className=\"dc:text-xs\">Invalid or missing chart axis configuration</div>\n </div>\n </div>\n )\n }\n\n if (!xAxisField || !yAxisField) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-warning\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">Configuration Error</div>\n <div className=\"dc:text-xs\">Missing required X-axis or Y-axis fields</div>\n </div>\n </div>\n )\n }\n\n // Extract time dimensions from query for tooltip display\n const timeDimensions = queryObject?.timeDimensions || []\n const timeDimensionFields = timeDimensions.map((td: any) => td.dimension)\n\n // Transform data for scatter plot\n // Null handling: Filter out data points where x or y coordinates are null\n let scatterData: any[]\n let seriesGroups: { [key: string]: any[] } = {}\n\n if (seriesFields.length > 0) {\n // Group data by series field\n const seriesField = seriesFields[0]\n data.forEach(item => {\n const seriesValue = String(item[seriesField] || 'Default')\n if (!seriesGroups[seriesValue]) {\n seriesGroups[seriesValue] = []\n }\n\n const xGranularity = getFieldGranularity(queryObject, xAxisField)\n const xValue = formatTimeValue(item[xAxisField], xGranularity) || item[xAxisField]\n const yValue = parseNumericValue(item[yAxisField])\n\n // Only add point if both x and y are valid numbers\n const xNum = typeof xValue === 'string' ? parseFloat(xValue) : xValue\n if (isValidNumericValue(xNum) && yValue !== null) {\n // Extract time dimension values for tooltip\n const timeValues: { [key: string]: string } = {}\n timeDimensionFields.forEach((field: string) => {\n if (item[field]) {\n const granularity = getFieldGranularity(queryObject, field)\n timeValues[field] = formatTimeValue(item[field], granularity)\n }\n })\n\n seriesGroups[seriesValue].push({\n x: xNum,\n y: yValue,\n name: seriesValue,\n timeValues,\n originalItem: item\n })\n }\n })\n\n // Collect all valid points from all series for validation\n // (The actual rendering uses seriesGroups with series separated)\n const seriesKeys = Object.keys(seriesGroups)\n scatterData = seriesKeys.flatMap(key => seriesGroups[key])\n } else {\n // Single series scatter plot\n const xGranularity = getFieldGranularity(queryObject, xAxisField)\n scatterData = data\n .map(item => {\n const xValue = formatTimeValue(item[xAxisField], xGranularity) || item[xAxisField]\n const yValue = parseNumericValue(item[yAxisField])\n const xNum = typeof xValue === 'string' ? parseFloat(xValue) : xValue\n\n // Extract time dimension values for tooltip\n const timeValues: { [key: string]: string } = {}\n timeDimensionFields.forEach((field: string) => {\n if (item[field]) {\n const granularity = getFieldGranularity(queryObject, field)\n timeValues[field] = formatTimeValue(item[field], granularity)\n }\n })\n\n return {\n x: xNum,\n y: yValue,\n name: `Point`,\n timeValues,\n originalItem: item,\n isValid: isValidNumericValue(xNum) && yValue !== null\n }\n })\n .filter(point => point.isValid)\n }\n \n // Validate transformed data\n if (!scatterData || scatterData.length === 0) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">No valid data</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">No valid data points for scatter chart after transformation</div>\n </div>\n </div>\n )\n }\n\n const seriesKeys = Object.keys(seriesGroups)\n // Limit series to prevent performance issues with high-cardinality fields (e.g., dates)\n // If more than 20 unique series, fall back to single-series mode\n const MAX_SERIES = 20\n const hasSeries = seriesKeys.length > 1 && seriesKeys.length <= MAX_SERIES\n \n // Determine if legend will be shown\n const showLegend = safeDisplayConfig.showLegend && hasSeries\n \n // Use custom chart margins with extra left space for Y-axis label\n const chartMargins = {\n ...CHART_MARGINS,\n left: 40 // Increased from 20 to 40 for Y-axis label space\n }\n\n return (\n <ChartContainer height={height}>\n <RechartsScatterChart margin={chartMargins} accessibilityLayer={false}>\n {safeDisplayConfig.showGrid && (\n <CartesianGrid strokeDasharray=\"3 3\" />\n )}\n <XAxis\n type=\"number\"\n dataKey=\"x\"\n name={xAxisFormat?.label || getFieldLabel(xAxisField)}\n tick={{ fontSize: 12 }}\n tickFormatter={xAxisFormat ? (value) => formatAxisValue(value, xAxisFormat) : undefined}\n />\n <YAxis\n type=\"number\"\n dataKey=\"y\"\n name={yAxisFormat?.label || getFieldLabel(yAxisField)}\n tick={{ fontSize: 12 }}\n tickFormatter={yAxisFormat ? (value) => formatAxisValue(value, yAxisFormat) : undefined}\n label={{ value: yAxisFormat?.label || getFieldLabel(yAxisField), angle: -90, position: 'left', style: { textAnchor: 'middle', fontSize: '12px' } }}\n />\n {safeDisplayConfig.showTooltip && (\n <Tooltip\n cursor={{ strokeDasharray: '3 3' }}\n content={({ active, payload }) => {\n if (!active || !payload || payload.length === 0) return null\n // Only show the first (active) point\n const point = payload[0]?.payload\n if (!point) return null\n\n return (\n <div style={{\n backgroundColor: 'white',\n border: '1px solid #e5e7eb',\n borderRadius: '0.5rem',\n fontSize: '0.875rem',\n color: '#1f2937',\n boxShadow: '0 4px 6px -1px rgba(0, 0, 0, 0.1)',\n padding: '8px 12px'\n }}>\n <div style={{ fontWeight: 600, marginBottom: '4px' }}>{point.name}</div>\n {/* Show time dimension values if present */}\n {point.timeValues && Object.keys(point.timeValues).length > 0 && (\n <div style={{ marginBottom: '4px', color: '#6b7280' }}>\n {Object.entries(point.timeValues).map(([field, value]) => (\n <div key={field}>{getFieldLabel(field)}: {value as string}</div>\n ))}\n </div>\n )}\n <div>{xAxisFormat?.label || getFieldLabel(xAxisField)}: {formatAxisValue(point.x, xAxisFormat)}</div>\n <div>{yAxisFormat?.label || getFieldLabel(yAxisField)}: {formatAxisValue(point.y, yAxisFormat)}</div>\n </div>\n )\n }}\n />\n )}\n {showLegend && (\n <Legend \n wrapperStyle={{ fontSize: '12px', paddingTop: '10px' }}\n iconType=\"circle\"\n iconSize={8}\n layout=\"horizontal\"\n align=\"center\"\n verticalAlign=\"bottom\"\n onMouseEnter={(o) => setHoveredLegend(String(o.dataKey || ''))}\n onMouseLeave={() => setHoveredLegend(null)}\n />\n )}\n {hasSeries ? (\n // Multiple series\n seriesKeys.map((seriesKey, index) => (\n <Scatter\n key={seriesKey}\n name={seriesKey}\n data={seriesGroups[seriesKey]}\n fill={(colorPalette?.colors && colorPalette.colors[index % colorPalette.colors.length]) || CHART_COLORS[index % CHART_COLORS.length]}\n fillOpacity={hoveredLegend ? (hoveredLegend === seriesKey ? 1 : 0.3) : 1}\n />\n ))\n ) : (\n // Single series\n <Scatter\n name=\"Data\"\n data={scatterData}\n fill={(colorPalette?.colors && colorPalette.colors[0]) || CHART_COLORS[0]}\n />\n )}\n </RechartsScatterChart>\n </ChartContainer>\n )\n } catch (error) {\n // 'ScatterChart rendering error\n return (\n <div className=\"dc:flex dc:flex-col dc:items-center dc:justify-center dc:w-full text-dc-error dc:p-4\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">Scatter Chart Error</div>\n <div className=\"dc:text-xs dc:mb-2\">{error instanceof Error ? error.message : 'Unknown rendering error'}</div>\n <div className=\"dc:text-xs text-dc-text-muted\">Check the data and configuration</div>\n </div>\n </div>\n )\n }\n})\n\nexport default ScatterChart"],"names":["ScatterChart","React","data","chartConfig","displayConfig","queryObject","height","colorPalette","hoveredLegend","setHoveredLegend","useState","getFieldLabel","useCubeFieldLabel","safeDisplayConfig","xAxisFormat","yAxisFormat","jsx","jsxs","xAxisField","yAxisField","seriesFields","seriesConfig","timeDimensionFields","td","scatterData","seriesGroups","seriesField","item","seriesValue","xGranularity","getFieldGranularity","xValue","formatTimeValue","yValue","parseNumericValue","xNum","isValidNumericValue","timeValues","field","granularity","key","point","seriesKeys","hasSeries","showLegend","chartMargins","CHART_MARGINS","ChartContainer","RechartsScatterChart","CartesianGrid","XAxis","value","formatAxisValue","YAxis","Tooltip","active","payload","Legend","o","seriesKey","index","Scatter","CHART_COLORS","error"],"mappings":";;;;AAQA,MAAMA,KAAeC,EAAM,KAAK,SAAsB;AAAA,EACpD,MAAAC;AAAA,EACA,aAAAC;AAAA,EACA,eAAAC,IAAgB,CAAA;AAAA,EAChB,aAAAC;AAAA,EACA,QAAAC,IAAS;AAAA,EACT,cAAAC;AACF,GAAe;AACb,QAAM,CAACC,GAAeC,CAAgB,IAAIC,EAAwB,IAAI,GAEhEC,IAAgBC,EAAA;AAEtB,MAAI;AACF,UAAMC,IAAoB;AAAA,MACxB,YAAYT,GAAe,cAAc;AAAA,MACzC,UAAUA,GAAe,YAAY;AAAA,MACrC,aAAaA,GAAe,eAAe;AAAA,IAAA,GAKvCU,IAAcV,GAAe,aAC7BW,IAAcX,GAAe;AAEnC,QAAI,CAACF,KAAQA,EAAK,WAAW;AAC3B,aACE,gBAAAc,EAAC,OAAA,EAAI,WAAU,0EAAyE,OAAO,EAAE,QAAAV,EAAA,GAC/F,UAAA,gBAAAW,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,QAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,uCAAsC,UAAA,qBAAiB;AAAA,QACtE,gBAAAA,EAAC,OAAA,EAAI,WAAU,qCAAoC,UAAA,6CAAA,CAA0C;AAAA,MAAA,EAAA,CAC/F,EAAA,CACF;AAKJ,QAAIE,GACAC,GACAC,IAAyB,CAAA;AAE7B,QAAIjB,GAAa,SAASA,GAAa,OAAO;AAE5C,MAAAe,IAAa,MAAM,QAAQf,EAAY,KAAK,IAAIA,EAAY,MAAM,CAAC,IAAIA,EAAY,OACnFgB,IAAa,MAAM,QAAQhB,EAAY,KAAK,IAAIA,EAAY,MAAM,CAAC,IAAIA,EAAY;AAEnF,YAAMkB,IAAelB,EAAY;AACjC,MAAAiB,IAAeC,IAAgB,MAAM,QAAQA,CAAY,IAAIA,IAAe,CAACA,CAAY,IAAK,CAAA;AAAA,IAChG,WAAWlB,GAAa,KAAKA,GAAa;AAExC,MAAAe,IAAaf,EAAY,GACzBgB,IAAa,MAAM,QAAQhB,EAAY,CAAC,IAAIA,EAAY,EAAE,CAAC,IAAIA,EAAY;AAAA;AAE3E,aACE,gBAAAa,EAAC,OAAA,EAAI,WAAU,uEAAsE,OAAO,EAAE,QAAAV,EAAA,GAC5F,UAAA,gBAAAW,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,QAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,uCAAsC,UAAA,uBAAmB;AAAA,QACxE,gBAAAA,EAAC,OAAA,EAAI,WAAU,cAAa,UAAA,8CAAA,CAA2C;AAAA,MAAA,EAAA,CACzE,EAAA,CACF;AAIJ,QAAI,CAACE,KAAc,CAACC;AAClB,aACE,gBAAAH,EAAC,OAAA,EAAI,WAAU,uEAAsE,OAAO,EAAE,QAAAV,EAAA,GAC5F,UAAA,gBAAAW,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,QAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,uCAAsC,UAAA,uBAAmB;AAAA,QACxE,gBAAAA,EAAC,OAAA,EAAI,WAAU,cAAa,UAAA,2CAAA,CAAwC;AAAA,MAAA,EAAA,CACtE,EAAA,CACF;AAMJ,UAAMM,KADiBjB,GAAa,kBAAkB,CAAA,GACX,IAAI,CAACkB,MAAYA,EAAG,SAAS;AAIxE,QAAIC,GACAC,IAAyC,CAAA;AAE7C,QAAIL,EAAa,SAAS,GAAG;AAE3B,YAAMM,IAAcN,EAAa,CAAC;AAClC,MAAAlB,EAAK,QAAQ,CAAAyB,MAAQ;AACnB,cAAMC,IAAc,OAAOD,EAAKD,CAAW,KAAK,SAAS;AACzD,QAAKD,EAAaG,CAAW,MAC3BH,EAAaG,CAAW,IAAI,CAAA;AAG9B,cAAMC,IAAeC,EAAoBzB,GAAaa,CAAU,GAC1Da,IAASC,EAAgBL,EAAKT,CAAU,GAAGW,CAAY,KAAKF,EAAKT,CAAU,GAC3Ee,IAASC,EAAkBP,EAAKR,CAAU,CAAC,GAG3CgB,IAAO,OAAOJ,KAAW,WAAW,WAAWA,CAAM,IAAIA;AAC/D,YAAIK,EAAoBD,CAAI,KAAKF,MAAW,MAAM;AAEhD,gBAAMI,IAAwC,CAAA;AAC9C,UAAAf,EAAoB,QAAQ,CAACgB,MAAkB;AAC7C,gBAAIX,EAAKW,CAAK,GAAG;AACf,oBAAMC,IAAcT,EAAoBzB,GAAaiC,CAAK;AAC1D,cAAAD,EAAWC,CAAK,IAAIN,EAAgBL,EAAKW,CAAK,GAAGC,CAAW;AAAA,YAC9D;AAAA,UACF,CAAC,GAEDd,EAAaG,CAAW,EAAE,KAAK;AAAA,YAC7B,GAAGO;AAAA,YACH,GAAGF;AAAA,YACH,MAAML;AAAA,YACN,YAAAS;AAAA,YACA,cAAcV;AAAA,UAAA,CACf;AAAA,QACH;AAAA,MACF,CAAC,GAKDH,IADmB,OAAO,KAAKC,CAAY,EAClB,QAAQ,CAAAe,MAAOf,EAAae,CAAG,CAAC;AAAA,IAC3D,OAAO;AAEL,YAAMX,IAAeC,EAAoBzB,GAAaa,CAAU;AAChE,MAAAM,IAActB,EACX,IAAI,CAAAyB,MAAQ;AACX,cAAMI,IAASC,EAAgBL,EAAKT,CAAU,GAAGW,CAAY,KAAKF,EAAKT,CAAU,GAC3Ee,IAASC,EAAkBP,EAAKR,CAAU,CAAC,GAC3CgB,IAAO,OAAOJ,KAAW,WAAW,WAAWA,CAAM,IAAIA,GAGzDM,IAAwC,CAAA;AAC9C,eAAAf,EAAoB,QAAQ,CAACgB,MAAkB;AAC7C,cAAIX,EAAKW,CAAK,GAAG;AACf,kBAAMC,IAAcT,EAAoBzB,GAAaiC,CAAK;AAC1D,YAAAD,EAAWC,CAAK,IAAIN,EAAgBL,EAAKW,CAAK,GAAGC,CAAW;AAAA,UAC9D;AAAA,QACF,CAAC,GAEM;AAAA,UACL,GAAGJ;AAAA,UACH,GAAGF;AAAA,UACH,MAAM;AAAA,UACN,YAAAI;AAAA,UACA,cAAcV;AAAA,UACd,SAASS,EAAoBD,CAAI,KAAKF,MAAW;AAAA,QAAA;AAAA,MAErD,CAAC,EACA,OAAO,CAAAQ,MAASA,EAAM,OAAO;AAAA,IAClC;AAGA,QAAI,CAACjB,KAAeA,EAAY,WAAW;AACzC,aACE,gBAAAR,EAAC,OAAA,EAAI,WAAU,0EAAyE,OAAO,EAAE,QAAAV,EAAA,GAC/F,UAAA,gBAAAW,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,QAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,uCAAsC,UAAA,iBAAa;AAAA,QAClE,gBAAAA,EAAC,OAAA,EAAI,WAAU,qCAAoC,UAAA,8DAAA,CAA2D;AAAA,MAAA,EAAA,CAChH,EAAA,CACF;AAIJ,UAAM0B,IAAa,OAAO,KAAKjB,CAAY,GAIrCkB,IAAYD,EAAW,SAAS,KAAKA,EAAW,UADnC,IAIbE,IAAa/B,EAAkB,cAAc8B,GAG7CE,IAAe;AAAA,MACnB,GAAGC;AAAA,MACH,MAAM;AAAA;AAAA,IAAA;AAGR,WACE,gBAAA9B,EAAC+B,KAAe,QAAAzC,GACd,UAAA,gBAAAW,EAAC+B,KAAqB,QAAQH,GAAc,oBAAoB,IAC7D,UAAA;AAAA,MAAAhC,EAAkB,YACjB,gBAAAG,EAACiC,GAAA,EAAc,iBAAgB,OAAM;AAAA,MAEvC,gBAAAjC;AAAA,QAACkC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAQ;AAAA,UACR,MAAMpC,GAAa,SAASH,EAAcO,CAAU;AAAA,UACpD,MAAM,EAAE,UAAU,GAAA;AAAA,UAClB,eAAeJ,IAAc,CAACqC,MAAUC,EAAgBD,GAAOrC,CAAW,IAAI;AAAA,QAAA;AAAA,MAAA;AAAA,MAEhF,gBAAAE;AAAA,QAACqC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAQ;AAAA,UACR,MAAMtC,GAAa,SAASJ,EAAcQ,CAAU;AAAA,UACpD,MAAM,EAAE,UAAU,GAAA;AAAA,UAClB,eAAeJ,IAAc,CAACoC,MAAUC,EAAgBD,GAAOpC,CAAW,IAAI;AAAA,UAC9E,OAAO,EAAE,OAAOA,GAAa,SAASJ,EAAcQ,CAAU,GAAG,OAAO,KAAK,UAAU,QAAQ,OAAO,EAAE,YAAY,UAAU,UAAU,SAAO;AAAA,QAAE;AAAA,MAAA;AAAA,MAElJN,EAAkB,eACjB,gBAAAG;AAAA,QAACsC;AAAA,QAAA;AAAA,UACC,QAAQ,EAAE,iBAAiB,MAAA;AAAA,UAC3B,SAAS,CAAC,EAAE,QAAAC,GAAQ,SAAAC,QAAc;AAChC,gBAAI,CAACD,KAAU,CAACC,KAAWA,EAAQ,WAAW,EAAG,QAAO;AAExD,kBAAMf,IAAQe,EAAQ,CAAC,GAAG;AAC1B,mBAAKf,IAGH,gBAAAxB,EAAC,SAAI,OAAO;AAAA,cACV,iBAAiB;AAAA,cACjB,QAAQ;AAAA,cACR,cAAc;AAAA,cACd,UAAU;AAAA,cACV,OAAO;AAAA,cACP,WAAW;AAAA,cACX,SAAS;AAAA,YAAA,GAET,UAAA;AAAA,cAAA,gBAAAD,EAAC,OAAA,EAAI,OAAO,EAAE,YAAY,KAAK,cAAc,MAAA,GAAU,UAAAyB,EAAM,KAAA,CAAK;AAAA,cAEjEA,EAAM,cAAc,OAAO,KAAKA,EAAM,UAAU,EAAE,SAAS,KAC1D,gBAAAzB,EAAC,OAAA,EAAI,OAAO,EAAE,cAAc,OAAO,OAAO,UAAA,GACvC,UAAA,OAAO,QAAQyB,EAAM,UAAU,EAAE,IAAI,CAAC,CAACH,GAAOa,CAAK,wBACjD,OAAA,EAAiB,UAAA;AAAA,gBAAAxC,EAAc2B,CAAK;AAAA,gBAAE;AAAA,gBAAGa;AAAA,cAAA,KAAhCb,CAAgD,CAC3D,GACH;AAAA,gCAED,OAAA,EAAK,UAAA;AAAA,gBAAAxB,GAAa,SAASH,EAAcO,CAAU;AAAA,gBAAE;AAAA,gBAAGkC,EAAgBX,EAAM,GAAG3B,CAAW;AAAA,cAAA,GAAE;AAAA,gCAC9F,OAAA,EAAK,UAAA;AAAA,gBAAAC,GAAa,SAASJ,EAAcQ,CAAU;AAAA,gBAAE;AAAA,gBAAGiC,EAAgBX,EAAM,GAAG1B,CAAW;AAAA,cAAA,EAAA,CAAE;AAAA,YAAA,GACjG,IAvBiB;AAAA,UAyBrB;AAAA,QAAA;AAAA,MAAA;AAAA,MAGH6B,KACC,gBAAA5B;AAAA,QAACyC;AAAA,QAAA;AAAA,UACC,cAAc,EAAE,UAAU,QAAQ,YAAY,OAAA;AAAA,UAC9C,UAAS;AAAA,UACT,UAAU;AAAA,UACV,QAAO;AAAA,UACP,OAAM;AAAA,UACN,eAAc;AAAA,UACd,cAAc,CAACC,MAAMjD,EAAiB,OAAOiD,EAAE,WAAW,EAAE,CAAC;AAAA,UAC7D,cAAc,MAAMjD,EAAiB,IAAI;AAAA,QAAA;AAAA,MAAA;AAAA,MAG5CkC;AAAA;AAAA,QAECD,EAAW,IAAI,CAACiB,GAAWC,MACzB,gBAAA5C;AAAA,UAAC6C;AAAA,UAAA;AAAA,YAEC,MAAMF;AAAA,YACN,MAAMlC,EAAakC,CAAS;AAAA,YAC5B,MAAOpD,GAAc,UAAUA,EAAa,OAAOqD,IAAQrD,EAAa,OAAO,MAAM,KAAMuD,EAAaF,IAAQE,EAAa,MAAM;AAAA,YACnI,aAAatD,IAAiBA,MAAkBmD,IAAY,IAAI,MAAO;AAAA,UAAA;AAAA,UAJlEA;AAAA,QAAA,CAMR;AAAA;AAAA;AAAA,QAGD,gBAAA3C;AAAA,UAAC6C;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,MAAMrC;AAAA,YACN,MAAOjB,GAAc,UAAUA,EAAa,OAAO,CAAC,KAAMuD,EAAa,CAAC;AAAA,UAAA;AAAA,QAAA;AAAA;AAAA,IAC1E,EAAA,CAEJ,EAAA,CACF;AAAA,EAEJ,SAASC,GAAO;AAEd,WACE,gBAAA/C,EAAC,OAAA,EAAI,WAAU,wFAAuF,OAAO,EAAE,QAAAV,EAAA,GAC7G,UAAA,gBAAAW,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,MAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,uCAAsC,UAAA,uBAAmB;AAAA,MACxE,gBAAAA,EAAC,SAAI,WAAU,sBAAsB,uBAAiB,QAAQ+C,EAAM,UAAU,0BAAA,CAA0B;AAAA,MACxG,gBAAA/C,EAAC,OAAA,EAAI,WAAU,iCAAgC,UAAA,mCAAA,CAAgC;AAAA,IAAA,EAAA,CACjF,EAAA,CACF;AAAA,EAEJ;AACF,CAAC;"}
1
+ {"version":3,"file":"chart-scatter-CAkbBDkK.js","sources":["../../../src/client/components/charts/ScatterChart.tsx"],"sourcesContent":["import React, { useState } from 'react'\nimport { ScatterChart as RechartsScatterChart, Scatter, XAxis, YAxis, CartesianGrid, Legend, Tooltip } from 'recharts'\nimport ChartContainer from './ChartContainer'\nimport { CHART_COLORS, CHART_MARGINS } from '../../utils/chartConstants'\nimport { formatTimeValue, getFieldGranularity, parseNumericValue, isValidNumericValue, formatAxisValue } from '../../utils/chartUtils'\nimport { useCubeFieldLabel } from '../../hooks/useCubeFieldLabel'\nimport type { ChartProps } from '../../types'\n\nconst ScatterChart = React.memo(function ScatterChart({ \n data, \n chartConfig, \n displayConfig = {},\n queryObject,\n height = \"100%\",\n colorPalette\n}: ChartProps) {\n const [hoveredLegend, setHoveredLegend] = useState<string | null>(null)\n // Use specialized hook to avoid re-renders from unrelated context changes\n const getFieldLabel = useCubeFieldLabel()\n \n try {\n const safeDisplayConfig = {\n showLegend: displayConfig?.showLegend ?? true,\n showGrid: displayConfig?.showGrid ?? true,\n showTooltip: displayConfig?.showTooltip ?? true\n }\n\n // Extract axis format configs\n // For scatter charts, xAxis uses xAxisFormat, yAxis uses leftYAxisFormat\n const xAxisFormat = displayConfig?.xAxisFormat\n const yAxisFormat = displayConfig?.leftYAxisFormat\n\n if (!data || data.length === 0) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">No data available</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">No data points to display in scatter chart</div>\n </div>\n </div>\n )\n }\n\n // Validate chartConfig - support both legacy and new formats\n let xAxisField: string\n let yAxisField: string\n let seriesFields: string[] = []\n \n if (chartConfig?.xAxis && chartConfig?.yAxis) {\n // New format - handle both string and array values\n xAxisField = Array.isArray(chartConfig.xAxis) ? chartConfig.xAxis[0] : chartConfig.xAxis\n yAxisField = Array.isArray(chartConfig.yAxis) ? chartConfig.yAxis[0] : chartConfig.yAxis\n // Normalize series to array\n const seriesConfig = chartConfig.series\n seriesFields = seriesConfig ? (Array.isArray(seriesConfig) ? seriesConfig : [seriesConfig]) : []\n } else if (chartConfig?.x && chartConfig?.y) {\n // Legacy format (adapt for scatter chart)\n xAxisField = chartConfig.x\n yAxisField = Array.isArray(chartConfig.y) ? chartConfig.y[0] : chartConfig.y\n } else {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-warning\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">Configuration Error</div>\n <div className=\"dc:text-xs\">Invalid or missing chart axis configuration</div>\n </div>\n </div>\n )\n }\n\n if (!xAxisField || !yAxisField) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-warning\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">Configuration Error</div>\n <div className=\"dc:text-xs\">Missing required X-axis or Y-axis fields</div>\n </div>\n </div>\n )\n }\n\n // Extract time dimensions from query for tooltip display\n const timeDimensions = queryObject?.timeDimensions || []\n const timeDimensionFields = timeDimensions.map((td: any) => td.dimension)\n\n // Transform data for scatter plot\n // Null handling: Filter out data points where x or y coordinates are null\n let scatterData: any[]\n let seriesGroups: { [key: string]: any[] } = {}\n\n if (seriesFields.length > 0) {\n // Group data by series field\n const seriesField = seriesFields[0]\n data.forEach(item => {\n const seriesValue = String(item[seriesField] || 'Default')\n if (!seriesGroups[seriesValue]) {\n seriesGroups[seriesValue] = []\n }\n\n const xGranularity = getFieldGranularity(queryObject, xAxisField)\n const xValue = formatTimeValue(item[xAxisField], xGranularity) || item[xAxisField]\n const yValue = parseNumericValue(item[yAxisField])\n\n // Only add point if both x and y are valid numbers\n const xNum = typeof xValue === 'string' ? parseFloat(xValue) : xValue\n if (isValidNumericValue(xNum) && yValue !== null) {\n // Extract time dimension values for tooltip\n const timeValues: { [key: string]: string } = {}\n timeDimensionFields.forEach((field: string) => {\n if (item[field]) {\n const granularity = getFieldGranularity(queryObject, field)\n timeValues[field] = formatTimeValue(item[field], granularity)\n }\n })\n\n seriesGroups[seriesValue].push({\n x: xNum,\n y: yValue,\n name: seriesValue,\n timeValues,\n originalItem: item\n })\n }\n })\n\n // Collect all valid points from all series for validation\n // (The actual rendering uses seriesGroups with series separated)\n const seriesKeys = Object.keys(seriesGroups)\n scatterData = seriesKeys.flatMap(key => seriesGroups[key])\n } else {\n // Single series scatter plot\n const xGranularity = getFieldGranularity(queryObject, xAxisField)\n scatterData = data\n .map(item => {\n const xValue = formatTimeValue(item[xAxisField], xGranularity) || item[xAxisField]\n const yValue = parseNumericValue(item[yAxisField])\n const xNum = typeof xValue === 'string' ? parseFloat(xValue) : xValue\n\n // Extract time dimension values for tooltip\n const timeValues: { [key: string]: string } = {}\n timeDimensionFields.forEach((field: string) => {\n if (item[field]) {\n const granularity = getFieldGranularity(queryObject, field)\n timeValues[field] = formatTimeValue(item[field], granularity)\n }\n })\n\n return {\n x: xNum,\n y: yValue,\n name: `Point`,\n timeValues,\n originalItem: item,\n isValid: isValidNumericValue(xNum) && yValue !== null\n }\n })\n .filter(point => point.isValid)\n }\n \n // Validate transformed data\n if (!scatterData || scatterData.length === 0) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">No valid data</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">No valid data points for scatter chart after transformation</div>\n </div>\n </div>\n )\n }\n\n const seriesKeys = Object.keys(seriesGroups)\n // Limit series to prevent performance issues with high-cardinality fields (e.g., dates)\n // If more than 20 unique series, fall back to single-series mode\n const MAX_SERIES = 20\n const hasSeries = seriesKeys.length > 1 && seriesKeys.length <= MAX_SERIES\n \n // Determine if legend will be shown\n const showLegend = safeDisplayConfig.showLegend && hasSeries\n \n // Use custom chart margins with extra left space for Y-axis label\n const chartMargins = {\n ...CHART_MARGINS,\n left: 40 // Increased from 20 to 40 for Y-axis label space\n }\n\n return (\n <ChartContainer height={height}>\n <RechartsScatterChart margin={chartMargins} accessibilityLayer={false}>\n {safeDisplayConfig.showGrid && (\n <CartesianGrid strokeDasharray=\"3 3\" />\n )}\n <XAxis\n type=\"number\"\n dataKey=\"x\"\n name={xAxisFormat?.label || getFieldLabel(xAxisField)}\n tick={{ fontSize: 12 }}\n tickFormatter={xAxisFormat ? (value) => formatAxisValue(value, xAxisFormat) : undefined}\n />\n <YAxis\n type=\"number\"\n dataKey=\"y\"\n name={yAxisFormat?.label || getFieldLabel(yAxisField)}\n tick={{ fontSize: 12 }}\n tickFormatter={yAxisFormat ? (value) => formatAxisValue(value, yAxisFormat) : undefined}\n label={{ value: yAxisFormat?.label || getFieldLabel(yAxisField), angle: -90, position: 'left', style: { textAnchor: 'middle', fontSize: '12px' } }}\n />\n {safeDisplayConfig.showTooltip && (\n <Tooltip\n cursor={{ strokeDasharray: '3 3' }}\n content={({ active, payload }) => {\n if (!active || !payload || payload.length === 0) return null\n // Only show the first (active) point\n const point = payload[0]?.payload\n if (!point) return null\n\n return (\n <div style={{\n backgroundColor: 'white',\n border: '1px solid #e5e7eb',\n borderRadius: '0.5rem',\n fontSize: '0.875rem',\n color: '#1f2937',\n boxShadow: '0 4px 6px -1px rgba(0, 0, 0, 0.1)',\n padding: '8px 12px'\n }}>\n <div style={{ fontWeight: 600, marginBottom: '4px' }}>{point.name}</div>\n {/* Show time dimension values if present */}\n {point.timeValues && Object.keys(point.timeValues).length > 0 && (\n <div style={{ marginBottom: '4px', color: '#6b7280' }}>\n {Object.entries(point.timeValues).map(([field, value]) => (\n <div key={field}>{getFieldLabel(field)}: {value as string}</div>\n ))}\n </div>\n )}\n <div>{xAxisFormat?.label || getFieldLabel(xAxisField)}: {formatAxisValue(point.x, xAxisFormat)}</div>\n <div>{yAxisFormat?.label || getFieldLabel(yAxisField)}: {formatAxisValue(point.y, yAxisFormat)}</div>\n </div>\n )\n }}\n />\n )}\n {showLegend && (\n <Legend \n wrapperStyle={{ fontSize: '12px', paddingTop: '10px' }}\n iconType=\"circle\"\n iconSize={8}\n layout=\"horizontal\"\n align=\"center\"\n verticalAlign=\"bottom\"\n onMouseEnter={(o) => setHoveredLegend(String(o.dataKey || ''))}\n onMouseLeave={() => setHoveredLegend(null)}\n />\n )}\n {hasSeries ? (\n // Multiple series\n seriesKeys.map((seriesKey, index) => (\n <Scatter\n key={seriesKey}\n name={seriesKey}\n data={seriesGroups[seriesKey]}\n fill={(colorPalette?.colors && colorPalette.colors[index % colorPalette.colors.length]) || CHART_COLORS[index % CHART_COLORS.length]}\n fillOpacity={hoveredLegend ? (hoveredLegend === seriesKey ? 1 : 0.3) : 1}\n />\n ))\n ) : (\n // Single series\n <Scatter\n name=\"Data\"\n data={scatterData}\n fill={(colorPalette?.colors && colorPalette.colors[0]) || CHART_COLORS[0]}\n />\n )}\n </RechartsScatterChart>\n </ChartContainer>\n )\n } catch (error) {\n // 'ScatterChart rendering error\n return (\n <div className=\"dc:flex dc:flex-col dc:items-center dc:justify-center dc:w-full text-dc-error dc:p-4\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">Scatter Chart Error</div>\n <div className=\"dc:text-xs dc:mb-2\">{error instanceof Error ? error.message : 'Unknown rendering error'}</div>\n <div className=\"dc:text-xs text-dc-text-muted\">Check the data and configuration</div>\n </div>\n </div>\n )\n }\n})\n\nexport default ScatterChart"],"names":["ScatterChart","React","data","chartConfig","displayConfig","queryObject","height","colorPalette","hoveredLegend","setHoveredLegend","useState","getFieldLabel","useCubeFieldLabel","safeDisplayConfig","xAxisFormat","yAxisFormat","jsx","jsxs","xAxisField","yAxisField","seriesFields","seriesConfig","timeDimensionFields","td","scatterData","seriesGroups","seriesField","item","seriesValue","xGranularity","getFieldGranularity","xValue","formatTimeValue","yValue","parseNumericValue","xNum","isValidNumericValue","timeValues","field","granularity","key","point","seriesKeys","hasSeries","showLegend","chartMargins","CHART_MARGINS","ChartContainer","RechartsScatterChart","CartesianGrid","XAxis","value","formatAxisValue","YAxis","Tooltip","active","payload","Legend","o","seriesKey","index","Scatter","CHART_COLORS","error"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { jsx as n, jsxs as o } from "react/jsx-runtime";
2
2
  import _, { useRef as j, useState as $, useEffect as A, useMemo as M } from "react";
3
3
  import { ResponsiveContainer as D, SunburstChart as O, Tooltip as T } from "recharts";
4
- import { c as L } from "./charts-core-CU9u_HtL.js";
4
+ import { c as L } from "./charts-core-B4Rbfdcn.js";
5
5
  import { i as z } from "./flow-utils-CjQZG5qq.js";
6
6
  function E(s) {
7
7
  if (!s || s.length === 0) return null;
@@ -185,4 +185,4 @@ const V = _.memo(function({
185
185
  export {
186
186
  V as default
187
187
  };
188
- //# sourceMappingURL=chart-sunburst-KhDcKhmZ.js.map
188
+ //# sourceMappingURL=chart-sunburst-DaxJ-cob.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chart-sunburst-KhDcKhmZ.js","sources":["../../../src/client/components/charts/SunburstChart.tsx"],"sourcesContent":["/**\n * SunburstChart Component\n *\n * Visualizes flow data using a radial sunburst diagram showing paths from a starting step.\n * Works with the same data as SankeyChart but displays it as hierarchical rings.\n *\n * The chart displays:\n * - Center: Starting step (layer 0)\n * - Outward rings: Steps after the starting step (layers 1, 2, 3...)\n * - Values indicating count of entities following each path\n *\n * Note: Unlike Sankey, Sunburst only shows \"after\" steps for cleaner visualization.\n */\n\nimport React, { useMemo, useRef, useState, useEffect } from 'react'\nimport { SunburstChart as RechartsSunburst, ResponsiveContainer, Tooltip } from 'recharts'\nimport { CHART_COLORS } from '../../utils/chartConstants'\nimport type { ChartProps } from '../../types'\nimport type { FlowChartData, SankeyNode, SankeyLink } from '../../types/flow'\nimport { isSankeyData } from '../../types/flow'\n\n/**\n * Hierarchical data structure for Recharts Sunburst\n */\ninterface SunburstNode {\n name: string\n value?: number\n fill?: string\n children?: SunburstNode[]\n /** Original event name (before path prefix was added) */\n originalName?: string\n}\n\n\n/**\n * Extract FlowChartData from various data formats\n */\nfunction extractFlowData(data: unknown[]): FlowChartData | null {\n if (!data || data.length === 0) return null\n\n // If first element is already FlowChartData (server returns as single-row array)\n if (isSankeyData(data[0])) {\n return data[0] as FlowChartData\n }\n\n // If data itself is FlowChartData shape\n if (isSankeyData(data)) {\n return data as unknown as FlowChartData\n }\n\n // Check if data is an array with nodes and links at top level\n const asAny = data as unknown as Record<string, unknown>\n if (asAny.nodes && asAny.links) {\n return asAny as unknown as FlowChartData\n }\n\n return null\n}\n\n/**\n * Transform FlowChartData (nodes + links) into hierarchical Sunburst format\n * Only includes layer 0 (starting) and positive layers (after steps)\n *\n * The transformation builds a tree where:\n * - Root = starting event(s) at layer 0\n * - Children = events linked from parent, following the flow\n * - Each path in the tree represents a unique user journey\n */\nfunction transformToSunburstFormat(\n data: FlowChartData,\n colorPalette?: string[]\n): SunburstNode | null {\n const { nodes, links } = data\n\n if (!nodes || nodes.length === 0) return null\n\n // Filter to only include layer 0 and positive layers (after steps)\n const afterNodes = nodes.filter((n) => n.layer >= 0)\n if (afterNodes.length === 0) return null\n\n // Use theme colors - either from palette or default CHART_COLORS\n const colors = colorPalette || CHART_COLORS\n\n // Get unique event names and create a color map\n // This ensures each event type gets a consistent, distinct color\n const uniqueNames = [...new Set(afterNodes.map((n) => n.name))]\n const colorMap = new Map<string, string>()\n uniqueNames.forEach((name, index) => {\n colorMap.set(name, colors[index % colors.length])\n })\n\n // Create a map of node IDs for quick lookup\n const nodeMap = new Map<string, SankeyNode>()\n afterNodes.forEach((node) => nodeMap.set(node.id, node))\n\n // Create a map of links from source to targets\n // Key: source node ID, Value: array of links from that source\n const linksBySource = new Map<string, SankeyLink[]>()\n links.forEach((link) => {\n // Only include links where source is in our afterNodes set\n if (!nodeMap.has(link.source)) return\n const sourceLinks = linksBySource.get(link.source) || []\n sourceLinks.push(link)\n linksBySource.set(link.source, sourceLinks)\n })\n\n // Find max layer for determining depth\n const maxLayer = Math.max(...afterNodes.map((n) => n.layer))\n\n // Counter for generating unique IDs\n let nodeCounter = 0\n\n /**\n * Recursively build children for a node by following outgoing links\n * Each link becomes a child node in the tree\n *\n * @param nodeId - The source node ID to build children from\n * @param currentLayer - Current layer depth\n * @param pathPrefix - Path from root to this node (for unique naming)\n */\n function buildChildren(nodeId: string, currentLayer: number, pathPrefix: string): SunburstNode[] {\n if (currentLayer >= maxLayer) return []\n\n const outgoingLinks = linksBySource.get(nodeId) || []\n if (outgoingLinks.length === 0) return []\n\n // Filter and map links to children\n const children: SunburstNode[] = []\n\n for (const link of outgoingLinks) {\n const targetNode = nodeMap.get(link.target)\n\n // Only include links to nodes in the next layer\n if (!targetNode || targetNode.layer !== currentLayer + 1) continue\n\n // Generate a unique name by including counter to avoid React key collisions\n nodeCounter++\n const uniqueName = `${targetNode.name}_${nodeCounter}`\n\n // Recursively build grandchildren with updated path\n const newPath = pathPrefix ? `${pathPrefix}→${targetNode.name}` : targetNode.name\n const grandchildren = buildChildren(link.target, currentLayer + 1, newPath)\n\n const child: SunburstNode = {\n name: uniqueName,\n originalName: targetNode.name,\n value: link.value,\n fill: colorMap.get(targetNode.name) || colors[0],\n }\n\n if (grandchildren.length > 0) {\n child.children = grandchildren\n }\n\n children.push(child)\n }\n\n return children\n }\n\n // Get starting nodes (layer 0)\n const startingNodes = afterNodes.filter((n) => n.layer === 0)\n if (startingNodes.length === 0) return null\n\n // Build the tree starting from layer 0 nodes\n if (startingNodes.length === 1) {\n // Single starting node - use it as root\n const startNode = startingNodes[0]\n const children = buildChildren(startNode.id, 0, startNode.name)\n\n const result: SunburstNode = {\n name: startNode.name,\n originalName: startNode.name,\n value: startNode.value || children.reduce((sum, c) => sum + (c.value || 0), 0),\n fill: colorMap.get(startNode.name) || colors[0],\n }\n\n if (children.length > 0) {\n result.children = children\n }\n\n return result\n }\n\n // Multiple starting nodes - create a virtual root\n const rootChildren = startingNodes.map((startNode, index) => {\n nodeCounter++\n const children = buildChildren(startNode.id, 0, startNode.name)\n\n const child: SunburstNode = {\n name: `${startNode.name}_root_${index}`,\n originalName: startNode.name,\n value: startNode.value || children.reduce((sum, c) => sum + (c.value || 0), 0),\n fill: colorMap.get(startNode.name) || colors[0],\n }\n\n if (children.length > 0) {\n child.children = children\n }\n\n return child\n })\n\n return {\n name: 'Start',\n originalName: 'Start',\n children: rootChildren,\n }\n}\n\n/**\n * Custom tooltip for Sunburst chart\n * Shows the original event name (not the unique key used internally)\n */\nfunction SunburstTooltip({\n active,\n payload,\n}: {\n active?: boolean\n payload?: Array<{ payload: SunburstNode }>\n}) {\n if (!active || !payload || payload.length === 0) return null\n\n const data = payload[0].payload\n // Use originalName if available, otherwise fall back to name\n const displayName = data.originalName || data.name\n\n return (\n <div className=\"bg-dc-surface dc:border border-dc-border dc:rounded-md dc:px-3 dc:py-2 dc:shadow-lg dc:text-sm\">\n <div className=\"dc:font-medium text-dc-text\">{displayName}</div>\n {data.value !== undefined && (\n <div className=\"text-dc-text-secondary dc:mt-1\">\n <span className=\"dc:font-medium\">{data.value.toLocaleString()}</span> entities\n </div>\n )}\n </div>\n )\n}\n\n/**\n * SunburstChart Component\n *\n * Renders a sunburst diagram visualization from FlowChartData.\n * Shows hierarchical flow paths radiating from a central starting step.\n */\nconst SunburstChart = React.memo(function SunburstChart({\n data,\n height = '100%',\n colorPalette,\n displayConfig,\n}: ChartProps) {\n // Track chart area dimensions (not the full container which includes footer)\n const chartAreaRef = useRef<HTMLDivElement>(null)\n const [chartSize, setChartSize] = useState({ width: 400, height: 400 })\n\n useEffect(() => {\n const updateSize = () => {\n if (chartAreaRef.current) {\n setChartSize({\n width: chartAreaRef.current.offsetWidth,\n height: chartAreaRef.current.offsetHeight,\n })\n }\n }\n updateSize()\n window.addEventListener('resize', updateSize)\n\n // Use ResizeObserver for more accurate size tracking\n const resizeObserver = new ResizeObserver(updateSize)\n if (chartAreaRef.current) {\n resizeObserver.observe(chartAreaRef.current)\n }\n\n return () => {\n window.removeEventListener('resize', updateSize)\n resizeObserver.disconnect()\n }\n }, [])\n\n // Get display config options\n const displayConfigAny = displayConfig as Record<string, unknown> | undefined\n const innerRadius = (displayConfigAny?.innerRadius as number) ?? 40\n\n // Extract and transform data\n const sunburstData = useMemo(() => {\n const extracted = extractFlowData(data || [])\n if (!extracted) return null\n\n return transformToSunburstFormat(extracted, colorPalette?.colors || CHART_COLORS)\n }, [data, colorPalette])\n\n // Calculate summary stats from original flow data\n const summaryStats = useMemo(() => {\n const extracted = extractFlowData(data || [])\n if (!extracted) return null\n\n // Only count after nodes (layer >= 0)\n const afterNodes = extracted.nodes.filter((n) => n.layer >= 0)\n const afterLinks = extracted.links.filter((link) => {\n const sourceNode = extracted.nodes.find((n) => n.id === link.source)\n return sourceNode && sourceNode.layer >= 0\n })\n\n const totalEntities = extracted.nodes\n .filter((n) => n.layer === 0)\n .reduce((sum, n) => sum + (n.value || 0), 0)\n\n return {\n nodeCount: afterNodes.length,\n linkCount: afterLinks.length,\n totalEntities,\n }\n }, [data])\n\n // Handle no data\n if (!data || data.length === 0 || !sunburstData) {\n return (\n <div\n className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-text-muted\"\n style={{ height }}\n >\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">No flow data</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">\n Configure a flow analysis with a starting step and event dimension\n </div>\n </div>\n </div>\n )\n }\n\n // Calculate outer radius based on chart area size\n const minDimension = Math.min(chartSize.width, chartSize.height)\n const outerRadius = Math.max(minDimension / 2 - 40, 100)\n\n // Get root node info for center label\n const rootName = sunburstData.originalName || sunburstData.name\n const rootValue = sunburstData.value\n\n return (\n <div className=\"dc:relative dc:w-full dc:h-full dc:flex dc:flex-col\" style={{ height }}>\n {/* Sunburst Diagram */}\n <div ref={chartAreaRef} className=\"dc:flex-1 dc:min-h-0 dc:relative\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsSunburst\n data={sunburstData}\n dataKey=\"value\"\n innerRadius={innerRadius}\n outerRadius={outerRadius}\n stroke=\"var(--dc-bg)\"\n >\n <Tooltip content={<SunburstTooltip />} />\n </RechartsSunburst>\n </ResponsiveContainer>\n\n {/* Center label showing the root node (starting event) */}\n {innerRadius > 0 && (\n <div\n className=\"dc:absolute dc:inset-0 dc:flex dc:items-center dc:justify-center dc:pointer-events-none\"\n style={{ zIndex: 10 }}\n >\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold text-dc-text\">{rootName}</div>\n {rootValue !== undefined && (\n <div className=\"dc:text-xs text-dc-text-secondary\">\n {rootValue.toLocaleString()}\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n\n {/* Summary Footer */}\n {!displayConfigAny?.hideSummaryFooter && summaryStats && (\n <div className=\"dc:flex-shrink-0 dc:px-4 dc:py-2 dc:border-t border-dc-border bg-dc-surface-secondary\">\n <div className=\"dc:flex dc:items-center dc:justify-between dc:text-sm\">\n <div className=\"text-dc-text-muted\">\n <span className=\"dc:font-medium\">{summaryStats.nodeCount}</span> events (after)\n </div>\n <div className=\"text-dc-text\">\n <span className=\"text-dc-text-muted\">Paths:</span>{' '}\n <span className=\"dc:font-medium\">{summaryStats.linkCount}</span>\n </div>\n <div className=\"text-dc-text-muted\">\n <span className=\"dc:font-medium\">{summaryStats.totalEntities.toLocaleString()}</span>{' '}\n starting entities\n </div>\n </div>\n </div>\n )}\n </div>\n )\n})\n\nexport default SunburstChart\n"],"names":["extractFlowData","data","isSankeyData","asAny","transformToSunburstFormat","colorPalette","nodes","links","afterNodes","n","colors","CHART_COLORS","uniqueNames","colorMap","name","index","nodeMap","node","linksBySource","link","sourceLinks","maxLayer","nodeCounter","buildChildren","nodeId","currentLayer","pathPrefix","outgoingLinks","children","targetNode","uniqueName","grandchildren","child","startingNodes","startNode","result","sum","c","SunburstTooltip","active","payload","displayName","jsxs","jsx","SunburstChart","React","height","displayConfig","chartAreaRef","useRef","chartSize","setChartSize","useState","useEffect","updateSize","resizeObserver","displayConfigAny","innerRadius","sunburstData","useMemo","extracted","summaryStats","afterLinks","sourceNode","totalEntities","minDimension","outerRadius","rootName","rootValue","ResponsiveContainer","RechartsSunburst","Tooltip"],"mappings":"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"}
1
+ {"version":3,"file":"chart-sunburst-DaxJ-cob.js","sources":["../../../src/client/components/charts/SunburstChart.tsx"],"sourcesContent":["/**\n * SunburstChart Component\n *\n * Visualizes flow data using a radial sunburst diagram showing paths from a starting step.\n * Works with the same data as SankeyChart but displays it as hierarchical rings.\n *\n * The chart displays:\n * - Center: Starting step (layer 0)\n * - Outward rings: Steps after the starting step (layers 1, 2, 3...)\n * - Values indicating count of entities following each path\n *\n * Note: Unlike Sankey, Sunburst only shows \"after\" steps for cleaner visualization.\n */\n\nimport React, { useMemo, useRef, useState, useEffect } from 'react'\nimport { SunburstChart as RechartsSunburst, ResponsiveContainer, Tooltip } from 'recharts'\nimport { CHART_COLORS } from '../../utils/chartConstants'\nimport type { ChartProps } from '../../types'\nimport type { FlowChartData, SankeyNode, SankeyLink } from '../../types/flow'\nimport { isSankeyData } from '../../types/flow'\n\n/**\n * Hierarchical data structure for Recharts Sunburst\n */\ninterface SunburstNode {\n name: string\n value?: number\n fill?: string\n children?: SunburstNode[]\n /** Original event name (before path prefix was added) */\n originalName?: string\n}\n\n\n/**\n * Extract FlowChartData from various data formats\n */\nfunction extractFlowData(data: unknown[]): FlowChartData | null {\n if (!data || data.length === 0) return null\n\n // If first element is already FlowChartData (server returns as single-row array)\n if (isSankeyData(data[0])) {\n return data[0] as FlowChartData\n }\n\n // If data itself is FlowChartData shape\n if (isSankeyData(data)) {\n return data as unknown as FlowChartData\n }\n\n // Check if data is an array with nodes and links at top level\n const asAny = data as unknown as Record<string, unknown>\n if (asAny.nodes && asAny.links) {\n return asAny as unknown as FlowChartData\n }\n\n return null\n}\n\n/**\n * Transform FlowChartData (nodes + links) into hierarchical Sunburst format\n * Only includes layer 0 (starting) and positive layers (after steps)\n *\n * The transformation builds a tree where:\n * - Root = starting event(s) at layer 0\n * - Children = events linked from parent, following the flow\n * - Each path in the tree represents a unique user journey\n */\nfunction transformToSunburstFormat(\n data: FlowChartData,\n colorPalette?: string[]\n): SunburstNode | null {\n const { nodes, links } = data\n\n if (!nodes || nodes.length === 0) return null\n\n // Filter to only include layer 0 and positive layers (after steps)\n const afterNodes = nodes.filter((n) => n.layer >= 0)\n if (afterNodes.length === 0) return null\n\n // Use theme colors - either from palette or default CHART_COLORS\n const colors = colorPalette || CHART_COLORS\n\n // Get unique event names and create a color map\n // This ensures each event type gets a consistent, distinct color\n const uniqueNames = [...new Set(afterNodes.map((n) => n.name))]\n const colorMap = new Map<string, string>()\n uniqueNames.forEach((name, index) => {\n colorMap.set(name, colors[index % colors.length])\n })\n\n // Create a map of node IDs for quick lookup\n const nodeMap = new Map<string, SankeyNode>()\n afterNodes.forEach((node) => nodeMap.set(node.id, node))\n\n // Create a map of links from source to targets\n // Key: source node ID, Value: array of links from that source\n const linksBySource = new Map<string, SankeyLink[]>()\n links.forEach((link) => {\n // Only include links where source is in our afterNodes set\n if (!nodeMap.has(link.source)) return\n const sourceLinks = linksBySource.get(link.source) || []\n sourceLinks.push(link)\n linksBySource.set(link.source, sourceLinks)\n })\n\n // Find max layer for determining depth\n const maxLayer = Math.max(...afterNodes.map((n) => n.layer))\n\n // Counter for generating unique IDs\n let nodeCounter = 0\n\n /**\n * Recursively build children for a node by following outgoing links\n * Each link becomes a child node in the tree\n *\n * @param nodeId - The source node ID to build children from\n * @param currentLayer - Current layer depth\n * @param pathPrefix - Path from root to this node (for unique naming)\n */\n function buildChildren(nodeId: string, currentLayer: number, pathPrefix: string): SunburstNode[] {\n if (currentLayer >= maxLayer) return []\n\n const outgoingLinks = linksBySource.get(nodeId) || []\n if (outgoingLinks.length === 0) return []\n\n // Filter and map links to children\n const children: SunburstNode[] = []\n\n for (const link of outgoingLinks) {\n const targetNode = nodeMap.get(link.target)\n\n // Only include links to nodes in the next layer\n if (!targetNode || targetNode.layer !== currentLayer + 1) continue\n\n // Generate a unique name by including counter to avoid React key collisions\n nodeCounter++\n const uniqueName = `${targetNode.name}_${nodeCounter}`\n\n // Recursively build grandchildren with updated path\n const newPath = pathPrefix ? `${pathPrefix}→${targetNode.name}` : targetNode.name\n const grandchildren = buildChildren(link.target, currentLayer + 1, newPath)\n\n const child: SunburstNode = {\n name: uniqueName,\n originalName: targetNode.name,\n value: link.value,\n fill: colorMap.get(targetNode.name) || colors[0],\n }\n\n if (grandchildren.length > 0) {\n child.children = grandchildren\n }\n\n children.push(child)\n }\n\n return children\n }\n\n // Get starting nodes (layer 0)\n const startingNodes = afterNodes.filter((n) => n.layer === 0)\n if (startingNodes.length === 0) return null\n\n // Build the tree starting from layer 0 nodes\n if (startingNodes.length === 1) {\n // Single starting node - use it as root\n const startNode = startingNodes[0]\n const children = buildChildren(startNode.id, 0, startNode.name)\n\n const result: SunburstNode = {\n name: startNode.name,\n originalName: startNode.name,\n value: startNode.value || children.reduce((sum, c) => sum + (c.value || 0), 0),\n fill: colorMap.get(startNode.name) || colors[0],\n }\n\n if (children.length > 0) {\n result.children = children\n }\n\n return result\n }\n\n // Multiple starting nodes - create a virtual root\n const rootChildren = startingNodes.map((startNode, index) => {\n nodeCounter++\n const children = buildChildren(startNode.id, 0, startNode.name)\n\n const child: SunburstNode = {\n name: `${startNode.name}_root_${index}`,\n originalName: startNode.name,\n value: startNode.value || children.reduce((sum, c) => sum + (c.value || 0), 0),\n fill: colorMap.get(startNode.name) || colors[0],\n }\n\n if (children.length > 0) {\n child.children = children\n }\n\n return child\n })\n\n return {\n name: 'Start',\n originalName: 'Start',\n children: rootChildren,\n }\n}\n\n/**\n * Custom tooltip for Sunburst chart\n * Shows the original event name (not the unique key used internally)\n */\nfunction SunburstTooltip({\n active,\n payload,\n}: {\n active?: boolean\n payload?: Array<{ payload: SunburstNode }>\n}) {\n if (!active || !payload || payload.length === 0) return null\n\n const data = payload[0].payload\n // Use originalName if available, otherwise fall back to name\n const displayName = data.originalName || data.name\n\n return (\n <div className=\"bg-dc-surface dc:border border-dc-border dc:rounded-md dc:px-3 dc:py-2 dc:shadow-lg dc:text-sm\">\n <div className=\"dc:font-medium text-dc-text\">{displayName}</div>\n {data.value !== undefined && (\n <div className=\"text-dc-text-secondary dc:mt-1\">\n <span className=\"dc:font-medium\">{data.value.toLocaleString()}</span> entities\n </div>\n )}\n </div>\n )\n}\n\n/**\n * SunburstChart Component\n *\n * Renders a sunburst diagram visualization from FlowChartData.\n * Shows hierarchical flow paths radiating from a central starting step.\n */\nconst SunburstChart = React.memo(function SunburstChart({\n data,\n height = '100%',\n colorPalette,\n displayConfig,\n}: ChartProps) {\n // Track chart area dimensions (not the full container which includes footer)\n const chartAreaRef = useRef<HTMLDivElement>(null)\n const [chartSize, setChartSize] = useState({ width: 400, height: 400 })\n\n useEffect(() => {\n const updateSize = () => {\n if (chartAreaRef.current) {\n setChartSize({\n width: chartAreaRef.current.offsetWidth,\n height: chartAreaRef.current.offsetHeight,\n })\n }\n }\n updateSize()\n window.addEventListener('resize', updateSize)\n\n // Use ResizeObserver for more accurate size tracking\n const resizeObserver = new ResizeObserver(updateSize)\n if (chartAreaRef.current) {\n resizeObserver.observe(chartAreaRef.current)\n }\n\n return () => {\n window.removeEventListener('resize', updateSize)\n resizeObserver.disconnect()\n }\n }, [])\n\n // Get display config options\n const displayConfigAny = displayConfig as Record<string, unknown> | undefined\n const innerRadius = (displayConfigAny?.innerRadius as number) ?? 40\n\n // Extract and transform data\n const sunburstData = useMemo(() => {\n const extracted = extractFlowData(data || [])\n if (!extracted) return null\n\n return transformToSunburstFormat(extracted, colorPalette?.colors || CHART_COLORS)\n }, [data, colorPalette])\n\n // Calculate summary stats from original flow data\n const summaryStats = useMemo(() => {\n const extracted = extractFlowData(data || [])\n if (!extracted) return null\n\n // Only count after nodes (layer >= 0)\n const afterNodes = extracted.nodes.filter((n) => n.layer >= 0)\n const afterLinks = extracted.links.filter((link) => {\n const sourceNode = extracted.nodes.find((n) => n.id === link.source)\n return sourceNode && sourceNode.layer >= 0\n })\n\n const totalEntities = extracted.nodes\n .filter((n) => n.layer === 0)\n .reduce((sum, n) => sum + (n.value || 0), 0)\n\n return {\n nodeCount: afterNodes.length,\n linkCount: afterLinks.length,\n totalEntities,\n }\n }, [data])\n\n // Handle no data\n if (!data || data.length === 0 || !sunburstData) {\n return (\n <div\n className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-text-muted\"\n style={{ height }}\n >\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">No flow data</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">\n Configure a flow analysis with a starting step and event dimension\n </div>\n </div>\n </div>\n )\n }\n\n // Calculate outer radius based on chart area size\n const minDimension = Math.min(chartSize.width, chartSize.height)\n const outerRadius = Math.max(minDimension / 2 - 40, 100)\n\n // Get root node info for center label\n const rootName = sunburstData.originalName || sunburstData.name\n const rootValue = sunburstData.value\n\n return (\n <div className=\"dc:relative dc:w-full dc:h-full dc:flex dc:flex-col\" style={{ height }}>\n {/* Sunburst Diagram */}\n <div ref={chartAreaRef} className=\"dc:flex-1 dc:min-h-0 dc:relative\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsSunburst\n data={sunburstData}\n dataKey=\"value\"\n innerRadius={innerRadius}\n outerRadius={outerRadius}\n stroke=\"var(--dc-bg)\"\n >\n <Tooltip content={<SunburstTooltip />} />\n </RechartsSunburst>\n </ResponsiveContainer>\n\n {/* Center label showing the root node (starting event) */}\n {innerRadius > 0 && (\n <div\n className=\"dc:absolute dc:inset-0 dc:flex dc:items-center dc:justify-center dc:pointer-events-none\"\n style={{ zIndex: 10 }}\n >\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold text-dc-text\">{rootName}</div>\n {rootValue !== undefined && (\n <div className=\"dc:text-xs text-dc-text-secondary\">\n {rootValue.toLocaleString()}\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n\n {/* Summary Footer */}\n {!displayConfigAny?.hideSummaryFooter && summaryStats && (\n <div className=\"dc:flex-shrink-0 dc:px-4 dc:py-2 dc:border-t border-dc-border bg-dc-surface-secondary\">\n <div className=\"dc:flex dc:items-center dc:justify-between dc:text-sm\">\n <div className=\"text-dc-text-muted\">\n <span className=\"dc:font-medium\">{summaryStats.nodeCount}</span> events (after)\n </div>\n <div className=\"text-dc-text\">\n <span className=\"text-dc-text-muted\">Paths:</span>{' '}\n <span className=\"dc:font-medium\">{summaryStats.linkCount}</span>\n </div>\n <div className=\"text-dc-text-muted\">\n <span className=\"dc:font-medium\">{summaryStats.totalEntities.toLocaleString()}</span>{' '}\n starting entities\n </div>\n </div>\n </div>\n )}\n </div>\n )\n})\n\nexport default SunburstChart\n"],"names":["extractFlowData","data","isSankeyData","asAny","transformToSunburstFormat","colorPalette","nodes","links","afterNodes","n","colors","CHART_COLORS","uniqueNames","colorMap","name","index","nodeMap","node","linksBySource","link","sourceLinks","maxLayer","nodeCounter","buildChildren","nodeId","currentLayer","pathPrefix","outgoingLinks","children","targetNode","uniqueName","grandchildren","child","startingNodes","startNode","result","sum","c","SunburstTooltip","active","payload","displayName","jsxs","jsx","SunburstChart","React","height","displayConfig","chartAreaRef","useRef","chartSize","setChartSize","useState","useEffect","updateSize","resizeObserver","displayConfigAny","innerRadius","sunburstData","useMemo","extracted","summaryStats","afterLinks","sourceNode","totalEntities","minDimension","outerRadius","rootName","rootValue","ResponsiveContainer","RechartsSunburst","Tooltip"],"mappings":";;;;;AAqCA,SAASA,EAAgBC,GAAuC;AAC9D,MAAI,CAACA,KAAQA,EAAK,WAAW,EAAG,QAAO;AAGvC,MAAIC,EAAaD,EAAK,CAAC,CAAC;AACtB,WAAOA,EAAK,CAAC;AAIf,MAAIC,EAAaD,CAAI;AACnB,WAAOA;AAIT,QAAME,IAAQF;AACd,SAAIE,EAAM,SAASA,EAAM,QAChBA,IAGF;AACT;AAWA,SAASC,EACPH,GACAI,GACqB;AACrB,QAAM,EAAE,OAAAC,GAAO,OAAAC,EAAA,IAAUN;AAEzB,MAAI,CAACK,KAASA,EAAM,WAAW,EAAG,QAAO;AAGzC,QAAME,IAAaF,EAAM,OAAO,CAACG,MAAMA,EAAE,SAAS,CAAC;AACnD,MAAID,EAAW,WAAW,EAAG,QAAO;AAGpC,QAAME,IAASL,KAAgBM,GAIzBC,IAAc,CAAC,GAAG,IAAI,IAAIJ,EAAW,IAAI,CAACC,MAAMA,EAAE,IAAI,CAAC,CAAC,GACxDI,wBAAe,IAAA;AACrB,EAAAD,EAAY,QAAQ,CAACE,GAAMC,MAAU;AACnC,IAAAF,EAAS,IAAIC,GAAMJ,EAAOK,IAAQL,EAAO,MAAM,CAAC;AAAA,EAClD,CAAC;AAGD,QAAMM,wBAAc,IAAA;AACpB,EAAAR,EAAW,QAAQ,CAACS,MAASD,EAAQ,IAAIC,EAAK,IAAIA,CAAI,CAAC;AAIvD,QAAMC,wBAAoB,IAAA;AAC1B,EAAAX,EAAM,QAAQ,CAACY,MAAS;AAEtB,QAAI,CAACH,EAAQ,IAAIG,EAAK,MAAM,EAAG;AAC/B,UAAMC,IAAcF,EAAc,IAAIC,EAAK,MAAM,KAAK,CAAA;AACtD,IAAAC,EAAY,KAAKD,CAAI,GACrBD,EAAc,IAAIC,EAAK,QAAQC,CAAW;AAAA,EAC5C,CAAC;AAGD,QAAMC,IAAW,KAAK,IAAI,GAAGb,EAAW,IAAI,CAACC,MAAMA,EAAE,KAAK,CAAC;AAG3D,MAAIa,IAAc;AAUlB,WAASC,EAAcC,GAAgBC,GAAsBC,GAAoC;AAC/F,QAAID,KAAgBJ,EAAU,QAAO,CAAA;AAErC,UAAMM,IAAgBT,EAAc,IAAIM,CAAM,KAAK,CAAA;AACnD,QAAIG,EAAc,WAAW,EAAG,QAAO,CAAA;AAGvC,UAAMC,IAA2B,CAAA;AAEjC,eAAWT,KAAQQ,GAAe;AAChC,YAAME,IAAab,EAAQ,IAAIG,EAAK,MAAM;AAG1C,UAAI,CAACU,KAAcA,EAAW,UAAUJ,IAAe,EAAG;AAG1D,MAAAH;AACA,YAAMQ,IAAa,GAAGD,EAAW,IAAI,IAAIP,CAAW,IAI9CS,IAAgBR,EAAcJ,EAAK,QAAQM,IAAe,CAAU,GAEpEO,IAAsB;AAAA,QAC1B,MAAMF;AAAA,QACN,cAAcD,EAAW;AAAA,QACzB,OAAOV,EAAK;AAAA,QACZ,MAAMN,EAAS,IAAIgB,EAAW,IAAI,KAAKnB,EAAO,CAAC;AAAA,MAAA;AAGjD,MAAIqB,EAAc,SAAS,MACzBC,EAAM,WAAWD,IAGnBH,EAAS,KAAKI,CAAK;AAAA,IACrB;AAEA,WAAOJ;AAAA,EACT;AAGA,QAAMK,IAAgBzB,EAAW,OAAO,CAACC,MAAMA,EAAE,UAAU,CAAC;AAC5D,MAAIwB,EAAc,WAAW,EAAG,QAAO;AAGvC,MAAIA,EAAc,WAAW,GAAG;AAE9B,UAAMC,IAAYD,EAAc,CAAC,GAC3BL,IAAWL,EAAcW,EAAU,IAAI,CAAiB,GAExDC,IAAuB;AAAA,MAC3B,MAAMD,EAAU;AAAA,MAChB,cAAcA,EAAU;AAAA,MACxB,OAAOA,EAAU,SAASN,EAAS,OAAO,CAACQ,GAAKC,MAAMD,KAAOC,EAAE,SAAS,IAAI,CAAC;AAAA,MAC7E,MAAMxB,EAAS,IAAIqB,EAAU,IAAI,KAAKxB,EAAO,CAAC;AAAA,IAAA;AAGhD,WAAIkB,EAAS,SAAS,MACpBO,EAAO,WAAWP,IAGbO;AAAA,EACT;AAqBA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,cAAc;AAAA,IACd,UArBmBF,EAAc,IAAI,CAACC,GAAWnB,MAAU;AAC3D,MAAAO;AACA,YAAMM,IAAWL,EAAcW,EAAU,IAAI,CAAiB,GAExDF,IAAsB;AAAA,QAC1B,MAAM,GAAGE,EAAU,IAAI,SAASnB,CAAK;AAAA,QACrC,cAAcmB,EAAU;AAAA,QACxB,OAAOA,EAAU,SAASN,EAAS,OAAO,CAACQ,GAAK,MAAMA,KAAO,EAAE,SAAS,IAAI,CAAC;AAAA,QAC7E,MAAMvB,EAAS,IAAIqB,EAAU,IAAI,KAAKxB,EAAO,CAAC;AAAA,MAAA;AAGhD,aAAIkB,EAAS,SAAS,MACpBI,EAAM,WAAWJ,IAGZI;AAAA,IACT,CAAC;AAAA,EAKW;AAEd;AAMA,SAASM,EAAgB;AAAA,EACvB,QAAAC;AAAA,EACA,SAAAC;AACF,GAGG;AACD,MAAI,CAACD,KAAU,CAACC,KAAWA,EAAQ,WAAW,EAAG,QAAO;AAExD,QAAMvC,IAAOuC,EAAQ,CAAC,EAAE,SAElBC,IAAcxC,EAAK,gBAAgBA,EAAK;AAE9C,SACE,gBAAAyC,EAAC,OAAA,EAAI,WAAU,kGACb,UAAA;AAAA,IAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,+BAA+B,UAAAF,GAAY;AAAA,IACzDxC,EAAK,UAAU,UACd,gBAAAyC,EAAC,OAAA,EAAI,WAAU,kCACb,UAAA;AAAA,MAAA,gBAAAC,EAAC,UAAK,WAAU,kBAAkB,UAAA1C,EAAK,MAAM,kBAAiB;AAAA,MAAO;AAAA,IAAA,EAAA,CACvE;AAAA,EAAA,GAEJ;AAEJ;AAQA,MAAM2C,IAAgBC,EAAM,KAAK,SAAuB;AAAA,EACtD,MAAA5C;AAAA,EACA,QAAA6C,IAAS;AAAA,EACT,cAAAzC;AAAA,EACA,eAAA0C;AACF,GAAe;AAEb,QAAMC,IAAeC,EAAuB,IAAI,GAC1C,CAACC,GAAWC,CAAY,IAAIC,EAAS,EAAE,OAAO,KAAK,QAAQ,KAAK;AAEtE,EAAAC,EAAU,MAAM;AACd,UAAMC,IAAa,MAAM;AACvB,MAAIN,EAAa,WACfG,EAAa;AAAA,QACX,OAAOH,EAAa,QAAQ;AAAA,QAC5B,QAAQA,EAAa,QAAQ;AAAA,MAAA,CAC9B;AAAA,IAEL;AACA,IAAAM,EAAA,GACA,OAAO,iBAAiB,UAAUA,CAAU;AAG5C,UAAMC,IAAiB,IAAI,eAAeD,CAAU;AACpD,WAAIN,EAAa,WACfO,EAAe,QAAQP,EAAa,OAAO,GAGtC,MAAM;AACX,aAAO,oBAAoB,UAAUM,CAAU,GAC/CC,EAAe,WAAA;AAAA,IACjB;AAAA,EACF,GAAG,CAAA,CAAE;AAGL,QAAMC,IAAmBT,GACnBU,IAAeD,GAAkB,eAA0B,IAG3DE,IAAeC,EAAQ,MAAM;AACjC,UAAMC,IAAY5D,EAAgBC,KAAQ,EAAE;AAC5C,WAAK2D,IAEExD,EAA0BwD,GAAWvD,GAAc,UAAUM,CAAY,IAFzD;AAAA,EAGzB,GAAG,CAACV,GAAMI,CAAY,CAAC,GAGjBwD,IAAeF,EAAQ,MAAM;AACjC,UAAMC,IAAY5D,EAAgBC,KAAQ,EAAE;AAC5C,QAAI,CAAC2D,EAAW,QAAO;AAGvB,UAAMpD,IAAaoD,EAAU,MAAM,OAAO,CAACnD,MAAMA,EAAE,SAAS,CAAC,GACvDqD,IAAaF,EAAU,MAAM,OAAO,CAACzC,MAAS;AAClD,YAAM4C,IAAaH,EAAU,MAAM,KAAK,CAACnD,MAAMA,EAAE,OAAOU,EAAK,MAAM;AACnE,aAAO4C,KAAcA,EAAW,SAAS;AAAA,IAC3C,CAAC,GAEKC,IAAgBJ,EAAU,MAC7B,OAAO,CAACnD,MAAMA,EAAE,UAAU,CAAC,EAC3B,OAAO,CAAC2B,GAAK3B,MAAM2B,KAAO3B,EAAE,SAAS,IAAI,CAAC;AAE7C,WAAO;AAAA,MACL,WAAWD,EAAW;AAAA,MACtB,WAAWsD,EAAW;AAAA,MACtB,eAAAE;AAAA,IAAA;AAAA,EAEJ,GAAG,CAAC/D,CAAI,CAAC;AAGT,MAAI,CAACA,KAAQA,EAAK,WAAW,KAAK,CAACyD;AACjC,WACE,gBAAAf;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAO,EAAE,QAAAG,EAAA;AAAA,QAET,UAAA,gBAAAJ,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,UAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,uCAAsC,UAAA,gBAAY;AAAA,UACjE,gBAAAA,EAAC,OAAA,EAAI,WAAU,qCAAoC,UAAA,qEAAA,CAEnD;AAAA,QAAA,EAAA,CACF;AAAA,MAAA;AAAA,IAAA;AAMN,QAAMsB,IAAe,KAAK,IAAIf,EAAU,OAAOA,EAAU,MAAM,GACzDgB,IAAc,KAAK,IAAID,IAAe,IAAI,IAAI,GAAG,GAGjDE,IAAWT,EAAa,gBAAgBA,EAAa,MACrDU,IAAYV,EAAa;AAE/B,2BACG,OAAA,EAAI,WAAU,uDAAsD,OAAO,EAAE,QAAAZ,KAE5E,UAAA;AAAA,IAAA,gBAAAJ,EAAC,OAAA,EAAI,KAAKM,GAAc,WAAU,oCAChC,UAAA;AAAA,MAAA,gBAAAL,EAAC0B,GAAA,EAAoB,OAAM,QAAO,QAAO,QACvC,UAAA,gBAAA1B;AAAA,QAAC2B;AAAAA,QAAA;AAAA,UACC,MAAMZ;AAAA,UACN,SAAQ;AAAA,UACR,aAAAD;AAAA,UACA,aAAAS;AAAA,UACA,QAAO;AAAA,UAEP,UAAA,gBAAAvB,EAAC4B,GAAA,EAAQ,SAAS,gBAAA5B,EAACL,KAAgB,EAAA,CAAI;AAAA,QAAA;AAAA,MAAA,GAE3C;AAAA,MAGCmB,IAAc,KACb,gBAAAd;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO,EAAE,QAAQ,GAAA;AAAA,UAEjB,UAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,YAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,4CAA4C,UAAAwB,GAAS;AAAA,YACnEC,MAAc,UACb,gBAAAzB,EAAC,OAAA,EAAI,WAAU,qCACZ,UAAAyB,EAAU,iBAAe,CAC5B;AAAA,UAAA,EAAA,CAEJ;AAAA,QAAA;AAAA,MAAA;AAAA,IACF,GAEJ;AAAA,IAGC,CAACZ,GAAkB,qBAAqBK,KACvC,gBAAAlB,EAAC,OAAA,EAAI,WAAU,yFACb,UAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,yDACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,sBACb,UAAA;AAAA,QAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,kBAAkB,UAAAkB,EAAa,WAAU;AAAA,QAAO;AAAA,MAAA,GAClE;AAAA,MACA,gBAAAnB,EAAC,OAAA,EAAI,WAAU,gBACb,UAAA;AAAA,QAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,sBAAqB,UAAA,UAAM;AAAA,QAAQ;AAAA,QACnD,gBAAAA,EAAC,QAAA,EAAK,WAAU,kBAAkB,YAAa,UAAA,CAAU;AAAA,MAAA,GAC3D;AAAA,MACA,gBAAAD,EAAC,OAAA,EAAI,WAAU,sBACb,UAAA;AAAA,QAAA,gBAAAC,EAAC,UAAK,WAAU,kBAAkB,UAAAkB,EAAa,cAAc,kBAAiB;AAAA,QAAQ;AAAA,QAAI;AAAA,MAAA,EAAA,CAE5F;AAAA,IAAA,EAAA,CACF,EAAA,CACF;AAAA,EAAA,GAEJ;AAEJ,CAAC;"}
@@ -2,7 +2,7 @@ import { jsx as n, jsxs as h } from "react/jsx-runtime";
2
2
  import I, { useState as D } from "react";
3
3
  import { Treemap as H } from "recharts";
4
4
  import { scaleQuantize as _, scaleOrdinal as U } from "d3";
5
- import { u as $, g as B, h as A, d as z, c as y, f as v, a as G, b as W } from "./charts-core-CU9u_HtL.js";
5
+ import { u as $, g as B, h as A, d as z, c as y, f as v, a as G, b as W } from "./charts-core-B4Rbfdcn.js";
6
6
  const ee = I.memo(function({
7
7
  data: c,
8
8
  chartConfig: f,
@@ -281,4 +281,4 @@ const ee = I.memo(function({
281
281
  export {
282
282
  ee as default
283
283
  };
284
- //# sourceMappingURL=chart-tree-map-CBbiaBXV.js.map
284
+ //# sourceMappingURL=chart-tree-map-CrDJAvZU.js.map