drizzle-cube 0.8.0 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (329) hide show
  1. package/dist/adapters/ActivityGridChart.config-Bc7mPqcf.cjs +1 -0
  2. package/dist/adapters/ActivityGridChart.config-Dd2YDeaM.js +2 -0
  3. package/dist/adapters/AreaChart.config-BqNusnpg.js +2 -0
  4. package/dist/adapters/AreaChart.config-dI84V34B.cjs +1 -0
  5. package/dist/adapters/BarChart.config-B9MQjgLJ.cjs +1 -0
  6. package/dist/adapters/BarChart.config-Cq_qcxBA.js +2 -0
  7. package/dist/adapters/BoxPlotChart.config-XmtRN2xq.cjs +1 -0
  8. package/dist/adapters/BoxPlotChart.config-Zc-JGV-W.js +2 -0
  9. package/dist/adapters/BubbleChart.config-CU_18uxb.js +2 -0
  10. package/dist/adapters/BubbleChart.config-CbhOzA6-.cjs +1 -0
  11. package/dist/adapters/CandlestickChart.config-Bwo3uaa-.js +2 -0
  12. package/dist/adapters/CandlestickChart.config-CmRBlWFv.cjs +1 -0
  13. package/dist/adapters/DataTable.config-7JNSj6qQ.js +2 -0
  14. package/dist/adapters/DataTable.config-DNxm1sYk.cjs +1 -0
  15. package/dist/adapters/DotStripChart.config-B7Dl-T1h.js +2 -0
  16. package/dist/adapters/DotStripChart.config-Co4g1fpZ.cjs +1 -0
  17. package/dist/adapters/FunnelChart.config-D1TpuGtL.cjs +1 -0
  18. package/dist/adapters/FunnelChart.config-vuZScOHQ.js +2 -0
  19. package/dist/adapters/GaugeChart.config-BMgUHKhC.cjs +1 -0
  20. package/dist/adapters/GaugeChart.config-zdpFydo6.js +2 -0
  21. package/dist/adapters/HeatMapChart.config-4XMab1zq.js +2 -0
  22. package/dist/adapters/HeatMapChart.config-C-Ns6QBq.cjs +1 -0
  23. package/dist/adapters/KpiDelta.config-BGdqsHcc.js +2 -0
  24. package/dist/adapters/KpiDelta.config-DuNxrGIi.cjs +1 -0
  25. package/dist/adapters/KpiNumber.config-CkPWpcSz.js +2 -0
  26. package/dist/adapters/KpiNumber.config-DMGmuA3i.cjs +1 -0
  27. package/dist/adapters/KpiText.config-Bvtuv8vE.js +2 -0
  28. package/dist/adapters/KpiText.config-DOMLO16U.cjs +1 -0
  29. package/dist/adapters/LineChart.config-CJmTSmZ1.js +2 -0
  30. package/dist/adapters/LineChart.config-CrkGu0aa.cjs +1 -0
  31. package/dist/adapters/MarkdownChart.config-BgY5Xc97.cjs +1 -0
  32. package/dist/adapters/MarkdownChart.config-Cm6G4Yuh.js +2 -0
  33. package/dist/adapters/MeasureProfileChart.config-BYwDo_ox.cjs +1 -0
  34. package/dist/adapters/MeasureProfileChart.config-Dt7npubZ.js +2 -0
  35. package/dist/adapters/PieChart.config-BRbPctBN.cjs +1 -0
  36. package/dist/adapters/PieChart.config-HZofeody.js +2 -0
  37. package/dist/adapters/ProportionBarChart.config-B_rTtGZr.cjs +1 -0
  38. package/dist/adapters/ProportionBarChart.config-ChCSoM0L.js +2 -0
  39. package/dist/adapters/RadarChart.config-B9OdMEib.js +2 -0
  40. package/dist/adapters/RadarChart.config-BOgPD2Kz.cjs +1 -0
  41. package/dist/adapters/RadialBarChart.config-CeP7jEbq.js +2 -0
  42. package/dist/adapters/RadialBarChart.config-sivA1Jmo.cjs +1 -0
  43. package/dist/adapters/RecordsTable.config-BInSgo-G.js +2 -0
  44. package/dist/adapters/RecordsTable.config-CVmxLdjz.cjs +1 -0
  45. package/dist/adapters/RetentionCombinedChart.config-8ry7gh6X.cjs +1 -0
  46. package/dist/adapters/RetentionCombinedChart.config-Bxtxnlcf.js +2 -0
  47. package/dist/adapters/RetentionHeatmap.config-DCtOD8dO.js +2 -0
  48. package/dist/adapters/RetentionHeatmap.config-i-LgmmIT.cjs +1 -0
  49. package/dist/adapters/SankeyChart.config-DfpeHfNT.cjs +1 -0
  50. package/dist/adapters/SankeyChart.config-hfM0ACm1.js +2 -0
  51. package/dist/adapters/ScatterChart.config-BD2vfOZ6.js +2 -0
  52. package/dist/adapters/ScatterChart.config-CdpvRueF.cjs +1 -0
  53. package/dist/adapters/SunburstChart.config-Boyt88L_.cjs +1 -0
  54. package/dist/adapters/SunburstChart.config-BvrofzMv.js +2 -0
  55. package/dist/adapters/TreeMapChart.config-DBrqwtqT.js +2 -0
  56. package/dist/adapters/TreeMapChart.config-KcRLlZAG.cjs +1 -0
  57. package/dist/adapters/WaterfallChart.config-CuCGaIl5.cjs +1 -0
  58. package/dist/adapters/WaterfallChart.config-DZ8H0V2L.js +2 -0
  59. package/dist/adapters/{compiler-CQJ5GOwF.js → compiler-BFLAXV7W.js} +1160 -1861
  60. package/dist/adapters/compiler-DG6dLFQU.cjs +166 -0
  61. package/dist/adapters/core/index.cjs +1 -1
  62. package/dist/adapters/core/index.js +1 -1
  63. package/dist/adapters/{core-DgTGXxDu.cjs → core-CrJu6vJY.cjs} +1 -1
  64. package/dist/adapters/{core-DXkuSUBg.js → core-l3KMTu9u.js} +3 -3
  65. package/dist/adapters/express/index.cjs +1 -1
  66. package/dist/adapters/express/index.js +5 -5
  67. package/dist/adapters/fastify/index.cjs +1 -1
  68. package/dist/adapters/fastify/index.js +23 -23
  69. package/dist/{server/google-eKAc20al.js → adapters/google-DRY7jnOh.js} +46 -28
  70. package/dist/adapters/{google-BhvizbFR.cjs → google-PsZzwedr.cjs} +2 -2
  71. package/dist/adapters/handler-CRGZ8gd2.cjs +25 -0
  72. package/dist/adapters/{handler-CphYSZRh.js → handler-DESp4wPg.js} +454 -237
  73. package/dist/adapters/hono/index.cjs +1 -1
  74. package/dist/adapters/hono/index.js +4 -4
  75. package/dist/adapters/mcp-tools.cjs +1 -1
  76. package/dist/adapters/mcp-tools.js +2 -2
  77. package/dist/adapters/mcp-transport-BqdBHmXL.js +730 -0
  78. package/dist/adapters/mcp-transport-D8xZJLPD.cjs +42 -0
  79. package/dist/adapters/nextjs/index.cjs +1 -1
  80. package/dist/adapters/nextjs/index.js +5 -5
  81. package/dist/adapters/{openai-CBrN4nxl.js → openai-BJyU4kvE.js} +3 -3
  82. package/dist/adapters/{openai-CSzWluuv.cjs → openai-DH9MtcLA.cjs} +1 -1
  83. package/dist/adapters/{openai-D-VMcPao.js → openai-DK_KWiI7.js} +1 -1
  84. package/dist/adapters/{openai-CI9vGKSf.cjs → openai-GO3M7Hwi.cjs} +2 -2
  85. package/dist/adapters/{utils-DkmShl5f.js → utils-BhlkVCzZ.js} +1985 -1122
  86. package/dist/adapters/utils-C1JpSDOX.cjs +128 -0
  87. package/dist/adapters/utils.cjs +1 -1
  88. package/dist/adapters/utils.d.ts +17 -3
  89. package/dist/adapters/utils.js +1 -1
  90. package/dist/cjs/adapters/utils.d.ts +17 -3
  91. package/dist/cjs/client/charts/chartConfigRegistry.d.ts +7 -0
  92. package/dist/cjs/client/charts/chartConfigs.d.ts +17 -1
  93. package/dist/cjs/client/client/CubeClient.d.ts +11 -1
  94. package/dist/cjs/client/components/AnalysisBuilder/AnalysisDisplayConfigPanel.d.ts +4 -2
  95. package/dist/cjs/client/components/AnalysisBuilder/ColumnFormatsEditor.d.ts +10 -0
  96. package/dist/cjs/client/components/AnalysisBuilder/DisplayOptionControl.d.ts +3 -2
  97. package/dist/cjs/client/components/AnalysisBuilder/utils/queryUtils.d.ts +7 -1
  98. package/dist/cjs/client/components/analyticsPortlet/PortletChart.d.ts +2 -1
  99. package/dist/cjs/client/components/analyticsPortlet/PortletChartView.d.ts +4 -1
  100. package/dist/cjs/client/components/analyticsPortlet/usePortletDeadMembers.d.ts +24 -0
  101. package/dist/cjs/client/components/analyticsPortlet/usePortletPagination.d.ts +21 -0
  102. package/dist/cjs/client/components/charts/DotStripChart.config.d.ts +15 -0
  103. package/dist/cjs/client/components/charts/DotStripChart.d.ts +4 -0
  104. package/dist/cjs/client/components/charts/DotStripChart.helpers.d.ts +91 -0
  105. package/dist/cjs/client/components/charts/RecordsTable.config.d.ts +10 -0
  106. package/dist/cjs/client/components/charts/RecordsTable.d.ts +4 -0
  107. package/dist/cjs/client/components/charts/recordsTableHooks.d.ts +68 -0
  108. package/dist/cjs/client/icons/types.d.ts +2 -0
  109. package/dist/cjs/client/index.d.ts +2 -2
  110. package/dist/cjs/client/types.d.ts +97 -1
  111. package/dist/cjs/client/utils/recordsTableUtils.d.ts +71 -0
  112. package/dist/cjs/client/utils/rowLinkUtils.d.ts +35 -0
  113. package/dist/cjs/server/agent/chart-validation.d.ts +1 -1
  114. package/dist/cjs/server/ai/chart-schema.d.ts +117 -0
  115. package/dist/cjs/server/ai/discovery-helpers.d.ts +14 -0
  116. package/dist/cjs/server/ai/discovery.d.ts +6 -0
  117. package/dist/cjs/server/ai/query-schema.d.ts +1 -1
  118. package/dist/cjs/server/attribute-dimensions.d.ts +11 -8
  119. package/dist/cjs/server/builders/group-by-builder.d.ts +15 -0
  120. package/dist/cjs/server/compiler.d.ts +3 -4
  121. package/dist/cjs/server/executor.d.ts +15 -0
  122. package/dist/cjs/server/index.d.ts +2 -0
  123. package/dist/cjs/server/query-handlers.d.ts +1 -0
  124. package/dist/cjs/server/query-validator.d.ts +36 -4
  125. package/dist/cjs/server/types/core.d.ts +5 -0
  126. package/dist/cjs/server/types/cube.d.ts +12 -0
  127. package/dist/cjs/server/types/query.d.ts +8 -0
  128. package/dist/cli/index.cjs +134 -52
  129. package/dist/client/charts/chartConfigRegistry.d.ts +7 -0
  130. package/dist/client/charts/chartConfigs.d.ts +17 -1
  131. package/dist/client/charts.js +13 -13
  132. package/dist/client/chunks/{DashboardEditModal-9An5EDAz.js → DashboardEditModal-BliiIHcI.js} +1653 -1188
  133. package/dist/client/chunks/DashboardEditModal-BliiIHcI.js.map +1 -0
  134. package/dist/client/chunks/DotStripChart-ChwsVeRU.js +408 -0
  135. package/dist/client/chunks/DotStripChart-ChwsVeRU.js.map +1 -0
  136. package/dist/client/chunks/{ProportionBarChart-BVcbGY2C.js → ProportionBarChart-D-Qt9nkF.js} +3 -3
  137. package/dist/client/chunks/{ProportionBarChart-BVcbGY2C.js.map → ProportionBarChart-D-Qt9nkF.js.map} +1 -1
  138. package/dist/client/chunks/RecordsTable-aG-QYXOH.js +556 -0
  139. package/dist/client/chunks/RecordsTable-aG-QYXOH.js.map +1 -0
  140. package/dist/client/chunks/{RetentionCombinedChart-D68Rvdi-.js → RetentionCombinedChart-BRZ9w7ah.js} +3 -3
  141. package/dist/client/chunks/{RetentionCombinedChart-D68Rvdi-.js.map → RetentionCombinedChart-BRZ9w7ah.js.map} +1 -1
  142. package/dist/client/chunks/{RetentionHeatmap-CE7BAjrB.js → RetentionHeatmap-LkTt89pK.js} +2 -2
  143. package/dist/client/chunks/{RetentionHeatmap-CE7BAjrB.js.map → RetentionHeatmap-LkTt89pK.js.map} +1 -1
  144. package/dist/client/chunks/{analysis-builder-D1pYvvwc.js → analysis-builder-C0gJ3kDD.js} +169 -168
  145. package/dist/client/chunks/{analysis-builder-D1pYvvwc.js.map → analysis-builder-C0gJ3kDD.js.map} +1 -1
  146. package/dist/client/chunks/{analysis-builder-shared-BQvwUc6z.js → analysis-builder-shared-dqcpl_WL.js} +965 -954
  147. package/dist/client/chunks/analysis-builder-shared-dqcpl_WL.js.map +1 -0
  148. package/dist/client/chunks/{chart-activity-grid-DvD_4wJz.js → chart-activity-grid-CJzxC18G.js} +175 -84
  149. package/dist/client/chunks/chart-activity-grid-CJzxC18G.js.map +1 -0
  150. package/dist/client/chunks/{chart-area-DPp3hSOK.js → chart-area-C66dgy84.js} +21 -21
  151. package/dist/client/chunks/{chart-area-DPp3hSOK.js.map → chart-area-C66dgy84.js.map} +1 -1
  152. package/dist/client/chunks/{chart-bar-Od3pOyZ0.js → chart-bar-D9kiSOCT.js} +5 -5
  153. package/dist/client/chunks/{chart-bar-Od3pOyZ0.js.map → chart-bar-D9kiSOCT.js.map} +1 -1
  154. package/dist/client/chunks/{chart-box-plot-l0iFn2n2.js → chart-box-plot-FsLIMisc.js} +2 -2
  155. package/dist/client/chunks/{chart-box-plot-l0iFn2n2.js.map → chart-box-plot-FsLIMisc.js.map} +1 -1
  156. package/dist/client/chunks/{chart-bubble-Dl0RcP8N.js → chart-bubble-BzyvrqKs.js} +2 -2
  157. package/dist/client/chunks/{chart-bubble-Dl0RcP8N.js.map → chart-bubble-BzyvrqKs.js.map} +1 -1
  158. package/dist/client/chunks/{chart-candlestick-DZMqbscF.js → chart-candlestick-6lD35bLw.js} +2 -2
  159. package/dist/client/chunks/{chart-candlestick-DZMqbscF.js.map → chart-candlestick-6lD35bLw.js.map} +1 -1
  160. package/dist/client/chunks/{chart-data-table-DgiNBOWf.js → chart-data-table-Cou9qOab.js} +1222 -1029
  161. package/dist/client/chunks/chart-data-table-Cou9qOab.js.map +1 -0
  162. package/dist/client/chunks/{chart-funnel-YLZlyN1X.js → chart-funnel-B0775aaT.js} +2 -2
  163. package/dist/client/chunks/{chart-funnel-YLZlyN1X.js.map → chart-funnel-B0775aaT.js.map} +1 -1
  164. package/dist/client/chunks/{chart-gauge-BsqE2wwF.js → chart-gauge-pf-2E8w9.js} +3 -3
  165. package/dist/client/chunks/{chart-gauge-BsqE2wwF.js.map → chart-gauge-pf-2E8w9.js.map} +1 -1
  166. package/dist/client/chunks/{chart-heat-map-BsND8RM_.js → chart-heat-map-EzVGe6fl.js} +3 -3
  167. package/dist/client/chunks/{chart-heat-map-BsND8RM_.js.map → chart-heat-map-EzVGe6fl.js.map} +1 -1
  168. package/dist/client/chunks/{chart-kpi-delta-m0azuva-.js → chart-kpi-delta-lfskDdx4.js} +3 -3
  169. package/dist/client/chunks/{chart-kpi-delta-m0azuva-.js.map → chart-kpi-delta-lfskDdx4.js.map} +1 -1
  170. package/dist/client/chunks/{chart-kpi-number-6JS15SqF.js → chart-kpi-number-BnsofbTf.js} +5 -5
  171. package/dist/client/chunks/{chart-kpi-number-6JS15SqF.js.map → chart-kpi-number-BnsofbTf.js.map} +1 -1
  172. package/dist/client/chunks/{chart-kpi-text-BqX8p8Jn.js → chart-kpi-text-U5EdmdkV.js} +3 -3
  173. package/dist/client/chunks/{chart-kpi-text-BqX8p8Jn.js.map → chart-kpi-text-U5EdmdkV.js.map} +1 -1
  174. package/dist/client/chunks/{chart-line-NCmpxBfE.js → chart-line-IwXqPY80.js} +3 -3
  175. package/dist/client/chunks/{chart-line-NCmpxBfE.js.map → chart-line-IwXqPY80.js.map} +1 -1
  176. package/dist/client/chunks/{chart-markdown-ZOobqiiX.js → chart-markdown-yxN_xBP9.js} +2 -2
  177. package/dist/client/chunks/{chart-markdown-ZOobqiiX.js.map → chart-markdown-yxN_xBP9.js.map} +1 -1
  178. package/dist/client/chunks/{chart-measure-profile-CBAZaicJ.js → chart-measure-profile-Bs4vhBJQ.js} +3 -3
  179. package/dist/client/chunks/{chart-measure-profile-CBAZaicJ.js.map → chart-measure-profile-Bs4vhBJQ.js.map} +1 -1
  180. package/dist/client/chunks/{chart-pie-ChrasEI8.js → chart-pie-LDJfDXfX.js} +15 -15
  181. package/dist/client/chunks/{chart-pie-ChrasEI8.js.map → chart-pie-LDJfDXfX.js.map} +1 -1
  182. package/dist/client/chunks/{chart-radar-CxSVF7yL.js → chart-radar-BZY6TP9m.js} +13 -13
  183. package/dist/client/chunks/{chart-radar-CxSVF7yL.js.map → chart-radar-BZY6TP9m.js.map} +1 -1
  184. package/dist/client/chunks/{chart-radial-bar--SN0Wph0.js → chart-radial-bar-aga05X7h.js} +3 -3
  185. package/dist/client/chunks/{chart-radial-bar--SN0Wph0.js.map → chart-radial-bar-aga05X7h.js.map} +1 -1
  186. package/dist/client/chunks/{chart-sankey-CDOSGg9r.js → chart-sankey-MRCoWFd4.js} +2 -2
  187. package/dist/client/chunks/{chart-sankey-CDOSGg9r.js.map → chart-sankey-MRCoWFd4.js.map} +1 -1
  188. package/dist/client/chunks/{chart-scatter-DgcEF-kI.js → chart-scatter-DP-nn9hH.js} +3 -3
  189. package/dist/client/chunks/{chart-scatter-DgcEF-kI.js.map → chart-scatter-DP-nn9hH.js.map} +1 -1
  190. package/dist/client/chunks/{chart-sunburst-MB-jlGBm.js → chart-sunburst-DE4EX7zi.js} +3 -3
  191. package/dist/client/chunks/{chart-sunburst-MB-jlGBm.js.map → chart-sunburst-DE4EX7zi.js.map} +1 -1
  192. package/dist/client/chunks/{chart-tree-map-DeDXveVd.js → chart-tree-map-C3O6uQcP.js} +3 -3
  193. package/dist/client/chunks/{chart-tree-map-DeDXveVd.js.map → chart-tree-map-C3O6uQcP.js.map} +1 -1
  194. package/dist/client/chunks/{chart-waterfall-ur4vkO1j.js → chart-waterfall-DU2Fg_7P.js} +3 -3
  195. package/dist/client/chunks/{chart-waterfall-ur4vkO1j.js.map → chart-waterfall-DU2Fg_7P.js.map} +1 -1
  196. package/dist/client/chunks/charts-core-DnirPG1F.js +190 -0
  197. package/dist/client/chunks/charts-core-DnirPG1F.js.map +1 -0
  198. package/dist/client/chunks/charts-loader-tCSbqT7H.js +87 -0
  199. package/dist/client/chunks/charts-loader-tCSbqT7H.js.map +1 -0
  200. package/dist/client/chunks/{en-US-BE6VoG0o.js → en-US-HP6FHuNy.js} +3 -1
  201. package/dist/client/chunks/{en-US-BE6VoG0o.js.map → en-US-HP6FHuNy.js.map} +1 -1
  202. package/dist/client/chunks/{nl-NL-CMXHDBr0.js → nl-NL-B9VnaVAm.js} +89 -1
  203. package/dist/client/chunks/nl-NL-B9VnaVAm.js.map +1 -0
  204. package/dist/client/chunks/{schema-visualization-BEbFtUIL.js → schema-visualization-o1zzuMQy.js} +3 -3
  205. package/dist/client/chunks/{schema-visualization-BEbFtUIL.js.map → schema-visualization-o1zzuMQy.js.map} +1 -1
  206. package/dist/client/chunks/{useDirtyStateTracking-CSDg96Rw.js → useDirtyStateTracking-DTYbmRBn.js} +15 -15
  207. package/dist/client/chunks/{useDirtyStateTracking-CSDg96Rw.js.map → useDirtyStateTracking-DTYbmRBn.js.map} +1 -1
  208. package/dist/client/chunks/{useExplainAI-BnkoZ-zS.js → useExplainAI-MuC9jBn-.js} +16 -16
  209. package/dist/client/chunks/{useExplainAI-BnkoZ-zS.js.map → useExplainAI-MuC9jBn-.js.map} +1 -1
  210. package/dist/client/chunks/{vendor-BmJDaduD.js → vendor-XQT9APIq.js} +49 -49
  211. package/dist/client/chunks/{vendor-BmJDaduD.js.map → vendor-XQT9APIq.js.map} +1 -1
  212. package/dist/client/client/CubeClient.d.ts +11 -1
  213. package/dist/client/components/AnalysisBuilder/AnalysisDisplayConfigPanel.d.ts +4 -2
  214. package/dist/client/components/AnalysisBuilder/ColumnFormatsEditor.d.ts +10 -0
  215. package/dist/client/components/AnalysisBuilder/DisplayOptionControl.d.ts +3 -2
  216. package/dist/client/components/AnalysisBuilder/utils/queryUtils.d.ts +7 -1
  217. package/dist/client/components/analyticsPortlet/PortletChart.d.ts +2 -1
  218. package/dist/client/components/analyticsPortlet/PortletChartView.d.ts +4 -1
  219. package/dist/client/components/analyticsPortlet/usePortletDeadMembers.d.ts +24 -0
  220. package/dist/client/components/analyticsPortlet/usePortletPagination.d.ts +21 -0
  221. package/dist/client/components/charts/DotStripChart.config.d.ts +15 -0
  222. package/dist/client/components/charts/DotStripChart.d.ts +4 -0
  223. package/dist/client/components/charts/DotStripChart.helpers.d.ts +91 -0
  224. package/dist/client/components/charts/RecordsTable.config.d.ts +10 -0
  225. package/dist/client/components/charts/RecordsTable.d.ts +4 -0
  226. package/dist/client/components/charts/recordsTableHooks.d.ts +68 -0
  227. package/dist/client/components.js +1 -1
  228. package/dist/client/hooks.js +3 -3
  229. package/dist/client/icons/types.d.ts +2 -0
  230. package/dist/client/icons.js +2 -2
  231. package/dist/client/index.d.ts +2 -2
  232. package/dist/client/index.js +213 -213
  233. package/dist/client/providers.js +1 -1
  234. package/dist/client/schema.js +1 -1
  235. package/dist/client/styles.css +1 -1
  236. package/dist/client/types.d.ts +97 -1
  237. package/dist/client/utils/recordsTableUtils.d.ts +71 -0
  238. package/dist/client/utils/rowLinkUtils.d.ts +35 -0
  239. package/dist/client/utils.js +14 -14
  240. package/dist/client-bundle-stats.html +1 -1
  241. package/dist/mcp-app/mcp-app.html +101 -101
  242. package/dist/server/agent/chart-validation.d.ts +1 -1
  243. package/dist/server/ai/chart-schema.d.ts +117 -0
  244. package/dist/server/ai/discovery-helpers.d.ts +14 -0
  245. package/dist/server/ai/discovery.d.ts +6 -0
  246. package/dist/server/ai/query-schema.d.ts +1 -1
  247. package/dist/server/attribute-dimensions.d.ts +11 -8
  248. package/dist/server/builders/group-by-builder.d.ts +15 -0
  249. package/dist/server/compiler.d.ts +3 -4
  250. package/dist/server/executor.d.ts +15 -0
  251. package/dist/{adapters/google-eKAc20al.js → server/google-DRY7jnOh.js} +46 -28
  252. package/dist/server/{google-BhvizbFR.cjs → google-PsZzwedr.cjs} +2 -2
  253. package/dist/server/index.cjs +34 -34
  254. package/dist/server/index.d.ts +2 -0
  255. package/dist/server/index.js +1913 -1445
  256. package/dist/server/query-handlers.d.ts +1 -0
  257. package/dist/server/query-validator.d.ts +36 -4
  258. package/dist/server/types/core.d.ts +5 -0
  259. package/dist/server/types/cube.d.ts +12 -0
  260. package/dist/server/types/query.d.ts +8 -0
  261. package/package.json +1 -1
  262. package/dist/adapters/ActivityGridChart.config-BQhBE_Mr.js +0 -2
  263. package/dist/adapters/ActivityGridChart.config-C3tSuOGV.cjs +0 -1
  264. package/dist/adapters/AreaChart.config-3cme8HyQ.js +0 -2
  265. package/dist/adapters/AreaChart.config-BSxrT52Z.cjs +0 -1
  266. package/dist/adapters/BarChart.config-BKS8IecE.cjs +0 -1
  267. package/dist/adapters/BarChart.config-lt_7PdIi.js +0 -2
  268. package/dist/adapters/BoxPlotChart.config-B7qvRnrF.cjs +0 -1
  269. package/dist/adapters/BoxPlotChart.config-Dv6ECj2j.js +0 -2
  270. package/dist/adapters/BubbleChart.config-BrIH7OAy.cjs +0 -1
  271. package/dist/adapters/BubbleChart.config-Fhotb7Pg.js +0 -2
  272. package/dist/adapters/CandlestickChart.config-CWH41FmF.cjs +0 -1
  273. package/dist/adapters/CandlestickChart.config-RPtXuxsX.js +0 -2
  274. package/dist/adapters/DataTable.config-71L0GzlT.js +0 -2
  275. package/dist/adapters/DataTable.config-BsOMQq3J.cjs +0 -1
  276. package/dist/adapters/FunnelChart.config-Cqte9C04.cjs +0 -1
  277. package/dist/adapters/FunnelChart.config-DJtwWeNz.js +0 -2
  278. package/dist/adapters/GaugeChart.config-WkwZ9VdS.cjs +0 -1
  279. package/dist/adapters/GaugeChart.config-vpVQlP5B.js +0 -2
  280. package/dist/adapters/HeatMapChart.config-DcmkDl07.cjs +0 -1
  281. package/dist/adapters/HeatMapChart.config-DsmMgGxJ.js +0 -2
  282. package/dist/adapters/KpiDelta.config-DVy561BH.js +0 -2
  283. package/dist/adapters/KpiDelta.config-dpqwLHNE.cjs +0 -1
  284. package/dist/adapters/KpiNumber.config-927l8nq8.js +0 -2
  285. package/dist/adapters/KpiNumber.config-BqFBMfPf.cjs +0 -1
  286. package/dist/adapters/KpiText.config-C-fZXuHq.cjs +0 -1
  287. package/dist/adapters/KpiText.config-CWoXuhMA.js +0 -2
  288. package/dist/adapters/LineChart.config-DTp7pqOY.js +0 -2
  289. package/dist/adapters/LineChart.config-DUGvSjcH.cjs +0 -1
  290. package/dist/adapters/MarkdownChart.config-23Dmv2Ty.cjs +0 -1
  291. package/dist/adapters/MarkdownChart.config-Cb2TnS0I.js +0 -2
  292. package/dist/adapters/MeasureProfileChart.config-B2qbWdhy.cjs +0 -1
  293. package/dist/adapters/MeasureProfileChart.config-CvBCeI5b.js +0 -2
  294. package/dist/adapters/PieChart.config-BzJb13QA.js +0 -2
  295. package/dist/adapters/PieChart.config-plCn5Ehr.cjs +0 -1
  296. package/dist/adapters/ProportionBarChart.config-1r-_moBH.cjs +0 -1
  297. package/dist/adapters/ProportionBarChart.config-CN6TtHTp.js +0 -2
  298. package/dist/adapters/RadarChart.config-BYhdj9M7.js +0 -2
  299. package/dist/adapters/RadarChart.config-CeUMP-1g.cjs +0 -1
  300. package/dist/adapters/RadialBarChart.config-B88yXNsq.cjs +0 -1
  301. package/dist/adapters/RadialBarChart.config-ZMK9HMoh.js +0 -2
  302. package/dist/adapters/RetentionCombinedChart.config-B5yvgUHM.cjs +0 -1
  303. package/dist/adapters/RetentionCombinedChart.config-Dd-YMdK8.js +0 -2
  304. package/dist/adapters/RetentionHeatmap.config-BYzDleoV.cjs +0 -1
  305. package/dist/adapters/RetentionHeatmap.config-Dvj7yTB0.js +0 -2
  306. package/dist/adapters/SankeyChart.config-CPFRmgFb.cjs +0 -1
  307. package/dist/adapters/SankeyChart.config-ClgqXM1N.js +0 -2
  308. package/dist/adapters/ScatterChart.config-CvJiqPa5.cjs +0 -1
  309. package/dist/adapters/ScatterChart.config-DLZ3rYMq.js +0 -2
  310. package/dist/adapters/SunburstChart.config-C_1V5hoQ.cjs +0 -1
  311. package/dist/adapters/SunburstChart.config-FNU75NCg.js +0 -2
  312. package/dist/adapters/TreeMapChart.config-CprZk_YF.js +0 -2
  313. package/dist/adapters/TreeMapChart.config-DNwd0ge9.cjs +0 -1
  314. package/dist/adapters/WaterfallChart.config-BBhcN_Fh.cjs +0 -1
  315. package/dist/adapters/WaterfallChart.config-H7s6SSV3.js +0 -2
  316. package/dist/adapters/compiler-BaLO10VN.cjs +0 -166
  317. package/dist/adapters/handler-DrRT6c14.cjs +0 -25
  318. package/dist/adapters/mcp-transport-BGkSz-ZT.cjs +0 -40
  319. package/dist/adapters/mcp-transport-fJud19xz.js +0 -606
  320. package/dist/adapters/utils-BY0-KFyI.cjs +0 -128
  321. package/dist/client/chunks/DashboardEditModal-9An5EDAz.js.map +0 -1
  322. package/dist/client/chunks/analysis-builder-shared-BQvwUc6z.js.map +0 -1
  323. package/dist/client/chunks/chart-activity-grid-DvD_4wJz.js.map +0 -1
  324. package/dist/client/chunks/chart-data-table-DgiNBOWf.js.map +0 -1
  325. package/dist/client/chunks/charts-core-BAH5pkSB.js +0 -215
  326. package/dist/client/chunks/charts-core-BAH5pkSB.js.map +0 -1
  327. package/dist/client/chunks/charts-loader-eToV8je7.js +0 -85
  328. package/dist/client/chunks/charts-loader-eToV8je7.js.map +0 -1
  329. package/dist/client/chunks/nl-NL-CMXHDBr0.js.map +0 -1
@@ -0,0 +1,408 @@
1
+ import { F as e, S as t, o as n, s as r, w as i } from "./chart-activity-grid-CJzxC18G.js";
2
+ import { D as a, O as o, k as s } from "./chart-area-C66dgy84.js";
3
+ import c, { useMemo as l, useState as u } from "react";
4
+ import { jsx as d, jsxs as f } from "react/jsx-runtime";
5
+ var p = {
6
+ small: 3.5,
7
+ medium: 5,
8
+ large: 7
9
+ }, m = 1.5;
10
+ function h(e) {
11
+ if (e == null || e === "") return null;
12
+ let t = typeof e == "number" ? e : parseFloat(String(e));
13
+ return Number.isFinite(t) ? t : null;
14
+ }
15
+ function g(e) {
16
+ let t = e.length;
17
+ if (t === 0) return null;
18
+ let n = Math.floor(t / 2);
19
+ return t % 2 == 0 ? (e[n - 1] + e[n]) / 2 : e[n];
20
+ }
21
+ function _(e) {
22
+ if (e === 0) return 0;
23
+ let t = Math.ceil(e / 2);
24
+ return e % 2 == 1 ? t : -t;
25
+ }
26
+ function v(e, t, n) {
27
+ let r = 2 * n + m, i = 2 * n + m, a = [...e].sort((e, t) => e.value - t.value || e.label.localeCompare(t.label)), o = /* @__PURE__ */ new Map(), s = [];
28
+ for (let e of a) {
29
+ let n = t(e.value), a = _(16);
30
+ for (let e = 0; e <= 16; e++) {
31
+ let t = _(e), i = o.get(t);
32
+ if (!i || i.every((e) => Math.abs(n - e) >= r)) {
33
+ a = t;
34
+ break;
35
+ }
36
+ }
37
+ let c = o.get(a);
38
+ c ? c.push(n) : o.set(a, [n]), s.push({
39
+ ...e,
40
+ x: n,
41
+ lane: a,
42
+ y: a * i
43
+ });
44
+ }
45
+ return s;
46
+ }
47
+ function y(e, t) {
48
+ let n = e.reduce((e, t) => Math.max(e, Math.abs(t.lane)), 0), r = 2 * t + m, i = (2 * n + 1) * r + 24;
49
+ return Math.min(Math.max(i, 44), 220);
50
+ }
51
+ function b(e, t, n) {
52
+ return e === null || t === null || n < 2 || e <= 0 ? null : t / e;
53
+ }
54
+ function x(e, t, n, r, i) {
55
+ let a = [], o = /* @__PURE__ */ new Map();
56
+ for (let i of e) {
57
+ let e = String(i[t] ?? "");
58
+ o.has(e) || (o.set(e, []), a.push(e));
59
+ let s = h(i[n]);
60
+ s !== null && o.get(e).push({
61
+ value: s,
62
+ label: r ? String(i[r] ?? "") : e,
63
+ row: i
64
+ });
65
+ }
66
+ let s = a.map((e) => {
67
+ let t = o.get(e);
68
+ return {
69
+ label: e,
70
+ values: t.slice(0, 500),
71
+ truncated: t.length > 500
72
+ };
73
+ });
74
+ if (i !== "none") {
75
+ let e = (e) => g(e.map((e) => e.value).sort((e, t) => e - t));
76
+ s = [...s].sort((t, n) => {
77
+ if (i === "count") return n.values.length - t.values.length;
78
+ let r = e(t.values), a = e(n.values);
79
+ return r === null && a === null ? 0 : r === null ? 1 : a === null ? -1 : i === "valueDesc" ? a - r : r - a;
80
+ });
81
+ }
82
+ return s.slice(0, 50);
83
+ }
84
+ function ee(e) {
85
+ if (e.length === 0) return {
86
+ min: 0,
87
+ max: 1
88
+ };
89
+ let t = Math.min(...e), n = Math.max(...e);
90
+ if (t === n) {
91
+ let e = Math.abs(t) * .1 || 1;
92
+ return {
93
+ min: t - e,
94
+ max: n + e
95
+ };
96
+ }
97
+ let r = (n - t) * .1;
98
+ return {
99
+ min: t - r,
100
+ max: n + r
101
+ };
102
+ }
103
+ function S(e, t, n = 5) {
104
+ if (t === e) return [e];
105
+ let r = (t - e) / (n - 1);
106
+ return Array.from({ length: n }, (t, n) => e + n * r);
107
+ }
108
+ //#endregion
109
+ //#region src/client/components/charts/DotStripChart.tsx
110
+ var C = 190, w = 44, T = 24, te = 60, ne = 36;
111
+ function E(e) {
112
+ return Array.isArray(e) ? typeof e[0] == "string" ? e[0] : void 0 : typeof e == "string" && e !== "" ? e : void 0;
113
+ }
114
+ function re({ band: e, width: t, radius: n, ticks: r, scale: i, showGrid: a, showMedianMarker: o, showExtremeLabels: s, color: c, accentColor: u, drillEnabled: p, onDotClick: m, onDotHover: h, onDotLeave: g }) {
115
+ let _ = e.height / 2, v = l(() => {
116
+ if (!s || e.dots.length < 2) return /* @__PURE__ */ new Set();
117
+ let t = [...e.dots].sort((e, t) => e.value - t.value);
118
+ return /* @__PURE__ */ new Set([t[0], t[t.length - 1]]);
119
+ }, [e.dots, s]);
120
+ return /* @__PURE__ */ f("svg", {
121
+ width: t,
122
+ height: e.height,
123
+ viewBox: `0 0 ${t} ${e.height}`,
124
+ "data-testid": `dot-strip-band-${e.label}`,
125
+ children: [
126
+ a && r.map((t, n) => /* @__PURE__ */ d("line", {
127
+ x1: i(t),
128
+ x2: i(t),
129
+ y1: 0,
130
+ y2: e.height,
131
+ stroke: "currentColor",
132
+ strokeOpacity: .08,
133
+ strokeWidth: 1,
134
+ className: "text-dc-text-secondary"
135
+ }, n)),
136
+ e.dots.length > 0 && /* @__PURE__ */ d("line", {
137
+ x1: i(e.min),
138
+ x2: i(e.max),
139
+ y1: _,
140
+ y2: _,
141
+ stroke: "currentColor",
142
+ strokeOpacity: .25,
143
+ strokeWidth: 1,
144
+ className: "text-dc-text-secondary"
145
+ }),
146
+ o && e.median !== null && /* @__PURE__ */ d("line", {
147
+ x1: i(e.median),
148
+ x2: i(e.median),
149
+ y1: _ - Math.min(_ - 2, 16),
150
+ y2: _ + Math.min(_ - 2, 16),
151
+ stroke: "currentColor",
152
+ strokeOpacity: .55,
153
+ strokeWidth: 2,
154
+ className: "text-dc-text-secondary",
155
+ "data-testid": `dot-strip-median-${e.label}`
156
+ }),
157
+ e.dots.map((t, r) => {
158
+ let i = v.has(t);
159
+ return /* @__PURE__ */ f("g", { children: [/* @__PURE__ */ d("circle", {
160
+ cx: t.x,
161
+ cy: _ + t.y,
162
+ r: n,
163
+ fill: i ? u : c,
164
+ stroke: "var(--dc-surface, #ffffff)",
165
+ strokeWidth: 1.25,
166
+ cursor: p ? "pointer" : void 0,
167
+ "data-testid": "dot-strip-dot",
168
+ onClick: (n) => m(e, t, n),
169
+ onMouseEnter: (n) => h(e, t, n),
170
+ onMouseLeave: g
171
+ }), i && /* @__PURE__ */ d("text", {
172
+ x: t.x,
173
+ y: _ + t.y + (t.y <= 0 ? -n - 6 : n + 14),
174
+ textAnchor: "middle",
175
+ fontSize: 11,
176
+ fill: u,
177
+ "data-testid": `dot-strip-extreme-${t.label}`,
178
+ children: t.label
179
+ })] }, `${t.label}-${r}`);
180
+ })
181
+ ]
182
+ });
183
+ }
184
+ var D = c.memo(function({ data: m, chartConfig: h, displayConfig: _ = {}, height: D = "100%", colorPalette: O, onDataPointClick: k, drillEnabled: A }) {
185
+ let { t: j } = e(), M = t(), { containerRef: N, dimensions: ie } = n(), [P, F] = u(null), ae = _.showGrid !== !1, I = _.showTooltip !== !1, oe = _.showMedianMarker !== !1, L = _.showBandStats !== !1, R = _.showExtremeLabels === !0, z = p[_.dotSize ?? "medium"] ?? p.medium, B = _.bandSort ?? "none", V = _.xAxisFormat, { bandField: H, valueField: U, labelField: W, configError: G } = l(() => {
186
+ let e = E(h?.xAxis) ?? E(h?.x), t = E(h?.yAxis) ?? E(h?.y), n = E(h?.series);
187
+ return !e || !t ? {
188
+ bandField: e,
189
+ valueField: t,
190
+ labelField: n,
191
+ configError: j("chart.runtime.configErrorHint.dotStrip")
192
+ } : {
193
+ bandField: e,
194
+ valueField: t,
195
+ labelField: n,
196
+ configError: null
197
+ };
198
+ }, [h, j]), K = Math.max((ie.width || 720) - C - T, 80), q = L ? te : ne, { bands: J, ticks: Y, scale: X, truncated: se } = l(() => {
199
+ let e = {
200
+ bands: [],
201
+ ticks: [],
202
+ scale: (e) => 0,
203
+ truncated: !1
204
+ };
205
+ if (G || !H || !U || !m || m.length === 0) return e;
206
+ let t = m, n = x(t, H, U, W, B), r = ee(n.flatMap((e) => e.values.map((e) => e.value))), i = r.max - r.min, a = Math.max(K - 2 * z - 2, 10), o = (e) => z + 1 + (i === 0 ? a / 2 : (e - r.min) / i * a);
207
+ return {
208
+ bands: n.map((e) => {
209
+ let t = v(e.values, o, z), n = e.values.map((e) => e.value).sort((e, t) => e - t), r = n.length > 0 ? n[0] : null, i = n.length > 0 ? n[n.length - 1] : null;
210
+ return {
211
+ label: e.label,
212
+ dots: t,
213
+ count: t.length,
214
+ median: g(n),
215
+ min: r,
216
+ max: i,
217
+ spread: b(r, i, t.length),
218
+ noData: t.length === 0,
219
+ height: Math.max(y(t, z), q),
220
+ truncated: e.truncated
221
+ };
222
+ }),
223
+ ticks: S(r.min, r.max, 5),
224
+ scale: o,
225
+ truncated: new Set(t.map((e) => String(e[H] ?? ""))).size > 50
226
+ };
227
+ }, [
228
+ m,
229
+ H,
230
+ U,
231
+ W,
232
+ B,
233
+ G,
234
+ K,
235
+ z,
236
+ q
237
+ ]), Z = O?.colors ?? r, ce = Z[0], le = Z[+(Z.length > 1)], Q = (e) => i(e, V), $ = (e, t, n) => {
238
+ !k || !A || !H || k({
239
+ dataPoint: t.row,
240
+ clickedField: H,
241
+ xValue: e.label,
242
+ position: {
243
+ x: n.clientX,
244
+ y: n.clientY
245
+ },
246
+ nativeEvent: n
247
+ });
248
+ }, ue = (e, t, n) => {
249
+ I && F({
250
+ band: e.label,
251
+ dot: t,
252
+ clientX: n.clientX,
253
+ clientY: n.clientY
254
+ });
255
+ };
256
+ if (G) return /* @__PURE__ */ d(a, {
257
+ height: D,
258
+ hint: G
259
+ });
260
+ if (!m || m.length === 0) return /* @__PURE__ */ d(o, {
261
+ height: D,
262
+ hint: j("chart.runtime.noDataHint.dotStrip")
263
+ });
264
+ if (J.length === 0) return /* @__PURE__ */ d(o, {
265
+ height: D,
266
+ titleKey: "chart.runtime.noValidData",
267
+ hint: j("chart.runtime.noValidDataHint.dotStrip")
268
+ });
269
+ try {
270
+ return /* @__PURE__ */ f("div", {
271
+ ref: N,
272
+ className: "dc:relative dc:w-full dc:overflow-y-auto",
273
+ style: { height: D },
274
+ children: [
275
+ /* @__PURE__ */ f("div", {
276
+ className: "dc:grid dc:items-stretch",
277
+ style: { gridTemplateColumns: `${C}px 1fr` },
278
+ "data-testid": "dot-strip-grid",
279
+ children: [
280
+ J.map((e) => /* @__PURE__ */ f(c.Fragment, { children: [/* @__PURE__ */ f("div", {
281
+ className: "dc:flex dc:flex-col dc:justify-center dc:gap-1 dc:pr-3 dc:py-2 dc:border-b border-dc-border",
282
+ style: { minHeight: e.height },
283
+ children: [/* @__PURE__ */ d("div", {
284
+ className: "dc:text-sm dc:font-semibold dc:truncate text-dc-text",
285
+ title: e.label,
286
+ children: e.label || j("chart.runtime.dotStrip.unlabelledBand")
287
+ }), L && /* @__PURE__ */ f("div", {
288
+ className: "dc:flex dc:flex-wrap dc:gap-1 dc:text-xs",
289
+ children: [/* @__PURE__ */ d("span", {
290
+ className: "dc:rounded-sm dc:px-1.5 dc:py-0.5 bg-dc-surface-secondary text-dc-text-secondary",
291
+ children: j(e.truncated ? "chart.runtime.dotStrip.countTruncated" : "chart.runtime.dotStrip.count", { count: e.count })
292
+ }), e.noData ? /* @__PURE__ */ d("span", {
293
+ className: "dc:rounded-sm dc:px-1.5 dc:py-0.5 bg-dc-surface-secondary text-dc-text-muted",
294
+ children: j("chart.runtime.dotStrip.noDataRecorded")
295
+ }) : e.spread !== null && /* @__PURE__ */ d("span", {
296
+ className: "dc:rounded-sm dc:px-1.5 dc:py-0.5 bg-dc-surface-secondary text-dc-text-secondary",
297
+ children: j("chart.runtime.dotStrip.spread", { spread: e.spread.toFixed(2) })
298
+ })]
299
+ })]
300
+ }), /* @__PURE__ */ d("div", {
301
+ className: "dc:flex dc:items-center dc:border-b border-dc-border",
302
+ style: {
303
+ minHeight: e.height,
304
+ paddingRight: T
305
+ },
306
+ children: /* @__PURE__ */ d(re, {
307
+ band: e,
308
+ width: K,
309
+ radius: z,
310
+ ticks: Y,
311
+ scale: X,
312
+ showGrid: ae,
313
+ showMedianMarker: oe,
314
+ showExtremeLabels: R,
315
+ color: ce,
316
+ accentColor: le,
317
+ drillEnabled: A === !0,
318
+ onDotClick: $,
319
+ onDotHover: ue,
320
+ onDotLeave: () => F(null)
321
+ })
322
+ })] }, e.label)),
323
+ /* @__PURE__ */ d("div", {}),
324
+ /* @__PURE__ */ d("div", {
325
+ style: { paddingRight: T },
326
+ children: /* @__PURE__ */ f("svg", {
327
+ width: K,
328
+ height: w,
329
+ viewBox: `0 0 ${K} ${w}`,
330
+ "data-testid": "dot-strip-axis",
331
+ children: [
332
+ /* @__PURE__ */ d("line", {
333
+ x1: 0,
334
+ x2: K,
335
+ y1: 1,
336
+ y2: 1,
337
+ stroke: "currentColor",
338
+ strokeOpacity: .2,
339
+ className: "text-dc-text-secondary"
340
+ }),
341
+ Y.map((e, t) => /* @__PURE__ */ f("g", {
342
+ transform: `translate(${X(e)}, 0)`,
343
+ children: [/* @__PURE__ */ d("line", {
344
+ y1: 1,
345
+ y2: 7,
346
+ stroke: "currentColor",
347
+ strokeOpacity: .4,
348
+ className: "text-dc-text-secondary"
349
+ }), /* @__PURE__ */ d("text", {
350
+ y: 22,
351
+ textAnchor: "middle",
352
+ fontSize: 11,
353
+ fill: "currentColor",
354
+ className: "text-dc-text-secondary",
355
+ children: Q(e)
356
+ })]
357
+ }, t)),
358
+ U && /* @__PURE__ */ d("text", {
359
+ x: K / 2,
360
+ y: 39,
361
+ textAnchor: "middle",
362
+ fontSize: 11,
363
+ fill: "currentColor",
364
+ className: "text-dc-text-muted",
365
+ children: M(U)
366
+ })
367
+ ]
368
+ })
369
+ })
370
+ ]
371
+ }),
372
+ se && /* @__PURE__ */ d("div", {
373
+ className: "dc:text-xs text-dc-warning dc:text-center dc:mt-1",
374
+ children: j("chart.runtime.dotStrip.truncated", { max: 50 })
375
+ }),
376
+ I && P && /* @__PURE__ */ f("div", {
377
+ className: "dc:fixed dc:z-50 dc:pointer-events-none dc:rounded-sm dc:px-2 dc:py-1 dc:text-xs dc:shadow-lg bg-dc-surface text-dc-text dc:border border-dc-border",
378
+ style: {
379
+ left: P.clientX + 12,
380
+ top: P.clientY + 12
381
+ },
382
+ "data-testid": "dot-strip-tooltip",
383
+ children: [
384
+ /* @__PURE__ */ d("div", {
385
+ className: "dc:font-semibold",
386
+ children: P.dot.label
387
+ }),
388
+ /* @__PURE__ */ d("div", {
389
+ className: "text-dc-text-secondary",
390
+ children: P.band
391
+ }),
392
+ /* @__PURE__ */ d("div", { children: Q(P.dot.value) })
393
+ ]
394
+ })
395
+ ]
396
+ });
397
+ } catch (e) {
398
+ return /* @__PURE__ */ d(s, {
399
+ height: D,
400
+ chartType: "Dot Strip Chart",
401
+ error: e
402
+ });
403
+ }
404
+ });
405
+ //#endregion
406
+ export { D as default };
407
+
408
+ //# sourceMappingURL=DotStripChart-ChwsVeRU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DotStripChart-ChwsVeRU.js","names":[],"sources":["../../../src/client/components/charts/DotStripChart.helpers.ts","../../../src/client/components/charts/DotStripChart.tsx"],"sourcesContent":["/**\n * Layout maths for the dot strip (beeswarm) chart.\n *\n * Kept out of the component — like `ScatterChart.helpers.ts` and\n * `BubbleChart.render.ts` — so the swarm packing can be unit-tested without a\n * DOM. Everything here is pure: same input, same output, every time.\n */\n\n/** Hard caps so one pathological band cannot blow up the layout. */\nexport const MAX_BANDS = 50\nexport const MAX_DOTS_PER_BAND = 500\nexport const MAX_LANES = 8\n\nexport const MIN_ROW_HEIGHT = 44\nexport const MAX_ROW_HEIGHT = 220\n/** Vertical breathing room added above and below the outermost lanes. */\nexport const ROW_VERTICAL_PADDING = 12\n\nexport const DOT_RADIUS: Record<'small' | 'medium' | 'large', number> = {\n small: 3.5,\n medium: 5,\n large: 7,\n}\n\n/** Gap between the edges of two adjacent dots in the same lane. */\nexport const DOT_GAP = 1.5\n\nexport interface DotDatum {\n /** Raw numeric value of the measure. */\n value: number\n /** Identity label for the dot (from the optional series dimension). */\n label: string\n /** The source row, handed back on click. */\n row: Record<string, unknown>\n}\n\nexport interface PlacedDot extends DotDatum {\n /** Pixel x within the plot area. */\n x: number\n /** Lane index: 0 is the centre line, then +1, -1, +2, -2, … */\n lane: number\n /** Pixel y offset from the band's centre line. */\n y: number\n}\n\nexport interface BandStats {\n /** The band's own label (the value of the band dimension). */\n label: string\n dots: PlacedDot[]\n count: number\n median: number | null\n min: number | null\n max: number | null\n /**\n * max / min. `null` when it cannot be stated meaningfully — fewer than two\n * dots, or a non-positive minimum (the ratio is infinite or sign-flipped).\n */\n spread: number | null\n /** True when the band has rows but not one usable numeric value. */\n noData: boolean\n /** Rendered height of this band's row, in px. */\n height: number\n /** True when the band's dots were truncated at MAX_DOTS_PER_BAND. */\n truncated: boolean\n}\n\nexport function parseNumeric(v: unknown): number | null {\n if (v === undefined || v === null || v === '') return null\n const n = typeof v === 'number' ? v : parseFloat(String(v))\n return Number.isFinite(n) ? n : null\n}\n\nexport function median(sortedValues: number[]): number | null {\n const n = sortedValues.length\n if (n === 0) return null\n const mid = Math.floor(n / 2)\n return n % 2 === 0 ? (sortedValues[mid - 1] + sortedValues[mid]) / 2 : sortedValues[mid]\n}\n\n/**\n * Walk lanes outward from the centre: 0, +1, -1, +2, -2, …\n * Returns the lane index for the nth step.\n */\nfunction laneAtStep(step: number): number {\n if (step === 0) return 0\n const magnitude = Math.ceil(step / 2)\n return step % 2 === 1 ? magnitude : -magnitude\n}\n\n/**\n * Greedy deterministic beeswarm packing.\n *\n * Dots are sorted by x (ties broken by label, so the output is stable for a\n * given input rather than dependent on row order) and each is dropped into the\n * first lane — searched outward from the centre — where it clears every dot\n * already in that lane by at least `2r + gap`. Beyond `MAX_LANES` the dot is\n * forced onto the outermost lane and simply overlaps; the surface-coloured\n * stroke keeps that readable.\n *\n * A force simulation would do this too, but it settles asynchronously and\n * non-deterministically, which makes it untestable and jittery on re-render.\n */\nexport function packSwarm(dots: DotDatum[], scale: (v: number) => number, radius: number): PlacedDot[] {\n const minSeparation = 2 * radius + DOT_GAP\n const laneHeight = 2 * radius + DOT_GAP\n\n const sorted = [...dots].sort((a, b) => (a.value - b.value) || a.label.localeCompare(b.label))\n\n // lane index -> x positions already placed in that lane\n const lanes = new Map<number, number[]>()\n const placed: PlacedDot[] = []\n\n for (const dot of sorted) {\n const x = scale(dot.value)\n\n let chosenLane = laneAtStep(2 * MAX_LANES)\n for (let step = 0; step <= 2 * MAX_LANES; step++) {\n const lane = laneAtStep(step)\n const occupied = lanes.get(lane)\n if (!occupied || occupied.every((other) => Math.abs(x - other) >= minSeparation)) {\n chosenLane = lane\n break\n }\n }\n\n const occupied = lanes.get(chosenLane)\n if (occupied) occupied.push(x)\n else lanes.set(chosenLane, [x])\n\n placed.push({ ...dot, x, lane: chosenLane, y: chosenLane * laneHeight })\n }\n\n return placed\n}\n\n/** Row height needed to show every lane the swarm used. */\nexport function swarmHeight(placed: PlacedDot[], radius: number): number {\n const maxAbsLane = placed.reduce((acc, d) => Math.max(acc, Math.abs(d.lane)), 0)\n const laneHeight = 2 * radius + DOT_GAP\n const needed = (2 * maxAbsLane + 1) * laneHeight + 2 * ROW_VERTICAL_PADDING\n return Math.min(Math.max(needed, MIN_ROW_HEIGHT), MAX_ROW_HEIGHT)\n}\n\n/** max / min, or null when the ratio would be meaningless. */\nexport function computeSpread(min: number | null, max: number | null, count: number): number | null {\n if (min === null || max === null || count < 2) return null\n if (min <= 0) return null\n return max / min\n}\n\nexport type BandSort = 'none' | 'valueDesc' | 'valueAsc' | 'count'\n\n/**\n * Group rows into bands, in the order requested. Sorting happens before the\n * swarm is packed so row heights follow the rows the user actually sees.\n */\nexport function groupIntoBands(\n rows: Record<string, unknown>[],\n bandField: string,\n valueField: string,\n labelField: string | undefined,\n sort: BandSort\n): Array<{ label: string; values: DotDatum[]; truncated: boolean }> {\n const order: string[] = []\n const grouped = new Map<string, DotDatum[]>()\n\n for (const row of rows) {\n const bandLabel = String(row[bandField] ?? '')\n if (!grouped.has(bandLabel)) {\n grouped.set(bandLabel, [])\n order.push(bandLabel)\n }\n const value = parseNumeric(row[valueField])\n if (value === null) continue\n grouped.get(bandLabel)!.push({\n value,\n label: labelField ? String(row[labelField] ?? '') : bandLabel,\n row,\n })\n }\n\n let bands = order.map((label) => {\n const all = grouped.get(label)!\n return {\n label,\n values: all.slice(0, MAX_DOTS_PER_BAND),\n truncated: all.length > MAX_DOTS_PER_BAND,\n }\n })\n\n if (sort !== 'none') {\n const medianOf = (values: DotDatum[]) => median(values.map((d) => d.value).sort((a, b) => a - b))\n bands = [...bands].sort((a, b) => {\n if (sort === 'count') return b.values.length - a.values.length\n const ma = medianOf(a.values)\n const mb = medianOf(b.values)\n if (ma === null && mb === null) return 0\n if (ma === null) return 1\n if (mb === null) return -1\n return sort === 'valueDesc' ? mb - ma : ma - mb\n })\n }\n\n return bands.slice(0, MAX_BANDS)\n}\n\n/** Nicely padded numeric domain across every dot in every band. */\nexport function computeDomain(values: number[]): { min: number; max: number } {\n if (values.length === 0) return { min: 0, max: 1 }\n const rawMin = Math.min(...values)\n const rawMax = Math.max(...values)\n if (rawMin === rawMax) {\n const pad = Math.abs(rawMin) * 0.1 || 1\n return { min: rawMin - pad, max: rawMax + pad }\n }\n const pad = (rawMax - rawMin) * 0.1\n return { min: rawMin - pad, max: rawMax + pad }\n}\n\n/** Evenly spaced axis ticks across the domain. */\nexport function computeTicks(min: number, max: number, count = 5): number[] {\n if (max === min) return [min]\n const step = (max - min) / (count - 1)\n return Array.from({ length: count }, (_, i) => min + i * step)\n}\n","import React, { useMemo, useState } from 'react'\nimport { useTranslation } from '../../hooks/useTranslation.js'\nimport { useCubeFieldLabel } from '../../hooks/useCubeFieldLabel.js'\nimport { CHART_COLORS } from '../../utils/chartConstants.js'\nimport { formatAxisValue } from '../../utils/chartUtils.js'\nimport { ChartConfigError, ChartEmptyState, ChartRenderError } from './ChartStates.js'\nimport { useChartDimensions } from './useChartDimensions.js'\nimport {\n DOT_RADIUS,\n MAX_BANDS,\n computeDomain,\n computeSpread,\n computeTicks,\n groupIntoBands,\n median,\n packSwarm,\n swarmHeight,\n type BandSort,\n type BandStats,\n type PlacedDot,\n} from './DotStripChart.helpers.js'\nimport type { ChartProps } from '../../types.js'\n\nconst GUTTER_WIDTH = 190\nconst AXIS_HEIGHT = 44\nconst PLOT_PADDING_X = 24\n\n/**\n * Height the left gutter needs for its own content, so a band with a flat swarm\n * still gets a row tall enough for the name and the badges. Folded into the\n * band height rather than left to the grid, so the strip SVG always fills the\n * whole row and its gridlines stay continuous between bands.\n *\n * `dc:text-sm` line (20) + `dc:gap-1` (4) + badge line (20) + `dc:py-2` (16).\n */\nconst GUTTER_HEIGHT_WITH_STATS = 60\nconst GUTTER_HEIGHT_NAME_ONLY = 36\n\n/**\n * Read a drop zone's field, tolerating both shapes it is stored in: the\n * AnalysisBuilder writes a bare string into any zone with `maxItems: 1`\n * (`addFieldToAxis` in `AnalysisBuilder/utils/axisConfigUtils.ts`), while the\n * agent's `inferChartConfig` always writes an array.\n */\nfunction firstField(value: unknown): string | undefined {\n if (Array.isArray(value)) return typeof value[0] === 'string' ? value[0] : undefined\n return typeof value === 'string' && value !== '' ? value : undefined\n}\n\ninterface HoveredDot {\n band: string\n dot: PlacedDot\n clientX: number\n clientY: number\n}\n\n/**\n * One band's strip: gridlines, the baseline, the median tick and the swarm.\n * The x-scale is passed in so every band and the axis share one domain.\n */\nfunction BandStrip({\n band,\n width,\n radius,\n ticks,\n scale,\n showGrid,\n showMedianMarker,\n showExtremeLabels,\n color,\n accentColor,\n drillEnabled,\n onDotClick,\n onDotHover,\n onDotLeave,\n}: {\n band: BandStats\n width: number\n radius: number\n ticks: number[]\n scale: (v: number) => number\n showGrid: boolean\n showMedianMarker: boolean\n showExtremeLabels: boolean\n color: string\n accentColor: string\n drillEnabled: boolean\n onDotClick: (band: BandStats, dot: PlacedDot, event: React.MouseEvent) => void\n onDotHover: (band: BandStats, dot: PlacedDot, event: React.MouseEvent) => void\n onDotLeave: () => void\n}) {\n const centreY = band.height / 2\n const extremes = useMemo(() => {\n if (!showExtremeLabels || band.dots.length < 2) return new Set<PlacedDot>()\n const sorted = [...band.dots].sort((a, b) => a.value - b.value)\n return new Set<PlacedDot>([sorted[0], sorted[sorted.length - 1]])\n }, [band.dots, showExtremeLabels])\n\n return (\n <svg\n width={width}\n height={band.height}\n viewBox={`0 0 ${width} ${band.height}`}\n data-testid={`dot-strip-band-${band.label}`}\n >\n {showGrid &&\n ticks.map((tick, i) => (\n <line\n key={i}\n x1={scale(tick)}\n x2={scale(tick)}\n y1={0}\n y2={band.height}\n stroke=\"currentColor\"\n strokeOpacity={0.08}\n strokeWidth={1}\n className=\"text-dc-text-secondary\"\n />\n ))}\n\n {band.dots.length > 0 && (\n <line\n x1={scale(band.min!)}\n x2={scale(band.max!)}\n y1={centreY}\n y2={centreY}\n stroke=\"currentColor\"\n strokeOpacity={0.25}\n strokeWidth={1}\n className=\"text-dc-text-secondary\"\n />\n )}\n\n {showMedianMarker && band.median !== null && (\n <line\n x1={scale(band.median)}\n x2={scale(band.median)}\n y1={centreY - Math.min(centreY - 2, 16)}\n y2={centreY + Math.min(centreY - 2, 16)}\n stroke=\"currentColor\"\n strokeOpacity={0.55}\n strokeWidth={2}\n className=\"text-dc-text-secondary\"\n data-testid={`dot-strip-median-${band.label}`}\n />\n )}\n\n {band.dots.map((dot, i) => {\n const isExtreme = extremes.has(dot)\n return (\n <g key={`${dot.label}-${i}`}>\n <circle\n cx={dot.x}\n cy={centreY + dot.y}\n r={radius}\n fill={isExtreme ? accentColor : color}\n stroke=\"var(--dc-surface, #ffffff)\"\n strokeWidth={1.25}\n cursor={drillEnabled ? 'pointer' : undefined}\n data-testid=\"dot-strip-dot\"\n onClick={(event) => onDotClick(band, dot, event)}\n onMouseEnter={(event) => onDotHover(band, dot, event)}\n onMouseLeave={onDotLeave}\n />\n {isExtreme && (\n <text\n x={dot.x}\n y={centreY + dot.y + (dot.y <= 0 ? -radius - 6 : radius + 14)}\n textAnchor=\"middle\"\n fontSize={11}\n fill={accentColor}\n data-testid={`dot-strip-extreme-${dot.label}`}\n >\n {dot.label}\n </text>\n )}\n </g>\n )\n })}\n </svg>\n )\n}\n\nconst DotStripChart = React.memo(function DotStripChart({\n data,\n chartConfig,\n displayConfig = {},\n height = '100%',\n colorPalette,\n onDataPointClick,\n drillEnabled,\n}: ChartProps) {\n const { t } = useTranslation()\n const getFieldLabel = useCubeFieldLabel()\n const { containerRef, dimensions } = useChartDimensions()\n const [hovered, setHovered] = useState<HoveredDot | null>(null)\n\n const showGrid = displayConfig.showGrid !== false\n const showTooltip = displayConfig.showTooltip !== false\n const showMedianMarker = displayConfig.showMedianMarker !== false\n const showBandStats = displayConfig.showBandStats !== false\n const showExtremeLabels = displayConfig.showExtremeLabels === true\n const radius = DOT_RADIUS[displayConfig.dotSize ?? 'medium'] ?? DOT_RADIUS.medium\n const bandSort: BandSort = displayConfig.bandSort ?? 'none'\n const xAxisFormat = displayConfig.xAxisFormat\n\n const { bandField, valueField, labelField, configError } = useMemo(() => {\n const bandField = firstField(chartConfig?.xAxis) ?? firstField(chartConfig?.x)\n const valueField = firstField(chartConfig?.yAxis) ?? firstField(chartConfig?.y)\n const labelField = firstField(chartConfig?.series)\n\n if (!bandField || !valueField) {\n return {\n bandField,\n valueField,\n labelField,\n configError: t('chart.runtime.configErrorHint.dotStrip'),\n }\n }\n return { bandField, valueField, labelField, configError: null as string | null }\n }, [chartConfig, t])\n\n const plotWidth = Math.max((dimensions.width || 720) - GUTTER_WIDTH - PLOT_PADDING_X, 80)\n\n const gutterHeight = showBandStats ? GUTTER_HEIGHT_WITH_STATS : GUTTER_HEIGHT_NAME_ONLY\n\n const { bands, ticks, scale, truncated } = useMemo(() => {\n const empty = { bands: [] as BandStats[], ticks: [] as number[], scale: (_: number) => 0, truncated: false }\n if (configError || !bandField || !valueField || !data || data.length === 0) return empty\n\n const rows = data as Record<string, unknown>[]\n const grouped = groupIntoBands(rows, bandField, valueField, labelField, bandSort)\n\n const allValues = grouped.flatMap((b) => b.values.map((d) => d.value))\n const domain = computeDomain(allValues)\n const span = domain.max - domain.min\n const inner = Math.max(plotWidth - 2 * radius - 2, 10)\n const scale = (v: number) => radius + 1 + (span === 0 ? inner / 2 : ((v - domain.min) / span) * inner)\n\n const bands: BandStats[] = grouped.map((group) => {\n const placed = packSwarm(group.values, scale, radius)\n const sortedValues = group.values.map((d) => d.value).sort((a, b) => a - b)\n const min = sortedValues.length > 0 ? sortedValues[0] : null\n const max = sortedValues.length > 0 ? sortedValues[sortedValues.length - 1] : null\n return {\n label: group.label,\n dots: placed,\n count: placed.length,\n median: median(sortedValues),\n min,\n max,\n spread: computeSpread(min, max, placed.length),\n noData: placed.length === 0,\n height: Math.max(swarmHeight(placed, radius), gutterHeight),\n truncated: group.truncated,\n }\n })\n\n return {\n bands,\n ticks: computeTicks(domain.min, domain.max, 5),\n scale,\n truncated: new Set(rows.map((r) => String(r[bandField] ?? ''))).size > MAX_BANDS,\n }\n }, [data, bandField, valueField, labelField, bandSort, configError, plotWidth, radius, gutterHeight])\n\n const palette = colorPalette?.colors ?? CHART_COLORS\n const color = palette[0]\n const accentColor = palette[palette.length > 1 ? 1 : 0]\n\n const formatValue = (v: number) => formatAxisValue(v, xAxisFormat)\n\n const handleDotClick = (band: BandStats, dot: PlacedDot, event: React.MouseEvent) => {\n if (!onDataPointClick || !drillEnabled || !bandField) return\n onDataPointClick({\n dataPoint: dot.row,\n clickedField: bandField,\n xValue: band.label,\n position: { x: event.clientX, y: event.clientY },\n nativeEvent: event,\n })\n }\n\n const handleDotHover = (band: BandStats, dot: PlacedDot, event: React.MouseEvent) => {\n if (!showTooltip) return\n setHovered({ band: band.label, dot, clientX: event.clientX, clientY: event.clientY })\n }\n\n if (configError) {\n return <ChartConfigError height={height} hint={configError} />\n }\n\n if (!data || data.length === 0) {\n return <ChartEmptyState height={height} hint={t('chart.runtime.noDataHint.dotStrip')} />\n }\n\n if (bands.length === 0) {\n return (\n <ChartEmptyState\n height={height}\n titleKey=\"chart.runtime.noValidData\"\n hint={t('chart.runtime.noValidDataHint.dotStrip')}\n />\n )\n }\n\n try {\n return (\n <div ref={containerRef} className=\"dc:relative dc:w-full dc:overflow-y-auto\" style={{ height }}>\n <div\n className=\"dc:grid dc:items-stretch\"\n style={{ gridTemplateColumns: `${GUTTER_WIDTH}px 1fr` }}\n data-testid=\"dot-strip-grid\"\n >\n {bands.map((band) => (\n <React.Fragment key={band.label}>\n <div\n className=\"dc:flex dc:flex-col dc:justify-center dc:gap-1 dc:pr-3 dc:py-2 dc:border-b border-dc-border\"\n style={{ minHeight: band.height }}\n >\n <div className=\"dc:text-sm dc:font-semibold dc:truncate text-dc-text\" title={band.label}>\n {band.label || t('chart.runtime.dotStrip.unlabelledBand')}\n </div>\n {showBandStats && (\n <div className=\"dc:flex dc:flex-wrap dc:gap-1 dc:text-xs\">\n <span className=\"dc:rounded-sm dc:px-1.5 dc:py-0.5 bg-dc-surface-secondary text-dc-text-secondary\">\n {t(\n band.truncated\n ? 'chart.runtime.dotStrip.countTruncated'\n : 'chart.runtime.dotStrip.count',\n { count: band.count }\n )}\n </span>\n {band.noData ? (\n <span className=\"dc:rounded-sm dc:px-1.5 dc:py-0.5 bg-dc-surface-secondary text-dc-text-muted\">\n {t('chart.runtime.dotStrip.noDataRecorded')}\n </span>\n ) : (\n band.spread !== null && (\n <span className=\"dc:rounded-sm dc:px-1.5 dc:py-0.5 bg-dc-surface-secondary text-dc-text-secondary\">\n {t('chart.runtime.dotStrip.spread', { spread: band.spread.toFixed(2) })}\n </span>\n )\n )}\n </div>\n )}\n </div>\n <div\n className=\"dc:flex dc:items-center dc:border-b border-dc-border\"\n style={{ minHeight: band.height, paddingRight: PLOT_PADDING_X }}\n >\n <BandStrip\n band={band}\n width={plotWidth}\n radius={radius}\n ticks={ticks}\n scale={scale}\n showGrid={showGrid}\n showMedianMarker={showMedianMarker}\n showExtremeLabels={showExtremeLabels}\n color={color}\n accentColor={accentColor}\n drillEnabled={drillEnabled === true}\n onDotClick={handleDotClick}\n onDotHover={handleDotHover}\n onDotLeave={() => setHovered(null)}\n />\n </div>\n </React.Fragment>\n ))}\n\n <div />\n <div style={{ paddingRight: PLOT_PADDING_X }}>\n <svg\n width={plotWidth}\n height={AXIS_HEIGHT}\n viewBox={`0 0 ${plotWidth} ${AXIS_HEIGHT}`}\n data-testid=\"dot-strip-axis\"\n >\n <line x1={0} x2={plotWidth} y1={1} y2={1} stroke=\"currentColor\" strokeOpacity={0.2} className=\"text-dc-text-secondary\" />\n {ticks.map((tick, i) => (\n <g key={i} transform={`translate(${scale(tick)}, 0)`}>\n <line y1={1} y2={7} stroke=\"currentColor\" strokeOpacity={0.4} className=\"text-dc-text-secondary\" />\n <text\n y={22}\n textAnchor=\"middle\"\n fontSize={11}\n fill=\"currentColor\"\n className=\"text-dc-text-secondary\"\n >\n {formatValue(tick)}\n </text>\n </g>\n ))}\n {valueField && (\n <text\n x={plotWidth / 2}\n y={39}\n textAnchor=\"middle\"\n fontSize={11}\n fill=\"currentColor\"\n className=\"text-dc-text-muted\"\n >\n {getFieldLabel(valueField)}\n </text>\n )}\n </svg>\n </div>\n </div>\n\n {truncated && (\n <div className=\"dc:text-xs text-dc-warning dc:text-center dc:mt-1\">\n {t('chart.runtime.dotStrip.truncated', { max: MAX_BANDS })}\n </div>\n )}\n\n {showTooltip && hovered && (\n <div\n className=\"dc:fixed dc:z-50 dc:pointer-events-none dc:rounded-sm dc:px-2 dc:py-1 dc:text-xs dc:shadow-lg bg-dc-surface text-dc-text dc:border border-dc-border\"\n style={{ left: hovered.clientX + 12, top: hovered.clientY + 12 }}\n data-testid=\"dot-strip-tooltip\"\n >\n <div className=\"dc:font-semibold\">{hovered.dot.label}</div>\n <div className=\"text-dc-text-secondary\">{hovered.band}</div>\n <div>{formatValue(hovered.dot.value)}</div>\n </div>\n )}\n </div>\n )\n } catch (error) {\n return <ChartRenderError height={height} chartType=\"Dot Strip Chart\" error={error} />\n }\n})\n\nexport default DotStripChart\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { P as e, S as t, w as n } from "./chart-activity-grid-DvD_4wJz.js";
2
- import { D as r, O as i, k as a, s as o } from "./chart-area-DPp3hSOK.js";
1
+ import { F as e, S as t, w as n } from "./chart-activity-grid-CJzxC18G.js";
2
+ import { D as r, O as i, k as a, s as o } from "./chart-area-C66dgy84.js";
3
3
  import s, { useMemo as c } from "react";
4
4
  import { jsx as l, jsxs as u } from "react/jsx-runtime";
5
5
  //#region src/client/components/charts/ProportionBarChart.tsx
@@ -106,4 +106,4 @@ var d = s.memo(function({ data: s, chartConfig: d, displayConfig: f = {}, height
106
106
  //#endregion
107
107
  export { d as default };
108
108
 
109
- //# sourceMappingURL=ProportionBarChart-BVcbGY2C.js.map
109
+ //# sourceMappingURL=ProportionBarChart-D-Qt9nkF.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ProportionBarChart-BVcbGY2C.js","names":[],"sources":["../../../src/client/components/charts/ProportionBarChart.tsx"],"sourcesContent":["import React, { useMemo } from 'react'\nimport { useTranslation } from '../../hooks/useTranslation.js'\nimport { useCubeFieldLabel } from '../../hooks/useCubeFieldLabel.js'\nimport { ChartEmptyState, ChartConfigError, ChartRenderError } from './ChartStates.js'\nimport { getSeriesColor } from './cartesianChartHelpers.js'\nimport { formatAxisValue } from '../../utils/chartUtils.js'\nimport type { ChartProps } from '../../types.js'\n\ninterface Segment {\n /**\n * React key. Category labels are not reliably unique - a query can return\n * duplicates, and every null collapses to the same empty string - so the key\n * is tied to the source row instead. Stable across sorting, which reorders\n * the segments under the same identity.\n */\n id: string\n label: string\n value: number\n share: number\n color: string\n}\n\n/**\n * A single 100%-wide stacked bar plus a labelled percentage legend.\n *\n * A flatter alternative to a pie chart for part-to-whole breakdowns: shares are\n * far easier to compare along one axis than as angles, and it costs a fraction\n * of the vertical space. Deliberately plain HTML rather than Recharts — there is\n * no axis, scale or interaction to justify an SVG chart.\n */\nconst ProportionBarChart = React.memo(function ProportionBarChart({\n data,\n chartConfig,\n displayConfig = {},\n height = '100%',\n colorPalette\n}: ChartProps) {\n const { t } = useTranslation()\n const getFieldLabel = useCubeFieldLabel()\n\n const categoryField = useMemo(() => {\n const x = chartConfig?.xAxis\n return (Array.isArray(x) ? x[0] : x) || ''\n }, [chartConfig?.xAxis])\n\n const valueField = useMemo(() => {\n const y = chartConfig?.yAxis\n return (Array.isArray(y) ? y[0] : y) || ''\n }, [chartConfig?.yAxis])\n\n const sortSegments = displayConfig.sortSegments ?? false\n\n const { segments, total } = useMemo(() => {\n if (!data || !categoryField || !valueField) return { segments: [] as Segment[], total: 0 }\n\n const rows = data\n .map((row: any, sourceIndex: number) => {\n const raw = row?.[valueField]\n const num = typeof raw === 'number' ? raw : parseFloat(String(raw))\n const label = String(row?.[categoryField] ?? '')\n return {\n id: `${sourceIndex}:${label}`,\n label,\n // Negative shares cannot be drawn in a part-to-whole bar.\n value: !isNaN(num) && isFinite(num) && num > 0 ? num : 0\n }\n })\n .filter((row) => row.value > 0)\n\n if (sortSegments) rows.sort((a, b) => b.value - a.value)\n\n const sum = rows.reduce((acc, row) => acc + row.value, 0)\n return {\n total: sum,\n segments: rows.map((row, index) => ({\n ...row,\n share: sum > 0 ? (row.value / sum) * 100 : 0,\n color: getSeriesColor(colorPalette, index)\n }))\n }\n }, [data, categoryField, valueField, colorPalette, sortSegments])\n\n try {\n if (!data || data.length === 0) {\n return <ChartEmptyState height={height} hint={t('chart.runtime.noDataHint.proportionBar')} />\n }\n\n if (!categoryField || !valueField) {\n return <ChartConfigError height={height} hint={t('chart.runtime.configErrorHint.proportionBar')} />\n }\n\n if (segments.length === 0 || total === 0) {\n return (\n <ChartEmptyState\n height={height}\n titleKey=\"chart.runtime.noValidData\"\n hint={t('chart.runtime.noValidDataHint.proportionBar')}\n />\n )\n }\n\n const showLabels = displayConfig.showLabels ?? true\n const showPercentages = displayConfig.showPercentages ?? true\n const decimals = displayConfig.decimals ?? 0\n\n return (\n <div\n className=\"dc:w-full dc:h-full dc:flex dc:flex-col dc:justify-center dc:gap-3 dc:px-3 dc:py-2 dc:overflow-hidden\"\n // Fill the parent rather than the `height` prop, which is a pixel value\n // that can exceed the visible panel and push this short content low.\n style={{ height: '100%', minHeight: '80px' }}\n data-testid=\"proportion-bar\"\n >\n <div className=\"dc:flex dc:w-full dc:overflow-hidden dc:rounded-sm\" style={{ height: 10 }}>\n {segments.map((segment) => (\n <div\n key={segment.id}\n data-testid=\"proportion-bar-segment\"\n title={`${segment.label}: ${formatAxisValue(segment.value, displayConfig.leftYAxisFormat)}`}\n style={{ width: `${segment.share}%`, backgroundColor: segment.color }}\n />\n ))}\n </div>\n\n {(showLabels || showPercentages) && (\n <div className=\"dc:flex dc:flex-wrap dc:gap-x-6 dc:gap-y-2\">\n {segments.map((segment) => (\n <div key={segment.id} className=\"dc:flex dc:flex-col dc:gap-0.5 dc:min-w-0\">\n {showLabels && (\n <span\n className=\"text-dc-text-muted dc:uppercase dc:truncate dc:font-semibold\"\n style={{ fontSize: '11px', letterSpacing: '0.06em' }}\n >\n {segment.label}\n </span>\n )}\n {showPercentages && (\n <span\n className=\"dc:font-semibold dc:leading-none\"\n style={{ fontSize: '18px', color: segment.color }}\n >\n {segment.share.toFixed(decimals)}%\n </span>\n )}\n </div>\n ))}\n </div>\n )}\n </div>\n )\n } catch (error) {\n return <ChartRenderError height={height} chartType={getFieldLabel(valueField)} error={error} />\n }\n})\n\nexport default ProportionBarChart\n"],"mappings":"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"}
1
+ {"version":3,"file":"ProportionBarChart-D-Qt9nkF.js","names":[],"sources":["../../../src/client/components/charts/ProportionBarChart.tsx"],"sourcesContent":["import React, { useMemo } from 'react'\nimport { useTranslation } from '../../hooks/useTranslation.js'\nimport { useCubeFieldLabel } from '../../hooks/useCubeFieldLabel.js'\nimport { ChartEmptyState, ChartConfigError, ChartRenderError } from './ChartStates.js'\nimport { getSeriesColor } from './cartesianChartHelpers.js'\nimport { formatAxisValue } from '../../utils/chartUtils.js'\nimport type { ChartProps } from '../../types.js'\n\ninterface Segment {\n /**\n * React key. Category labels are not reliably unique - a query can return\n * duplicates, and every null collapses to the same empty string - so the key\n * is tied to the source row instead. Stable across sorting, which reorders\n * the segments under the same identity.\n */\n id: string\n label: string\n value: number\n share: number\n color: string\n}\n\n/**\n * A single 100%-wide stacked bar plus a labelled percentage legend.\n *\n * A flatter alternative to a pie chart for part-to-whole breakdowns: shares are\n * far easier to compare along one axis than as angles, and it costs a fraction\n * of the vertical space. Deliberately plain HTML rather than Recharts — there is\n * no axis, scale or interaction to justify an SVG chart.\n */\nconst ProportionBarChart = React.memo(function ProportionBarChart({\n data,\n chartConfig,\n displayConfig = {},\n height = '100%',\n colorPalette\n}: ChartProps) {\n const { t } = useTranslation()\n const getFieldLabel = useCubeFieldLabel()\n\n const categoryField = useMemo(() => {\n const x = chartConfig?.xAxis\n return (Array.isArray(x) ? x[0] : x) || ''\n }, [chartConfig?.xAxis])\n\n const valueField = useMemo(() => {\n const y = chartConfig?.yAxis\n return (Array.isArray(y) ? y[0] : y) || ''\n }, [chartConfig?.yAxis])\n\n const sortSegments = displayConfig.sortSegments ?? false\n\n const { segments, total } = useMemo(() => {\n if (!data || !categoryField || !valueField) return { segments: [] as Segment[], total: 0 }\n\n const rows = data\n .map((row: any, sourceIndex: number) => {\n const raw = row?.[valueField]\n const num = typeof raw === 'number' ? raw : parseFloat(String(raw))\n const label = String(row?.[categoryField] ?? '')\n return {\n id: `${sourceIndex}:${label}`,\n label,\n // Negative shares cannot be drawn in a part-to-whole bar.\n value: !isNaN(num) && isFinite(num) && num > 0 ? num : 0\n }\n })\n .filter((row) => row.value > 0)\n\n if (sortSegments) rows.sort((a, b) => b.value - a.value)\n\n const sum = rows.reduce((acc, row) => acc + row.value, 0)\n return {\n total: sum,\n segments: rows.map((row, index) => ({\n ...row,\n share: sum > 0 ? (row.value / sum) * 100 : 0,\n color: getSeriesColor(colorPalette, index)\n }))\n }\n }, [data, categoryField, valueField, colorPalette, sortSegments])\n\n try {\n if (!data || data.length === 0) {\n return <ChartEmptyState height={height} hint={t('chart.runtime.noDataHint.proportionBar')} />\n }\n\n if (!categoryField || !valueField) {\n return <ChartConfigError height={height} hint={t('chart.runtime.configErrorHint.proportionBar')} />\n }\n\n if (segments.length === 0 || total === 0) {\n return (\n <ChartEmptyState\n height={height}\n titleKey=\"chart.runtime.noValidData\"\n hint={t('chart.runtime.noValidDataHint.proportionBar')}\n />\n )\n }\n\n const showLabels = displayConfig.showLabels ?? true\n const showPercentages = displayConfig.showPercentages ?? true\n const decimals = displayConfig.decimals ?? 0\n\n return (\n <div\n className=\"dc:w-full dc:h-full dc:flex dc:flex-col dc:justify-center dc:gap-3 dc:px-3 dc:py-2 dc:overflow-hidden\"\n // Fill the parent rather than the `height` prop, which is a pixel value\n // that can exceed the visible panel and push this short content low.\n style={{ height: '100%', minHeight: '80px' }}\n data-testid=\"proportion-bar\"\n >\n <div className=\"dc:flex dc:w-full dc:overflow-hidden dc:rounded-sm\" style={{ height: 10 }}>\n {segments.map((segment) => (\n <div\n key={segment.id}\n data-testid=\"proportion-bar-segment\"\n title={`${segment.label}: ${formatAxisValue(segment.value, displayConfig.leftYAxisFormat)}`}\n style={{ width: `${segment.share}%`, backgroundColor: segment.color }}\n />\n ))}\n </div>\n\n {(showLabels || showPercentages) && (\n <div className=\"dc:flex dc:flex-wrap dc:gap-x-6 dc:gap-y-2\">\n {segments.map((segment) => (\n <div key={segment.id} className=\"dc:flex dc:flex-col dc:gap-0.5 dc:min-w-0\">\n {showLabels && (\n <span\n className=\"text-dc-text-muted dc:uppercase dc:truncate dc:font-semibold\"\n style={{ fontSize: '11px', letterSpacing: '0.06em' }}\n >\n {segment.label}\n </span>\n )}\n {showPercentages && (\n <span\n className=\"dc:font-semibold dc:leading-none\"\n style={{ fontSize: '18px', color: segment.color }}\n >\n {segment.share.toFixed(decimals)}%\n </span>\n )}\n </div>\n ))}\n </div>\n )}\n </div>\n )\n } catch (error) {\n return <ChartRenderError height={height} chartType={getFieldLabel(valueField)} error={error} />\n }\n})\n\nexport default ProportionBarChart\n"],"mappings":"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"}