drizzle-cube 0.5.8 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (388) hide show
  1. package/README.md +2 -0
  2. package/dist/adapters/adapters/hono/agent-handler.d.ts +9 -0
  3. package/dist/adapters/adapters/hono/mcp-handler.d.ts +37 -0
  4. package/dist/adapters/adapters/mcp-tools-handlers.d.ts +18 -0
  5. package/dist/adapters/adapters/nextjs/mcp-handler.d.ts +36 -0
  6. package/dist/adapters/adapters/utils.d.ts +6 -81
  7. package/dist/adapters/express/index.cjs +1 -1
  8. package/dist/adapters/express/index.js +50 -50
  9. package/dist/adapters/fastify/index.cjs +1 -1
  10. package/dist/adapters/fastify/index.js +78 -78
  11. package/dist/adapters/google-BOnRIN1w.cjs +2 -0
  12. package/dist/adapters/{google-CFYljAOF.js → google-CvKM9yVM.js} +83 -71
  13. package/dist/adapters/{handler-Cx8QYLk6.js → handler-CfgE0JSL.js} +499 -576
  14. package/dist/adapters/handler-Cn0dOctE.cjs +25 -0
  15. package/dist/adapters/hono/index.cjs +2 -2
  16. package/dist/adapters/hono/index.js +205 -175
  17. package/dist/adapters/locale-DDvZDFVn.js +8114 -0
  18. package/dist/adapters/locale-ZLUUNUxr.cjs +166 -0
  19. package/dist/adapters/mcp-tools.cjs +1 -1
  20. package/dist/adapters/mcp-tools.js +49 -38
  21. package/dist/adapters/mcp-transport-Chiaj4ll.cjs +40 -0
  22. package/dist/adapters/mcp-transport-H96VG3WY.js +591 -0
  23. package/dist/adapters/nextjs/index.cjs +1 -1
  24. package/dist/adapters/nextjs/index.js +190 -197
  25. package/dist/adapters/{openai-BZdAA7Ji.js → openai-cDlFSTk6.js} +60 -58
  26. package/dist/adapters/openai-vXvLni8v.cjs +1 -0
  27. package/dist/adapters/{utils-D9JPLmfl.js → utils-BPWZsX7k.js} +1271 -1218
  28. package/dist/adapters/utils-_whV4fXL.cjs +128 -0
  29. package/dist/adapters/utils.cjs +1 -1
  30. package/dist/adapters/utils.js +2 -2
  31. package/dist/client/charts/ChartLoader.d.ts +2 -16
  32. package/dist/client/charts/chartComponentRegistry.d.ts +46 -0
  33. package/dist/client/charts/chartConfigHelpers.d.ts +38 -0
  34. package/dist/client/charts.js +14 -13
  35. package/dist/client/chunks/{DashboardEditModal-CjCIAT-J.js → DashboardEditModal-okVfH8ZK.js} +5296 -4544
  36. package/dist/client/chunks/DashboardEditModal-okVfH8ZK.js.map +1 -0
  37. package/dist/client/chunks/{RetentionCombinedChart-BPkfcTa8.js → RetentionCombinedChart-BgbDhsPz.js} +10 -10
  38. package/dist/client/chunks/{RetentionCombinedChart-BPkfcTa8.js.map → RetentionCombinedChart-BgbDhsPz.js.map} +1 -1
  39. package/dist/client/chunks/{RetentionHeatmap-DGzLzr7h.js → RetentionHeatmap-DjXZaTPq.js} +5 -5
  40. package/dist/client/chunks/{RetentionHeatmap-DGzLzr7h.js.map → RetentionHeatmap-DjXZaTPq.js.map} +1 -1
  41. package/dist/client/chunks/analysis-builder-DB88FojM.js +5674 -0
  42. package/dist/client/chunks/analysis-builder-DB88FojM.js.map +1 -0
  43. package/dist/client/chunks/{analysis-builder-shared-CYVwSPqt.js → analysis-builder-shared-BVK4TYfR.js} +1578 -1292
  44. package/dist/client/chunks/analysis-builder-shared-BVK4TYfR.js.map +1 -0
  45. package/dist/client/chunks/{chart-activity-grid-DmruKPab.js → chart-activity-grid-DX0SJbxs.js} +635 -492
  46. package/dist/client/chunks/chart-activity-grid-DX0SJbxs.js.map +1 -0
  47. package/dist/client/chunks/chart-area-of01_62R.js +775 -0
  48. package/dist/client/chunks/chart-area-of01_62R.js.map +1 -0
  49. package/dist/client/chunks/chart-bar-BqelQE_I.js +194 -0
  50. package/dist/client/chunks/chart-bar-BqelQE_I.js.map +1 -0
  51. package/dist/client/chunks/{chart-box-plot-DYKfyOI8.js → chart-box-plot-kkBixZ27.js} +2 -2
  52. package/dist/client/chunks/{chart-box-plot-DYKfyOI8.js.map → chart-box-plot-kkBixZ27.js.map} +1 -1
  53. package/dist/client/chunks/chart-bubble-B2he1--4.js +221 -0
  54. package/dist/client/chunks/chart-bubble-B2he1--4.js.map +1 -0
  55. package/dist/client/chunks/{chart-candlestick-Dwc92Mrj.js → chart-candlestick-DZp19Tzh.js} +2 -2
  56. package/dist/client/chunks/{chart-candlestick-Dwc92Mrj.js.map → chart-candlestick-DZp19Tzh.js.map} +1 -1
  57. package/dist/client/chunks/chart-config-area-BNigHUy8.js +124 -0
  58. package/dist/client/chunks/chart-config-area-BNigHUy8.js.map +1 -0
  59. package/dist/client/chunks/chart-config-bar-DSO_LRTx.js +54 -0
  60. package/dist/client/chunks/chart-config-bar-DSO_LRTx.js.map +1 -0
  61. package/dist/client/chunks/{chart-config-box-plot-DJ-dWWXA.js → chart-config-box-plot-oW8axV2q.js} +5 -10
  62. package/dist/client/chunks/chart-config-box-plot-oW8axV2q.js.map +1 -0
  63. package/dist/client/chunks/{chart-config-gauge-DSwC04l0.js → chart-config-gauge-Dq-_H9UN.js} +5 -7
  64. package/dist/client/chunks/chart-config-gauge-Dq-_H9UN.js.map +1 -0
  65. package/dist/client/chunks/{chart-config-kpi-delta-D6BIkHL3.js → chart-config-kpi-delta-DSQbvqu_.js} +5 -10
  66. package/dist/client/chunks/chart-config-kpi-delta-DSQbvqu_.js.map +1 -0
  67. package/dist/client/chunks/{chart-config-kpi-number-Bx-V9a62.js → chart-config-kpi-number-EFSWY1We.js} +5 -7
  68. package/dist/client/chunks/chart-config-kpi-number-EFSWY1We.js.map +1 -0
  69. package/dist/client/chunks/{chart-config-kpi-text-CcqC1u-8.js → chart-config-kpi-text-KM3V5X2u.js} +5 -7
  70. package/dist/client/chunks/chart-config-kpi-text-KM3V5X2u.js.map +1 -0
  71. package/dist/client/chunks/{chart-config-line-Db3jDsWc.js → chart-config-line-D6jG8PCH.js} +9 -36
  72. package/dist/client/chunks/chart-config-line-D6jG8PCH.js.map +1 -0
  73. package/dist/client/chunks/{chart-config-pie-DD4SmRTF.js → chart-config-pie-BhzW-fdn.js} +6 -16
  74. package/dist/client/chunks/chart-config-pie-BhzW-fdn.js.map +1 -0
  75. package/dist/client/chunks/{chart-config-radar-CC2XAaGr.js → chart-config-radar-D7REP1q_.js} +6 -16
  76. package/dist/client/chunks/chart-config-radar-D7REP1q_.js.map +1 -0
  77. package/dist/client/chunks/{chart-config-radial-bar-DmxKx1R0.js → chart-config-radial-bar-Byx6qOPU.js} +6 -16
  78. package/dist/client/chunks/chart-config-radial-bar-Byx6qOPU.js.map +1 -0
  79. package/dist/client/chunks/{chart-config-tree-map-BI-oQStO.js → chart-config-tree-map-DVrvf3yQ.js} +6 -16
  80. package/dist/client/chunks/chart-config-tree-map-DVrvf3yQ.js.map +1 -0
  81. package/dist/client/chunks/{chart-config-waterfall-DSnyixbI.js → chart-config-waterfall-DmFeQdIk.js} +5 -10
  82. package/dist/client/chunks/chart-config-waterfall-DmFeQdIk.js.map +1 -0
  83. package/dist/client/chunks/{chart-data-table-BO4sXsim.js → chart-data-table-CKauQXme.js} +1046 -1121
  84. package/dist/client/chunks/chart-data-table-CKauQXme.js.map +1 -0
  85. package/dist/client/chunks/{chart-funnel-DnWRsmnS.js → chart-funnel-CToKSBaL.js} +184 -222
  86. package/dist/client/chunks/chart-funnel-CToKSBaL.js.map +1 -0
  87. package/dist/client/chunks/chart-gauge-DTVezSk7.js +403 -0
  88. package/dist/client/chunks/chart-gauge-DTVezSk7.js.map +1 -0
  89. package/dist/client/chunks/chart-heat-map-DTuUl0BR.js +236 -0
  90. package/dist/client/chunks/chart-heat-map-DTuUl0BR.js.map +1 -0
  91. package/dist/client/chunks/chart-kpi-delta-Dn-jjO-2.js +408 -0
  92. package/dist/client/chunks/chart-kpi-delta-Dn-jjO-2.js.map +1 -0
  93. package/dist/client/chunks/chart-kpi-number-P_WBiO5S.js +244 -0
  94. package/dist/client/chunks/chart-kpi-number-P_WBiO5S.js.map +1 -0
  95. package/dist/client/chunks/chart-kpi-text-C-Y4eb5H.js +185 -0
  96. package/dist/client/chunks/chart-kpi-text-C-Y4eb5H.js.map +1 -0
  97. package/dist/client/chunks/chart-line-DKgrQA6c.js +101 -0
  98. package/dist/client/chunks/chart-line-DKgrQA6c.js.map +1 -0
  99. package/dist/client/chunks/{chart-markdown-dgUetjyM.js → chart-markdown-CV75S_zL.js} +2 -2
  100. package/dist/client/chunks/{chart-markdown-dgUetjyM.js.map → chart-markdown-CV75S_zL.js.map} +1 -1
  101. package/dist/client/chunks/{chart-measure-profile-ClfpLs4q.js → chart-measure-profile-Ket8fJyf.js} +7 -7
  102. package/dist/client/chunks/{chart-measure-profile-ClfpLs4q.js.map → chart-measure-profile-Ket8fJyf.js.map} +1 -1
  103. package/dist/client/chunks/chart-pie-ByieAX5H.js +119 -0
  104. package/dist/client/chunks/chart-pie-ByieAX5H.js.map +1 -0
  105. package/dist/client/chunks/chart-radar-CiSwHWp4.js +138 -0
  106. package/dist/client/chunks/chart-radar-CiSwHWp4.js.map +1 -0
  107. package/dist/client/chunks/chart-radial-bar-BF6Mhl6f.js +122 -0
  108. package/dist/client/chunks/chart-radial-bar-BF6Mhl6f.js.map +1 -0
  109. package/dist/client/chunks/{chart-sankey-M3XpO_ah.js → chart-sankey-DjrvKw6K.js} +36 -39
  110. package/dist/client/chunks/{chart-sankey-M3XpO_ah.js.map → chart-sankey-DjrvKw6K.js.map} +1 -1
  111. package/dist/client/chunks/chart-scatter-Dd9WFqnS.js +258 -0
  112. package/dist/client/chunks/chart-scatter-Dd9WFqnS.js.map +1 -0
  113. package/dist/client/chunks/{chart-sunburst-A_u6lqlS.js → chart-sunburst-leGpuDj7.js} +3 -3
  114. package/dist/client/chunks/{chart-sunburst-A_u6lqlS.js.map → chart-sunburst-leGpuDj7.js.map} +1 -1
  115. package/dist/client/chunks/chart-tree-map-Ceq5sLZA.js +323 -0
  116. package/dist/client/chunks/chart-tree-map-Ceq5sLZA.js.map +1 -0
  117. package/dist/client/chunks/{chart-waterfall-BuhMoagf.js → chart-waterfall-DyvQReN5.js} +7 -7
  118. package/dist/client/chunks/{chart-waterfall-BuhMoagf.js.map → chart-waterfall-DyvQReN5.js.map} +1 -1
  119. package/dist/client/chunks/{charts-core-jRtb0S2M.js → charts-core-DaXSt1Dd.js} +2 -2
  120. package/dist/client/chunks/{charts-core-jRtb0S2M.js.map → charts-core-DaXSt1Dd.js.map} +1 -1
  121. package/dist/client/chunks/charts-loader-DdTeCeNo.js +84 -0
  122. package/dist/client/chunks/charts-loader-DdTeCeNo.js.map +1 -0
  123. package/dist/client/chunks/{nl-NL-CpVs7ox3.js → nl-NL-2zTAWTej.js} +2 -1
  124. package/dist/client/chunks/{nl-NL-CpVs7ox3.js.map → nl-NL-2zTAWTej.js.map} +1 -1
  125. package/dist/client/chunks/retention-ChW9jYdy.js.map +1 -1
  126. package/dist/client/chunks/{schema-visualization-DE09kQE3.js → schema-visualization-Cb_E9_Gd.js} +12 -12
  127. package/dist/client/chunks/{schema-visualization-DE09kQE3.js.map → schema-visualization-Cb_E9_Gd.js.map} +1 -1
  128. package/dist/client/chunks/{useDirtyStateTracking-CoeQbprt.js → useDirtyStateTracking-MbpxH_v6.js} +95 -84
  129. package/dist/client/chunks/useDirtyStateTracking-MbpxH_v6.js.map +1 -0
  130. package/dist/client/chunks/{useExplainAI-DlnXWdmz.js → useExplainAI-evnZkjCY.js} +14 -14
  131. package/dist/client/chunks/{useExplainAI-DlnXWdmz.js.map → useExplainAI-evnZkjCY.js.map} +1 -1
  132. package/dist/client/chunks/{utils-CTKNaXS8.js → utils-3P6z1vz5.js} +2 -2
  133. package/dist/client/chunks/{utils-CTKNaXS8.js.map → utils-3P6z1vz5.js.map} +1 -1
  134. package/dist/client/chunks/{vendor-CPIYyeuD.js → vendor-DSpR0IW6.js} +43 -43
  135. package/dist/client/chunks/{vendor-CPIYyeuD.js.map → vendor-DSpR0IW6.js.map} +1 -1
  136. package/dist/client/components/AgenticNotebook/agentChatParts.d.ts +34 -0
  137. package/dist/client/components/AgenticNotebook/chatMessageParts.d.ts +39 -0
  138. package/dist/client/components/AgenticNotebook/useAgentChatController.d.ts +25 -0
  139. package/dist/client/components/AgenticNotebook/useNotebookAutosave.d.ts +12 -0
  140. package/dist/client/components/AnalysisBuilder/AnalysisQueryPanelParts.d.ts +64 -0
  141. package/dist/client/components/AnalysisBuilder/AnalysisResultsHeader.d.ts +67 -0
  142. package/dist/client/components/AnalysisBuilder/BreakdownComparisonToggle.d.ts +13 -0
  143. package/dist/client/components/AnalysisBuilder/BreakdownRow.d.ts +26 -0
  144. package/dist/client/components/AnalysisBuilder/DisplayOptionControl.d.ts +10 -0
  145. package/dist/client/components/AnalysisBuilder/ExecutionPlanPanelParts.d.ts +22 -0
  146. package/dist/client/components/AnalysisBuilder/FieldSearchResults.d.ts +16 -0
  147. package/dist/client/components/AnalysisBuilder/FilterValueInput.d.ts +63 -0
  148. package/dist/client/components/AnalysisBuilder/FlowDepthControls.d.ts +10 -0
  149. package/dist/client/components/AnalysisBuilder/FlowVisualizationPicker.d.ts +7 -0
  150. package/dist/client/components/AnalysisBuilder/LegacyBooleanOptions.d.ts +8 -0
  151. package/dist/client/components/AnalysisBuilder/MetricRow.d.ts +23 -0
  152. package/dist/client/components/AnalysisBuilder/SortToggleButton.d.ts +13 -0
  153. package/dist/client/components/AnalysisBuilder/StringArrayInput.d.ts +17 -0
  154. package/dist/client/components/AnalysisBuilder/filterConfigModalUtils.d.ts +30 -0
  155. package/dist/client/components/AnalysisBuilder/hooks/useAnalysisBuilderImperativeHandle.d.ts +13 -0
  156. package/dist/client/components/AnalysisBuilder/hooks/useDragReorder.d.ts +25 -0
  157. package/dist/client/components/AnalysisBuilder/hooks/useFieldSearchKeyboard.d.ts +11 -0
  158. package/dist/client/components/AnalysisBuilder/utils/axisConfigUtils.d.ts +23 -0
  159. package/dist/client/components/AnalysisBuilder/utils/executionPlanMarkdown.d.ts +8 -0
  160. package/dist/client/components/AnalysisBuilder/utils/fieldUtils.d.ts +5 -0
  161. package/dist/client/components/AnalysisBuilder/utils/resultsPanelDerive.d.ts +68 -0
  162. package/dist/client/components/AnalysisBuilder/utils/shareStateUtils.d.ts +68 -0
  163. package/dist/client/components/AnalysisBuilder/utils/sortUtils.d.ts +7 -0
  164. package/dist/client/components/DashboardFilters/CompactFilterBarParts.d.ts +26 -0
  165. package/dist/client/components/DashboardFilters/DashboardFilterConfigModalParts.d.ts +27 -0
  166. package/dist/client/components/DashboardFilters/DashboardFilterValueInput.d.ts +39 -0
  167. package/dist/client/components/DashboardFilters/dashboardFilterConfigModalUtils.d.ts +21 -0
  168. package/dist/client/components/DashboardFilters/useCompactFilterBar.d.ts +19 -0
  169. package/dist/client/components/DashboardFilters/useDashboardFilterConfigModal.d.ts +69 -0
  170. package/dist/client/components/DashboardFilters/useDateRangeState.d.ts +19 -0
  171. package/dist/client/components/DashboardFilters/useFilterDropdowns.d.ts +21 -0
  172. package/dist/client/components/DashboardFilters/useFilterValueFetch.d.ts +23 -0
  173. package/dist/client/components/DashboardPortletCard.d.ts +2 -57
  174. package/dist/client/components/analyticsPortlet/PortletChart.d.ts +31 -0
  175. package/dist/client/components/analyticsPortlet/PortletChartView.d.ts +35 -0
  176. package/dist/client/components/analyticsPortlet/PortletStates.d.ts +65 -0
  177. package/dist/client/components/analyticsPortlet/parsePortletQuery.d.ts +22 -0
  178. package/dist/client/components/analyticsPortlet/portletRenderState.d.ts +31 -0
  179. package/dist/client/components/analyticsPortlet/usePortletDebugData.d.ts +37 -0
  180. package/dist/client/components/analyticsPortlet/usePortletDrillState.d.ts +17 -0
  181. package/dist/client/components/analyticsPortlet/usePortletQueryResults.d.ts +37 -0
  182. package/dist/client/components/charts/ActivityGridChart.helpers.d.ts +33 -0
  183. package/dist/client/components/charts/ActivityGridChart.render.d.ts +31 -0
  184. package/dist/client/components/charts/AxisFormatControls.d.ts +3 -1
  185. package/dist/client/components/charts/BarChart.helpers.d.ts +23 -0
  186. package/dist/client/components/charts/BarSeries.d.ts +29 -0
  187. package/dist/client/components/charts/BubbleChart.helpers.d.ts +43 -0
  188. package/dist/client/components/charts/BubbleChart.render.d.ts +21 -0
  189. package/dist/client/components/charts/ChartStates.d.ts +38 -0
  190. package/dist/client/components/charts/FunnelChart.helpers.d.ts +25 -0
  191. package/dist/client/components/charts/FunnelViews.d.ts +16 -0
  192. package/dist/client/components/charts/HeatMapCanvas.d.ts +25 -0
  193. package/dist/client/components/charts/HeatMapChart.helpers.d.ts +64 -0
  194. package/dist/client/components/charts/KpiDelta.helpers.d.ts +20 -0
  195. package/dist/client/components/charts/KpiNumber.helpers.d.ts +30 -0
  196. package/dist/client/components/charts/KpiStates.d.ts +19 -0
  197. package/dist/client/components/charts/ScatterChart.helpers.d.ts +43 -0
  198. package/dist/client/components/charts/ScatterSeries.d.ts +17 -0
  199. package/dist/client/components/charts/ScatterTooltip.d.ts +21 -0
  200. package/dist/client/components/charts/TreeMapChart.helpers.d.ts +37 -0
  201. package/dist/client/components/charts/TreeMapContent.d.ts +24 -0
  202. package/dist/client/components/charts/TreeMapLegend.d.ts +13 -0
  203. package/dist/client/components/charts/cartesianChartHelpers.d.ts +126 -0
  204. package/dist/client/components/charts/chartAxisResolution.d.ts +32 -0
  205. package/dist/client/components/charts/chartScaffolding.d.ts +77 -0
  206. package/dist/client/components/charts/gaugeChartHelpers.d.ts +36 -0
  207. package/dist/client/components/charts/kpiTextHelpers.d.ts +46 -0
  208. package/dist/client/components/charts/radarChartHelpers.d.ts +14 -0
  209. package/dist/client/components/charts/radialBarChartHelpers.d.ts +22 -0
  210. package/dist/client/components/charts/useChartDimensions.d.ts +20 -0
  211. package/dist/client/components/charts/useKpiDimensions.d.ts +30 -0
  212. package/dist/client/components/dashboard/DashboardEditBar.d.ts +5 -0
  213. package/dist/client/components/dashboard/LayoutModeToggle.d.ts +10 -0
  214. package/dist/client/components/dashboardPortletCard/FilterFieldChip.d.ts +12 -0
  215. package/dist/client/components/dashboardPortletCard/PortletCardHeader.d.ts +43 -0
  216. package/dist/client/components/dashboardPortletCard/cardStyles.d.ts +33 -0
  217. package/dist/client/components/dashboardPortletCard/filterField.d.ts +12 -0
  218. package/dist/client/components/dashboardPortletCard/propsEqual.d.ts +55 -0
  219. package/dist/client/components/dashboardPortletCard/usePortletCardActions.d.ts +16 -0
  220. package/dist/client/components/portletAnalysisModal/saveValidation.d.ts +8 -0
  221. package/dist/client/components/shared/dateRangeUtils.d.ts +40 -0
  222. package/dist/client/components/shared/filterDisplayUtils.d.ts +10 -0
  223. package/dist/client/components/shared/filterItem/FilterDateRangeSelector.d.ts +17 -0
  224. package/dist/client/components/shared/filterItem/FilterFieldDropdown.d.ts +16 -0
  225. package/dist/client/components/shared/filterItem/dateRangeSync.d.ts +14 -0
  226. package/dist/client/components/shared/filterItem/fieldVisuals.d.ts +5 -0
  227. package/dist/client/components/shared/filterValueSelector/FilterValueInputs.d.ts +55 -0
  228. package/dist/client/components/shared/filterValueSelector/useFilterValueSelectorState.d.ts +25 -0
  229. package/dist/client/components/shared/queryFieldUtils.d.ts +21 -0
  230. package/dist/client/components/shared/utils.d.ts +4 -43
  231. package/dist/client/components.js +3 -3
  232. package/dist/client/hooks/agentChatStream.d.ts +39 -0
  233. package/dist/client/hooks/analysisQueryExecutionModes.d.ts +133 -0
  234. package/dist/client/hooks/drillNavigation.d.ts +25 -0
  235. package/dist/client/hooks.js +3 -3
  236. package/dist/client/icons.js +2 -2
  237. package/dist/client/index.js +816 -669
  238. package/dist/client/index.js.map +1 -1
  239. package/dist/client/providers.js +3 -3
  240. package/dist/client/schema.js +1 -1
  241. package/dist/client/shared/chartConfigBuilders.d.ts +18 -0
  242. package/dist/client/shared/components/QueryAnalysisPanel.sections.d.ts +41 -0
  243. package/dist/client/shared/queryTransforms.d.ts +20 -0
  244. package/dist/client/shared/utils.d.ts +2 -4
  245. package/dist/client/stores/optionsToAnalysisConfig.d.ts +17 -0
  246. package/dist/client/styles.css +1 -1
  247. package/dist/client/utils/axisValueFormatting.d.ts +32 -0
  248. package/dist/client/utils/timeValueFormatting.d.ts +32 -0
  249. package/dist/client/utils.js +6 -6
  250. package/dist/client-bundle-stats.html +1 -1
  251. package/dist/mcp-app/mcp-app.html +55 -55
  252. package/dist/server/google-BOnRIN1w.cjs +2 -0
  253. package/dist/server/{google-CFYljAOF.js → google-CvKM9yVM.js} +83 -71
  254. package/dist/server/index.cjs +179 -211
  255. package/dist/server/index.js +6330 -6458
  256. package/dist/server/{openai-BZdAA7Ji.js → openai-cDlFSTk6.js} +60 -58
  257. package/dist/server/openai-vXvLni8v.cjs +1 -0
  258. package/dist/server/server/adapters/base-adapter.d.ts +80 -35
  259. package/dist/server/server/adapters/databend-adapter.d.ts +8 -59
  260. package/dist/server/server/adapters/duckdb-adapter.d.ts +5 -59
  261. package/dist/server/server/adapters/mysql-adapter.d.ts +13 -70
  262. package/dist/server/server/adapters/postgres-adapter.d.ts +1 -65
  263. package/dist/server/server/adapters/snowflake-adapter.d.ts +5 -68
  264. package/dist/server/server/adapters/sqlite-adapter.d.ts +12 -32
  265. package/dist/server/server/adapters/window-function-builder.d.ts +11 -0
  266. package/dist/server/server/agent/chart-validation.d.ts +0 -5
  267. package/dist/server/server/agent/handler-steps.d.ts +37 -0
  268. package/dist/server/server/ai/discovery-helpers.d.ts +29 -0
  269. package/dist/server/server/ai/discovery.d.ts +4 -0
  270. package/dist/server/server/ai/suggestion-helpers.d.ts +33 -0
  271. package/dist/server/server/ai/suggestion.d.ts +0 -3
  272. package/dist/server/server/ai/validation-helpers.d.ts +21 -0
  273. package/dist/server/server/ai/validation.d.ts +0 -3
  274. package/dist/server/server/builders/analysis-utils.d.ts +106 -0
  275. package/dist/server/server/builders/cte-builder.d.ts +46 -0
  276. package/dist/server/server/builders/date-time-builder.d.ts +5 -0
  277. package/dist/server/server/builders/date-time-helpers.d.ts +34 -0
  278. package/dist/server/server/builders/filter-builder.d.ts +2 -0
  279. package/dist/server/server/builders/filter-operators.d.ts +23 -0
  280. package/dist/server/server/builders/flow-query-builder.d.ts +46 -19
  281. package/dist/server/server/builders/funnel-query-builder.d.ts +16 -5
  282. package/dist/server/server/builders/group-by-builder.d.ts +11 -0
  283. package/dist/server/server/builders/measure-builder.d.ts +43 -0
  284. package/dist/server/server/builders/retention-query-builder.d.ts +12 -14
  285. package/dist/server/server/cache-utils.d.ts +25 -5
  286. package/dist/server/server/compiler-metadata.d.ts +11 -0
  287. package/dist/server/server/compiler.d.ts +8 -14
  288. package/dist/server/server/cube-utils.d.ts +29 -4
  289. package/dist/server/server/execution/annotation-builder.d.ts +12 -0
  290. package/dist/server/server/execution/filter-cache-preloader.d.ts +19 -0
  291. package/dist/server/server/execution/mode-router.d.ts +25 -0
  292. package/dist/server/server/execution/query-result-cache.d.ts +21 -0
  293. package/dist/server/server/execution/result-post-processor.d.ts +10 -0
  294. package/dist/server/server/executor.d.ts +33 -30
  295. package/dist/server/server/executors/explain-utils.d.ts +28 -0
  296. package/dist/server/server/explain/explain-tree.d.ts +20 -0
  297. package/dist/server/server/filter-cache.d.ts +2 -2
  298. package/dist/server/server/gap-filler.d.ts +6 -0
  299. package/dist/server/server/index.d.ts +3 -1
  300. package/dist/server/server/logical-plan/cte-planner-helpers.d.ts +37 -0
  301. package/dist/server/server/logical-plan/cte-planner.d.ts +104 -0
  302. package/dist/server/server/logical-plan/filter-propagation.d.ts +44 -0
  303. package/dist/server/server/logical-plan/index.d.ts +6 -1
  304. package/dist/server/server/logical-plan/join-planner.d.ts +27 -0
  305. package/dist/server/server/logical-plan/logical-planner.d.ts +7 -200
  306. package/dist/server/server/logical-plan/optimiser.d.ts +3 -1
  307. package/dist/server/server/logical-plan/plan-analysis-reporter.d.ts +59 -0
  308. package/dist/server/server/logical-plan/planner-utils.d.ts +20 -0
  309. package/dist/server/server/logical-plan/types.d.ts +17 -9
  310. package/dist/server/server/measure-classification.d.ts +40 -0
  311. package/dist/server/server/physical-plan/drizzle-plan-builder.d.ts +21 -21
  312. package/dist/server/server/physical-plan/drizzle-sql-builder.d.ts +11 -0
  313. package/dist/server/server/physical-plan/processors/index.d.ts +2 -0
  314. package/dist/server/server/physical-plan/processors/keys-dedup-processor.d.ts +13 -0
  315. package/dist/server/server/physical-plan/processors/multi-fact-processor.d.ts +13 -0
  316. package/dist/server/server/physical-plan/processors/shared.d.ts +5 -0
  317. package/dist/server/server/query-handlers.d.ts +79 -0
  318. package/dist/server/server/query-modes.d.ts +28 -0
  319. package/dist/server/server/query-validator.d.ts +9 -0
  320. package/dist/server/server/resolvers/calculated-measure-resolver.d.ts +5 -0
  321. package/dist/server/server/resolvers/join-path-resolver.d.ts +6 -0
  322. package/dist/server/server/sql-format.d.ts +11 -0
  323. package/dist/server/server/types/cube.d.ts +18 -4
  324. package/dist/server/server/types/flow.d.ts +6 -5
  325. package/dist/server/server/types/index.d.ts +1 -1
  326. package/dist/server/server/types/validation.d.ts +14 -0
  327. package/package.json +11 -4
  328. package/dist/adapters/google-DUlXeeDA.cjs +0 -2
  329. package/dist/adapters/handler-CzbCuS6_.cjs +0 -25
  330. package/dist/adapters/locale-BPB7flIG.js +0 -8249
  331. package/dist/adapters/locale-tIMrNcCr.cjs +0 -198
  332. package/dist/adapters/mcp-transport-C2QzXm6h.cjs +0 -40
  333. package/dist/adapters/mcp-transport-D0B3S1tB.js +0 -579
  334. package/dist/adapters/openai-D_U4V0kT.cjs +0 -1
  335. package/dist/adapters/utils-KV37IBIv.cjs +0 -128
  336. package/dist/client/chunks/DashboardEditModal-CjCIAT-J.js.map +0 -1
  337. package/dist/client/chunks/analysis-builder-MuMIzoRq.js +0 -5367
  338. package/dist/client/chunks/analysis-builder-MuMIzoRq.js.map +0 -1
  339. package/dist/client/chunks/analysis-builder-shared-CYVwSPqt.js.map +0 -1
  340. package/dist/client/chunks/chart-activity-grid-DmruKPab.js.map +0 -1
  341. package/dist/client/chunks/chart-area-DHCPM4Em.js +0 -450
  342. package/dist/client/chunks/chart-area-DHCPM4Em.js.map +0 -1
  343. package/dist/client/chunks/chart-bar-KddciGDv.js +0 -271
  344. package/dist/client/chunks/chart-bar-KddciGDv.js.map +0 -1
  345. package/dist/client/chunks/chart-bubble-CfqiB538.js +0 -273
  346. package/dist/client/chunks/chart-bubble-CfqiB538.js.map +0 -1
  347. package/dist/client/chunks/chart-config-area-Bq_UsW3x.js +0 -101
  348. package/dist/client/chunks/chart-config-area-Bq_UsW3x.js.map +0 -1
  349. package/dist/client/chunks/chart-config-bar-_JEGZnAu.js +0 -95
  350. package/dist/client/chunks/chart-config-bar-_JEGZnAu.js.map +0 -1
  351. package/dist/client/chunks/chart-config-box-plot-DJ-dWWXA.js.map +0 -1
  352. package/dist/client/chunks/chart-config-gauge-DSwC04l0.js.map +0 -1
  353. package/dist/client/chunks/chart-config-kpi-delta-D6BIkHL3.js.map +0 -1
  354. package/dist/client/chunks/chart-config-kpi-number-Bx-V9a62.js.map +0 -1
  355. package/dist/client/chunks/chart-config-kpi-text-CcqC1u-8.js.map +0 -1
  356. package/dist/client/chunks/chart-config-line-Db3jDsWc.js.map +0 -1
  357. package/dist/client/chunks/chart-config-pie-DD4SmRTF.js.map +0 -1
  358. package/dist/client/chunks/chart-config-radar-CC2XAaGr.js.map +0 -1
  359. package/dist/client/chunks/chart-config-radial-bar-DmxKx1R0.js.map +0 -1
  360. package/dist/client/chunks/chart-config-tree-map-BI-oQStO.js.map +0 -1
  361. package/dist/client/chunks/chart-config-waterfall-DSnyixbI.js.map +0 -1
  362. package/dist/client/chunks/chart-data-table-BO4sXsim.js.map +0 -1
  363. package/dist/client/chunks/chart-funnel-DnWRsmnS.js.map +0 -1
  364. package/dist/client/chunks/chart-gauge-CgMeqeGb.js +0 -424
  365. package/dist/client/chunks/chart-gauge-CgMeqeGb.js.map +0 -1
  366. package/dist/client/chunks/chart-heat-map-DcGm9SWK.js +0 -231
  367. package/dist/client/chunks/chart-heat-map-DcGm9SWK.js.map +0 -1
  368. package/dist/client/chunks/chart-kpi-delta-C2wKPqCb.js +0 -343
  369. package/dist/client/chunks/chart-kpi-delta-C2wKPqCb.js.map +0 -1
  370. package/dist/client/chunks/chart-kpi-number-gWYF44ol.js +0 -322
  371. package/dist/client/chunks/chart-kpi-number-gWYF44ol.js.map +0 -1
  372. package/dist/client/chunks/chart-kpi-text-DIYtJtk4.js +0 -149
  373. package/dist/client/chunks/chart-kpi-text-DIYtJtk4.js.map +0 -1
  374. package/dist/client/chunks/chart-line-9BEGN5Ti.js +0 -433
  375. package/dist/client/chunks/chart-line-9BEGN5Ti.js.map +0 -1
  376. package/dist/client/chunks/chart-pie-BjAIhyOi.js +0 -172
  377. package/dist/client/chunks/chart-pie-BjAIhyOi.js.map +0 -1
  378. package/dist/client/chunks/chart-radar-Dgkcl2bN.js +0 -154
  379. package/dist/client/chunks/chart-radar-Dgkcl2bN.js.map +0 -1
  380. package/dist/client/chunks/chart-radial-bar-DdWJjAhK.js +0 -148
  381. package/dist/client/chunks/chart-radial-bar-DdWJjAhK.js.map +0 -1
  382. package/dist/client/chunks/chart-scatter-DaHYP_OL.js +0 -255
  383. package/dist/client/chunks/chart-scatter-DaHYP_OL.js.map +0 -1
  384. package/dist/client/chunks/chart-tree-map-uiwUU4nb.js +0 -298
  385. package/dist/client/chunks/chart-tree-map-uiwUU4nb.js.map +0 -1
  386. package/dist/client/chunks/useDirtyStateTracking-CoeQbprt.js.map +0 -1
  387. package/dist/server/google-DUlXeeDA.cjs +0 -2
  388. package/dist/server/openai-D_U4V0kT.cjs +0 -1
@@ -1,5 +1,5 @@
1
1
  import { n as e } from "./rolldown-runtime-CWhphoD1.js";
2
- import { k as t, n } from "./chart-activity-grid-DmruKPab.js";
2
+ import { P as t, s as n } from "./chart-activity-grid-DX0SJbxs.js";
3
3
  import r, { useEffect as i, useMemo as a, useRef as o, useState as s } from "react";
4
4
  import { jsx as c, jsxs as l } from "react/jsx-runtime";
5
5
  import { ResponsiveContainer as u, Sankey as d, Tooltip as f } from "recharts";
@@ -14,7 +14,7 @@ function m(e) {
14
14
  }
15
15
  //#endregion
16
16
  //#region src/client/components/charts/SankeyChart.tsx
17
- var h = /* @__PURE__ */ e({ default: () => S }), g = {
17
+ var h = /* @__PURE__ */ e({ default: () => w }), g = {
18
18
  before: "#F97316",
19
19
  start: "#3B82F6",
20
20
  after: "#10B981"
@@ -79,48 +79,45 @@ function b({ x: e, y: t, width: n, height: r, payload: i, containerWidth: a, sho
79
79
  })]
80
80
  })] });
81
81
  }
82
- function x({ active: e, payload: t }) {
83
- if (!e || !t || t.length === 0) return null;
84
- let n = t[0].payload;
85
- return n.source && n.target ? /* @__PURE__ */ l("div", {
86
- className: "bg-dc-surface dc:border border-dc-border dc:rounded-md dc:px-3 dc:py-2 dc:shadow-lg dc:text-sm",
87
- children: [/* @__PURE__ */ l("div", {
88
- className: "dc:font-medium text-dc-text",
89
- children: [
90
- n.source.name,
91
- " → ",
92
- n.target.name
93
- ]
94
- }), /* @__PURE__ */ l("div", {
95
- className: "text-dc-text-secondary dc:mt-1",
96
- children: [/* @__PURE__ */ c("span", {
97
- className: "dc:font-medium",
98
- children: n.value.toLocaleString()
99
- }), " entities"]
100
- })]
101
- }) : /* @__PURE__ */ l("div", {
82
+ function x({ children: e }) {
83
+ return /* @__PURE__ */ c("div", {
102
84
  className: "bg-dc-surface dc:border border-dc-border dc:rounded-md dc:px-3 dc:py-2 dc:shadow-lg dc:text-sm",
103
- children: [/* @__PURE__ */ c("div", {
104
- className: "dc:font-medium text-dc-text",
105
- children: n.name
106
- }), n.value !== void 0 && /* @__PURE__ */ l("div", {
107
- className: "text-dc-text-secondary dc:mt-1",
108
- children: [/* @__PURE__ */ c("span", {
109
- className: "dc:font-medium",
110
- children: n.value.toLocaleString()
111
- }), " entities"]
112
- })]
85
+ children: e
86
+ });
87
+ }
88
+ function S({ value: e }) {
89
+ return /* @__PURE__ */ l("div", {
90
+ className: "text-dc-text-secondary dc:mt-1",
91
+ children: [/* @__PURE__ */ c("span", {
92
+ className: "dc:font-medium",
93
+ children: e.toLocaleString()
94
+ }), " entities"]
113
95
  });
114
96
  }
115
- var S = r.memo(function({ data: e, height: r = "100%", colorPalette: p, displayConfig: m }) {
116
- let { t: h } = t(), g = o(null), [_, S] = s(800);
97
+ function C({ active: e, payload: t }) {
98
+ if (!e || !t || t.length === 0) return null;
99
+ let n = t[0].payload, { source: r, target: i } = n;
100
+ return r && i ? /* @__PURE__ */ l(x, { children: [/* @__PURE__ */ l("div", {
101
+ className: "dc:font-medium text-dc-text",
102
+ children: [
103
+ r.name,
104
+ " → ",
105
+ i.name
106
+ ]
107
+ }), /* @__PURE__ */ c(S, { value: n.value })] }) : /* @__PURE__ */ l(x, { children: [/* @__PURE__ */ c("div", {
108
+ className: "dc:font-medium text-dc-text",
109
+ children: n.name
110
+ }), n.value !== void 0 && /* @__PURE__ */ c(S, { value: n.value })] });
111
+ }
112
+ var w = r.memo(function({ data: e, height: r = "100%", colorPalette: p, displayConfig: m }) {
113
+ let { t: h } = t(), g = o(null), [_, x] = s(800);
117
114
  i(() => {
118
115
  let e = () => {
119
- g.current && S(g.current.offsetWidth);
116
+ g.current && x(g.current.offsetWidth);
120
117
  };
121
118
  return e(), window.addEventListener("resize", e), () => window.removeEventListener("resize", e);
122
119
  }, []);
123
- let C = m, w = parseFloat(String(C?.linkOpacity || "0.5")), T = C?.nodeWidth ?? 10, E = C?.nodePadding ?? 50, D = C?.showNodeLabels !== !1, O = a(() => {
120
+ let S = m, w = parseFloat(String(S?.linkOpacity || "0.5")), T = S?.nodeWidth ?? 10, E = S?.nodePadding ?? 50, D = S?.showNodeLabels !== !1, O = a(() => {
124
121
  let t = y(e || []);
125
122
  return t ? v(t, p?.colors || n) : null;
126
123
  }, [e, p]), k = a(() => {
@@ -175,10 +172,10 @@ var S = r.memo(function({ data: e, height: r = "100%", colorPalette: p, displayC
175
172
  containerWidth: _,
176
173
  showLabels: D
177
174
  }),
178
- children: /* @__PURE__ */ c(f, { content: /* @__PURE__ */ c(x, {}) })
175
+ children: /* @__PURE__ */ c(f, { content: /* @__PURE__ */ c(C, {}) })
179
176
  })
180
177
  })
181
- }), !C?.hideSummaryFooter && k && /* @__PURE__ */ c("div", {
178
+ }), !S?.hideSummaryFooter && k && /* @__PURE__ */ c("div", {
182
179
  className: "dc:flex-shrink-0 dc:px-4 dc:py-2 dc:border-t border-dc-border bg-dc-surface-secondary",
183
180
  children: /* @__PURE__ */ l("div", {
184
181
  className: "dc:flex dc:items-center dc:justify-between dc:text-sm",
@@ -219,4 +216,4 @@ var S = r.memo(function({ data: e, height: r = "100%", colorPalette: p, displayC
219
216
  //#endregion
220
217
  export { p as n, m as r, h as t };
221
218
 
222
- //# sourceMappingURL=chart-sankey-M3XpO_ah.js.map
219
+ //# sourceMappingURL=chart-sankey-DjrvKw6K.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chart-sankey-M3XpO_ah.js","names":[],"sources":["../../../src/client/types/flow.ts","../../../src/client/components/charts/SankeyChart.tsx"],"sourcesContent":["/**\n * Flow Analysis Types\n *\n * Types for Flow analysis mode which visualizes user journeys using Sankey diagrams.\n * Flow analysis explores paths BEFORE and AFTER a defined starting step (bidirectional),\n * unlike funnel which only tracks linear forward progression.\n */\n\nimport type { Filter } from '../types'\nimport type { FunnelBindingKey } from './funnel'\n\n// ============================================================================\n// Starting Step Definition\n// ============================================================================\n\n/**\n * Starting step definition for flow analysis\n * The starting step is the anchor point from which we explore paths\n * in both directions (before and after)\n */\nexport interface FlowStartingStep {\n /** Display name for the starting step */\n name: string\n /** Filters that define which events qualify as the starting step */\n filters: Filter[]\n}\n\n// ============================================================================\n// Server Query Format\n// ============================================================================\n\n/**\n * Server flow query format\n * This is the shape sent to the server for execution\n * Wrapped in { flow: {...} } similar to funnel queries\n */\nexport interface ServerFlowQuery {\n flow: FlowQueryConfig\n}\n\n/**\n * Flow query configuration\n * Contains all parameters needed for server-side flow analysis\n */\nexport interface FlowQueryConfig {\n /**\n * Binding key that identifies individual entities (e.g., userId)\n * Can be a single string like 'Events.userId' or array for multi-cube\n */\n bindingKey: string | { cube: string; dimension: string }[]\n\n /**\n * Time dimension used for ordering events\n * Can be a single string like 'Events.timestamp' or array for multi-cube\n */\n timeDimension: string | { cube: string; dimension: string }[]\n\n /**\n * The starting step from which we explore paths\n * Defines the anchor point for bidirectional flow analysis\n */\n startingStep: {\n /** Display name for the starting step */\n name: string\n /** Filter(s) that identify events for this starting step */\n filter?: Filter | Filter[]\n }\n\n /** Number of steps to explore BEFORE the starting step (0-5) */\n stepsBefore: number\n\n /** Number of steps to explore AFTER the starting step (0-5) */\n stepsAfter: number\n\n /**\n * Event dimension that categorizes events (e.g., 'Events.eventType')\n * This dimension's values become the node labels in the Sankey diagram\n */\n eventDimension: string\n\n /**\n * Optional limit on the number of entities to process\n * Useful for performance on large datasets\n */\n entityLimit?: number\n\n /**\n * Output mode for flow data aggregation\n * - 'sankey': Aggregate by (layer, event_type) - standard flow visualization where paths can converge\n * - 'sunburst': Path-qualified nodes for hierarchical tree visualization where each path is unique\n * @default 'sankey'\n */\n outputMode?: 'sankey' | 'sunburst'\n\n /**\n * Join strategy for fetching steps\n * - 'auto' (default): use lateral when supported, otherwise window\n * - 'lateral': force lateral joins\n * - 'window': force window function strategy\n */\n joinStrategy: 'auto' | 'lateral' | 'window'\n}\n\n// ============================================================================\n// Sankey Result Types\n// ============================================================================\n\n/**\n * A node in the Sankey diagram\n * Represents an event type at a specific layer (distance from starting step)\n */\nexport interface SankeyNode {\n /**\n * Unique identifier for this node\n * Format: \"before_{depth}_{eventType}\" or \"after_{depth}_{eventType}\" or \"start_{eventType}\"\n * Examples: \"before_2_Signup\", \"start_Purchase\", \"after_1_Checkout\"\n */\n id: string\n\n /** Display name (typically the event type value) */\n name: string\n\n /**\n * Layer position in the Sankey diagram\n * Negative for steps before starting step, 0 for starting step, positive for after\n * Example: -2, -1, 0, 1, 2 for a flow with 2 steps before and 2 after\n */\n layer: number\n\n /** Total count of entities passing through this node */\n value?: number\n}\n\n/**\n * A link (edge) in the Sankey diagram\n * Represents a transition between two nodes\n */\nexport interface SankeyLink {\n /** Source node ID */\n source: string\n\n /** Target node ID */\n target: string\n\n /** Count of entities that follow this path */\n value: number\n}\n\n/**\n * Complete flow result row returned from server\n * Contains the full Sankey diagram data\n */\nexport interface FlowResultRow {\n nodes: SankeyNode[]\n links: SankeyLink[]\n}\n\n/**\n * Chart-ready flow data format\n * Same structure as FlowResultRow, used for chart components\n */\nexport interface FlowChartData {\n nodes: SankeyNode[]\n links: SankeyLink[]\n}\n\n// ============================================================================\n// Flow Slice State (for Zustand store)\n// ============================================================================\n\n/**\n * Flow mode state for the AnalysisBuilder store\n * Contains all UI state needed to configure a flow analysis\n */\nexport interface FlowSliceState {\n /** Selected cube for flow analysis (must be an eventStream cube) */\n flowCube: string | null\n\n /** Binding key that identifies entities (reuses funnel binding key type) */\n flowBindingKey: FunnelBindingKey | null\n\n /** Time dimension for ordering events */\n flowTimeDimension: string | null\n\n /** Starting step configuration */\n startingStep: FlowStartingStep\n\n /** Number of steps to explore before starting step (0-5, default 3) */\n stepsBefore: number\n\n /** Number of steps to explore after starting step (0-5, default 3) */\n stepsAfter: number\n\n /** Event dimension that categorizes events */\n eventDimension: string | null\n\n /** Join strategy for flow execution */\n joinStrategy: 'auto' | 'lateral' | 'window'\n}\n\n/**\n * Flow slice actions for the store\n */\nexport interface FlowSliceActions {\n setFlowCube: (cube: string | null) => void\n setFlowBindingKey: (key: FunnelBindingKey | null) => void\n setFlowTimeDimension: (dim: string | null) => void\n setEventDimension: (dim: string | null) => void\n setStartingStepName: (name: string) => void\n setStartingStepFilters: (filters: Filter[]) => void\n addStartingStepFilter: (filter: Filter) => void\n removeStartingStepFilter: (index: number) => void\n updateStartingStepFilter: (index: number, filter: Filter) => void\n setStepsBefore: (count: number) => void\n setStepsAfter: (count: number) => void\n setJoinStrategy: (strategy: 'auto' | 'lateral' | 'window') => void\n isFlowMode: () => boolean\n isFlowModeEnabled: () => boolean\n buildFlowQuery: () => ServerFlowQuery | null\n}\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\n/**\n * Type guard to check if data is Sankey/Flow chart data\n */\nexport function isSankeyData(data: unknown): data is FlowChartData {\n if (!data || typeof data !== 'object') return false\n const d = data as Record<string, unknown>\n return (\n Array.isArray(d.nodes) &&\n Array.isArray(d.links) &&\n (d.nodes.length === 0 ||\n (typeof d.nodes[0] === 'object' &&\n d.nodes[0] !== null &&\n 'id' in d.nodes[0]))\n )\n}\n\n/**\n * Type guard to detect server flow query format\n * Used to distinguish { flow: {...} } from CubeQuery, MultiQueryConfig, or ServerFunnelQuery\n */\nexport function isServerFlowQuery(obj: unknown): obj is ServerFlowQuery {\n return (\n typeof obj === 'object' &&\n obj !== null &&\n 'flow' in obj &&\n typeof (obj as { flow: unknown }).flow === 'object'\n )\n}\n\n// ============================================================================\n// Default Values\n// ============================================================================\n\n/**\n * Default flow slice state for store initialization\n */\nexport const defaultFlowSliceState: FlowSliceState = {\n flowCube: null,\n flowBindingKey: null,\n flowTimeDimension: null,\n startingStep: {\n name: '',\n filters: [],\n },\n stepsBefore: 3,\n stepsAfter: 3,\n eventDimension: null,\n joinStrategy: 'auto',\n}\n\n/**\n * Minimum and maximum values for step depth\n */\nexport const FLOW_MIN_DEPTH = 0\nexport const FLOW_MAX_DEPTH = 5\n","/**\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 { useTranslation } from '../../hooks/useTranslation'\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 const { t } = useTranslation()\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\">{t('chart.runtime.flow.noData')}</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">\n {t('chart.runtime.noDataHint.flow')}\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\">{t('chart.runtime.flow.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"],"mappings":"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"}
1
+ {"version":3,"file":"chart-sankey-DjrvKw6K.js","names":[],"sources":["../../../src/client/types/flow.ts","../../../src/client/components/charts/SankeyChart.tsx"],"sourcesContent":["/**\n * Flow Analysis Types\n *\n * Types for Flow analysis mode which visualizes user journeys using Sankey diagrams.\n * Flow analysis explores paths BEFORE and AFTER a defined starting step (bidirectional),\n * unlike funnel which only tracks linear forward progression.\n */\n\nimport type { Filter } from '../types'\nimport type { FunnelBindingKey } from './funnel'\n\n// ============================================================================\n// Starting Step Definition\n// ============================================================================\n\n/**\n * Starting step definition for flow analysis\n * The starting step is the anchor point from which we explore paths\n * in both directions (before and after)\n */\nexport interface FlowStartingStep {\n /** Display name for the starting step */\n name: string\n /** Filters that define which events qualify as the starting step */\n filters: Filter[]\n}\n\n// ============================================================================\n// Server Query Format\n// ============================================================================\n\n/**\n * Server flow query format\n * This is the shape sent to the server for execution\n * Wrapped in { flow: {...} } similar to funnel queries\n */\nexport interface ServerFlowQuery {\n flow: FlowQueryConfig\n}\n\n/**\n * Flow query configuration\n * Contains all parameters needed for server-side flow analysis\n */\nexport interface FlowQueryConfig {\n /**\n * Binding key that identifies individual entities (e.g., userId)\n * Can be a single string like 'Events.userId' or array for multi-cube\n */\n bindingKey: string | { cube: string; dimension: string }[]\n\n /**\n * Time dimension used for ordering events\n * Can be a single string like 'Events.timestamp' or array for multi-cube\n */\n timeDimension: string | { cube: string; dimension: string }[]\n\n /**\n * The starting step from which we explore paths\n * Defines the anchor point for bidirectional flow analysis\n */\n startingStep: {\n /** Display name for the starting step */\n name: string\n /** Filter(s) that identify events for this starting step */\n filter?: Filter | Filter[]\n }\n\n /** Number of steps to explore BEFORE the starting step (0-5) */\n stepsBefore: number\n\n /** Number of steps to explore AFTER the starting step (0-5) */\n stepsAfter: number\n\n /**\n * Event dimension that categorizes events (e.g., 'Events.eventType')\n * This dimension's values become the node labels in the Sankey diagram\n */\n eventDimension: string\n\n /**\n * Optional limit on the number of entities to process\n * Useful for performance on large datasets\n */\n entityLimit?: number\n\n /**\n * Output mode for flow data aggregation\n * - 'sankey': Aggregate by (layer, event_type) - standard flow visualization where paths can converge\n * - 'sunburst': Path-qualified nodes for hierarchical tree visualization where each path is unique\n * @default 'sankey'\n */\n outputMode?: 'sankey' | 'sunburst'\n\n /**\n * Join strategy for fetching steps\n * - 'auto' (default): use lateral when supported, otherwise window\n * - 'lateral': force lateral joins\n * - 'window': force window function strategy\n */\n joinStrategy: 'auto' | 'lateral' | 'window'\n}\n\n// ============================================================================\n// Sankey Result Types\n// ============================================================================\n\n/**\n * A node in the Sankey diagram\n * Represents an event type at a specific layer (distance from starting step)\n */\nexport interface SankeyNode {\n /**\n * Unique identifier for this node\n * Format: \"before_{depth}_{eventType}\" or \"after_{depth}_{eventType}\" or \"start_{eventType}\"\n * Examples: \"before_2_Signup\", \"start_Purchase\", \"after_1_Checkout\"\n */\n id: string\n\n /** Display name (typically the event type value) */\n name: string\n\n /**\n * Layer position in the Sankey diagram\n * Negative for steps before starting step, 0 for starting step, positive for after\n * Example: -2, -1, 0, 1, 2 for a flow with 2 steps before and 2 after\n */\n layer: number\n\n /** Total count of entities passing through this node */\n value?: number\n}\n\n/**\n * A link (edge) in the Sankey diagram\n * Represents a transition between two nodes\n */\nexport interface SankeyLink {\n /** Source node ID */\n source: string\n\n /** Target node ID */\n target: string\n\n /** Count of entities that follow this path */\n value: number\n}\n\n/**\n * Complete flow result row returned from server\n * Contains the full Sankey diagram data\n */\nexport interface FlowResultRow {\n nodes: SankeyNode[]\n links: SankeyLink[]\n}\n\n/**\n * Chart-ready flow data format\n * Same structure as FlowResultRow, used for chart components\n */\nexport interface FlowChartData {\n nodes: SankeyNode[]\n links: SankeyLink[]\n}\n\n// ============================================================================\n// Flow Slice State (for Zustand store)\n// ============================================================================\n\n/**\n * Flow mode state for the AnalysisBuilder store\n * Contains all UI state needed to configure a flow analysis\n */\nexport interface FlowSliceState {\n /** Selected cube for flow analysis (must be an eventStream cube) */\n flowCube: string | null\n\n /** Binding key that identifies entities (reuses funnel binding key type) */\n flowBindingKey: FunnelBindingKey | null\n\n /** Time dimension for ordering events */\n flowTimeDimension: string | null\n\n /** Starting step configuration */\n startingStep: FlowStartingStep\n\n /** Number of steps to explore before starting step (0-5, default 3) */\n stepsBefore: number\n\n /** Number of steps to explore after starting step (0-5, default 3) */\n stepsAfter: number\n\n /** Event dimension that categorizes events */\n eventDimension: string | null\n\n /** Join strategy for flow execution */\n joinStrategy: 'auto' | 'lateral' | 'window'\n}\n\n/**\n * Flow slice actions for the store\n */\nexport interface FlowSliceActions {\n setFlowCube: (cube: string | null) => void\n setFlowBindingKey: (key: FunnelBindingKey | null) => void\n setFlowTimeDimension: (dim: string | null) => void\n setEventDimension: (dim: string | null) => void\n setStartingStepName: (name: string) => void\n setStartingStepFilters: (filters: Filter[]) => void\n addStartingStepFilter: (filter: Filter) => void\n removeStartingStepFilter: (index: number) => void\n updateStartingStepFilter: (index: number, filter: Filter) => void\n setStepsBefore: (count: number) => void\n setStepsAfter: (count: number) => void\n setJoinStrategy: (strategy: 'auto' | 'lateral' | 'window') => void\n isFlowMode: () => boolean\n isFlowModeEnabled: () => boolean\n buildFlowQuery: () => ServerFlowQuery | null\n}\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\n/**\n * Type guard to check if data is Sankey/Flow chart data\n */\nexport function isSankeyData(data: unknown): data is FlowChartData {\n if (!data || typeof data !== 'object') return false\n const d = data as Record<string, unknown>\n return (\n Array.isArray(d.nodes) &&\n Array.isArray(d.links) &&\n (d.nodes.length === 0 ||\n (typeof d.nodes[0] === 'object' &&\n d.nodes[0] !== null &&\n 'id' in d.nodes[0]))\n )\n}\n\n/**\n * Type guard to detect server flow query format\n * Used to distinguish { flow: {...} } from CubeQuery, MultiQueryConfig, or ServerFunnelQuery\n */\nexport function isServerFlowQuery(obj: unknown): obj is ServerFlowQuery {\n return (\n typeof obj === 'object' &&\n obj !== null &&\n 'flow' in obj &&\n typeof (obj as { flow: unknown }).flow === 'object'\n )\n}\n\n// ============================================================================\n// Default Values\n// ============================================================================\n\n/**\n * Default flow slice state for store initialization\n */\nexport const defaultFlowSliceState: FlowSliceState = {\n flowCube: null,\n flowBindingKey: null,\n flowTimeDimension: null,\n startingStep: {\n name: '',\n filters: [],\n },\n stepsBefore: 3,\n stepsAfter: 3,\n eventDimension: null,\n joinStrategy: 'auto',\n}\n\n/**\n * Minimum and maximum values for step depth\n */\nexport const FLOW_MIN_DEPTH = 0\nexport const FLOW_MAX_DEPTH = 5\n","/**\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 { useTranslation } from '../../hooks/useTranslation'\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/** Shared tooltip card wrapper for the Sankey tooltip variants. */\nfunction SankeyTooltipCard({ children }: { children: React.ReactNode }) {\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 {children}\n </div>\n )\n}\n\n/** Entity count row shared by both tooltip variants. */\nfunction SankeyEntityCount({ value }: { value: number }) {\n return (\n <div className=\"text-dc-text-secondary dc:mt-1\">\n <span className=\"dc:font-medium\">{value.toLocaleString()}</span> entities\n </div>\n )\n}\n\ninterface SankeyTooltipDatum {\n name: string\n value: number\n source?: { name: string }\n target?: { name: string }\n}\n\n/**\n * Custom tooltip for Sankey chart. Renders a link variant (source → target)\n * when both endpoints are present, otherwise a node variant.\n */\nfunction SankeyTooltip({ active, payload }: {\n active?: boolean\n payload?: Array<{ payload: SankeyTooltipDatum }>\n}) {\n if (!active || !payload || payload.length === 0) return null\n\n const data = payload[0].payload\n const { source, target } = data\n\n if (source && target) {\n return (\n <SankeyTooltipCard>\n <div className=\"dc:font-medium text-dc-text\">\n {source.name} → {target.name}\n </div>\n <SankeyEntityCount value={data.value} />\n </SankeyTooltipCard>\n )\n }\n\n return (\n <SankeyTooltipCard>\n <div className=\"dc:font-medium text-dc-text\">{data.name}</div>\n {data.value !== undefined && <SankeyEntityCount value={data.value} />}\n </SankeyTooltipCard>\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 const { t } = useTranslation()\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\">{t('chart.runtime.flow.noData')}</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">\n {t('chart.runtime.noDataHint.flow')}\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\">{t('chart.runtime.flow.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"],"mappings":"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"}
@@ -0,0 +1,258 @@
1
+ import { n as e } from "./rolldown-runtime-CWhphoD1.js";
2
+ import { A as t, D as n, E as r, P as i, S as a, k as o, l as s, s as c, w as l } from "./chart-activity-grid-DX0SJbxs.js";
3
+ import { S as u, T as d, b as f, x as p } from "./chart-area-of01_62R.js";
4
+ import m, { useState as h } from "react";
5
+ import { Fragment as g, jsx as _, jsxs as v } from "react/jsx-runtime";
6
+ import { CartesianGrid as y, Legend as b, Scatter as x, ScatterChart as S, Tooltip as C, XAxis as w, YAxis as T } from "recharts";
7
+ //#region src/client/components/charts/ScatterChart.helpers.ts
8
+ var E = 20;
9
+ function D(e, t) {
10
+ let n = e?.showLegend ?? !0, r = t.length > 1 && t.length <= E;
11
+ return {
12
+ showLegend: n && r,
13
+ showGrid: e?.showGrid ?? !0,
14
+ showTooltip: e?.showTooltip ?? !0,
15
+ hasSeries: r,
16
+ xAxisFormat: e?.xAxisFormat,
17
+ yAxisFormat: e?.leftYAxisFormat,
18
+ chartMargins: {
19
+ ...s,
20
+ left: 40
21
+ }
22
+ };
23
+ }
24
+ function O(e) {
25
+ let t, n, r = [];
26
+ if (e?.xAxis && e?.yAxis) {
27
+ t = Array.isArray(e.xAxis) ? e.xAxis[0] : e.xAxis, n = Array.isArray(e.yAxis) ? e.yAxis[0] : e.yAxis;
28
+ let i = e.series;
29
+ r = i ? Array.isArray(i) ? i : [i] : [];
30
+ } else if (e?.x && e?.y) t = e.x, n = Array.isArray(e.y) ? e.y[0] : e.y;
31
+ else return {
32
+ xAxisField: "",
33
+ yAxisField: "",
34
+ seriesFields: [],
35
+ errorCode: "axisInvalid"
36
+ };
37
+ return !t || !n ? {
38
+ xAxisField: "",
39
+ yAxisField: "",
40
+ seriesFields: [],
41
+ errorCode: "axisFields"
42
+ } : {
43
+ xAxisField: t,
44
+ yAxisField: n,
45
+ seriesFields: r
46
+ };
47
+ }
48
+ function k(e, t, i) {
49
+ let a = {};
50
+ return t.forEach((t) => {
51
+ if (e[t]) {
52
+ let o = n(i, t);
53
+ a[t] = r(e[t], o);
54
+ }
55
+ }), a;
56
+ }
57
+ function A(e, t, n) {
58
+ let i = r(e[t], n) || e[t];
59
+ return typeof i == "string" ? parseFloat(i) : i;
60
+ }
61
+ function j(e, r, i, a, s, c) {
62
+ let l = n(c, r);
63
+ if (a.length > 0) {
64
+ let n = a[0], u = {};
65
+ return e.forEach((e) => {
66
+ let a = String(e[n] || "Default");
67
+ u[a] || (u[a] = []);
68
+ let d = A(e, r, l), f = t(e[i]);
69
+ o(d) && f !== null && u[a].push({
70
+ x: d,
71
+ y: f,
72
+ name: a,
73
+ timeValues: k(e, s, c),
74
+ originalItem: e
75
+ });
76
+ }), {
77
+ scatterData: Object.keys(u).flatMap((e) => u[e]),
78
+ seriesGroups: u
79
+ };
80
+ }
81
+ return {
82
+ scatterData: e.map((e) => {
83
+ let n = A(e, r, l), a = t(e[i]);
84
+ return {
85
+ x: n,
86
+ y: a,
87
+ name: "Point",
88
+ timeValues: k(e, s, c),
89
+ originalItem: e,
90
+ isValid: o(n) && a !== null
91
+ };
92
+ }).filter((e) => e.isValid).map(({ isValid: e, ...t }) => t),
93
+ seriesGroups: {}
94
+ };
95
+ }
96
+ //#endregion
97
+ //#region src/client/components/charts/ScatterTooltip.tsx
98
+ function M({ active: e, payload: t, xAxisField: n, yAxisField: r, xAxisFormat: i, yAxisFormat: a, getFieldLabel: o }) {
99
+ if (!e || !t || t.length === 0) return null;
100
+ let s = t[0]?.payload;
101
+ return s ? /* @__PURE__ */ v("div", {
102
+ style: {
103
+ backgroundColor: "white",
104
+ border: "1px solid #e5e7eb",
105
+ borderRadius: "0.5rem",
106
+ fontSize: "0.875rem",
107
+ color: "#1f2937",
108
+ boxShadow: "0 4px 6px -1px rgba(0, 0, 0, 0.1)",
109
+ padding: "8px 12px"
110
+ },
111
+ children: [
112
+ /* @__PURE__ */ _("div", {
113
+ style: {
114
+ fontWeight: 600,
115
+ marginBottom: "4px"
116
+ },
117
+ children: s.name
118
+ }),
119
+ s.timeValues && Object.keys(s.timeValues).length > 0 && /* @__PURE__ */ _("div", {
120
+ style: {
121
+ marginBottom: "4px",
122
+ color: "#6b7280"
123
+ },
124
+ children: Object.entries(s.timeValues).map(([e, t]) => /* @__PURE__ */ v("div", { children: [
125
+ o(e),
126
+ ": ",
127
+ t
128
+ ] }, e))
129
+ }),
130
+ /* @__PURE__ */ v("div", { children: [
131
+ i?.label || o(n),
132
+ ": ",
133
+ l(s.x, i)
134
+ ] }),
135
+ /* @__PURE__ */ v("div", { children: [
136
+ a?.label || o(r),
137
+ ": ",
138
+ l(s.y, a)
139
+ ] })
140
+ ]
141
+ }) : null;
142
+ }
143
+ //#endregion
144
+ //#region src/client/components/charts/ScatterSeries.tsx
145
+ function N(e, t) {
146
+ return e?.colors && e.colors[t % e.colors.length] || c[t % c.length];
147
+ }
148
+ function P({ hasSeries: e, seriesKeys: t, seriesGroups: n, scatterData: r, colorPalette: i, hoveredLegend: a }) {
149
+ return e ? /* @__PURE__ */ _(g, { children: t.map((e, t) => /* @__PURE__ */ _(x, {
150
+ name: e,
151
+ data: n[e],
152
+ fill: N(i, t),
153
+ fillOpacity: a ? a === e ? 1 : .3 : 1
154
+ }, e)) }) : /* @__PURE__ */ _(x, {
155
+ name: "Data",
156
+ data: r,
157
+ fill: i?.colors && i.colors[0] || c[0]
158
+ });
159
+ }
160
+ //#endregion
161
+ //#region src/client/components/charts/ScatterChart.tsx
162
+ var F = /* @__PURE__ */ e({ default: () => I }), I = m.memo(function({ data: e, chartConfig: t, displayConfig: n = {}, queryObject: r, height: o = "100%", colorPalette: s }) {
163
+ let { t: c } = i(), [m, g] = h(null), x = a();
164
+ try {
165
+ if (!e || e.length === 0) return /* @__PURE__ */ _(p, {
166
+ height: o,
167
+ hint: c("chart.runtime.noDataHint.scatter")
168
+ });
169
+ let { xAxisField: i, yAxisField: a, seriesFields: u, errorCode: h } = O(t);
170
+ if (h) return /* @__PURE__ */ _(f, {
171
+ height: o,
172
+ hint: c(`chart.runtime.configErrorHint.${h}`)
173
+ });
174
+ let { scatterData: E, seriesGroups: k } = j(e, i, a, u, (r?.timeDimensions || []).map((e) => e.dimension), r);
175
+ if (!E || E.length === 0) return /* @__PURE__ */ _(p, {
176
+ height: o,
177
+ titleKey: "chart.runtime.noValidData",
178
+ hint: "No valid data points for scatter chart after transformation"
179
+ });
180
+ let A = Object.keys(k), { showLegend: N, showGrid: F, showTooltip: I, hasSeries: L, xAxisFormat: R, yAxisFormat: z, chartMargins: B } = D(n, A);
181
+ return /* @__PURE__ */ _(d, {
182
+ height: o,
183
+ children: /* @__PURE__ */ v(S, {
184
+ margin: B,
185
+ accessibilityLayer: !1,
186
+ children: [
187
+ F && /* @__PURE__ */ _(y, { strokeDasharray: "3 3" }),
188
+ /* @__PURE__ */ _(w, {
189
+ type: "number",
190
+ dataKey: "x",
191
+ name: R?.label || x(i),
192
+ tick: { fontSize: 12 },
193
+ tickFormatter: R ? (e) => l(e, R) : void 0
194
+ }),
195
+ /* @__PURE__ */ _(T, {
196
+ type: "number",
197
+ dataKey: "y",
198
+ name: z?.label || x(a),
199
+ tick: { fontSize: 12 },
200
+ tickFormatter: z ? (e) => l(e, z) : void 0,
201
+ label: {
202
+ value: z?.label || x(a),
203
+ angle: -90,
204
+ position: "left",
205
+ style: {
206
+ textAnchor: "middle",
207
+ fontSize: "12px"
208
+ }
209
+ }
210
+ }),
211
+ I && /* @__PURE__ */ _(C, {
212
+ cursor: { strokeDasharray: "3 3" },
213
+ content: ({ active: e, payload: t }) => /* @__PURE__ */ _(M, {
214
+ active: e,
215
+ payload: t,
216
+ xAxisField: i,
217
+ yAxisField: a,
218
+ xAxisFormat: R,
219
+ yAxisFormat: z,
220
+ getFieldLabel: x
221
+ })
222
+ }),
223
+ N && /* @__PURE__ */ _(b, {
224
+ wrapperStyle: {
225
+ fontSize: "12px",
226
+ paddingTop: "10px"
227
+ },
228
+ iconType: "circle",
229
+ iconSize: 8,
230
+ layout: "horizontal",
231
+ align: "center",
232
+ verticalAlign: "bottom",
233
+ onMouseEnter: (e) => g(String(e.dataKey || "")),
234
+ onMouseLeave: () => g(null)
235
+ }),
236
+ /* @__PURE__ */ _(P, {
237
+ hasSeries: L,
238
+ seriesKeys: A,
239
+ seriesGroups: k,
240
+ scatterData: E,
241
+ colorPalette: s,
242
+ hoveredLegend: m
243
+ })
244
+ ]
245
+ })
246
+ });
247
+ } catch (e) {
248
+ return /* @__PURE__ */ _(u, {
249
+ height: o,
250
+ chartType: "Scatter Chart",
251
+ error: e
252
+ });
253
+ }
254
+ });
255
+ //#endregion
256
+ export { F as n, I as t };
257
+
258
+ //# sourceMappingURL=chart-scatter-Dd9WFqnS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chart-scatter-Dd9WFqnS.js","names":[],"sources":["../../../src/client/components/charts/ScatterChart.helpers.ts","../../../src/client/components/charts/ScatterTooltip.tsx","../../../src/client/components/charts/ScatterSeries.tsx","../../../src/client/components/charts/ScatterChart.tsx"],"sourcesContent":["/**\n * Co-located helpers for ScatterChart.\n *\n * Pure config-resolution + data-shaping extracted from the component. No\n * behaviour change — these mirror the original inline logic exactly.\n */\nimport {\n formatTimeValue,\n getFieldGranularity,\n parseNumericValue,\n isValidNumericValue\n} from '../../utils/chartUtils'\nimport { CHART_MARGINS } from '../../utils/chartConstants'\nimport type { AxisFormatConfig, ChartAxisConfig, ChartDisplayConfig, CubeQuery } from '../../types'\n\n// Limit series to prevent performance issues with high-cardinality fields (e.g.,\n// dates). Above this, the chart falls back to single-series mode.\nconst MAX_SERIES = 20\n\nexport interface ScatterRenderState {\n showLegend: boolean\n showGrid: boolean\n showTooltip: boolean\n /** Whether to render one Scatter per series group vs a single series. */\n hasSeries: boolean\n xAxisFormat?: AxisFormatConfig\n /** For scatter charts the y-axis uses the left-axis format config. */\n yAxisFormat?: AxisFormatConfig\n chartMargins: typeof CHART_MARGINS\n}\n\n/**\n * Resolve all render-time display flags, axis formats and margins for the\n * scatter chart from the display config and the transformed series keys.\n */\nexport function resolveScatterRenderState(\n displayConfig: ChartDisplayConfig | undefined,\n seriesKeys: string[]\n): ScatterRenderState {\n const showLegendConfig = displayConfig?.showLegend ?? true\n const hasSeries = seriesKeys.length > 1 && seriesKeys.length <= MAX_SERIES\n return {\n showLegend: showLegendConfig && hasSeries,\n showGrid: displayConfig?.showGrid ?? true,\n showTooltip: displayConfig?.showTooltip ?? true,\n hasSeries,\n xAxisFormat: displayConfig?.xAxisFormat,\n yAxisFormat: displayConfig?.leftYAxisFormat,\n // Custom chart margins with extra left space for Y-axis label (40 vs 20)\n chartMargins: { ...CHART_MARGINS, left: 40 }\n }\n}\n\nexport interface ScatterAxisFields {\n xAxisField: string\n yAxisField: string\n seriesFields: string[]\n /** Set when the config is invalid (no usable axis fields). */\n errorCode?: 'axisInvalid' | 'axisFields'\n}\n\n/** Resolve x/y/series fields supporting both the new and legacy config shapes. */\nexport function resolveScatterAxisFields(\n chartConfig: ChartAxisConfig | undefined\n): ScatterAxisFields {\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 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 { xAxisField: '', yAxisField: '', seriesFields: [], errorCode: 'axisInvalid' }\n }\n\n if (!xAxisField || !yAxisField) {\n return { xAxisField: '', yAxisField: '', seriesFields: [], errorCode: 'axisFields' }\n }\n\n return { xAxisField, yAxisField, seriesFields }\n}\n\nexport interface ScatterPoint {\n x: number\n y: number\n name: string\n timeValues: Record<string, string>\n originalItem: Record<string, any>\n}\n\n/** Build the time-dimension value map for a single row (for tooltip display). */\nfunction buildTimeValues(\n item: Record<string, any>,\n timeDimensionFields: string[],\n queryObject: CubeQuery | undefined\n): Record<string, string> {\n const timeValues: Record<string, string> = {}\n timeDimensionFields.forEach((field) => {\n if (item[field]) {\n const granularity = getFieldGranularity(queryObject, field)\n timeValues[field] = formatTimeValue(item[field], granularity)\n }\n })\n return timeValues\n}\n\n/** Convert a formatted x value to a number (parses time strings via parseFloat). */\nfunction toXNumber(item: Record<string, any>, xAxisField: string, xGranularity?: string): number {\n const xValue = formatTimeValue(item[xAxisField], xGranularity) || item[xAxisField]\n return typeof xValue === 'string' ? parseFloat(xValue) : xValue\n}\n\nexport interface ScatterTransform {\n scatterData: ScatterPoint[]\n seriesGroups: Record<string, ScatterPoint[]>\n}\n\n/**\n * Transform rows into scatter points, grouping by series when configured.\n * Null x/y coordinates are filtered out. Mirrors the original two-branch logic.\n */\nexport function transformScatterData(\n data: Record<string, any>[],\n xAxisField: string,\n yAxisField: string,\n seriesFields: string[],\n timeDimensionFields: string[],\n queryObject: CubeQuery | undefined\n): ScatterTransform {\n const xGranularity = getFieldGranularity(queryObject, xAxisField)\n\n if (seriesFields.length > 0) {\n const seriesField = seriesFields[0]\n const seriesGroups: Record<string, ScatterPoint[]> = {}\n\n data.forEach((item) => {\n const seriesValue = String(item[seriesField] || 'Default')\n if (!seriesGroups[seriesValue]) {\n seriesGroups[seriesValue] = []\n }\n\n const xNum = toXNumber(item, xAxisField, xGranularity)\n const yValue = parseNumericValue(item[yAxisField])\n\n if (isValidNumericValue(xNum) && yValue !== null) {\n seriesGroups[seriesValue].push({\n x: xNum,\n y: yValue,\n name: seriesValue,\n timeValues: buildTimeValues(item, timeDimensionFields, queryObject),\n originalItem: item\n })\n }\n })\n\n const scatterData = Object.keys(seriesGroups).flatMap((key) => seriesGroups[key])\n return { scatterData, seriesGroups }\n }\n\n // Single series scatter plot\n const scatterData = data\n .map((item) => {\n const xNum = toXNumber(item, xAxisField, xGranularity)\n const yValue = parseNumericValue(item[yAxisField])\n return {\n x: xNum,\n y: yValue as number,\n name: 'Point',\n timeValues: buildTimeValues(item, timeDimensionFields, queryObject),\n originalItem: item,\n isValid: isValidNumericValue(xNum) && yValue !== null\n }\n })\n .filter((point) => point.isValid)\n .map(({ isValid: _isValid, ...point }) => point)\n\n return { scatterData, seriesGroups: {} }\n}\n","import { formatAxisValue } from '../../utils/chartUtils'\nimport type { AxisFormatConfig } from '../../types'\nimport type { ScatterPoint } from './ScatterChart.helpers'\n\ninterface ScatterTooltipProps {\n active?: boolean\n payload?: Array<{ payload?: ScatterPoint }>\n xAxisField: string\n yAxisField: string\n xAxisFormat?: AxisFormatConfig\n yAxisFormat?: AxisFormatConfig\n getFieldLabel: (field: string) => string\n}\n\n/**\n * Custom Recharts tooltip content for ScatterChart.\n *\n * Extracted from the inline `content` render prop to keep the chart body lean.\n * Renders the point name, any time-dimension values, and the formatted x/y.\n */\nexport function ScatterTooltip({\n active,\n payload,\n xAxisField,\n yAxisField,\n xAxisFormat,\n yAxisFormat,\n getFieldLabel\n}: ScatterTooltipProps) {\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","import { Scatter } from 'recharts'\nimport { CHART_COLORS } from '../../utils/chartConstants'\nimport type { ColorPalette } from '../../types'\nimport type { ScatterPoint } from './ScatterChart.helpers'\n\ninterface ScatterSeriesProps {\n hasSeries: boolean\n seriesKeys: string[]\n seriesGroups: Record<string, ScatterPoint[]>\n scatterData: ScatterPoint[]\n colorPalette?: ColorPalette\n hoveredLegend: string | null\n}\n\n/** Resolve the fill colour for a series index from the palette. */\nfunction seriesColor(colorPalette: ColorPalette | undefined, index: number): string {\n return (colorPalette?.colors && colorPalette.colors[index % colorPalette.colors.length]) ||\n CHART_COLORS[index % CHART_COLORS.length]\n}\n\n/**\n * Renders the `<Scatter>` series for ScatterChart — one per series group when\n * `hasSeries`, otherwise a single series. Returned as a fragment so it composes\n * inside the Recharts chart children. Behaviour matches the original inline JSX.\n */\nexport function ScatterSeries({\n hasSeries,\n seriesKeys,\n seriesGroups,\n scatterData,\n colorPalette,\n hoveredLegend\n}: ScatterSeriesProps) {\n if (hasSeries) {\n return (\n <>\n {seriesKeys.map((seriesKey, index) => (\n <Scatter\n key={seriesKey}\n name={seriesKey}\n data={seriesGroups[seriesKey]}\n fill={seriesColor(colorPalette, index)}\n fillOpacity={hoveredLegend ? (hoveredLegend === seriesKey ? 1 : 0.3) : 1}\n />\n ))}\n </>\n )\n }\n\n return (\n <Scatter\n name=\"Data\"\n data={scatterData}\n fill={(colorPalette?.colors && colorPalette.colors[0]) || CHART_COLORS[0]}\n />\n )\n}\n","import React, { useState } from 'react'\nimport { useTranslation } from '../../hooks/useTranslation'\nimport { ScatterChart as RechartsScatterChart, XAxis, YAxis, CartesianGrid, Legend, Tooltip } from 'recharts'\nimport ChartContainer from './ChartContainer'\nimport { ChartEmptyState, ChartConfigError, ChartRenderError } from './ChartStates'\nimport { resolveScatterAxisFields, transformScatterData, resolveScatterRenderState } from './ScatterChart.helpers'\nimport { ScatterTooltip } from './ScatterTooltip'\nimport { ScatterSeries } from './ScatterSeries'\nimport { 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 { t } = useTranslation()\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 if (!data || data.length === 0) {\n return <ChartEmptyState height={height} hint={t('chart.runtime.noDataHint.scatter')} />\n }\n\n // Validate chartConfig - support both legacy and new formats\n const { xAxisField, yAxisField, seriesFields, errorCode } = resolveScatterAxisFields(chartConfig)\n\n if (errorCode) {\n return <ChartConfigError height={height} hint={t(`chart.runtime.configErrorHint.${errorCode}`)} />\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 (filters out null x/y coordinates)\n const { scatterData, seriesGroups } = transformScatterData(\n data,\n xAxisField,\n yAxisField,\n seriesFields,\n timeDimensionFields,\n queryObject\n )\n\n // Validate transformed data\n if (!scatterData || scatterData.length === 0) {\n return (\n <ChartEmptyState\n height={height}\n titleKey=\"chart.runtime.noValidData\"\n hint=\"No valid data points for scatter chart after transformation\"\n />\n )\n }\n\n const seriesKeys = Object.keys(seriesGroups)\n const { showLegend, showGrid, showTooltip, hasSeries, xAxisFormat, yAxisFormat, chartMargins } =\n resolveScatterRenderState(displayConfig, seriesKeys)\n\n return (\n <ChartContainer height={height}>\n <RechartsScatterChart margin={chartMargins} accessibilityLayer={false}>\n {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 {showTooltip && (\n <Tooltip\n cursor={{ strokeDasharray: '3 3' }}\n content={({ active, payload }) => (\n <ScatterTooltip\n active={active}\n payload={payload as any}\n xAxisField={xAxisField}\n yAxisField={yAxisField}\n xAxisFormat={xAxisFormat}\n yAxisFormat={yAxisFormat}\n getFieldLabel={getFieldLabel}\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 <ScatterSeries\n hasSeries={hasSeries}\n seriesKeys={seriesKeys}\n seriesGroups={seriesGroups}\n scatterData={scatterData}\n colorPalette={colorPalette}\n hoveredLegend={hoveredLegend}\n />\n </RechartsScatterChart>\n </ChartContainer>\n )\n } catch (error) {\n // 'ScatterChart rendering error\n return <ChartRenderError height={height} chartType=\"Scatter Chart\" error={error} />\n }\n})\n\nexport default ScatterChart"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { n as e } from "./rolldown-runtime-CWhphoD1.js";
2
- import { n as t } from "./chart-sankey-M3XpO_ah.js";
3
- import { k as n, n as r } from "./chart-activity-grid-DmruKPab.js";
2
+ import { n as t } from "./chart-sankey-DjrvKw6K.js";
3
+ import { P as n, s as r } from "./chart-activity-grid-DX0SJbxs.js";
4
4
  import i, { useEffect as a, useMemo as o, useRef as s, useState as c } from "react";
5
5
  import { jsx as l, jsxs as u } from "react/jsx-runtime";
6
6
  import { ResponsiveContainer as d, SunburstChart as f, Tooltip as p } from "recharts";
@@ -218,4 +218,4 @@ var v = i.memo(function({ data: e, height: t = "100%", colorPalette: i, displayC
218
218
  //#endregion
219
219
  export { m as t };
220
220
 
221
- //# sourceMappingURL=chart-sunburst-A_u6lqlS.js.map
221
+ //# sourceMappingURL=chart-sunburst-leGpuDj7.js.map