drizzle-cube 0.5.4 → 0.5.5
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.
- package/dist/adapters/express/index.cjs +1 -1
- package/dist/adapters/express/index.js +4 -4
- package/dist/adapters/fastify/index.cjs +1 -1
- package/dist/adapters/fastify/index.js +4 -4
- package/dist/adapters/{handler-CNn3q29F.cjs → handler-C1Qs8JMY.cjs} +3 -3
- package/dist/adapters/{handler-_TKfigrZ.js → handler-CoaNnZyf.js} +122 -1
- package/dist/adapters/hono/index.cjs +1 -1
- package/dist/adapters/hono/index.js +4 -4
- package/dist/adapters/{locale-Dl_3R6hP.cjs → locale-CTuvUGBs.cjs} +1 -1
- package/dist/adapters/{locale-BQQrZYhz.js → locale-wMBdZ3Ks.js} +1 -1
- package/dist/adapters/mcp-tools.cjs +1 -1
- package/dist/adapters/mcp-tools.js +8 -3
- package/dist/adapters/mcp-transport-B_HoB1HQ.js +579 -0
- package/dist/adapters/mcp-transport-bQzyrBPI.cjs +40 -0
- package/dist/adapters/nextjs/index.cjs +1 -1
- package/dist/adapters/nextjs/index.js +4 -4
- package/dist/adapters/utils-CIRA5_JO.cjs +128 -0
- package/dist/adapters/{utils-DG8ti3FT.js → utils-hC7Z8V39.js} +19 -5
- package/dist/adapters/utils.cjs +1 -1
- package/dist/adapters/utils.d.ts +6 -1
- package/dist/adapters/utils.js +1 -1
- package/dist/client/charts/chartConfigs.d.ts +34 -0
- package/dist/client/charts.js +12 -12
- package/dist/client/chunks/{DashboardEditModal-BBcB0E2g.js → DashboardEditModal-DayTXEH0.js} +10 -10
- package/dist/client/chunks/{DashboardEditModal-BBcB0E2g.js.map → DashboardEditModal-DayTXEH0.js.map} +1 -1
- package/dist/client/chunks/{FieldSearchModal-CisOov-_.js → FieldSearchModal-B7Mr8UNT.js} +4 -4
- package/dist/client/chunks/{FieldSearchModal-CisOov-_.js.map → FieldSearchModal-B7Mr8UNT.js.map} +1 -1
- package/dist/client/chunks/KpiDelta-C-hZ1x01.js +2 -0
- package/dist/client/chunks/KpiNumber-Beo8CK0a.js +2 -0
- package/dist/client/chunks/KpiText-ytYiRTRO.js +2 -0
- package/dist/client/chunks/{RetentionCombinedChart-DiyZwiPv.js → RetentionCombinedChart-D3dRmoos.js} +3 -3
- package/dist/client/chunks/{RetentionCombinedChart-DiyZwiPv.js.map → RetentionCombinedChart-D3dRmoos.js.map} +1 -1
- package/dist/client/chunks/{RetentionHeatmap-usGF7BCo.js → RetentionHeatmap-DHPnn0qH.js} +2 -2
- package/dist/client/chunks/{RetentionHeatmap-usGF7BCo.js.map → RetentionHeatmap-DHPnn0qH.js.map} +1 -1
- package/dist/client/chunks/SchemaVisualization-DbYZBTyi.js +2 -0
- package/dist/client/chunks/SchemaVisualizationLazy-BGo-1S3q.js +2 -0
- package/dist/client/chunks/{af-ZA-xDmO5F0s.js → af-ZA-BtTNqvHF.js} +8 -3
- package/dist/client/chunks/af-ZA-BtTNqvHF.js.map +1 -0
- package/dist/client/chunks/{analysis-builder-0o1W-k3K.js → analysis-builder-lcGl099d.js} +245 -255
- package/dist/client/chunks/analysis-builder-lcGl099d.js.map +1 -0
- package/dist/client/chunks/{analysis-builder-shared-Cz4KAlIC.js → analysis-builder-shared-6BRZcEnu.js} +391 -459
- package/dist/client/chunks/analysis-builder-shared-6BRZcEnu.js.map +1 -0
- package/dist/client/chunks/{chart-activity-grid-VFFm85hC.js → chart-activity-grid-BnY-jaoa.js} +10 -5
- package/dist/client/chunks/chart-activity-grid-BnY-jaoa.js.map +1 -0
- package/dist/client/chunks/{chart-area-CwwIHTmK.js → chart-area-G3OvLLK4.js} +2 -2
- package/dist/client/chunks/{chart-area-CwwIHTmK.js.map → chart-area-G3OvLLK4.js.map} +1 -1
- package/dist/client/chunks/{chart-bar-Bmny922L.js → chart-bar-MLIWiLrc.js} +3 -3
- package/dist/client/chunks/{chart-bar-Bmny922L.js.map → chart-bar-MLIWiLrc.js.map} +1 -1
- package/dist/client/chunks/{chart-box-plot-DM7GwtCV.js → chart-box-plot-c2XqKTWq.js} +2 -2
- package/dist/client/chunks/{chart-box-plot-DM7GwtCV.js.map → chart-box-plot-c2XqKTWq.js.map} +1 -1
- package/dist/client/chunks/{chart-bubble-DJOq4IpT.js → chart-bubble-CAGvnYb1.js} +2 -2
- package/dist/client/chunks/{chart-bubble-DJOq4IpT.js.map → chart-bubble-CAGvnYb1.js.map} +1 -1
- package/dist/client/chunks/{chart-candlestick-C2nzVCv1.js → chart-candlestick-oSPk-KQp.js} +2 -2
- package/dist/client/chunks/{chart-candlestick-C2nzVCv1.js.map → chart-candlestick-oSPk-KQp.js.map} +1 -1
- package/dist/client/chunks/{chart-config-activity-grid-C-EkgYoa.js → chart-config-activity-grid-Dssynumw.js} +8 -1
- package/dist/client/chunks/chart-config-activity-grid-Dssynumw.js.map +1 -0
- package/dist/client/chunks/{chart-config-area-CMZpbIah.js → chart-config-area-40fbx2Ah.js} +8 -1
- package/dist/client/chunks/chart-config-area-40fbx2Ah.js.map +1 -0
- package/dist/client/chunks/{chart-config-bar-B8_V4YLg.js → chart-config-bar-CUWHwOPN.js} +8 -1
- package/dist/client/chunks/chart-config-bar-CUWHwOPN.js.map +1 -0
- package/dist/client/chunks/{chart-config-box-plot-Dwj7sEbU.js → chart-config-box-plot-D3Y0ien3.js} +8 -1
- package/dist/client/chunks/chart-config-box-plot-D3Y0ien3.js.map +1 -0
- package/dist/client/chunks/{chart-config-bubble-B0w0ZVp4.js → chart-config-bubble-BXSTKLn-.js} +8 -1
- package/dist/client/chunks/chart-config-bubble-BXSTKLn-.js.map +1 -0
- package/dist/client/chunks/{chart-config-candlestick-Bvo3zeIn.js → chart-config-candlestick-DEuD2Av0.js} +8 -1
- package/dist/client/chunks/chart-config-candlestick-DEuD2Av0.js.map +1 -0
- package/dist/client/chunks/{chart-config-gauge-C5ZiyZy7.js → chart-config-gauge-CCva3FfA.js} +5 -1
- package/dist/client/chunks/chart-config-gauge-CCva3FfA.js.map +1 -0
- package/dist/client/chunks/{chart-config-heat-map-Cv8qNnVP.js → chart-config-heat-map-Db4Z8UUn.js} +8 -1
- package/dist/client/chunks/chart-config-heat-map-Db4Z8UUn.js.map +1 -0
- package/dist/client/chunks/{chart-config-kpi-delta-BraHQc2E.js → chart-config-kpi-delta-BfLf3iyi.js} +8 -1
- package/dist/client/chunks/chart-config-kpi-delta-BfLf3iyi.js.map +1 -0
- package/dist/client/chunks/{chart-config-kpi-number-CeCkx7mC.js → chart-config-kpi-number-DWKFc9PX.js} +5 -1
- package/dist/client/chunks/chart-config-kpi-number-DWKFc9PX.js.map +1 -0
- package/dist/client/chunks/{chart-config-kpi-text-CImM3SvH.js → chart-config-kpi-text-Dr4OG6cY.js} +5 -1
- package/dist/client/chunks/chart-config-kpi-text-Dr4OG6cY.js.map +1 -0
- package/dist/client/chunks/{chart-config-line-BVKapAQK.js → chart-config-line-DGYYdDw9.js} +8 -1
- package/dist/client/chunks/chart-config-line-DGYYdDw9.js.map +1 -0
- package/dist/client/chunks/{chart-config-measure-profile-KTVV1gO3.js → chart-config-measure-profile-sB3n_Azv.js} +5 -1
- package/dist/client/chunks/chart-config-measure-profile-sB3n_Azv.js.map +1 -0
- package/dist/client/chunks/{chart-config-pie-BZxVl25X.js → chart-config-pie-kte7OXa9.js} +8 -1
- package/dist/client/chunks/chart-config-pie-kte7OXa9.js.map +1 -0
- package/dist/client/chunks/{chart-config-radar-B7FByX3t.js → chart-config-radar-C9IxP5tc.js} +8 -1
- package/dist/client/chunks/chart-config-radar-C9IxP5tc.js.map +1 -0
- package/dist/client/chunks/{chart-config-radial-bar-UfW_3yyX.js → chart-config-radial-bar-C3WJ8Uhm.js} +8 -1
- package/dist/client/chunks/chart-config-radial-bar-C3WJ8Uhm.js.map +1 -0
- package/dist/client/chunks/{chart-config-scatter-BVVJuOnt.js → chart-config-scatter-BVN_29G5.js} +8 -1
- package/dist/client/chunks/chart-config-scatter-BVN_29G5.js.map +1 -0
- package/dist/client/chunks/{chart-config-tree-map-IHp97OyV.js → chart-config-tree-map-meeJEDi8.js} +8 -1
- package/dist/client/chunks/chart-config-tree-map-meeJEDi8.js.map +1 -0
- package/dist/client/chunks/{chart-config-waterfall-BdqG1V-x.js → chart-config-waterfall-CaPeWZMl.js} +8 -1
- package/dist/client/chunks/chart-config-waterfall-CaPeWZMl.js.map +1 -0
- package/dist/client/chunks/{chart-data-table-zZtwLf55.js → chart-data-table-BRXHT2H-.js} +65 -65
- package/dist/client/chunks/{chart-data-table-zZtwLf55.js.map → chart-data-table-BRXHT2H-.js.map} +1 -1
- package/dist/client/chunks/{chart-funnel-COTJy8BP.js → chart-funnel-aQ7G_CqU.js} +2 -2
- package/dist/client/chunks/{chart-funnel-COTJy8BP.js.map → chart-funnel-aQ7G_CqU.js.map} +1 -1
- package/dist/client/chunks/{chart-gauge-C8lIneI0.js → chart-gauge-DqbDKr9E.js} +2 -2
- package/dist/client/chunks/{chart-gauge-C8lIneI0.js.map → chart-gauge-DqbDKr9E.js.map} +1 -1
- package/dist/client/chunks/{chart-heat-map-BJXt3RMt.js → chart-heat-map--6QnhUM8.js} +2 -2
- package/dist/client/chunks/{chart-heat-map-BJXt3RMt.js.map → chart-heat-map--6QnhUM8.js.map} +1 -1
- package/dist/client/chunks/{chart-kpi-delta-DHkNqufb.js → chart-kpi-delta-DOSpRjfs.js} +3 -3
- package/dist/client/chunks/{chart-kpi-delta-DHkNqufb.js.map → chart-kpi-delta-DOSpRjfs.js.map} +1 -1
- package/dist/client/chunks/{chart-kpi-number-BrXw7m-S.js → chart-kpi-number-BcMjeKm8.js} +5 -5
- package/dist/client/chunks/{chart-kpi-number-BrXw7m-S.js.map → chart-kpi-number-BcMjeKm8.js.map} +1 -1
- package/dist/client/chunks/{chart-kpi-text-D0plngLV.js → chart-kpi-text-BI9isc2i.js} +3 -3
- package/dist/client/chunks/{chart-kpi-text-D0plngLV.js.map → chart-kpi-text-BI9isc2i.js.map} +1 -1
- package/dist/client/chunks/{chart-line-DKvW32U-.js → chart-line-C0IHQteu.js} +3 -3
- package/dist/client/chunks/{chart-line-DKvW32U-.js.map → chart-line-C0IHQteu.js.map} +1 -1
- package/dist/client/chunks/{chart-markdown-CJU2hUq3.js → chart-markdown-BmgSMqPg.js} +2 -2
- package/dist/client/chunks/{chart-markdown-CJU2hUq3.js.map → chart-markdown-BmgSMqPg.js.map} +1 -1
- package/dist/client/chunks/{chart-measure-profile-DNT_tbh4.js → chart-measure-profile-DEyLW1fd.js} +3 -3
- package/dist/client/chunks/{chart-measure-profile-DNT_tbh4.js.map → chart-measure-profile-DEyLW1fd.js.map} +1 -1
- package/dist/client/chunks/{chart-pie-CzYnncO-.js → chart-pie-DSIekr7p.js} +3 -3
- package/dist/client/chunks/{chart-pie-CzYnncO-.js.map → chart-pie-DSIekr7p.js.map} +1 -1
- package/dist/client/chunks/{chart-radar-8iAt3QZl.js → chart-radar-SGl62hK8.js} +3 -3
- package/dist/client/chunks/{chart-radar-8iAt3QZl.js.map → chart-radar-SGl62hK8.js.map} +1 -1
- package/dist/client/chunks/{chart-radial-bar-CJbG7RIe.js → chart-radial-bar-C42EykOa.js} +3 -3
- package/dist/client/chunks/{chart-radial-bar-CJbG7RIe.js.map → chart-radial-bar-C42EykOa.js.map} +1 -1
- package/dist/client/chunks/{chart-sankey-C-wLBUmb.js → chart-sankey-DguImp0W.js} +2 -2
- package/dist/client/chunks/{chart-sankey-C-wLBUmb.js.map → chart-sankey-DguImp0W.js.map} +1 -1
- package/dist/client/chunks/{chart-scatter-NMjD1lbW.js → chart-scatter-Doeox4OP.js} +3 -3
- package/dist/client/chunks/{chart-scatter-NMjD1lbW.js.map → chart-scatter-Doeox4OP.js.map} +1 -1
- package/dist/client/chunks/{chart-sunburst-HtJ-LJ7n.js → chart-sunburst-F3tgCpL-.js} +3 -3
- package/dist/client/chunks/{chart-sunburst-HtJ-LJ7n.js.map → chart-sunburst-F3tgCpL-.js.map} +1 -1
- package/dist/client/chunks/{chart-tree-map-CetaLMt8.js → chart-tree-map-DvuSCIc8.js} +3 -3
- package/dist/client/chunks/{chart-tree-map-CetaLMt8.js.map → chart-tree-map-DvuSCIc8.js.map} +1 -1
- package/dist/client/chunks/{chart-waterfall-ontNp1Sd.js → chart-waterfall-Be5duXlO.js} +3 -3
- package/dist/client/chunks/{chart-waterfall-ontNp1Sd.js.map → chart-waterfall-Be5duXlO.js.map} +1 -1
- package/dist/client/chunks/{charts-core-B5UXUg6_.js → charts-core-XlOwoP_r.js} +2 -2
- package/dist/client/chunks/{charts-core-B5UXUg6_.js.map → charts-core-XlOwoP_r.js.map} +1 -1
- package/dist/client/chunks/{nl-NL-DDf0OdfW.js → nl-NL-BLDeSy_P.js} +8 -3
- package/dist/client/chunks/nl-NL-BLDeSy_P.js.map +1 -0
- package/dist/client/chunks/{schema-visualization-cnB2xZxn.js → schema-visualization-CM5ikSWB.js} +4 -4
- package/dist/client/chunks/{schema-visualization-cnB2xZxn.js.map → schema-visualization-CM5ikSWB.js.map} +1 -1
- package/dist/client/chunks/{useDebounce-BOBSvhHy.js → useDebounce-NEZQbfxN.js} +4 -4
- package/dist/client/chunks/{useDebounce-BOBSvhHy.js.map → useDebounce-NEZQbfxN.js.map} +1 -1
- package/dist/client/chunks/{useExplainAI-B_Pi4eXW.js → useExplainAI-DivfI0dW.js} +4 -4
- package/dist/client/chunks/{useExplainAI-B_Pi4eXW.js.map → useExplainAI-DivfI0dW.js.map} +1 -1
- package/dist/client/chunks/{utils-BIuqPQuJ.js → utils-Ctl_cVNR.js} +2 -2
- package/dist/client/chunks/{utils-BIuqPQuJ.js.map → utils-Ctl_cVNR.js.map} +1 -1
- package/dist/client/chunks/{vendor-BxLCTfvm.js → vendor-BcLQ6iVZ.js} +2 -2
- package/dist/client/chunks/{vendor-BxLCTfvm.js.map → vendor-BcLQ6iVZ.js.map} +1 -1
- package/dist/client/components/AnalysisBuilder/types.d.ts +2 -2
- package/dist/client/components.js +3 -3
- package/dist/client/hooks.js +3 -3
- package/dist/client/icons.js +1 -1
- package/dist/client/index.js +14 -14
- package/dist/client/providers.js +1 -1
- package/dist/client/schema.js +1 -1
- package/dist/client/shared/chartDefaults.d.ts +5 -10
- package/dist/client/utils.js +5 -5
- package/dist/client-bundle-stats.html +1 -1
- package/dist/mcp-app/mcp-app.html +5 -5
- package/dist/server/index.cjs +4 -4
- package/dist/server/index.js +128 -2
- package/package.json +2 -2
- package/dist/adapters/mcp-transport-CkyawtUT.cjs +0 -40
- package/dist/adapters/mcp-transport-DSbd6M_u.js +0 -586
- package/dist/adapters/utils-DrWvXf0G.cjs +0 -128
- package/dist/client/chunks/KpiDelta-D09hA_UJ.js +0 -2
- package/dist/client/chunks/KpiNumber-B7F9F9fC.js +0 -2
- package/dist/client/chunks/KpiText-C3ZXOF8b.js +0 -2
- package/dist/client/chunks/SchemaVisualization-DP4k1fPp.js +0 -2
- package/dist/client/chunks/SchemaVisualizationLazy-Brqv_PY9.js +0 -2
- package/dist/client/chunks/af-ZA-xDmO5F0s.js.map +0 -1
- package/dist/client/chunks/analysis-builder-0o1W-k3K.js.map +0 -1
- package/dist/client/chunks/analysis-builder-shared-Cz4KAlIC.js.map +0 -1
- package/dist/client/chunks/chart-activity-grid-VFFm85hC.js.map +0 -1
- package/dist/client/chunks/chart-config-activity-grid-C-EkgYoa.js.map +0 -1
- package/dist/client/chunks/chart-config-area-CMZpbIah.js.map +0 -1
- package/dist/client/chunks/chart-config-bar-B8_V4YLg.js.map +0 -1
- package/dist/client/chunks/chart-config-box-plot-Dwj7sEbU.js.map +0 -1
- package/dist/client/chunks/chart-config-bubble-B0w0ZVp4.js.map +0 -1
- package/dist/client/chunks/chart-config-candlestick-Bvo3zeIn.js.map +0 -1
- package/dist/client/chunks/chart-config-gauge-C5ZiyZy7.js.map +0 -1
- package/dist/client/chunks/chart-config-heat-map-Cv8qNnVP.js.map +0 -1
- package/dist/client/chunks/chart-config-kpi-delta-BraHQc2E.js.map +0 -1
- package/dist/client/chunks/chart-config-kpi-number-CeCkx7mC.js.map +0 -1
- package/dist/client/chunks/chart-config-kpi-text-CImM3SvH.js.map +0 -1
- package/dist/client/chunks/chart-config-line-BVKapAQK.js.map +0 -1
- package/dist/client/chunks/chart-config-measure-profile-KTVV1gO3.js.map +0 -1
- package/dist/client/chunks/chart-config-pie-BZxVl25X.js.map +0 -1
- package/dist/client/chunks/chart-config-radar-B7FByX3t.js.map +0 -1
- package/dist/client/chunks/chart-config-radial-bar-UfW_3yyX.js.map +0 -1
- package/dist/client/chunks/chart-config-scatter-BVVJuOnt.js.map +0 -1
- package/dist/client/chunks/chart-config-tree-map-IHp97OyV.js.map +0 -1
- package/dist/client/chunks/chart-config-waterfall-BdqG1V-x.js.map +0 -1
- package/dist/client/chunks/nl-NL-DDf0OdfW.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-bubble-DJOq4IpT.js","names":[],"sources":["../../../src/client/hooks/useTheme.ts","../../../src/client/components/charts/BubbleChart.tsx"],"sourcesContent":["/**\n * useTheme - External Theme State Hook\n *\n * Uses React 18's useSyncExternalStore to prevent parent component re-renders.\n * The theme state is stored externally and changes are propagated through\n * a subscribe/notify pattern.\n *\n * This prevents the ThemeToggle component from causing Layout re-renders.\n */\n\nimport { useSyncExternalStore, useCallback } from 'react'\nimport { getTheme, setTheme as setThemeUtil, watchThemeChanges, type Theme } from '../theme'\n\n// External store for theme state\nconst themeStore = {\n listeners: new Set<() => void>(),\n\n subscribe(listener: () => void) {\n this.listeners.add(listener)\n return () => this.listeners.delete(listener)\n },\n\n notify() {\n this.listeners.forEach(listener => listener())\n }\n}\n\n// Watch theme changes from DOM/system and notify subscribers\nwatchThemeChanges(() => {\n themeStore.notify()\n})\n\n/**\n * Hook to access and update theme\n *\n * Returns current theme and a setter function.\n * Only components using this hook will re-render on theme changes.\n */\nexport function useTheme() {\n // Subscribe to external theme store\n const theme = useSyncExternalStore(\n themeStore.subscribe.bind(themeStore),\n getTheme, // Client-side snapshot\n getTheme // Server-side snapshot (SSR)\n )\n\n // Stable setter function\n const setTheme = useCallback((newTheme: Theme) => {\n setThemeUtil(newTheme)\n themeStore.notify()\n }, [])\n\n return { theme, setTheme }\n}\n","import React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'\nimport { useTranslation } from '../../hooks/useTranslation'\nimport { select, scaleLinear, scaleSqrt, scaleOrdinal, scaleQuantize, extent, max, axisBottom, axisLeft, transition as _transition, type ScaleOrdinal, type ScaleQuantize } from 'd3'\n// _transition import is for side effects only - it extends Selection.prototype with .transition() method\nimport { CHART_COLORS, CHART_COLORS_GRADIENT, CHART_MARGINS } from '../../utils/chartConstants'\nimport { formatTimeValue, getFieldGranularity, parseNumericValue, isValidNumericValue, formatAxisValue } from '../../utils/chartUtils'\nimport { useCubeFieldLabel } from '../../hooks/useCubeFieldLabel'\nimport { useTheme } from '../../hooks/useTheme'\nimport type { ChartProps } from '../../types'\n\ninterface BubbleData {\n x: number\n xLabel?: string // Formatted label for time dimensions\n y: number\n size: number\n color?: string | number\n label: string\n series?: string\n}\n\nconst BubbleChart = React.memo(function BubbleChart({\n data,\n chartConfig,\n displayConfig = {},\n queryObject,\n height = \"100%\",\n colorPalette\n}: ChartProps) {\n const { t } = useTranslation()\n const svgRef = useRef<SVGSVGElement | null>(null)\n const containerRef = useRef<HTMLDivElement | null>(null)\n const [dimensions, setDimensions] = useState({ width: 0, height: 0 })\n const [dimensionsReady, setDimensionsReady] = useState(false)\n const { theme } = useTheme()\n const getFieldLabel = useCubeFieldLabel()\n\n // Memoize safeDisplayConfig to prevent unnecessary re-renders\n const safeDisplayConfig = useMemo(() => ({\n showLegend: displayConfig?.showLegend ?? true,\n showGrid: displayConfig?.showGrid ?? true,\n showTooltip: displayConfig?.showTooltip ?? true,\n minBubbleSize: displayConfig?.minBubbleSize ?? 5,\n maxBubbleSize: displayConfig?.maxBubbleSize ?? 50,\n bubbleOpacity: displayConfig?.bubbleOpacity ?? 0.7,\n xAxisFormat: displayConfig?.xAxisFormat,\n leftYAxisFormat: displayConfig?.leftYAxisFormat\n }), [\n displayConfig?.showLegend,\n displayConfig?.showGrid,\n displayConfig?.showTooltip,\n displayConfig?.minBubbleSize,\n displayConfig?.maxBubbleSize,\n displayConfig?.bubbleOpacity,\n displayConfig?.xAxisFormat,\n displayConfig?.leftYAxisFormat\n ])\n\n // Enhanced dimension measurement with retry mechanism\n useLayoutEffect(() => {\n let retryCount = 0\n const maxRetries = 10\n let rafId: number\n let timeoutId: ReturnType<typeof setTimeout>\n \n const updateDimensions = () => {\n if (containerRef.current) {\n const { width, height } = containerRef.current.getBoundingClientRect()\n \n if (width > 0 && height > 0) {\n setDimensions({ width, height })\n setDimensionsReady(true)\n return true\n }\n }\n return false\n }\n \n // Immediate measurement\n const success = updateDimensions()\n \n if (!success && retryCount < maxRetries) {\n // Retry with requestAnimationFrame\n const retryWithRaf = () => {\n const rafSuccess = updateDimensions()\n \n if (!rafSuccess && retryCount < maxRetries) {\n retryCount++\n // Use setTimeout for additional retries with increasing delays\n timeoutId = setTimeout(() => {\n rafId = requestAnimationFrame(retryWithRaf)\n }, 50 * retryCount) // Increasing delay: 50ms, 100ms, 150ms, etc.\n }\n }\n \n rafId = requestAnimationFrame(retryWithRaf)\n }\n \n return () => {\n if (rafId) cancelAnimationFrame(rafId)\n if (timeoutId) clearTimeout(timeoutId)\n }\n }, [])\n\n // Enhanced ResizeObserver for dynamic resizing with immediate initialization\n useEffect(() => {\n let resizeObserver: ResizeObserver | null = null\n \n const updateDimensions = () => {\n if (containerRef.current) {\n const { width, height } = containerRef.current.getBoundingClientRect()\n if (width > 0 && height > 0) {\n setDimensions({ width, height })\n if (!dimensionsReady) {\n setDimensionsReady(true)\n }\n }\n }\n }\n \n // Initialize ResizeObserver immediately\n if (containerRef.current) {\n resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const { width, height } = entry.contentRect\n if (width > 0 && height > 0) {\n setDimensions({ width, height })\n if (!dimensionsReady) {\n setDimensionsReady(true)\n }\n }\n }\n })\n \n resizeObserver.observe(containerRef.current)\n \n // Also try immediate measurement as fallback\n updateDimensions()\n }\n\n // Window resize as additional fallback\n window.addEventListener('resize', updateDimensions)\n \n return () => {\n if (resizeObserver) {\n resizeObserver.disconnect()\n }\n window.removeEventListener('resize', updateDimensions)\n }\n }, [dimensionsReady])\n\n useEffect(() => {\n if (!data || data.length === 0 || !svgRef.current || !dimensionsReady || dimensions.width === 0) {\n return\n }\n\n // Clear previous chart\n select(svgRef.current).selectAll('*').remove()\n\n\n // Validate chartConfig - only new format supported\n if (!chartConfig?.xAxis || !chartConfig?.yAxis || !chartConfig?.series) {\n return\n }\n\n const xAxisField = Array.isArray(chartConfig.xAxis) ? chartConfig.xAxis[0] : chartConfig.xAxis\n const yAxisField = Array.isArray(chartConfig.yAxis) ? chartConfig.yAxis[0] : chartConfig.yAxis\n const seriesField = Array.isArray(chartConfig.series) ? chartConfig.series[0] : chartConfig.series\n const sizeFieldName = Array.isArray(chartConfig.sizeField) ? chartConfig.sizeField[0] : chartConfig.sizeField || yAxisField\n const colorFieldName = Array.isArray(chartConfig.colorField) ? chartConfig.colorField[0] : chartConfig.colorField\n\n\n if (!xAxisField || !yAxisField || !seriesField || !sizeFieldName) {\n return\n }\n\n // Transform data for bubble chart\n // Null handling: Filter out bubbles where x, y, or size are null\n const xGranularity = getFieldGranularity(queryObject, xAxisField)\n\n // Check if x-axis field is a time dimension\n const isTimeDimension = queryObject?.timeDimensions?.some(\n (td: { dimension: string }) => td.dimension === xAxisField\n ) || false\n\n const bubbleData: BubbleData[] = data\n .map(item => {\n const rawXValue = item[xAxisField]\n let xNum: number\n let xLabel: string\n\n if (isTimeDimension && rawXValue) {\n // For time dimensions, convert to timestamp for proper numeric positioning\n const dateStr = String(rawXValue)\n // Try to parse as date - handle ISO format and PostgreSQL format\n let date: Date\n if (dateStr.match(/^\\d{4}-\\d{2}-\\d{2}[T ]/)) {\n // Full timestamp format\n let isoStr = dateStr\n if (dateStr.includes(' ')) {\n isoStr = dateStr.replace(' ', 'T').replace('+00', 'Z').replace(/\\+\\d{2}:\\d{2}$/, 'Z')\n }\n if (!isoStr.endsWith('Z') && !isoStr.includes('+')) {\n isoStr = isoStr + 'Z'\n }\n date = new Date(isoStr)\n } else {\n date = new Date(dateStr)\n }\n\n xNum = isNaN(date.getTime()) ? parseFloat(dateStr) : date.getTime()\n xLabel = formatTimeValue(rawXValue, xGranularity)\n } else {\n // Non-time value - use as-is\n const formattedValue = formatTimeValue(rawXValue, xGranularity) || rawXValue\n xNum = typeof formattedValue === 'string' ? parseFloat(formattedValue) : formattedValue\n xLabel = String(formattedValue)\n }\n\n const yValue = parseNumericValue(item[yAxisField])\n const sizeValue = parseNumericValue(item[sizeFieldName])\n const seriesValue = item[seriesField]\n\n return {\n x: xNum,\n xLabel, // Store formatted label for tooltip display\n y: yValue as number, // Type assertion: filter below ensures this is never null\n size: sizeValue !== null ? Math.abs(sizeValue) : 0, // Ensure positive size\n color: colorFieldName ? item[colorFieldName] : seriesValue,\n series: seriesValue,\n label: `${seriesValue || 'Unknown'}`,\n isValid: isValidNumericValue(xNum) && yValue !== null && sizeValue !== null && sizeValue > 0\n }\n })\n .filter(d => d.isValid && d.size > 0) // Filter out bubbles with invalid coordinates or no size\n\n if (bubbleData.length === 0) return\n\n const margin = { \n ...CHART_MARGINS, \n left: CHART_MARGINS.left + 30, // Add extra 30px left margin for Y-axis label\n bottom: (safeDisplayConfig.showLegend && colorFieldName) ? 100 : 40 // Add extra space for legend\n }\n const width = dimensions.width - margin.left - margin.right\n const chartHeight = dimensions.height - margin.top - margin.bottom\n\n const svg = select(svgRef.current)\n .attr('width', dimensions.width)\n .attr('height', dimensions.height)\n\n const g = svg.append('g')\n .attr('transform', `translate(${margin.left},${margin.top})`)\n\n // Set up scales\n const xScale = scaleLinear()\n .domain(extent(bubbleData, d => d.x) as [number, number])\n .range([0, width])\n .nice()\n\n const yScale = scaleLinear()\n .domain(extent(bubbleData, d => d.y) as [number, number])\n .range([chartHeight, 0])\n .nice()\n\n const sizeScale = scaleSqrt()\n .domain([0, max(bubbleData, d => d.size) as number])\n .range([safeDisplayConfig.minBubbleSize, safeDisplayConfig.maxBubbleSize])\n\n // Set up color scale\n let colorScale: ScaleOrdinal<string, string> | ScaleQuantize<string>\n let isNumericColorField = false\n let uniqueColors: string[] = []\n \n if (colorFieldName && bubbleData.length > 0) {\n // Check if color field is numeric for color scaling (same logic as TreeMapChart)\n const colorValues = bubbleData.map(item => {\n const value = item.color\n return typeof value === 'string' ? parseFloat(value) : value\n }).filter((val): val is number => !isNaN(val as number))\n \n isNumericColorField = colorValues.length === bubbleData.length && colorValues.every(val => typeof val === 'number')\n \n if (isNumericColorField) {\n // Use D3 quantize scale for better color distribution with small ranges\n const minValue = Math.min(...colorValues)\n const maxValue = Math.max(...colorValues)\n \n // Create D3 quantize color scale - maps continuous data to discrete color bands\n colorScale = scaleQuantize<string>()\n .domain([minValue, maxValue])\n .range(colorPalette?.gradient || CHART_COLORS_GRADIENT)\n } else {\n // Categorical color field - use series colors\n uniqueColors = [...new Set(bubbleData.map(d => String(d.color)))]\n colorScale = scaleOrdinal<string>()\n .domain(uniqueColors)\n .range(colorPalette?.colors || CHART_COLORS)\n }\n } else {\n // Single color for all bubbles\n colorScale = scaleOrdinal<string>()\n .domain(['default'])\n .range([CHART_COLORS[0]])\n }\n\n // Get theme colors from CSS variables\n const getThemeColor = (varName: string, fallback: string) => {\n const value = getComputedStyle(document.documentElement).getPropertyValue(varName).trim()\n return value || fallback\n }\n\n const isDark = theme !== 'light'\n const textColor = isDark\n ? getThemeColor('--dc-text-muted', '#cbd5e1') // Lighter text for dark mode\n : getThemeColor('--dc-text-secondary', '#374151') // Darker text for light mode\n const gridColor = isDark\n ? getThemeColor('--dc-border', '#475569') // Lighter grid for dark mode\n : '#9ca3af' // Much darker gray for light mode visibility\n\n // Add grid\n if (safeDisplayConfig.showGrid) {\n // X-axis grid\n const xGrid = g.append('g')\n .attr('class', 'grid')\n .attr('transform', `translate(0,${chartHeight})`)\n .call(axisBottom(xScale)\n .tickSize(-chartHeight)\n .tickFormat(() => '')\n )\n\n xGrid.selectAll('line')\n .style('stroke', gridColor)\n .style('stroke-dasharray', '3,3')\n .style('opacity', 0.3)\n\n xGrid.select('.domain')\n .style('stroke', 'none')\n\n // Y-axis grid\n const yGrid = g.append('g')\n .attr('class', 'grid')\n .call(axisLeft(yScale)\n .tickSize(-width)\n .tickFormat(() => '')\n )\n\n yGrid.selectAll('line')\n .style('stroke', gridColor)\n .style('stroke-dasharray', '3,3')\n .style('opacity', 0.3)\n\n yGrid.select('.domain')\n .style('stroke', 'none')\n }\n\n // Add X axis with proper time formatting if needed\n const xAxisGenerator = axisBottom(xScale)\n\n // If it's a time dimension, format the tick labels\n if (isTimeDimension) {\n xAxisGenerator.tickFormat((d) => {\n const date = new Date(d as number)\n if (isNaN(date.getTime())) return String(d)\n\n // Format based on granularity\n switch (xGranularity?.toLowerCase()) {\n case 'year':\n return String(date.getUTCFullYear())\n case 'quarter': {\n const q = Math.floor(date.getUTCMonth() / 3) + 1\n return `${date.getUTCFullYear()}-Q${q}`\n }\n case 'month':\n return `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, '0')}`\n case 'week':\n case 'day':\n return `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, '0')}-${String(date.getUTCDate()).padStart(2, '0')}`\n case 'hour':\n return `${String(date.getUTCMonth() + 1).padStart(2, '0')}-${String(date.getUTCDate()).padStart(2, '0')} ${String(date.getUTCHours()).padStart(2, '0')}:00`\n default:\n return `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, '0')}`\n }\n })\n } else if (safeDisplayConfig.xAxisFormat) {\n // Apply custom formatting for non-time X-axis\n xAxisGenerator.tickFormat((d) => formatAxisValue(d as number, safeDisplayConfig.xAxisFormat))\n }\n\n const xAxis = g.append('g')\n .attr('transform', `translate(0,${chartHeight})`)\n .call(xAxisGenerator)\n\n xAxis.selectAll('text')\n .style('fill', textColor)\n\n xAxis.selectAll('line, path')\n .style('stroke', gridColor)\n\n xAxis.append('text')\n .attr('x', width / 2)\n .attr('y', 35)\n .attr('fill', textColor)\n .style('text-anchor', 'middle')\n .style('font-size', '12px')\n .text(safeDisplayConfig.xAxisFormat?.label || getFieldLabel(xAxisField))\n\n // Add Y axis with optional formatting\n const yAxisGenerator = axisLeft(yScale)\n if (safeDisplayConfig.leftYAxisFormat) {\n yAxisGenerator.tickFormat((d) => formatAxisValue(d as number, safeDisplayConfig.leftYAxisFormat))\n }\n const yAxis = g.append('g')\n .call(yAxisGenerator)\n\n yAxis.selectAll('text')\n .style('fill', textColor)\n\n yAxis.selectAll('line, path')\n .style('stroke', gridColor)\n\n yAxis.append('text')\n .attr('transform', 'rotate(-90)')\n .attr('y', -35)\n .attr('x', -chartHeight / 2)\n .attr('fill', textColor)\n .style('text-anchor', 'middle')\n .style('font-size', '12px')\n .text(safeDisplayConfig.leftYAxisFormat?.label || getFieldLabel(yAxisField))\n\n // Create tooltip\n const tooltip = select('body').append('div')\n .attr('class', 'bubble-chart-tooltip')\n .style('position', 'absolute')\n .style('padding', '8px')\n .style('background', 'rgba(0, 0, 0, 0.8)')\n .style('color', 'white')\n .style('border-radius', '4px')\n .style('font-size', '12px')\n .style('pointer-events', 'none')\n .style('opacity', 0)\n .style('z-index', 1000)\n\n // Add bubbles\n const bubbles = g.selectAll('.bubble')\n .data(bubbleData)\n .enter().append('circle')\n .attr('class', 'bubble')\n .attr('cx', d => xScale(d.x))\n .attr('cy', d => yScale(d.y))\n .attr('r', d => sizeScale(d.size))\n .style('fill', d => {\n if (colorFieldName && d.color !== undefined) {\n return isNumericColorField\n ? (colorScale as ScaleQuantize<string>)(d.color as number)\n : (colorScale as ScaleOrdinal<string, string>)(String(d.color))\n }\n return CHART_COLORS[0]\n })\n .style('opacity', safeDisplayConfig.bubbleOpacity)\n .style('stroke', '#fff')\n .style('stroke-width', 1)\n .style('cursor', 'pointer')\n\n // Add hover effects\n if (safeDisplayConfig.showTooltip) {\n bubbles\n .on('mouseover', function(event, d) {\n select(this)\n .transition()\n .duration(200)\n .style('opacity', 1)\n .attr('r', sizeScale(d.size) * 1.1)\n\n const tooltipContent = [\n `<strong>${d.series || 'Unknown'}</strong>`,\n `${getFieldLabel(xAxisField)}: ${d.xLabel || (safeDisplayConfig.xAxisFormat ? formatAxisValue(d.x, safeDisplayConfig.xAxisFormat) : d.x)}`,\n `${getFieldLabel(yAxisField)}: ${safeDisplayConfig.leftYAxisFormat ? formatAxisValue(d.y, safeDisplayConfig.leftYAxisFormat) : d.y}`,\n `${getFieldLabel(sizeFieldName)}: ${safeDisplayConfig.leftYAxisFormat ? formatAxisValue(d.size, safeDisplayConfig.leftYAxisFormat) : d.size}`,\n colorFieldName && d.color ? `${getFieldLabel(colorFieldName)}: ${d.color}` : ''\n ].filter(Boolean).join('<br>')\n\n tooltip\n .html(tooltipContent)\n .style('left', (event.pageX + 10) + 'px')\n .style('top', (event.pageY - 10) + 'px')\n .transition()\n .duration(200)\n .style('opacity', 1)\n })\n .on('mousemove', function(event) {\n tooltip\n .style('left', (event.pageX + 10) + 'px')\n .style('top', (event.pageY - 10) + 'px')\n })\n .on('mouseout', function(_event, d) {\n select(this)\n .transition()\n .duration(200)\n .style('opacity', safeDisplayConfig.bubbleOpacity)\n .attr('r', sizeScale(d.size))\n\n tooltip\n .transition()\n .duration(200)\n .style('opacity', 0)\n })\n }\n\n // Add legend if needed\n if (safeDisplayConfig.showLegend && colorFieldName) {\n if (isNumericColorField) {\n // Create gradient legend for numeric color field\n const legendWidth = 200\n const legendHeight = 20\n const minValue = Math.min(...bubbleData.map(d => d.color as number))\n const maxValue = Math.max(...bubbleData.map(d => d.color as number))\n \n const legend = g.append('g')\n .attr('class', 'color-legend')\n .attr('transform', `translate(${width / 2 - legendWidth / 2}, ${chartHeight + 60})`)\n\n // Create gradient definition\n const defs = svg.append('defs')\n const gradient = defs.append('linearGradient')\n .attr('id', 'color-scale-gradient')\n .attr('x1', '0%')\n .attr('y1', '0%')\n .attr('x2', '100%')\n .attr('y2', '0%')\n\n // Add color stops for the gradient\n const gradientColors = colorPalette?.gradient || CHART_COLORS_GRADIENT\n gradientColors.forEach((color, i) => {\n gradient.append('stop')\n .attr('offset', `${(i / (gradientColors.length - 1)) * 100}%`)\n .attr('stop-color', color)\n })\n\n // Add the gradient rectangle\n legend.append('rect')\n .attr('width', legendWidth)\n .attr('height', legendHeight)\n .style('fill', 'url(#color-scale-gradient)')\n .style('stroke', '#ccc')\n .style('stroke-width', 1)\n\n // Add min value label\n legend.append('text')\n .attr('x', 0)\n .attr('y', legendHeight + 15)\n .attr('text-anchor', 'start')\n .style('font-size', '11px')\n .style('fill', textColor)\n .text(safeDisplayConfig.leftYAxisFormat ? formatAxisValue(minValue, safeDisplayConfig.leftYAxisFormat) : minValue.toFixed(2))\n\n // Add max value label\n legend.append('text')\n .attr('x', legendWidth)\n .attr('y', legendHeight + 15)\n .attr('text-anchor', 'end')\n .style('font-size', '11px')\n .style('fill', textColor)\n .text(safeDisplayConfig.leftYAxisFormat ? formatAxisValue(maxValue, safeDisplayConfig.leftYAxisFormat) : maxValue.toFixed(2))\n\n // Add field name label\n legend.append('text')\n .attr('x', legendWidth / 2)\n .attr('y', -5)\n .attr('text-anchor', 'middle')\n .style('font-size', '12px')\n .style('font-weight', 'bold')\n .style('fill', textColor)\n .text(getFieldLabel(colorFieldName))\n\n } else {\n // Original categorical legend\n const legendItems = uniqueColors\n\n if (legendItems.length > 0) {\n const legend = g.append('g')\n .attr('class', 'legend')\n .attr('transform', `translate(${width / 2 - (legendItems.length * 80) / 2}, ${chartHeight + 60})`)\n\n const legendItem = legend.selectAll('.legend-item')\n .data(legendItems)\n .enter().append('g')\n .attr('class', 'legend-item')\n .attr('transform', (_d, i) => `translate(${i * 80}, 0)`)\n .style('cursor', 'pointer')\n\n legendItem.append('circle')\n .attr('cx', 5)\n .attr('cy', 5)\n .attr('r', 5)\n .style('fill', d => (colorScale as ScaleOrdinal<string, string>)(d as string))\n .style('opacity', safeDisplayConfig.bubbleOpacity)\n\n legendItem.append('text')\n .attr('x', 15)\n .attr('y', 5)\n .attr('dy', '.35em')\n .style('font-size', '11px')\n .style('fill', textColor)\n .text(d => String(d))\n\n // Legend hover effects\n legendItem\n .on('mouseover', function(_event, legendKey) {\n // Highlight matching bubbles\n bubbles\n .transition()\n .duration(200)\n .style('opacity', d => {\n const matches = colorFieldName && String(d.color) === legendKey\n return matches ? 1 : 0.2\n })\n })\n .on('mouseout', function() {\n // Reset all bubbles\n bubbles\n .transition()\n .duration(200)\n .style('opacity', safeDisplayConfig.bubbleOpacity)\n })\n }\n }\n }\n\n // Cleanup function\n return () => {\n tooltip.remove()\n }\n }, [data, chartConfig, safeDisplayConfig, queryObject, dimensions, dimensionsReady, colorPalette, theme, getFieldLabel])\n\n if (!data || data.length === 0) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">{t('chart.runtime.noData')}</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">{t('chart.runtime.noDataHint.bubble')}</div>\n </div>\n </div>\n )\n }\n\n // Validate that we have required fields\n const hasValidConfig = chartConfig?.xAxis && chartConfig?.yAxis && chartConfig?.series\n if (!hasValidConfig) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-warning\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">{t('chart.runtime.activityGridConfigRequired')}</div>\n <div className=\"dc:text-xs\">{t('chart.runtime.configErrorHint.bubbleRequired')}</div>\n <div className=\"dc:text-xs dc:mt-1\">{t('chart.runtime.configErrorHint.bubbleOptional')}</div>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"dc:w-full dc:flex-1 dc:flex dc:flex-col dc:relative\" style={{ height, minHeight: '250px', overflow: 'hidden' }}>\n <div ref={containerRef} className=\"dc:w-full dc:h-full dc:relative\">\n <svg ref={svgRef} className=\"dc:w-full dc:h-full\" />\n {!dimensionsReady && (\n <div className=\"dc:absolute dc:inset-0 dc:flex dc:items-center dc:justify-center\">\n <div className=\"text-dc-text-muted dc:text-sm\">{t('chart.runtime.measuringDimensions')}</div>\n </div>\n )}\n </div>\n </div>\n )\n})\n\nexport default BubbleChart"],"mappings":";;;;;;AAcA,IAAM,IAAa;CACjB,2BAAW,IAAI,KAAiB;CAEhC,UAAU,GAAsB;AAE9B,SADA,KAAK,UAAU,IAAI,EAAS,QACf,KAAK,UAAU,OAAO,EAAS;;CAG9C,SAAS;AACP,OAAK,UAAU,SAAQ,MAAY,GAAU,CAAC;;CAEjD;AAGD,QAAwB;AACtB,GAAW,QAAQ;EACnB;AAQF,SAAgB,IAAW;AAczB,QAAO;EAAE,OAZK,EACZ,EAAW,UAAU,KAAK,EAAW,EACrC,GACA,EACD;EAQe,UALC,GAAa,MAAoB;AAEhD,GADA,EAAa,EAAS,EACtB,EAAW,QAAQ;KAClB,EAAE,CAAC;EAEoB;;;;iDChCtB,IAAc,EAAM,KAAK,SAAqB,EAClD,SACA,gBACA,mBAAgB,EAAE,EAClB,gBACA,YAAS,QACT,mBACa;CACb,IAAM,EAAE,SAAM,GAAgB,EACxB,IAAS,EAA6B,KAAK,EAC3C,IAAe,EAA8B,KAAK,EAClD,CAAC,GAAY,KAAiB,EAAS;EAAE,OAAO;EAAG,QAAQ;EAAG,CAAC,EAC/D,CAAC,GAAiB,KAAsB,EAAS,GAAM,EACvD,EAAE,aAAU,GAAU,EACtB,IAAgB,GAAmB,EAGnC,IAAoB,SAAe;EACvC,YAAY,GAAe,cAAc;EACzC,UAAU,GAAe,YAAY;EACrC,aAAa,GAAe,eAAe;EAC3C,eAAe,GAAe,iBAAiB;EAC/C,eAAe,GAAe,iBAAiB;EAC/C,eAAe,GAAe,iBAAiB;EAC/C,aAAa,GAAe;EAC5B,iBAAiB,GAAe;EACjC,GAAG;EACF,GAAe;EACf,GAAe;EACf,GAAe;EACf,GAAe;EACf,GAAe;EACf,GAAe;EACf,GAAe;EACf,GAAe;EAChB,CAAC;AA2lBF,QAxlBA,QAAsB;EACpB,IAAI,IAAa,GAEb,GACA,GAEE,UAAyB;AAC7B,OAAI,EAAa,SAAS;IACxB,IAAM,EAAE,UAAO,cAAW,EAAa,QAAQ,uBAAuB;AAEtE,QAAI,IAAQ,KAAK,IAAS,EAGxB,QAFA,EAAc;KAAE;KAAO;KAAQ,CAAC,EAChC,EAAmB,GAAK,EACjB;;AAGX,UAAO;;AAMT,MAAI,CAFY,GAAkB,IAElB,IAAa,IAAY;GAEvC,IAAM,UAAqB;AAGzB,IAAI,CAFe,GAAkB,IAElB,IAAa,OAC9B,KAEA,IAAY,iBAAiB;AAC3B,SAAQ,sBAAsB,EAAa;OAC1C,KAAK,EAAW;;AAIvB,OAAQ,sBAAsB,EAAa;;AAG7C,eAAa;AAEX,GADI,KAAO,qBAAqB,EAAM,EAClC,KAAW,aAAa,EAAU;;IAEvC,EAAE,CAAC,EAGN,QAAgB;EACd,IAAI,IAAwC,MAEtC,UAAyB;AAC7B,OAAI,EAAa,SAAS;IACxB,IAAM,EAAE,UAAO,cAAW,EAAa,QAAQ,uBAAuB;AACtE,IAAI,IAAQ,KAAK,IAAS,MACxB,EAAc;KAAE;KAAO;KAAQ,CAAC,EAC3B,KACH,EAAmB,GAAK;;;AA6BhC,SAtBI,EAAa,YACf,IAAiB,IAAI,gBAAgB,MAAY;AAC/C,QAAK,IAAM,KAAS,GAAS;IAC3B,IAAM,EAAE,UAAO,cAAW,EAAM;AAChC,IAAI,IAAQ,KAAK,IAAS,MACxB,EAAc;KAAE;KAAO;KAAQ,CAAC,EAC3B,KACH,EAAmB,GAAK;;IAI9B,EAEF,EAAe,QAAQ,EAAa,QAAQ,EAG5C,GAAkB,GAIpB,OAAO,iBAAiB,UAAU,EAAiB,QAEtC;AAIX,GAHI,KACF,EAAe,YAAY,EAE7B,OAAO,oBAAoB,UAAU,EAAiB;;IAEvD,CAAC,EAAgB,CAAC,EAErB,QAAgB;AAUd,MATI,CAAC,KAAQ,EAAK,WAAW,KAAK,CAAC,EAAO,WAAW,CAAC,KAAmB,EAAW,UAAU,MAK9F,EAAO,EAAO,QAAQ,CAAC,UAAU,IAAI,CAAC,QAAQ,EAI1C,CAAC,GAAa,SAAS,CAAC,GAAa,SAAS,CAAC,GAAa,QAC9D;EAGF,IAAM,IAAa,MAAM,QAAQ,EAAY,MAAM,GAAG,EAAY,MAAM,KAAK,EAAY,OACnF,IAAa,MAAM,QAAQ,EAAY,MAAM,GAAG,EAAY,MAAM,KAAK,EAAY,OACnF,IAAc,MAAM,QAAQ,EAAY,OAAO,GAAG,EAAY,OAAO,KAAK,EAAY,QACtF,IAAgB,MAAM,QAAQ,EAAY,UAAU,GAAG,EAAY,UAAU,KAAK,EAAY,aAAa,GAC3G,IAAiB,MAAM,QAAQ,EAAY,WAAW,GAAG,EAAY,WAAW,KAAK,EAAY;AAGvG,MAAI,CAAC,KAAc,CAAC,KAAc,CAAC,KAAe,CAAC,EACjD;EAKF,IAAM,IAAe,EAAoB,GAAa,EAAW,EAG3D,IAAkB,GAAa,gBAAgB,MAClD,MAA8B,EAAG,cAAc,EACjD,IAAI,IAEC,IAA2B,EAC9B,KAAI,MAAQ;GACX,IAAM,IAAY,EAAK,IACnB,GACA;AAEJ,OAAI,KAAmB,GAAW;IAEhC,IAAM,IAAU,OAAO,EAAU,EAE7B;AACJ,QAAI,EAAQ,MAAM,yBAAyB,EAAE;KAE3C,IAAI,IAAS;AAOb,KANI,EAAQ,SAAS,IAAI,KACvB,IAAS,EAAQ,QAAQ,KAAK,IAAI,CAAC,QAAQ,OAAO,IAAI,CAAC,QAAQ,kBAAkB,IAAI,GAEnF,CAAC,EAAO,SAAS,IAAI,IAAI,CAAC,EAAO,SAAS,IAAI,KAChD,KAAkB,MAEpB,IAAO,IAAI,KAAK,EAAO;UAEvB,KAAO,IAAI,KAAK,EAAQ;AAI1B,IADA,IAAO,MAAM,EAAK,SAAS,CAAC,GAAG,WAAW,EAAQ,GAAG,EAAK,SAAS,EACnE,IAAS,EAAgB,GAAW,EAAa;UAC5C;IAEL,IAAM,IAAiB,EAAgB,GAAW,EAAa,IAAI;AAEnE,IADA,IAAO,OAAO,KAAmB,WAAW,WAAW,EAAe,GAAG,GACzE,IAAS,OAAO,EAAe;;GAGjC,IAAM,IAAS,EAAkB,EAAK,GAAY,EAC5C,IAAY,EAAkB,EAAK,GAAe,EAClD,IAAc,EAAK;AAEzB,UAAO;IACL,GAAG;IACH;IACA,GAAG;IACH,MAAM,MAAc,OAA6B,IAAtB,KAAK,IAAI,EAAU;IAC9C,OAAO,IAAiB,EAAK,KAAkB;IAC/C,QAAQ;IACR,OAAO,GAAG,KAAe;IACzB,SAAS,EAAoB,EAAK,IAAI,MAAW,QAAQ,MAAc,QAAQ,IAAY;IAC5F;IACD,CACD,QAAO,MAAK,EAAE,WAAW,EAAE,OAAO,EAAE;AAEvC,MAAI,EAAW,WAAW,EAAG;EAE7B,IAAM,IAAS;GACb,GAAG;GACH,MAAM,EAAc,OAAO;GAC3B,QAAS,EAAkB,cAAc,IAAkB,MAAM;GAClE,EACK,IAAQ,EAAW,QAAQ,EAAO,OAAO,EAAO,OAChD,IAAc,EAAW,SAAS,EAAO,MAAM,EAAO,QAEtD,IAAM,EAAO,EAAO,QAAQ,CAC/B,KAAK,SAAS,EAAW,MAAM,CAC/B,KAAK,UAAU,EAAW,OAAO,EAE9B,IAAI,EAAI,OAAO,IAAI,CACtB,KAAK,aAAa,aAAa,EAAO,KAAK,GAAG,EAAO,IAAI,GAAG,EAGzD,IAAS,GAAa,CACzB,OAAO,EAAO,IAAY,MAAK,EAAE,EAAE,CAAqB,CACxD,MAAM,CAAC,GAAG,EAAM,CAAC,CACjB,MAAM,EAEH,IAAS,GAAa,CACzB,OAAO,EAAO,IAAY,MAAK,EAAE,EAAE,CAAqB,CACxD,MAAM,CAAC,GAAa,EAAE,CAAC,CACvB,MAAM,EAEH,IAAY,IAAW,CAC1B,OAAO,CAAC,GAAG,EAAI,IAAY,MAAK,EAAE,KAAK,CAAW,CAAC,CACnD,MAAM,CAAC,EAAkB,eAAe,EAAkB,cAAc,CAAC,EAGxE,GACA,IAAsB,IACtB,IAAyB,EAAE;AAE/B,MAAI,KAAkB,EAAW,SAAS,GAAG;GAE3C,IAAM,IAAc,EAAW,KAAI,MAAQ;IACzC,IAAM,IAAQ,EAAK;AACnB,WAAO,OAAO,KAAU,WAAW,WAAW,EAAM,GAAG;KACvD,CAAC,QAAQ,MAAuB,CAAC,MAAM,EAAc,CAAC;AAIxD,OAFA,IAAsB,EAAY,WAAW,EAAW,UAAU,EAAY,OAAM,MAAO,OAAO,KAAQ,SAAS,EAE/G,GAAqB;IAEvB,IAAM,IAAW,KAAK,IAAI,GAAG,EAAY,EACnC,IAAW,KAAK,IAAI,GAAG,EAAY;AAGzC,QAAa,IAAuB,CACjC,OAAO,CAAC,GAAU,EAAS,CAAC,CAC5B,MAAM,GAAc,YAAY,EAAsB;SAIzD,CADA,IAAe,CAAC,GAAG,IAAI,IAAI,EAAW,KAAI,MAAK,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EACjE,IAAa,GAAsB,CAChC,OAAO,EAAa,CACpB,MAAM,GAAc,UAAU,EAAa;QAIhD,KAAa,GAAsB,CAChC,OAAO,CAAC,UAAU,CAAC,CACnB,MAAM,CAAC,EAAa,GAAG,CAAC;EAI7B,IAAM,KAAiB,GAAiB,MACxB,iBAAiB,SAAS,gBAAgB,CAAC,iBAAiB,EAAQ,CAAC,MAAM,IACzE,GAGZ,IAAS,MAAU,SACnB,IAAY,IACd,EAAc,mBAAmB,UAAU,GAC3C,EAAc,uBAAuB,UAAU,EAC7C,IAAY,IACd,EAAc,eAAe,UAAU,GACvC;AAGJ,MAAI,EAAkB,UAAU;GAE9B,IAAM,IAAQ,EAAE,OAAO,IAAI,CACxB,KAAK,SAAS,OAAO,CACrB,KAAK,aAAa,eAAe,EAAY,GAAG,CAChD,KAAK,EAAW,EAAO,CACrB,SAAS,CAAC,EAAY,CACtB,iBAAiB,GAAG,CACtB;AAOH,GALA,EAAM,UAAU,OAAO,CACpB,MAAM,UAAU,EAAU,CAC1B,MAAM,oBAAoB,MAAM,CAChC,MAAM,WAAW,GAAI,EAExB,EAAM,OAAO,UAAU,CACpB,MAAM,UAAU,OAAO;GAG1B,IAAM,IAAQ,EAAE,OAAO,IAAI,CACxB,KAAK,SAAS,OAAO,CACrB,KAAK,EAAS,EAAO,CACnB,SAAS,CAAC,EAAM,CAChB,iBAAiB,GAAG,CACtB;AAOH,GALA,EAAM,UAAU,OAAO,CACpB,MAAM,UAAU,EAAU,CAC1B,MAAM,oBAAoB,MAAM,CAChC,MAAM,WAAW,GAAI,EAExB,EAAM,OAAO,UAAU,CACpB,MAAM,UAAU,OAAO;;EAI5B,IAAM,IAAiB,EAAW,EAAO;AAGzC,EAAI,IACF,EAAe,YAAY,MAAM;GAC/B,IAAM,IAAO,IAAI,KAAK,EAAY;AAClC,OAAI,MAAM,EAAK,SAAS,CAAC,CAAE,QAAO,OAAO,EAAE;AAG3C,WAAQ,GAAc,aAAa,EAAnC;IACE,KAAK,OACH,QAAO,OAAO,EAAK,gBAAgB,CAAC;IACtC,KAAK,WAAW;KACd,IAAM,IAAI,KAAK,MAAM,EAAK,aAAa,GAAG,EAAE,GAAG;AAC/C,YAAO,GAAG,EAAK,gBAAgB,CAAC,IAAI;;IAEtC,KAAK,QACH,QAAO,GAAG,EAAK,gBAAgB,CAAC,GAAG,OAAO,EAAK,aAAa,GAAG,EAAE,CAAC,SAAS,GAAG,IAAI;IACpF,KAAK;IACL,KAAK,MACH,QAAO,GAAG,EAAK,gBAAgB,CAAC,GAAG,OAAO,EAAK,aAAa,GAAG,EAAE,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,OAAO,EAAK,YAAY,CAAC,CAAC,SAAS,GAAG,IAAI;IAClI,KAAK,OACH,QAAO,GAAG,OAAO,EAAK,aAAa,GAAG,EAAE,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,OAAO,EAAK,YAAY,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,OAAO,EAAK,aAAa,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC;IACzJ,QACE,QAAO,GAAG,EAAK,gBAAgB,CAAC,GAAG,OAAO,EAAK,aAAa,GAAG,EAAE,CAAC,SAAS,GAAG,IAAI;;IAEtF,GACO,EAAkB,eAE3B,EAAe,YAAY,MAAM,EAAgB,GAAa,EAAkB,YAAY,CAAC;EAG/F,IAAM,IAAQ,EAAE,OAAO,IAAI,CACxB,KAAK,aAAa,eAAe,EAAY,GAAG,CAChD,KAAK,EAAe;AAQvB,EANA,EAAM,UAAU,OAAO,CACpB,MAAM,QAAQ,EAAU,EAE3B,EAAM,UAAU,aAAa,CAC1B,MAAM,UAAU,EAAU,EAE7B,EAAM,OAAO,OAAO,CACjB,KAAK,KAAK,IAAQ,EAAE,CACpB,KAAK,KAAK,GAAG,CACb,KAAK,QAAQ,EAAU,CACvB,MAAM,eAAe,SAAS,CAC9B,MAAM,aAAa,OAAO,CAC1B,KAAK,EAAkB,aAAa,SAAS,EAAc,EAAW,CAAC;EAG1E,IAAM,IAAiB,EAAS,EAAO;AACvC,EAAI,EAAkB,mBACpB,EAAe,YAAY,MAAM,EAAgB,GAAa,EAAkB,gBAAgB,CAAC;EAEnG,IAAM,IAAQ,EAAE,OAAO,IAAI,CACxB,KAAK,EAAe;AAQvB,EANA,EAAM,UAAU,OAAO,CACpB,MAAM,QAAQ,EAAU,EAE3B,EAAM,UAAU,aAAa,CAC1B,MAAM,UAAU,EAAU,EAE7B,EAAM,OAAO,OAAO,CACjB,KAAK,aAAa,cAAc,CAChC,KAAK,KAAK,IAAI,CACd,KAAK,KAAK,CAAC,IAAc,EAAE,CAC3B,KAAK,QAAQ,EAAU,CACvB,MAAM,eAAe,SAAS,CAC9B,MAAM,aAAa,OAAO,CAC1B,KAAK,EAAkB,iBAAiB,SAAS,EAAc,EAAW,CAAC;EAG9E,IAAM,IAAU,EAAO,OAAO,CAAC,OAAO,MAAM,CACzC,KAAK,SAAS,uBAAuB,CACrC,MAAM,YAAY,WAAW,CAC7B,MAAM,WAAW,MAAM,CACvB,MAAM,cAAc,qBAAqB,CACzC,MAAM,SAAS,QAAQ,CACvB,MAAM,iBAAiB,MAAM,CAC7B,MAAM,aAAa,OAAO,CAC1B,MAAM,kBAAkB,OAAO,CAC/B,MAAM,WAAW,EAAE,CACnB,MAAM,WAAW,IAAK,EAGnB,IAAU,EAAE,UAAU,UAAU,CACnC,KAAK,EAAW,CAChB,OAAO,CAAC,OAAO,SAAS,CACxB,KAAK,SAAS,SAAS,CACvB,KAAK,OAAM,MAAK,EAAO,EAAE,EAAE,CAAC,CAC5B,KAAK,OAAM,MAAK,EAAO,EAAE,EAAE,CAAC,CAC5B,KAAK,MAAK,MAAK,EAAU,EAAE,KAAK,CAAC,CACjC,MAAM,SAAQ,MACT,KAAkB,EAAE,UAAU,KAAA,IAE3B,EADE,IACmC,EAAE,QACK,OAAO,EAAE,MAAM,CAAC,GAE5D,EAAa,GACpB,CACD,MAAM,WAAW,EAAkB,cAAc,CACjD,MAAM,UAAU,OAAO,CACvB,MAAM,gBAAgB,EAAE,CACxB,MAAM,UAAU,UAAU;AAgD7B,MA7CI,EAAkB,eACpB,EACG,GAAG,aAAa,SAAS,GAAO,GAAG;AAClC,KAAO,KAAK,CACT,YAAY,CACZ,SAAS,IAAI,CACb,MAAM,WAAW,EAAE,CACnB,KAAK,KAAK,EAAU,EAAE,KAAK,GAAG,IAAI;GAErC,IAAM,IAAiB;IACrB,WAAW,EAAE,UAAU,UAAU;IACjC,GAAG,EAAc,EAAW,CAAC,IAAI,EAAE,WAAW,EAAkB,cAAc,EAAgB,EAAE,GAAG,EAAkB,YAAY,GAAG,EAAE;IACtI,GAAG,EAAc,EAAW,CAAC,IAAI,EAAkB,kBAAkB,EAAgB,EAAE,GAAG,EAAkB,gBAAgB,GAAG,EAAE;IACjI,GAAG,EAAc,EAAc,CAAC,IAAI,EAAkB,kBAAkB,EAAgB,EAAE,MAAM,EAAkB,gBAAgB,GAAG,EAAE;IACvI,KAAkB,EAAE,QAAQ,GAAG,EAAc,EAAe,CAAC,IAAI,EAAE,UAAU;IAC9E,CAAC,OAAO,QAAQ,CAAC,KAAK,OAAO;AAE9B,KACG,KAAK,EAAe,CACpB,MAAM,QAAS,EAAM,QAAQ,KAAM,KAAK,CACxC,MAAM,OAAQ,EAAM,QAAQ,KAAM,KAAK,CACvC,YAAY,CACZ,SAAS,IAAI,CACb,MAAM,WAAW,EAAE;IACtB,CACD,GAAG,aAAa,SAAS,GAAO;AAC/B,KACG,MAAM,QAAS,EAAM,QAAQ,KAAM,KAAK,CACxC,MAAM,OAAQ,EAAM,QAAQ,KAAM,KAAK;IAC1C,CACD,GAAG,YAAY,SAAS,GAAQ,GAAG;AAOlC,GANA,EAAO,KAAK,CACT,YAAY,CACZ,SAAS,IAAI,CACb,MAAM,WAAW,EAAkB,cAAc,CACjD,KAAK,KAAK,EAAU,EAAE,KAAK,CAAC,EAE/B,EACG,YAAY,CACZ,SAAS,IAAI,CACb,MAAM,WAAW,EAAE;IACtB,EAIF,EAAkB,cAAc,EAClC,KAAI,GAAqB;GAEvB,IAEM,IAAW,KAAK,IAAI,GAAG,EAAW,KAAI,MAAK,EAAE,MAAgB,CAAC,EAC9D,IAAW,KAAK,IAAI,GAAG,EAAW,KAAI,MAAK,EAAE,MAAgB,CAAC,EAE9D,IAAS,EAAE,OAAO,IAAI,CACzB,KAAK,SAAS,eAAe,CAC7B,KAAK,aAAa,aAAa,IAAQ,IAAI,MAAc,EAAE,IAAI,IAAc,GAAG,GAAG,EAIhF,IADO,EAAI,OAAO,OAAO,CACT,OAAO,iBAAiB,CAC3C,KAAK,MAAM,uBAAuB,CAClC,KAAK,MAAM,KAAK,CAChB,KAAK,MAAM,KAAK,CAChB,KAAK,MAAM,OAAO,CAClB,KAAK,MAAM,KAAK,EAGb,IAAiB,GAAc,YAAY;AAkCjD,GAjCA,EAAe,SAAS,GAAO,MAAM;AACnC,MAAS,OAAO,OAAO,CACpB,KAAK,UAAU,GAAI,KAAK,EAAe,SAAS,KAAM,IAAI,GAAG,CAC7D,KAAK,cAAc,EAAM;KAC5B,EAGF,EAAO,OAAO,OAAO,CAClB,KAAK,SAAS,IAAY,CAC1B,KAAK,UAAU,GAAa,CAC5B,MAAM,QAAQ,6BAA6B,CAC3C,MAAM,UAAU,OAAO,CACvB,MAAM,gBAAgB,EAAE,EAG3B,EAAO,OAAO,OAAO,CAClB,KAAK,KAAK,EAAE,CACZ,KAAK,KAAK,GAAkB,CAC5B,KAAK,eAAe,QAAQ,CAC5B,MAAM,aAAa,OAAO,CAC1B,MAAM,QAAQ,EAAU,CACxB,KAAK,EAAkB,kBAAkB,EAAgB,GAAU,EAAkB,gBAAgB,GAAG,EAAS,QAAQ,EAAE,CAAC,EAG/H,EAAO,OAAO,OAAO,CAClB,KAAK,KAAK,IAAY,CACtB,KAAK,KAAK,GAAkB,CAC5B,KAAK,eAAe,MAAM,CAC1B,MAAM,aAAa,OAAO,CAC1B,MAAM,QAAQ,EAAU,CACxB,KAAK,EAAkB,kBAAkB,EAAgB,GAAU,EAAkB,gBAAgB,GAAG,EAAS,QAAQ,EAAE,CAAC,EAG/H,EAAO,OAAO,OAAO,CAClB,KAAK,KAAK,MAAc,EAAE,CAC1B,KAAK,KAAK,GAAG,CACb,KAAK,eAAe,SAAS,CAC7B,MAAM,aAAa,OAAO,CAC1B,MAAM,eAAe,OAAO,CAC5B,MAAM,QAAQ,EAAU,CACxB,KAAK,EAAc,EAAe,CAAC;SAEjC;GAEL,IAAM,IAAc;AAEpB,OAAI,EAAY,SAAS,GAAG;IAK1B,IAAM,IAJS,EAAE,OAAO,IAAI,CACzB,KAAK,SAAS,SAAS,CACvB,KAAK,aAAa,aAAa,IAAQ,IAAK,EAAY,SAAS,KAAM,EAAE,IAAI,IAAc,GAAG,GAAG,CAE1E,UAAU,eAAe,CAChD,KAAK,EAAY,CACjB,OAAO,CAAC,OAAO,IAAI,CACnB,KAAK,SAAS,cAAc,CAC5B,KAAK,cAAc,GAAI,MAAM,aAAa,IAAI,GAAG,MAAM,CACvD,MAAM,UAAU,UAAU;AAkB7B,IAhBA,EAAW,OAAO,SAAS,CACxB,KAAK,MAAM,EAAE,CACb,KAAK,MAAM,EAAE,CACb,KAAK,KAAK,EAAE,CACZ,MAAM,SAAQ,MAAM,EAA4C,EAAY,CAAC,CAC7E,MAAM,WAAW,EAAkB,cAAc,EAEpD,EAAW,OAAO,OAAO,CACtB,KAAK,KAAK,GAAG,CACb,KAAK,KAAK,EAAE,CACZ,KAAK,MAAM,QAAQ,CACnB,MAAM,aAAa,OAAO,CAC1B,MAAM,QAAQ,EAAU,CACxB,MAAK,MAAK,OAAO,EAAE,CAAC,EAGvB,EACG,GAAG,aAAa,SAAS,GAAQ,GAAW;AAE3C,OACG,YAAY,CACZ,SAAS,IAAI,CACb,MAAM,YAAW,MACA,KAAkB,OAAO,EAAE,MAAM,KAAK,IACrC,IAAI,GACrB;MACJ,CACD,GAAG,YAAY,WAAW;AAEzB,OACG,YAAY,CACZ,SAAS,IAAI,CACb,MAAM,WAAW,EAAkB,cAAc;MACpD;;;AAMV,eAAa;AACX,KAAQ,QAAQ;;IAEjB;EAAC;EAAM;EAAa;EAAmB;EAAa;EAAY;EAAiB;EAAc;EAAO;EAAc,CAAC,EAEpH,CAAC,KAAQ,EAAK,WAAW,IAEzB,kBAAC,OAAD;EAAK,WAAU;EAAyE,OAAO,EAAE,WAAQ;YACvG,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAuC,EAAE,uBAAuB;IAAO,CAAA,EACtF,kBAAC,OAAD;IAAK,WAAU;cAAqC,EAAE,kCAAkC;IAAO,CAAA,CAC3F;;EACF,CAAA,GAKa,GAAa,SAAS,GAAa,SAAS,GAAa,SAc9E,kBAAC,OAAD;EAAK,WAAU;EAAsD,OAAO;GAAE;GAAQ,WAAW;GAAS,UAAU;GAAU;YAC5H,kBAAC,OAAD;GAAK,KAAK;GAAc,WAAU;aAAlC,CACE,kBAAC,OAAD;IAAK,KAAK;IAAQ,WAAU;IAAwB,CAAA,EACnD,CAAC,KACA,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,OAAD;KAAK,WAAU;eAAiC,EAAE,oCAAoC;KAAO,CAAA;IACzF,CAAA,CAEJ;;EACF,CAAA,GApBJ,kBAAC,OAAD;EAAK,WAAU;EAAsE,OAAO,EAAE,WAAQ;YACpG,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,OAAD;KAAK,WAAU;eAAuC,EAAE,2CAA2C;KAAO,CAAA;IAC1G,kBAAC,OAAD;KAAK,WAAU;eAAc,EAAE,+CAA+C;KAAO,CAAA;IACrF,kBAAC,OAAD;KAAK,WAAU;eAAsB,EAAE,+CAA+C;KAAO,CAAA;IACzF;;EACF,CAAA;EAgBV"}
|
|
1
|
+
{"version":3,"file":"chart-bubble-CAGvnYb1.js","names":[],"sources":["../../../src/client/hooks/useTheme.ts","../../../src/client/components/charts/BubbleChart.tsx"],"sourcesContent":["/**\n * useTheme - External Theme State Hook\n *\n * Uses React 18's useSyncExternalStore to prevent parent component re-renders.\n * The theme state is stored externally and changes are propagated through\n * a subscribe/notify pattern.\n *\n * This prevents the ThemeToggle component from causing Layout re-renders.\n */\n\nimport { useSyncExternalStore, useCallback } from 'react'\nimport { getTheme, setTheme as setThemeUtil, watchThemeChanges, type Theme } from '../theme'\n\n// External store for theme state\nconst themeStore = {\n listeners: new Set<() => void>(),\n\n subscribe(listener: () => void) {\n this.listeners.add(listener)\n return () => this.listeners.delete(listener)\n },\n\n notify() {\n this.listeners.forEach(listener => listener())\n }\n}\n\n// Watch theme changes from DOM/system and notify subscribers\nwatchThemeChanges(() => {\n themeStore.notify()\n})\n\n/**\n * Hook to access and update theme\n *\n * Returns current theme and a setter function.\n * Only components using this hook will re-render on theme changes.\n */\nexport function useTheme() {\n // Subscribe to external theme store\n const theme = useSyncExternalStore(\n themeStore.subscribe.bind(themeStore),\n getTheme, // Client-side snapshot\n getTheme // Server-side snapshot (SSR)\n )\n\n // Stable setter function\n const setTheme = useCallback((newTheme: Theme) => {\n setThemeUtil(newTheme)\n themeStore.notify()\n }, [])\n\n return { theme, setTheme }\n}\n","import React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'\nimport { useTranslation } from '../../hooks/useTranslation'\nimport { select, scaleLinear, scaleSqrt, scaleOrdinal, scaleQuantize, extent, max, axisBottom, axisLeft, transition as _transition, type ScaleOrdinal, type ScaleQuantize } from 'd3'\n// _transition import is for side effects only - it extends Selection.prototype with .transition() method\nimport { CHART_COLORS, CHART_COLORS_GRADIENT, CHART_MARGINS } from '../../utils/chartConstants'\nimport { formatTimeValue, getFieldGranularity, parseNumericValue, isValidNumericValue, formatAxisValue } from '../../utils/chartUtils'\nimport { useCubeFieldLabel } from '../../hooks/useCubeFieldLabel'\nimport { useTheme } from '../../hooks/useTheme'\nimport type { ChartProps } from '../../types'\n\ninterface BubbleData {\n x: number\n xLabel?: string // Formatted label for time dimensions\n y: number\n size: number\n color?: string | number\n label: string\n series?: string\n}\n\nconst BubbleChart = React.memo(function BubbleChart({\n data,\n chartConfig,\n displayConfig = {},\n queryObject,\n height = \"100%\",\n colorPalette\n}: ChartProps) {\n const { t } = useTranslation()\n const svgRef = useRef<SVGSVGElement | null>(null)\n const containerRef = useRef<HTMLDivElement | null>(null)\n const [dimensions, setDimensions] = useState({ width: 0, height: 0 })\n const [dimensionsReady, setDimensionsReady] = useState(false)\n const { theme } = useTheme()\n const getFieldLabel = useCubeFieldLabel()\n\n // Memoize safeDisplayConfig to prevent unnecessary re-renders\n const safeDisplayConfig = useMemo(() => ({\n showLegend: displayConfig?.showLegend ?? true,\n showGrid: displayConfig?.showGrid ?? true,\n showTooltip: displayConfig?.showTooltip ?? true,\n minBubbleSize: displayConfig?.minBubbleSize ?? 5,\n maxBubbleSize: displayConfig?.maxBubbleSize ?? 50,\n bubbleOpacity: displayConfig?.bubbleOpacity ?? 0.7,\n xAxisFormat: displayConfig?.xAxisFormat,\n leftYAxisFormat: displayConfig?.leftYAxisFormat\n }), [\n displayConfig?.showLegend,\n displayConfig?.showGrid,\n displayConfig?.showTooltip,\n displayConfig?.minBubbleSize,\n displayConfig?.maxBubbleSize,\n displayConfig?.bubbleOpacity,\n displayConfig?.xAxisFormat,\n displayConfig?.leftYAxisFormat\n ])\n\n // Enhanced dimension measurement with retry mechanism\n useLayoutEffect(() => {\n let retryCount = 0\n const maxRetries = 10\n let rafId: number\n let timeoutId: ReturnType<typeof setTimeout>\n \n const updateDimensions = () => {\n if (containerRef.current) {\n const { width, height } = containerRef.current.getBoundingClientRect()\n \n if (width > 0 && height > 0) {\n setDimensions({ width, height })\n setDimensionsReady(true)\n return true\n }\n }\n return false\n }\n \n // Immediate measurement\n const success = updateDimensions()\n \n if (!success && retryCount < maxRetries) {\n // Retry with requestAnimationFrame\n const retryWithRaf = () => {\n const rafSuccess = updateDimensions()\n \n if (!rafSuccess && retryCount < maxRetries) {\n retryCount++\n // Use setTimeout for additional retries with increasing delays\n timeoutId = setTimeout(() => {\n rafId = requestAnimationFrame(retryWithRaf)\n }, 50 * retryCount) // Increasing delay: 50ms, 100ms, 150ms, etc.\n }\n }\n \n rafId = requestAnimationFrame(retryWithRaf)\n }\n \n return () => {\n if (rafId) cancelAnimationFrame(rafId)\n if (timeoutId) clearTimeout(timeoutId)\n }\n }, [])\n\n // Enhanced ResizeObserver for dynamic resizing with immediate initialization\n useEffect(() => {\n let resizeObserver: ResizeObserver | null = null\n \n const updateDimensions = () => {\n if (containerRef.current) {\n const { width, height } = containerRef.current.getBoundingClientRect()\n if (width > 0 && height > 0) {\n setDimensions({ width, height })\n if (!dimensionsReady) {\n setDimensionsReady(true)\n }\n }\n }\n }\n \n // Initialize ResizeObserver immediately\n if (containerRef.current) {\n resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const { width, height } = entry.contentRect\n if (width > 0 && height > 0) {\n setDimensions({ width, height })\n if (!dimensionsReady) {\n setDimensionsReady(true)\n }\n }\n }\n })\n \n resizeObserver.observe(containerRef.current)\n \n // Also try immediate measurement as fallback\n updateDimensions()\n }\n\n // Window resize as additional fallback\n window.addEventListener('resize', updateDimensions)\n \n return () => {\n if (resizeObserver) {\n resizeObserver.disconnect()\n }\n window.removeEventListener('resize', updateDimensions)\n }\n }, [dimensionsReady])\n\n useEffect(() => {\n if (!data || data.length === 0 || !svgRef.current || !dimensionsReady || dimensions.width === 0) {\n return\n }\n\n // Clear previous chart\n select(svgRef.current).selectAll('*').remove()\n\n\n // Validate chartConfig - only new format supported\n if (!chartConfig?.xAxis || !chartConfig?.yAxis || !chartConfig?.series) {\n return\n }\n\n const xAxisField = Array.isArray(chartConfig.xAxis) ? chartConfig.xAxis[0] : chartConfig.xAxis\n const yAxisField = Array.isArray(chartConfig.yAxis) ? chartConfig.yAxis[0] : chartConfig.yAxis\n const seriesField = Array.isArray(chartConfig.series) ? chartConfig.series[0] : chartConfig.series\n const sizeFieldName = Array.isArray(chartConfig.sizeField) ? chartConfig.sizeField[0] : chartConfig.sizeField || yAxisField\n const colorFieldName = Array.isArray(chartConfig.colorField) ? chartConfig.colorField[0] : chartConfig.colorField\n\n\n if (!xAxisField || !yAxisField || !seriesField || !sizeFieldName) {\n return\n }\n\n // Transform data for bubble chart\n // Null handling: Filter out bubbles where x, y, or size are null\n const xGranularity = getFieldGranularity(queryObject, xAxisField)\n\n // Check if x-axis field is a time dimension\n const isTimeDimension = queryObject?.timeDimensions?.some(\n (td: { dimension: string }) => td.dimension === xAxisField\n ) || false\n\n const bubbleData: BubbleData[] = data\n .map(item => {\n const rawXValue = item[xAxisField]\n let xNum: number\n let xLabel: string\n\n if (isTimeDimension && rawXValue) {\n // For time dimensions, convert to timestamp for proper numeric positioning\n const dateStr = String(rawXValue)\n // Try to parse as date - handle ISO format and PostgreSQL format\n let date: Date\n if (dateStr.match(/^\\d{4}-\\d{2}-\\d{2}[T ]/)) {\n // Full timestamp format\n let isoStr = dateStr\n if (dateStr.includes(' ')) {\n isoStr = dateStr.replace(' ', 'T').replace('+00', 'Z').replace(/\\+\\d{2}:\\d{2}$/, 'Z')\n }\n if (!isoStr.endsWith('Z') && !isoStr.includes('+')) {\n isoStr = isoStr + 'Z'\n }\n date = new Date(isoStr)\n } else {\n date = new Date(dateStr)\n }\n\n xNum = isNaN(date.getTime()) ? parseFloat(dateStr) : date.getTime()\n xLabel = formatTimeValue(rawXValue, xGranularity)\n } else {\n // Non-time value - use as-is\n const formattedValue = formatTimeValue(rawXValue, xGranularity) || rawXValue\n xNum = typeof formattedValue === 'string' ? parseFloat(formattedValue) : formattedValue\n xLabel = String(formattedValue)\n }\n\n const yValue = parseNumericValue(item[yAxisField])\n const sizeValue = parseNumericValue(item[sizeFieldName])\n const seriesValue = item[seriesField]\n\n return {\n x: xNum,\n xLabel, // Store formatted label for tooltip display\n y: yValue as number, // Type assertion: filter below ensures this is never null\n size: sizeValue !== null ? Math.abs(sizeValue) : 0, // Ensure positive size\n color: colorFieldName ? item[colorFieldName] : seriesValue,\n series: seriesValue,\n label: `${seriesValue || 'Unknown'}`,\n isValid: isValidNumericValue(xNum) && yValue !== null && sizeValue !== null && sizeValue > 0\n }\n })\n .filter(d => d.isValid && d.size > 0) // Filter out bubbles with invalid coordinates or no size\n\n if (bubbleData.length === 0) return\n\n const margin = { \n ...CHART_MARGINS, \n left: CHART_MARGINS.left + 30, // Add extra 30px left margin for Y-axis label\n bottom: (safeDisplayConfig.showLegend && colorFieldName) ? 100 : 40 // Add extra space for legend\n }\n const width = dimensions.width - margin.left - margin.right\n const chartHeight = dimensions.height - margin.top - margin.bottom\n\n const svg = select(svgRef.current)\n .attr('width', dimensions.width)\n .attr('height', dimensions.height)\n\n const g = svg.append('g')\n .attr('transform', `translate(${margin.left},${margin.top})`)\n\n // Set up scales\n const xScale = scaleLinear()\n .domain(extent(bubbleData, d => d.x) as [number, number])\n .range([0, width])\n .nice()\n\n const yScale = scaleLinear()\n .domain(extent(bubbleData, d => d.y) as [number, number])\n .range([chartHeight, 0])\n .nice()\n\n const sizeScale = scaleSqrt()\n .domain([0, max(bubbleData, d => d.size) as number])\n .range([safeDisplayConfig.minBubbleSize, safeDisplayConfig.maxBubbleSize])\n\n // Set up color scale\n let colorScale: ScaleOrdinal<string, string> | ScaleQuantize<string>\n let isNumericColorField = false\n let uniqueColors: string[] = []\n \n if (colorFieldName && bubbleData.length > 0) {\n // Check if color field is numeric for color scaling (same logic as TreeMapChart)\n const colorValues = bubbleData.map(item => {\n const value = item.color\n return typeof value === 'string' ? parseFloat(value) : value\n }).filter((val): val is number => !isNaN(val as number))\n \n isNumericColorField = colorValues.length === bubbleData.length && colorValues.every(val => typeof val === 'number')\n \n if (isNumericColorField) {\n // Use D3 quantize scale for better color distribution with small ranges\n const minValue = Math.min(...colorValues)\n const maxValue = Math.max(...colorValues)\n \n // Create D3 quantize color scale - maps continuous data to discrete color bands\n colorScale = scaleQuantize<string>()\n .domain([minValue, maxValue])\n .range(colorPalette?.gradient || CHART_COLORS_GRADIENT)\n } else {\n // Categorical color field - use series colors\n uniqueColors = [...new Set(bubbleData.map(d => String(d.color)))]\n colorScale = scaleOrdinal<string>()\n .domain(uniqueColors)\n .range(colorPalette?.colors || CHART_COLORS)\n }\n } else {\n // Single color for all bubbles\n colorScale = scaleOrdinal<string>()\n .domain(['default'])\n .range([CHART_COLORS[0]])\n }\n\n // Get theme colors from CSS variables\n const getThemeColor = (varName: string, fallback: string) => {\n const value = getComputedStyle(document.documentElement).getPropertyValue(varName).trim()\n return value || fallback\n }\n\n const isDark = theme !== 'light'\n const textColor = isDark\n ? getThemeColor('--dc-text-muted', '#cbd5e1') // Lighter text for dark mode\n : getThemeColor('--dc-text-secondary', '#374151') // Darker text for light mode\n const gridColor = isDark\n ? getThemeColor('--dc-border', '#475569') // Lighter grid for dark mode\n : '#9ca3af' // Much darker gray for light mode visibility\n\n // Add grid\n if (safeDisplayConfig.showGrid) {\n // X-axis grid\n const xGrid = g.append('g')\n .attr('class', 'grid')\n .attr('transform', `translate(0,${chartHeight})`)\n .call(axisBottom(xScale)\n .tickSize(-chartHeight)\n .tickFormat(() => '')\n )\n\n xGrid.selectAll('line')\n .style('stroke', gridColor)\n .style('stroke-dasharray', '3,3')\n .style('opacity', 0.3)\n\n xGrid.select('.domain')\n .style('stroke', 'none')\n\n // Y-axis grid\n const yGrid = g.append('g')\n .attr('class', 'grid')\n .call(axisLeft(yScale)\n .tickSize(-width)\n .tickFormat(() => '')\n )\n\n yGrid.selectAll('line')\n .style('stroke', gridColor)\n .style('stroke-dasharray', '3,3')\n .style('opacity', 0.3)\n\n yGrid.select('.domain')\n .style('stroke', 'none')\n }\n\n // Add X axis with proper time formatting if needed\n const xAxisGenerator = axisBottom(xScale)\n\n // If it's a time dimension, format the tick labels\n if (isTimeDimension) {\n xAxisGenerator.tickFormat((d) => {\n const date = new Date(d as number)\n if (isNaN(date.getTime())) return String(d)\n\n // Format based on granularity\n switch (xGranularity?.toLowerCase()) {\n case 'year':\n return String(date.getUTCFullYear())\n case 'quarter': {\n const q = Math.floor(date.getUTCMonth() / 3) + 1\n return `${date.getUTCFullYear()}-Q${q}`\n }\n case 'month':\n return `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, '0')}`\n case 'week':\n case 'day':\n return `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, '0')}-${String(date.getUTCDate()).padStart(2, '0')}`\n case 'hour':\n return `${String(date.getUTCMonth() + 1).padStart(2, '0')}-${String(date.getUTCDate()).padStart(2, '0')} ${String(date.getUTCHours()).padStart(2, '0')}:00`\n default:\n return `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, '0')}`\n }\n })\n } else if (safeDisplayConfig.xAxisFormat) {\n // Apply custom formatting for non-time X-axis\n xAxisGenerator.tickFormat((d) => formatAxisValue(d as number, safeDisplayConfig.xAxisFormat))\n }\n\n const xAxis = g.append('g')\n .attr('transform', `translate(0,${chartHeight})`)\n .call(xAxisGenerator)\n\n xAxis.selectAll('text')\n .style('fill', textColor)\n\n xAxis.selectAll('line, path')\n .style('stroke', gridColor)\n\n xAxis.append('text')\n .attr('x', width / 2)\n .attr('y', 35)\n .attr('fill', textColor)\n .style('text-anchor', 'middle')\n .style('font-size', '12px')\n .text(safeDisplayConfig.xAxisFormat?.label || getFieldLabel(xAxisField))\n\n // Add Y axis with optional formatting\n const yAxisGenerator = axisLeft(yScale)\n if (safeDisplayConfig.leftYAxisFormat) {\n yAxisGenerator.tickFormat((d) => formatAxisValue(d as number, safeDisplayConfig.leftYAxisFormat))\n }\n const yAxis = g.append('g')\n .call(yAxisGenerator)\n\n yAxis.selectAll('text')\n .style('fill', textColor)\n\n yAxis.selectAll('line, path')\n .style('stroke', gridColor)\n\n yAxis.append('text')\n .attr('transform', 'rotate(-90)')\n .attr('y', -35)\n .attr('x', -chartHeight / 2)\n .attr('fill', textColor)\n .style('text-anchor', 'middle')\n .style('font-size', '12px')\n .text(safeDisplayConfig.leftYAxisFormat?.label || getFieldLabel(yAxisField))\n\n // Create tooltip\n const tooltip = select('body').append('div')\n .attr('class', 'bubble-chart-tooltip')\n .style('position', 'absolute')\n .style('padding', '8px')\n .style('background', 'rgba(0, 0, 0, 0.8)')\n .style('color', 'white')\n .style('border-radius', '4px')\n .style('font-size', '12px')\n .style('pointer-events', 'none')\n .style('opacity', 0)\n .style('z-index', 1000)\n\n // Add bubbles\n const bubbles = g.selectAll('.bubble')\n .data(bubbleData)\n .enter().append('circle')\n .attr('class', 'bubble')\n .attr('cx', d => xScale(d.x))\n .attr('cy', d => yScale(d.y))\n .attr('r', d => sizeScale(d.size))\n .style('fill', d => {\n if (colorFieldName && d.color !== undefined) {\n return isNumericColorField\n ? (colorScale as ScaleQuantize<string>)(d.color as number)\n : (colorScale as ScaleOrdinal<string, string>)(String(d.color))\n }\n return CHART_COLORS[0]\n })\n .style('opacity', safeDisplayConfig.bubbleOpacity)\n .style('stroke', '#fff')\n .style('stroke-width', 1)\n .style('cursor', 'pointer')\n\n // Add hover effects\n if (safeDisplayConfig.showTooltip) {\n bubbles\n .on('mouseover', function(event, d) {\n select(this)\n .transition()\n .duration(200)\n .style('opacity', 1)\n .attr('r', sizeScale(d.size) * 1.1)\n\n const tooltipContent = [\n `<strong>${d.series || 'Unknown'}</strong>`,\n `${getFieldLabel(xAxisField)}: ${d.xLabel || (safeDisplayConfig.xAxisFormat ? formatAxisValue(d.x, safeDisplayConfig.xAxisFormat) : d.x)}`,\n `${getFieldLabel(yAxisField)}: ${safeDisplayConfig.leftYAxisFormat ? formatAxisValue(d.y, safeDisplayConfig.leftYAxisFormat) : d.y}`,\n `${getFieldLabel(sizeFieldName)}: ${safeDisplayConfig.leftYAxisFormat ? formatAxisValue(d.size, safeDisplayConfig.leftYAxisFormat) : d.size}`,\n colorFieldName && d.color ? `${getFieldLabel(colorFieldName)}: ${d.color}` : ''\n ].filter(Boolean).join('<br>')\n\n tooltip\n .html(tooltipContent)\n .style('left', (event.pageX + 10) + 'px')\n .style('top', (event.pageY - 10) + 'px')\n .transition()\n .duration(200)\n .style('opacity', 1)\n })\n .on('mousemove', function(event) {\n tooltip\n .style('left', (event.pageX + 10) + 'px')\n .style('top', (event.pageY - 10) + 'px')\n })\n .on('mouseout', function(_event, d) {\n select(this)\n .transition()\n .duration(200)\n .style('opacity', safeDisplayConfig.bubbleOpacity)\n .attr('r', sizeScale(d.size))\n\n tooltip\n .transition()\n .duration(200)\n .style('opacity', 0)\n })\n }\n\n // Add legend if needed\n if (safeDisplayConfig.showLegend && colorFieldName) {\n if (isNumericColorField) {\n // Create gradient legend for numeric color field\n const legendWidth = 200\n const legendHeight = 20\n const minValue = Math.min(...bubbleData.map(d => d.color as number))\n const maxValue = Math.max(...bubbleData.map(d => d.color as number))\n \n const legend = g.append('g')\n .attr('class', 'color-legend')\n .attr('transform', `translate(${width / 2 - legendWidth / 2}, ${chartHeight + 60})`)\n\n // Create gradient definition\n const defs = svg.append('defs')\n const gradient = defs.append('linearGradient')\n .attr('id', 'color-scale-gradient')\n .attr('x1', '0%')\n .attr('y1', '0%')\n .attr('x2', '100%')\n .attr('y2', '0%')\n\n // Add color stops for the gradient\n const gradientColors = colorPalette?.gradient || CHART_COLORS_GRADIENT\n gradientColors.forEach((color, i) => {\n gradient.append('stop')\n .attr('offset', `${(i / (gradientColors.length - 1)) * 100}%`)\n .attr('stop-color', color)\n })\n\n // Add the gradient rectangle\n legend.append('rect')\n .attr('width', legendWidth)\n .attr('height', legendHeight)\n .style('fill', 'url(#color-scale-gradient)')\n .style('stroke', '#ccc')\n .style('stroke-width', 1)\n\n // Add min value label\n legend.append('text')\n .attr('x', 0)\n .attr('y', legendHeight + 15)\n .attr('text-anchor', 'start')\n .style('font-size', '11px')\n .style('fill', textColor)\n .text(safeDisplayConfig.leftYAxisFormat ? formatAxisValue(minValue, safeDisplayConfig.leftYAxisFormat) : minValue.toFixed(2))\n\n // Add max value label\n legend.append('text')\n .attr('x', legendWidth)\n .attr('y', legendHeight + 15)\n .attr('text-anchor', 'end')\n .style('font-size', '11px')\n .style('fill', textColor)\n .text(safeDisplayConfig.leftYAxisFormat ? formatAxisValue(maxValue, safeDisplayConfig.leftYAxisFormat) : maxValue.toFixed(2))\n\n // Add field name label\n legend.append('text')\n .attr('x', legendWidth / 2)\n .attr('y', -5)\n .attr('text-anchor', 'middle')\n .style('font-size', '12px')\n .style('font-weight', 'bold')\n .style('fill', textColor)\n .text(getFieldLabel(colorFieldName))\n\n } else {\n // Original categorical legend\n const legendItems = uniqueColors\n\n if (legendItems.length > 0) {\n const legend = g.append('g')\n .attr('class', 'legend')\n .attr('transform', `translate(${width / 2 - (legendItems.length * 80) / 2}, ${chartHeight + 60})`)\n\n const legendItem = legend.selectAll('.legend-item')\n .data(legendItems)\n .enter().append('g')\n .attr('class', 'legend-item')\n .attr('transform', (_d, i) => `translate(${i * 80}, 0)`)\n .style('cursor', 'pointer')\n\n legendItem.append('circle')\n .attr('cx', 5)\n .attr('cy', 5)\n .attr('r', 5)\n .style('fill', d => (colorScale as ScaleOrdinal<string, string>)(d as string))\n .style('opacity', safeDisplayConfig.bubbleOpacity)\n\n legendItem.append('text')\n .attr('x', 15)\n .attr('y', 5)\n .attr('dy', '.35em')\n .style('font-size', '11px')\n .style('fill', textColor)\n .text(d => String(d))\n\n // Legend hover effects\n legendItem\n .on('mouseover', function(_event, legendKey) {\n // Highlight matching bubbles\n bubbles\n .transition()\n .duration(200)\n .style('opacity', d => {\n const matches = colorFieldName && String(d.color) === legendKey\n return matches ? 1 : 0.2\n })\n })\n .on('mouseout', function() {\n // Reset all bubbles\n bubbles\n .transition()\n .duration(200)\n .style('opacity', safeDisplayConfig.bubbleOpacity)\n })\n }\n }\n }\n\n // Cleanup function\n return () => {\n tooltip.remove()\n }\n }, [data, chartConfig, safeDisplayConfig, queryObject, dimensions, dimensionsReady, colorPalette, theme, getFieldLabel])\n\n if (!data || data.length === 0) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">{t('chart.runtime.noData')}</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">{t('chart.runtime.noDataHint.bubble')}</div>\n </div>\n </div>\n )\n }\n\n // Validate that we have required fields\n const hasValidConfig = chartConfig?.xAxis && chartConfig?.yAxis && chartConfig?.series\n if (!hasValidConfig) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-warning\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">{t('chart.runtime.activityGridConfigRequired')}</div>\n <div className=\"dc:text-xs\">{t('chart.runtime.configErrorHint.bubbleRequired')}</div>\n <div className=\"dc:text-xs dc:mt-1\">{t('chart.runtime.configErrorHint.bubbleOptional')}</div>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"dc:w-full dc:flex-1 dc:flex dc:flex-col dc:relative\" style={{ height, minHeight: '250px', overflow: 'hidden' }}>\n <div ref={containerRef} className=\"dc:w-full dc:h-full dc:relative\">\n <svg ref={svgRef} className=\"dc:w-full dc:h-full\" />\n {!dimensionsReady && (\n <div className=\"dc:absolute dc:inset-0 dc:flex dc:items-center dc:justify-center\">\n <div className=\"text-dc-text-muted dc:text-sm\">{t('chart.runtime.measuringDimensions')}</div>\n </div>\n )}\n </div>\n </div>\n )\n})\n\nexport default BubbleChart"],"mappings":";;;;;;AAcA,IAAM,IAAa;CACjB,2BAAW,IAAI,KAAiB;CAEhC,UAAU,GAAsB;AAE9B,SADA,KAAK,UAAU,IAAI,EAAS,QACf,KAAK,UAAU,OAAO,EAAS;;CAG9C,SAAS;AACP,OAAK,UAAU,SAAQ,MAAY,GAAU,CAAC;;CAEjD;AAGD,QAAwB;AACtB,GAAW,QAAQ;EACnB;AAQF,SAAgB,IAAW;AAczB,QAAO;EAAE,OAZK,EACZ,EAAW,UAAU,KAAK,EAAW,EACrC,GACA,EACD;EAQe,UALC,GAAa,MAAoB;AAEhD,GADA,EAAa,EAAS,EACtB,EAAW,QAAQ;KAClB,EAAE,CAAC;EAEoB;;;;iDChCtB,IAAc,EAAM,KAAK,SAAqB,EAClD,SACA,gBACA,mBAAgB,EAAE,EAClB,gBACA,YAAS,QACT,mBACa;CACb,IAAM,EAAE,SAAM,GAAgB,EACxB,IAAS,EAA6B,KAAK,EAC3C,IAAe,EAA8B,KAAK,EAClD,CAAC,GAAY,KAAiB,EAAS;EAAE,OAAO;EAAG,QAAQ;EAAG,CAAC,EAC/D,CAAC,GAAiB,KAAsB,EAAS,GAAM,EACvD,EAAE,aAAU,GAAU,EACtB,IAAgB,GAAmB,EAGnC,IAAoB,SAAe;EACvC,YAAY,GAAe,cAAc;EACzC,UAAU,GAAe,YAAY;EACrC,aAAa,GAAe,eAAe;EAC3C,eAAe,GAAe,iBAAiB;EAC/C,eAAe,GAAe,iBAAiB;EAC/C,eAAe,GAAe,iBAAiB;EAC/C,aAAa,GAAe;EAC5B,iBAAiB,GAAe;EACjC,GAAG;EACF,GAAe;EACf,GAAe;EACf,GAAe;EACf,GAAe;EACf,GAAe;EACf,GAAe;EACf,GAAe;EACf,GAAe;EAChB,CAAC;AA2lBF,QAxlBA,QAAsB;EACpB,IAAI,IAAa,GAEb,GACA,GAEE,UAAyB;AAC7B,OAAI,EAAa,SAAS;IACxB,IAAM,EAAE,UAAO,cAAW,EAAa,QAAQ,uBAAuB;AAEtE,QAAI,IAAQ,KAAK,IAAS,EAGxB,QAFA,EAAc;KAAE;KAAO;KAAQ,CAAC,EAChC,EAAmB,GAAK,EACjB;;AAGX,UAAO;;AAMT,MAAI,CAFY,GAAkB,IAElB,IAAa,IAAY;GAEvC,IAAM,UAAqB;AAGzB,IAAI,CAFe,GAAkB,IAElB,IAAa,OAC9B,KAEA,IAAY,iBAAiB;AAC3B,SAAQ,sBAAsB,EAAa;OAC1C,KAAK,EAAW;;AAIvB,OAAQ,sBAAsB,EAAa;;AAG7C,eAAa;AAEX,GADI,KAAO,qBAAqB,EAAM,EAClC,KAAW,aAAa,EAAU;;IAEvC,EAAE,CAAC,EAGN,QAAgB;EACd,IAAI,IAAwC,MAEtC,UAAyB;AAC7B,OAAI,EAAa,SAAS;IACxB,IAAM,EAAE,UAAO,cAAW,EAAa,QAAQ,uBAAuB;AACtE,IAAI,IAAQ,KAAK,IAAS,MACxB,EAAc;KAAE;KAAO;KAAQ,CAAC,EAC3B,KACH,EAAmB,GAAK;;;AA6BhC,SAtBI,EAAa,YACf,IAAiB,IAAI,gBAAgB,MAAY;AAC/C,QAAK,IAAM,KAAS,GAAS;IAC3B,IAAM,EAAE,UAAO,cAAW,EAAM;AAChC,IAAI,IAAQ,KAAK,IAAS,MACxB,EAAc;KAAE;KAAO;KAAQ,CAAC,EAC3B,KACH,EAAmB,GAAK;;IAI9B,EAEF,EAAe,QAAQ,EAAa,QAAQ,EAG5C,GAAkB,GAIpB,OAAO,iBAAiB,UAAU,EAAiB,QAEtC;AAIX,GAHI,KACF,EAAe,YAAY,EAE7B,OAAO,oBAAoB,UAAU,EAAiB;;IAEvD,CAAC,EAAgB,CAAC,EAErB,QAAgB;AAUd,MATI,CAAC,KAAQ,EAAK,WAAW,KAAK,CAAC,EAAO,WAAW,CAAC,KAAmB,EAAW,UAAU,MAK9F,EAAO,EAAO,QAAQ,CAAC,UAAU,IAAI,CAAC,QAAQ,EAI1C,CAAC,GAAa,SAAS,CAAC,GAAa,SAAS,CAAC,GAAa,QAC9D;EAGF,IAAM,IAAa,MAAM,QAAQ,EAAY,MAAM,GAAG,EAAY,MAAM,KAAK,EAAY,OACnF,IAAa,MAAM,QAAQ,EAAY,MAAM,GAAG,EAAY,MAAM,KAAK,EAAY,OACnF,IAAc,MAAM,QAAQ,EAAY,OAAO,GAAG,EAAY,OAAO,KAAK,EAAY,QACtF,IAAgB,MAAM,QAAQ,EAAY,UAAU,GAAG,EAAY,UAAU,KAAK,EAAY,aAAa,GAC3G,IAAiB,MAAM,QAAQ,EAAY,WAAW,GAAG,EAAY,WAAW,KAAK,EAAY;AAGvG,MAAI,CAAC,KAAc,CAAC,KAAc,CAAC,KAAe,CAAC,EACjD;EAKF,IAAM,IAAe,EAAoB,GAAa,EAAW,EAG3D,IAAkB,GAAa,gBAAgB,MAClD,MAA8B,EAAG,cAAc,EACjD,IAAI,IAEC,IAA2B,EAC9B,KAAI,MAAQ;GACX,IAAM,IAAY,EAAK,IACnB,GACA;AAEJ,OAAI,KAAmB,GAAW;IAEhC,IAAM,IAAU,OAAO,EAAU,EAE7B;AACJ,QAAI,EAAQ,MAAM,yBAAyB,EAAE;KAE3C,IAAI,IAAS;AAOb,KANI,EAAQ,SAAS,IAAI,KACvB,IAAS,EAAQ,QAAQ,KAAK,IAAI,CAAC,QAAQ,OAAO,IAAI,CAAC,QAAQ,kBAAkB,IAAI,GAEnF,CAAC,EAAO,SAAS,IAAI,IAAI,CAAC,EAAO,SAAS,IAAI,KAChD,KAAkB,MAEpB,IAAO,IAAI,KAAK,EAAO;UAEvB,KAAO,IAAI,KAAK,EAAQ;AAI1B,IADA,IAAO,MAAM,EAAK,SAAS,CAAC,GAAG,WAAW,EAAQ,GAAG,EAAK,SAAS,EACnE,IAAS,EAAgB,GAAW,EAAa;UAC5C;IAEL,IAAM,IAAiB,EAAgB,GAAW,EAAa,IAAI;AAEnE,IADA,IAAO,OAAO,KAAmB,WAAW,WAAW,EAAe,GAAG,GACzE,IAAS,OAAO,EAAe;;GAGjC,IAAM,IAAS,EAAkB,EAAK,GAAY,EAC5C,IAAY,EAAkB,EAAK,GAAe,EAClD,IAAc,EAAK;AAEzB,UAAO;IACL,GAAG;IACH;IACA,GAAG;IACH,MAAM,MAAc,OAA6B,IAAtB,KAAK,IAAI,EAAU;IAC9C,OAAO,IAAiB,EAAK,KAAkB;IAC/C,QAAQ;IACR,OAAO,GAAG,KAAe;IACzB,SAAS,EAAoB,EAAK,IAAI,MAAW,QAAQ,MAAc,QAAQ,IAAY;IAC5F;IACD,CACD,QAAO,MAAK,EAAE,WAAW,EAAE,OAAO,EAAE;AAEvC,MAAI,EAAW,WAAW,EAAG;EAE7B,IAAM,IAAS;GACb,GAAG;GACH,MAAM,EAAc,OAAO;GAC3B,QAAS,EAAkB,cAAc,IAAkB,MAAM;GAClE,EACK,IAAQ,EAAW,QAAQ,EAAO,OAAO,EAAO,OAChD,IAAc,EAAW,SAAS,EAAO,MAAM,EAAO,QAEtD,IAAM,EAAO,EAAO,QAAQ,CAC/B,KAAK,SAAS,EAAW,MAAM,CAC/B,KAAK,UAAU,EAAW,OAAO,EAE9B,IAAI,EAAI,OAAO,IAAI,CACtB,KAAK,aAAa,aAAa,EAAO,KAAK,GAAG,EAAO,IAAI,GAAG,EAGzD,IAAS,GAAa,CACzB,OAAO,EAAO,IAAY,MAAK,EAAE,EAAE,CAAqB,CACxD,MAAM,CAAC,GAAG,EAAM,CAAC,CACjB,MAAM,EAEH,IAAS,GAAa,CACzB,OAAO,EAAO,IAAY,MAAK,EAAE,EAAE,CAAqB,CACxD,MAAM,CAAC,GAAa,EAAE,CAAC,CACvB,MAAM,EAEH,IAAY,IAAW,CAC1B,OAAO,CAAC,GAAG,EAAI,IAAY,MAAK,EAAE,KAAK,CAAW,CAAC,CACnD,MAAM,CAAC,EAAkB,eAAe,EAAkB,cAAc,CAAC,EAGxE,GACA,IAAsB,IACtB,IAAyB,EAAE;AAE/B,MAAI,KAAkB,EAAW,SAAS,GAAG;GAE3C,IAAM,IAAc,EAAW,KAAI,MAAQ;IACzC,IAAM,IAAQ,EAAK;AACnB,WAAO,OAAO,KAAU,WAAW,WAAW,EAAM,GAAG;KACvD,CAAC,QAAQ,MAAuB,CAAC,MAAM,EAAc,CAAC;AAIxD,OAFA,IAAsB,EAAY,WAAW,EAAW,UAAU,EAAY,OAAM,MAAO,OAAO,KAAQ,SAAS,EAE/G,GAAqB;IAEvB,IAAM,IAAW,KAAK,IAAI,GAAG,EAAY,EACnC,IAAW,KAAK,IAAI,GAAG,EAAY;AAGzC,QAAa,IAAuB,CACjC,OAAO,CAAC,GAAU,EAAS,CAAC,CAC5B,MAAM,GAAc,YAAY,EAAsB;SAIzD,CADA,IAAe,CAAC,GAAG,IAAI,IAAI,EAAW,KAAI,MAAK,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EACjE,IAAa,GAAsB,CAChC,OAAO,EAAa,CACpB,MAAM,GAAc,UAAU,EAAa;QAIhD,KAAa,GAAsB,CAChC,OAAO,CAAC,UAAU,CAAC,CACnB,MAAM,CAAC,EAAa,GAAG,CAAC;EAI7B,IAAM,KAAiB,GAAiB,MACxB,iBAAiB,SAAS,gBAAgB,CAAC,iBAAiB,EAAQ,CAAC,MAAM,IACzE,GAGZ,IAAS,MAAU,SACnB,IAAY,IACd,EAAc,mBAAmB,UAAU,GAC3C,EAAc,uBAAuB,UAAU,EAC7C,IAAY,IACd,EAAc,eAAe,UAAU,GACvC;AAGJ,MAAI,EAAkB,UAAU;GAE9B,IAAM,IAAQ,EAAE,OAAO,IAAI,CACxB,KAAK,SAAS,OAAO,CACrB,KAAK,aAAa,eAAe,EAAY,GAAG,CAChD,KAAK,EAAW,EAAO,CACrB,SAAS,CAAC,EAAY,CACtB,iBAAiB,GAAG,CACtB;AAOH,GALA,EAAM,UAAU,OAAO,CACpB,MAAM,UAAU,EAAU,CAC1B,MAAM,oBAAoB,MAAM,CAChC,MAAM,WAAW,GAAI,EAExB,EAAM,OAAO,UAAU,CACpB,MAAM,UAAU,OAAO;GAG1B,IAAM,IAAQ,EAAE,OAAO,IAAI,CACxB,KAAK,SAAS,OAAO,CACrB,KAAK,EAAS,EAAO,CACnB,SAAS,CAAC,EAAM,CAChB,iBAAiB,GAAG,CACtB;AAOH,GALA,EAAM,UAAU,OAAO,CACpB,MAAM,UAAU,EAAU,CAC1B,MAAM,oBAAoB,MAAM,CAChC,MAAM,WAAW,GAAI,EAExB,EAAM,OAAO,UAAU,CACpB,MAAM,UAAU,OAAO;;EAI5B,IAAM,IAAiB,EAAW,EAAO;AAGzC,EAAI,IACF,EAAe,YAAY,MAAM;GAC/B,IAAM,IAAO,IAAI,KAAK,EAAY;AAClC,OAAI,MAAM,EAAK,SAAS,CAAC,CAAE,QAAO,OAAO,EAAE;AAG3C,WAAQ,GAAc,aAAa,EAAnC;IACE,KAAK,OACH,QAAO,OAAO,EAAK,gBAAgB,CAAC;IACtC,KAAK,WAAW;KACd,IAAM,IAAI,KAAK,MAAM,EAAK,aAAa,GAAG,EAAE,GAAG;AAC/C,YAAO,GAAG,EAAK,gBAAgB,CAAC,IAAI;;IAEtC,KAAK,QACH,QAAO,GAAG,EAAK,gBAAgB,CAAC,GAAG,OAAO,EAAK,aAAa,GAAG,EAAE,CAAC,SAAS,GAAG,IAAI;IACpF,KAAK;IACL,KAAK,MACH,QAAO,GAAG,EAAK,gBAAgB,CAAC,GAAG,OAAO,EAAK,aAAa,GAAG,EAAE,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,OAAO,EAAK,YAAY,CAAC,CAAC,SAAS,GAAG,IAAI;IAClI,KAAK,OACH,QAAO,GAAG,OAAO,EAAK,aAAa,GAAG,EAAE,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,OAAO,EAAK,YAAY,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,OAAO,EAAK,aAAa,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC;IACzJ,QACE,QAAO,GAAG,EAAK,gBAAgB,CAAC,GAAG,OAAO,EAAK,aAAa,GAAG,EAAE,CAAC,SAAS,GAAG,IAAI;;IAEtF,GACO,EAAkB,eAE3B,EAAe,YAAY,MAAM,EAAgB,GAAa,EAAkB,YAAY,CAAC;EAG/F,IAAM,IAAQ,EAAE,OAAO,IAAI,CACxB,KAAK,aAAa,eAAe,EAAY,GAAG,CAChD,KAAK,EAAe;AAQvB,EANA,EAAM,UAAU,OAAO,CACpB,MAAM,QAAQ,EAAU,EAE3B,EAAM,UAAU,aAAa,CAC1B,MAAM,UAAU,EAAU,EAE7B,EAAM,OAAO,OAAO,CACjB,KAAK,KAAK,IAAQ,EAAE,CACpB,KAAK,KAAK,GAAG,CACb,KAAK,QAAQ,EAAU,CACvB,MAAM,eAAe,SAAS,CAC9B,MAAM,aAAa,OAAO,CAC1B,KAAK,EAAkB,aAAa,SAAS,EAAc,EAAW,CAAC;EAG1E,IAAM,IAAiB,EAAS,EAAO;AACvC,EAAI,EAAkB,mBACpB,EAAe,YAAY,MAAM,EAAgB,GAAa,EAAkB,gBAAgB,CAAC;EAEnG,IAAM,IAAQ,EAAE,OAAO,IAAI,CACxB,KAAK,EAAe;AAQvB,EANA,EAAM,UAAU,OAAO,CACpB,MAAM,QAAQ,EAAU,EAE3B,EAAM,UAAU,aAAa,CAC1B,MAAM,UAAU,EAAU,EAE7B,EAAM,OAAO,OAAO,CACjB,KAAK,aAAa,cAAc,CAChC,KAAK,KAAK,IAAI,CACd,KAAK,KAAK,CAAC,IAAc,EAAE,CAC3B,KAAK,QAAQ,EAAU,CACvB,MAAM,eAAe,SAAS,CAC9B,MAAM,aAAa,OAAO,CAC1B,KAAK,EAAkB,iBAAiB,SAAS,EAAc,EAAW,CAAC;EAG9E,IAAM,IAAU,EAAO,OAAO,CAAC,OAAO,MAAM,CACzC,KAAK,SAAS,uBAAuB,CACrC,MAAM,YAAY,WAAW,CAC7B,MAAM,WAAW,MAAM,CACvB,MAAM,cAAc,qBAAqB,CACzC,MAAM,SAAS,QAAQ,CACvB,MAAM,iBAAiB,MAAM,CAC7B,MAAM,aAAa,OAAO,CAC1B,MAAM,kBAAkB,OAAO,CAC/B,MAAM,WAAW,EAAE,CACnB,MAAM,WAAW,IAAK,EAGnB,IAAU,EAAE,UAAU,UAAU,CACnC,KAAK,EAAW,CAChB,OAAO,CAAC,OAAO,SAAS,CACxB,KAAK,SAAS,SAAS,CACvB,KAAK,OAAM,MAAK,EAAO,EAAE,EAAE,CAAC,CAC5B,KAAK,OAAM,MAAK,EAAO,EAAE,EAAE,CAAC,CAC5B,KAAK,MAAK,MAAK,EAAU,EAAE,KAAK,CAAC,CACjC,MAAM,SAAQ,MACT,KAAkB,EAAE,UAAU,KAAA,IAE3B,EADE,IACmC,EAAE,QACK,OAAO,EAAE,MAAM,CAAC,GAE5D,EAAa,GACpB,CACD,MAAM,WAAW,EAAkB,cAAc,CACjD,MAAM,UAAU,OAAO,CACvB,MAAM,gBAAgB,EAAE,CACxB,MAAM,UAAU,UAAU;AAgD7B,MA7CI,EAAkB,eACpB,EACG,GAAG,aAAa,SAAS,GAAO,GAAG;AAClC,KAAO,KAAK,CACT,YAAY,CACZ,SAAS,IAAI,CACb,MAAM,WAAW,EAAE,CACnB,KAAK,KAAK,EAAU,EAAE,KAAK,GAAG,IAAI;GAErC,IAAM,IAAiB;IACrB,WAAW,EAAE,UAAU,UAAU;IACjC,GAAG,EAAc,EAAW,CAAC,IAAI,EAAE,WAAW,EAAkB,cAAc,EAAgB,EAAE,GAAG,EAAkB,YAAY,GAAG,EAAE;IACtI,GAAG,EAAc,EAAW,CAAC,IAAI,EAAkB,kBAAkB,EAAgB,EAAE,GAAG,EAAkB,gBAAgB,GAAG,EAAE;IACjI,GAAG,EAAc,EAAc,CAAC,IAAI,EAAkB,kBAAkB,EAAgB,EAAE,MAAM,EAAkB,gBAAgB,GAAG,EAAE;IACvI,KAAkB,EAAE,QAAQ,GAAG,EAAc,EAAe,CAAC,IAAI,EAAE,UAAU;IAC9E,CAAC,OAAO,QAAQ,CAAC,KAAK,OAAO;AAE9B,KACG,KAAK,EAAe,CACpB,MAAM,QAAS,EAAM,QAAQ,KAAM,KAAK,CACxC,MAAM,OAAQ,EAAM,QAAQ,KAAM,KAAK,CACvC,YAAY,CACZ,SAAS,IAAI,CACb,MAAM,WAAW,EAAE;IACtB,CACD,GAAG,aAAa,SAAS,GAAO;AAC/B,KACG,MAAM,QAAS,EAAM,QAAQ,KAAM,KAAK,CACxC,MAAM,OAAQ,EAAM,QAAQ,KAAM,KAAK;IAC1C,CACD,GAAG,YAAY,SAAS,GAAQ,GAAG;AAOlC,GANA,EAAO,KAAK,CACT,YAAY,CACZ,SAAS,IAAI,CACb,MAAM,WAAW,EAAkB,cAAc,CACjD,KAAK,KAAK,EAAU,EAAE,KAAK,CAAC,EAE/B,EACG,YAAY,CACZ,SAAS,IAAI,CACb,MAAM,WAAW,EAAE;IACtB,EAIF,EAAkB,cAAc,EAClC,KAAI,GAAqB;GAEvB,IAEM,IAAW,KAAK,IAAI,GAAG,EAAW,KAAI,MAAK,EAAE,MAAgB,CAAC,EAC9D,IAAW,KAAK,IAAI,GAAG,EAAW,KAAI,MAAK,EAAE,MAAgB,CAAC,EAE9D,IAAS,EAAE,OAAO,IAAI,CACzB,KAAK,SAAS,eAAe,CAC7B,KAAK,aAAa,aAAa,IAAQ,IAAI,MAAc,EAAE,IAAI,IAAc,GAAG,GAAG,EAIhF,IADO,EAAI,OAAO,OAAO,CACT,OAAO,iBAAiB,CAC3C,KAAK,MAAM,uBAAuB,CAClC,KAAK,MAAM,KAAK,CAChB,KAAK,MAAM,KAAK,CAChB,KAAK,MAAM,OAAO,CAClB,KAAK,MAAM,KAAK,EAGb,IAAiB,GAAc,YAAY;AAkCjD,GAjCA,EAAe,SAAS,GAAO,MAAM;AACnC,MAAS,OAAO,OAAO,CACpB,KAAK,UAAU,GAAI,KAAK,EAAe,SAAS,KAAM,IAAI,GAAG,CAC7D,KAAK,cAAc,EAAM;KAC5B,EAGF,EAAO,OAAO,OAAO,CAClB,KAAK,SAAS,IAAY,CAC1B,KAAK,UAAU,GAAa,CAC5B,MAAM,QAAQ,6BAA6B,CAC3C,MAAM,UAAU,OAAO,CACvB,MAAM,gBAAgB,EAAE,EAG3B,EAAO,OAAO,OAAO,CAClB,KAAK,KAAK,EAAE,CACZ,KAAK,KAAK,GAAkB,CAC5B,KAAK,eAAe,QAAQ,CAC5B,MAAM,aAAa,OAAO,CAC1B,MAAM,QAAQ,EAAU,CACxB,KAAK,EAAkB,kBAAkB,EAAgB,GAAU,EAAkB,gBAAgB,GAAG,EAAS,QAAQ,EAAE,CAAC,EAG/H,EAAO,OAAO,OAAO,CAClB,KAAK,KAAK,IAAY,CACtB,KAAK,KAAK,GAAkB,CAC5B,KAAK,eAAe,MAAM,CAC1B,MAAM,aAAa,OAAO,CAC1B,MAAM,QAAQ,EAAU,CACxB,KAAK,EAAkB,kBAAkB,EAAgB,GAAU,EAAkB,gBAAgB,GAAG,EAAS,QAAQ,EAAE,CAAC,EAG/H,EAAO,OAAO,OAAO,CAClB,KAAK,KAAK,MAAc,EAAE,CAC1B,KAAK,KAAK,GAAG,CACb,KAAK,eAAe,SAAS,CAC7B,MAAM,aAAa,OAAO,CAC1B,MAAM,eAAe,OAAO,CAC5B,MAAM,QAAQ,EAAU,CACxB,KAAK,EAAc,EAAe,CAAC;SAEjC;GAEL,IAAM,IAAc;AAEpB,OAAI,EAAY,SAAS,GAAG;IAK1B,IAAM,IAJS,EAAE,OAAO,IAAI,CACzB,KAAK,SAAS,SAAS,CACvB,KAAK,aAAa,aAAa,IAAQ,IAAK,EAAY,SAAS,KAAM,EAAE,IAAI,IAAc,GAAG,GAAG,CAE1E,UAAU,eAAe,CAChD,KAAK,EAAY,CACjB,OAAO,CAAC,OAAO,IAAI,CACnB,KAAK,SAAS,cAAc,CAC5B,KAAK,cAAc,GAAI,MAAM,aAAa,IAAI,GAAG,MAAM,CACvD,MAAM,UAAU,UAAU;AAkB7B,IAhBA,EAAW,OAAO,SAAS,CACxB,KAAK,MAAM,EAAE,CACb,KAAK,MAAM,EAAE,CACb,KAAK,KAAK,EAAE,CACZ,MAAM,SAAQ,MAAM,EAA4C,EAAY,CAAC,CAC7E,MAAM,WAAW,EAAkB,cAAc,EAEpD,EAAW,OAAO,OAAO,CACtB,KAAK,KAAK,GAAG,CACb,KAAK,KAAK,EAAE,CACZ,KAAK,MAAM,QAAQ,CACnB,MAAM,aAAa,OAAO,CAC1B,MAAM,QAAQ,EAAU,CACxB,MAAK,MAAK,OAAO,EAAE,CAAC,EAGvB,EACG,GAAG,aAAa,SAAS,GAAQ,GAAW;AAE3C,OACG,YAAY,CACZ,SAAS,IAAI,CACb,MAAM,YAAW,MACA,KAAkB,OAAO,EAAE,MAAM,KAAK,IACrC,IAAI,GACrB;MACJ,CACD,GAAG,YAAY,WAAW;AAEzB,OACG,YAAY,CACZ,SAAS,IAAI,CACb,MAAM,WAAW,EAAkB,cAAc;MACpD;;;AAMV,eAAa;AACX,KAAQ,QAAQ;;IAEjB;EAAC;EAAM;EAAa;EAAmB;EAAa;EAAY;EAAiB;EAAc;EAAO;EAAc,CAAC,EAEpH,CAAC,KAAQ,EAAK,WAAW,IAEzB,kBAAC,OAAD;EAAK,WAAU;EAAyE,OAAO,EAAE,WAAQ;YACvG,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAuC,EAAE,uBAAuB;IAAO,CAAA,EACtF,kBAAC,OAAD;IAAK,WAAU;cAAqC,EAAE,kCAAkC;IAAO,CAAA,CAC3F;;EACF,CAAA,GAKa,GAAa,SAAS,GAAa,SAAS,GAAa,SAc9E,kBAAC,OAAD;EAAK,WAAU;EAAsD,OAAO;GAAE;GAAQ,WAAW;GAAS,UAAU;GAAU;YAC5H,kBAAC,OAAD;GAAK,KAAK;GAAc,WAAU;aAAlC,CACE,kBAAC,OAAD;IAAK,KAAK;IAAQ,WAAU;IAAwB,CAAA,EACnD,CAAC,KACA,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,OAAD;KAAK,WAAU;eAAiC,EAAE,oCAAoC;KAAO,CAAA;IACzF,CAAA,CAEJ;;EACF,CAAA,GApBJ,kBAAC,OAAD;EAAK,WAAU;EAAsE,OAAO,EAAE,WAAQ;YACpG,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,OAAD;KAAK,WAAU;eAAuC,EAAE,2CAA2C;KAAO,CAAA;IAC1G,kBAAC,OAAD;KAAK,WAAU;eAAc,EAAE,+CAA+C;KAAO,CAAA;IACrF,kBAAC,OAAD;KAAK,WAAU;eAAsB,EAAE,+CAA+C;KAAO,CAAA;IACzF;;EACF,CAAA;EAgBV"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as e } from "./rolldown-runtime-CCl2IeXn.js";
|
|
2
|
-
import { k as t, y as n } from "./chart-activity-grid-
|
|
2
|
+
import { k as t, y as n } from "./chart-activity-grid-BnY-jaoa.js";
|
|
3
3
|
import r, { useLayoutEffect as i, useMemo as a, useRef as o, useState as s } from "react";
|
|
4
4
|
import { Fragment as c, jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
5
5
|
//#region src/client/components/charts/CandlestickChart.tsx
|
|
@@ -300,4 +300,4 @@ var y = r.memo(function({ data: e, chartConfig: r, displayConfig: c = {}, height
|
|
|
300
300
|
//#endregion
|
|
301
301
|
export { d as t };
|
|
302
302
|
|
|
303
|
-
//# sourceMappingURL=chart-candlestick-
|
|
303
|
+
//# sourceMappingURL=chart-candlestick-oSPk-KQp.js.map
|
package/dist/client/chunks/{chart-candlestick-C2nzVCv1.js.map → chart-candlestick-oSPk-KQp.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-candlestick-C2nzVCv1.js","names":[],"sources":["../../../src/client/components/charts/CandlestickChart.tsx"],"sourcesContent":["import React, { useLayoutEffect, useMemo, useRef, useState } from 'react'\nimport { useTranslation } from '../../hooks/useTranslation'\nimport { formatAxisValue } from '../../utils/chartUtils'\nimport type { ChartProps } from '../../types'\n\nconst BULL_COLOR_DEFAULT = '#22c55e'\nconst BEAR_COLOR_DEFAULT = '#ef4444'\nconst WICK_COLOR = '#94a3b8'\nconst MAX_CANDLES = 200\n\ninterface CandleData {\n label: string\n open: number\n close: number\n high: number\n low: number\n isBullish: boolean\n originalIndex: number\n}\n\nfunction parseNum(v: unknown): number | null {\n if (v === undefined || v === null) return null\n const n = typeof v === 'number' ? v : parseFloat(String(v))\n return isNaN(n) ? null : n\n}\n\nfunction Candle({\n x,\n candleWidth,\n openY,\n closeY,\n highY,\n lowY,\n isBullish,\n bullColor,\n bearColor,\n showWicks,\n label,\n}: {\n x: number\n candleWidth: number\n openY: number\n closeY: number\n highY: number\n lowY: number\n isBullish: boolean\n bullColor: string\n bearColor: string\n showWicks: boolean\n label: string\n}) {\n const fill = isBullish ? bullColor : bearColor\n const bodyTop = Math.min(openY, closeY)\n const bodyBottom = Math.max(openY, closeY)\n const bodyHeight = Math.max(bodyBottom - bodyTop, 1)\n const halfWidth = candleWidth / 2\n\n return (\n <g data-testid={`candle-${label}`}>\n <rect\n x={x - halfWidth}\n y={bodyTop}\n width={candleWidth}\n height={bodyHeight}\n fill={fill}\n data-testid={`candle-body-${label}`}\n data-bullish={isBullish}\n />\n {showWicks && (\n <>\n <line\n x1={x}\n y1={highY}\n x2={x}\n y2={bodyTop}\n stroke={WICK_COLOR}\n strokeWidth={1}\n data-testid={`wick-high-${label}`}\n />\n <line\n x1={x}\n y1={bodyBottom}\n x2={x}\n y2={lowY}\n stroke={WICK_COLOR}\n strokeWidth={1}\n data-testid={`wick-low-${label}`}\n />\n </>\n )}\n </g>\n )\n}\n\nfunction YAxisTicks({\n domainMin,\n domainMax,\n innerHeight,\n tickCount,\n format,\n}: {\n domainMin: number\n domainMax: number\n innerHeight: number\n tickCount: number\n format?: (v: number) => string\n}) {\n const ticks = useMemo(() => {\n const step = (domainMax - domainMin) / (tickCount - 1)\n return Array.from({ length: tickCount }, (_, i) => domainMin + i * step)\n }, [domainMin, domainMax, tickCount])\n\n const yScale = (v: number) => innerHeight - ((v - domainMin) / (domainMax - domainMin)) * innerHeight\n\n return (\n <g data-testid=\"y-axis\">\n <line y1={0} y2={innerHeight} stroke=\"currentColor\" strokeWidth={1} />\n {ticks.map((tick, i) => (\n <g key={i} transform={`translate(0, ${yScale(tick)})`}>\n <line x1={0} x2={-6} stroke=\"currentColor\" strokeWidth={1} />\n <text\n x={-10}\n textAnchor=\"end\"\n dominantBaseline=\"middle\"\n fontSize={11}\n fill=\"currentColor\"\n className=\"text-dc-text-secondary\"\n >\n {format ? format(tick) : tick.toLocaleString()}\n </text>\n <line x1={0} x2=\"100%\" stroke=\"currentColor\" strokeOpacity={0.1} strokeWidth={1} />\n </g>\n ))}\n </g>\n )\n}\n\nconst CandlestickChart = React.memo(function CandlestickChart({\n data,\n chartConfig,\n displayConfig = {},\n height = '100%',\n onDataPointClick,\n drillEnabled,\n}: ChartProps) {\n const { t } = useTranslation()\n const containerRef = useRef<HTMLDivElement>(null)\n const [dimensions, setDimensions] = useState({ width: 0, height: 0 })\n\n useLayoutEffect(() => {\n const el = containerRef.current\n if (!el) return\n const observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const { width, height: h } = entry.contentRect\n if (width > 0 && h > 0) setDimensions({ width, height: h })\n }\n })\n observer.observe(el)\n const rect = el.getBoundingClientRect()\n if (rect.width > 0 && rect.height > 0) setDimensions({ width: rect.width, height: rect.height })\n return () => observer.disconnect()\n }, [])\n\n const bullColor = displayConfig?.bullColor ?? BULL_COLOR_DEFAULT\n const bearColor = displayConfig?.bearColor ?? BEAR_COLOR_DEFAULT\n const showWicks = displayConfig?.showWicks ?? true\n const rangeMode = displayConfig?.rangeMode ?? 'ohlc'\n const yAxisFormat = displayConfig?.leftYAxisFormat\n\n const { xField, openField, closeField, highField, lowField, configError } = useMemo(() => {\n const xField = Array.isArray(chartConfig?.xAxis)\n ? chartConfig.xAxis[0]\n : chartConfig?.xAxis ?? chartConfig?.x\n\n const yAxisFields: string[] = Array.isArray(chartConfig?.yAxis)\n ? chartConfig.yAxis\n : []\n\n const openField = yAxisFields[0] ?? ''\n const closeField = (rangeMode === 'range' ? yAxisFields[0] : yAxisFields[1]) ?? ''\n const highField = (rangeMode === 'range' ? yAxisFields[0] : yAxisFields[2]) ?? ''\n const lowField = (rangeMode === 'range' ? yAxisFields[1] : yAxisFields[3]) ?? ''\n\n if (!xField) {\n return {\n xField,\n openField,\n closeField,\n highField,\n lowField,\n configError: 'Candlestick chart requires an X-Axis (time or category dimension)',\n }\n }\n\n if (rangeMode === 'range' && (!highField || !lowField)) {\n return {\n xField,\n openField,\n closeField,\n highField,\n lowField,\n configError: 'Range mode requires at least 2 measures (high, low) in Y-Axis',\n }\n }\n\n if (rangeMode === 'ohlc' && (!openField || !closeField)) {\n return {\n xField,\n openField,\n closeField,\n highField,\n lowField,\n configError: 'OHLC mode requires at least 2 measures (open, close) in Y-Axis',\n }\n }\n\n return { xField, openField, closeField, highField, lowField, configError: null }\n }, [chartConfig, rangeMode])\n\n const candles: CandleData[] = useMemo(() => {\n if (configError || !data || data.length === 0) return []\n const rows = (data as Record<string, unknown>[]).slice(0, MAX_CANDLES)\n const result: CandleData[] = []\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i]\n const label = String(row[xField!] ?? `Bar ${i + 1}`)\n const rawOpen = parseNum(row[openField])\n const rawClose = parseNum(row[closeField])\n if (rawOpen === null || rawClose === null) continue\n\n let open = rawOpen\n let close = rawClose\n const high = highField ? (parseNum(row[highField]) ?? Math.max(open, close)) : Math.max(open, close)\n const low = lowField ? (parseNum(row[lowField]) ?? Math.min(open, close)) : Math.min(open, close)\n\n if (rangeMode === 'range') {\n open = low\n close = high\n }\n\n result.push({\n label,\n open,\n close,\n high: Math.max(open, close, high),\n low: Math.min(open, close, low),\n isBullish: close >= open,\n originalIndex: i,\n })\n }\n return result\n }, [data, xField, openField, closeField, highField, lowField, rangeMode, configError])\n\n try {\n if (!data || data.length === 0) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">{t('chart.runtime.noData')}</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">{t('chart.runtime.noDataHint.candlestick')}</div>\n </div>\n </div>\n )\n }\n\n if (configError) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-warning\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">{t('chart.runtime.configError')}</div>\n <div className=\"dc:text-xs\">{configError}</div>\n </div>\n </div>\n )\n }\n const margin = { top: 20, right: 20, bottom: 60, left: 70 }\n const containerWidth = dimensions.width || 600\n const containerHeight =\n typeof height === 'number' ? height : dimensions.height || 400\n const innerWidth = Math.max(containerWidth - margin.left - margin.right, 50)\n const innerHeight = Math.max(\n (typeof containerHeight === 'number' ? containerHeight : parseInt(String(containerHeight)) || 400) -\n margin.top -\n margin.bottom,\n 50\n )\n\n const allValues = candles.flatMap((c) => [c.low, c.high])\n const rawMin = Math.min(...allValues)\n const rawMax = Math.max(...allValues)\n const pad = (rawMax - rawMin) * 0.05 || 1\n const domainMin = rawMin - pad\n const domainMax = rawMax + pad\n\n const yScale = (v: number) =>\n innerHeight - ((v - domainMin) / (domainMax - domainMin)) * innerHeight\n\n const candleSpacing = innerWidth / candles.length\n const candleWidth = Math.min(candleSpacing * 0.7, 20)\n\n const isTruncated = (data as unknown[]).length > MAX_CANDLES\n\n return (\n <div ref={containerRef} className=\"dc:relative dc:w-full\" style={{ height }}>\n <svg\n width=\"100%\"\n height={isTruncated ? 'calc(100% - 20px)' : '100%'}\n viewBox={`0 0 ${containerWidth} ${typeof containerHeight === 'number' ? containerHeight : 400}`}\n data-testid=\"candlestick-svg\"\n >\n <g transform={`translate(${margin.left}, ${margin.top})`}>\n <YAxisTicks\n domainMin={domainMin}\n domainMax={domainMax}\n innerHeight={innerHeight}\n tickCount={5}\n format={yAxisFormat ? (v) => formatAxisValue(v, yAxisFormat) : undefined}\n />\n\n {candles.map((candle, i) => {\n const cx = candleSpacing * i + candleSpacing / 2\n return (\n <g\n key={candle.label + i}\n onClick={(event: React.MouseEvent) => {\n if (onDataPointClick && drillEnabled) {\n onDataPointClick({\n dataPoint: { ...candle },\n clickedField: xField ?? '',\n xValue: candle.label,\n position: { x: event.clientX, y: event.clientY },\n nativeEvent: event,\n })\n }\n }}\n cursor={drillEnabled ? 'pointer' : undefined}\n >\n <title>{`${candle.label}: O=${candle.open} H=${candle.high} L=${candle.low} C=${candle.close}`}</title>\n <Candle\n x={cx}\n candleWidth={candleWidth}\n openY={yScale(candle.open)}\n closeY={yScale(candle.close)}\n highY={yScale(candle.high)}\n lowY={yScale(candle.low)}\n isBullish={candle.isBullish}\n bullColor={bullColor}\n bearColor={bearColor}\n showWicks={showWicks}\n label={candle.label}\n />\n <text\n x={cx}\n y={innerHeight + 20}\n textAnchor=\"middle\"\n fontSize={10}\n fill=\"currentColor\"\n className=\"text-dc-text-secondary\"\n data-testid={`x-label-${candle.label}`}\n >\n {candle.label}\n </text>\n </g>\n )\n })}\n </g>\n </svg>\n {isTruncated && (\n <div className=\"dc:text-xs text-dc-warning dc:text-center dc:mt-1\">\n {t('chart.runtime.candlestick.truncated', {\n max: MAX_CANDLES,\n total: (data as unknown[]).length\n })}\n </div>\n )}\n </div>\n )\n } catch (error) {\n return (\n <div className=\"dc:flex dc:flex-col dc:items-center dc:justify-center dc:w-full text-dc-error dc:p-4\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">{t('chart.runtime.chartError', { chartType: 'Candlestick Chart' })}</div>\n <div className=\"dc:text-xs dc:mb-2\">{error instanceof Error ? error.message : t('chart.runtime.unknownError')}</div>\n <div className=\"dc:text-xs text-dc-text-muted\">{t('chart.runtime.checkConfig')}</div>\n </div>\n </div>\n )\n }\n})\n\nexport default CandlestickChart\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"chart-candlestick-oSPk-KQp.js","names":[],"sources":["../../../src/client/components/charts/CandlestickChart.tsx"],"sourcesContent":["import React, { useLayoutEffect, useMemo, useRef, useState } from 'react'\nimport { useTranslation } from '../../hooks/useTranslation'\nimport { formatAxisValue } from '../../utils/chartUtils'\nimport type { ChartProps } from '../../types'\n\nconst BULL_COLOR_DEFAULT = '#22c55e'\nconst BEAR_COLOR_DEFAULT = '#ef4444'\nconst WICK_COLOR = '#94a3b8'\nconst MAX_CANDLES = 200\n\ninterface CandleData {\n label: string\n open: number\n close: number\n high: number\n low: number\n isBullish: boolean\n originalIndex: number\n}\n\nfunction parseNum(v: unknown): number | null {\n if (v === undefined || v === null) return null\n const n = typeof v === 'number' ? v : parseFloat(String(v))\n return isNaN(n) ? null : n\n}\n\nfunction Candle({\n x,\n candleWidth,\n openY,\n closeY,\n highY,\n lowY,\n isBullish,\n bullColor,\n bearColor,\n showWicks,\n label,\n}: {\n x: number\n candleWidth: number\n openY: number\n closeY: number\n highY: number\n lowY: number\n isBullish: boolean\n bullColor: string\n bearColor: string\n showWicks: boolean\n label: string\n}) {\n const fill = isBullish ? bullColor : bearColor\n const bodyTop = Math.min(openY, closeY)\n const bodyBottom = Math.max(openY, closeY)\n const bodyHeight = Math.max(bodyBottom - bodyTop, 1)\n const halfWidth = candleWidth / 2\n\n return (\n <g data-testid={`candle-${label}`}>\n <rect\n x={x - halfWidth}\n y={bodyTop}\n width={candleWidth}\n height={bodyHeight}\n fill={fill}\n data-testid={`candle-body-${label}`}\n data-bullish={isBullish}\n />\n {showWicks && (\n <>\n <line\n x1={x}\n y1={highY}\n x2={x}\n y2={bodyTop}\n stroke={WICK_COLOR}\n strokeWidth={1}\n data-testid={`wick-high-${label}`}\n />\n <line\n x1={x}\n y1={bodyBottom}\n x2={x}\n y2={lowY}\n stroke={WICK_COLOR}\n strokeWidth={1}\n data-testid={`wick-low-${label}`}\n />\n </>\n )}\n </g>\n )\n}\n\nfunction YAxisTicks({\n domainMin,\n domainMax,\n innerHeight,\n tickCount,\n format,\n}: {\n domainMin: number\n domainMax: number\n innerHeight: number\n tickCount: number\n format?: (v: number) => string\n}) {\n const ticks = useMemo(() => {\n const step = (domainMax - domainMin) / (tickCount - 1)\n return Array.from({ length: tickCount }, (_, i) => domainMin + i * step)\n }, [domainMin, domainMax, tickCount])\n\n const yScale = (v: number) => innerHeight - ((v - domainMin) / (domainMax - domainMin)) * innerHeight\n\n return (\n <g data-testid=\"y-axis\">\n <line y1={0} y2={innerHeight} stroke=\"currentColor\" strokeWidth={1} />\n {ticks.map((tick, i) => (\n <g key={i} transform={`translate(0, ${yScale(tick)})`}>\n <line x1={0} x2={-6} stroke=\"currentColor\" strokeWidth={1} />\n <text\n x={-10}\n textAnchor=\"end\"\n dominantBaseline=\"middle\"\n fontSize={11}\n fill=\"currentColor\"\n className=\"text-dc-text-secondary\"\n >\n {format ? format(tick) : tick.toLocaleString()}\n </text>\n <line x1={0} x2=\"100%\" stroke=\"currentColor\" strokeOpacity={0.1} strokeWidth={1} />\n </g>\n ))}\n </g>\n )\n}\n\nconst CandlestickChart = React.memo(function CandlestickChart({\n data,\n chartConfig,\n displayConfig = {},\n height = '100%',\n onDataPointClick,\n drillEnabled,\n}: ChartProps) {\n const { t } = useTranslation()\n const containerRef = useRef<HTMLDivElement>(null)\n const [dimensions, setDimensions] = useState({ width: 0, height: 0 })\n\n useLayoutEffect(() => {\n const el = containerRef.current\n if (!el) return\n const observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const { width, height: h } = entry.contentRect\n if (width > 0 && h > 0) setDimensions({ width, height: h })\n }\n })\n observer.observe(el)\n const rect = el.getBoundingClientRect()\n if (rect.width > 0 && rect.height > 0) setDimensions({ width: rect.width, height: rect.height })\n return () => observer.disconnect()\n }, [])\n\n const bullColor = displayConfig?.bullColor ?? BULL_COLOR_DEFAULT\n const bearColor = displayConfig?.bearColor ?? BEAR_COLOR_DEFAULT\n const showWicks = displayConfig?.showWicks ?? true\n const rangeMode = displayConfig?.rangeMode ?? 'ohlc'\n const yAxisFormat = displayConfig?.leftYAxisFormat\n\n const { xField, openField, closeField, highField, lowField, configError } = useMemo(() => {\n const xField = Array.isArray(chartConfig?.xAxis)\n ? chartConfig.xAxis[0]\n : chartConfig?.xAxis ?? chartConfig?.x\n\n const yAxisFields: string[] = Array.isArray(chartConfig?.yAxis)\n ? chartConfig.yAxis\n : []\n\n const openField = yAxisFields[0] ?? ''\n const closeField = (rangeMode === 'range' ? yAxisFields[0] : yAxisFields[1]) ?? ''\n const highField = (rangeMode === 'range' ? yAxisFields[0] : yAxisFields[2]) ?? ''\n const lowField = (rangeMode === 'range' ? yAxisFields[1] : yAxisFields[3]) ?? ''\n\n if (!xField) {\n return {\n xField,\n openField,\n closeField,\n highField,\n lowField,\n configError: 'Candlestick chart requires an X-Axis (time or category dimension)',\n }\n }\n\n if (rangeMode === 'range' && (!highField || !lowField)) {\n return {\n xField,\n openField,\n closeField,\n highField,\n lowField,\n configError: 'Range mode requires at least 2 measures (high, low) in Y-Axis',\n }\n }\n\n if (rangeMode === 'ohlc' && (!openField || !closeField)) {\n return {\n xField,\n openField,\n closeField,\n highField,\n lowField,\n configError: 'OHLC mode requires at least 2 measures (open, close) in Y-Axis',\n }\n }\n\n return { xField, openField, closeField, highField, lowField, configError: null }\n }, [chartConfig, rangeMode])\n\n const candles: CandleData[] = useMemo(() => {\n if (configError || !data || data.length === 0) return []\n const rows = (data as Record<string, unknown>[]).slice(0, MAX_CANDLES)\n const result: CandleData[] = []\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i]\n const label = String(row[xField!] ?? `Bar ${i + 1}`)\n const rawOpen = parseNum(row[openField])\n const rawClose = parseNum(row[closeField])\n if (rawOpen === null || rawClose === null) continue\n\n let open = rawOpen\n let close = rawClose\n const high = highField ? (parseNum(row[highField]) ?? Math.max(open, close)) : Math.max(open, close)\n const low = lowField ? (parseNum(row[lowField]) ?? Math.min(open, close)) : Math.min(open, close)\n\n if (rangeMode === 'range') {\n open = low\n close = high\n }\n\n result.push({\n label,\n open,\n close,\n high: Math.max(open, close, high),\n low: Math.min(open, close, low),\n isBullish: close >= open,\n originalIndex: i,\n })\n }\n return result\n }, [data, xField, openField, closeField, highField, lowField, rangeMode, configError])\n\n try {\n if (!data || data.length === 0) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">{t('chart.runtime.noData')}</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">{t('chart.runtime.noDataHint.candlestick')}</div>\n </div>\n </div>\n )\n }\n\n if (configError) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-warning\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">{t('chart.runtime.configError')}</div>\n <div className=\"dc:text-xs\">{configError}</div>\n </div>\n </div>\n )\n }\n const margin = { top: 20, right: 20, bottom: 60, left: 70 }\n const containerWidth = dimensions.width || 600\n const containerHeight =\n typeof height === 'number' ? height : dimensions.height || 400\n const innerWidth = Math.max(containerWidth - margin.left - margin.right, 50)\n const innerHeight = Math.max(\n (typeof containerHeight === 'number' ? containerHeight : parseInt(String(containerHeight)) || 400) -\n margin.top -\n margin.bottom,\n 50\n )\n\n const allValues = candles.flatMap((c) => [c.low, c.high])\n const rawMin = Math.min(...allValues)\n const rawMax = Math.max(...allValues)\n const pad = (rawMax - rawMin) * 0.05 || 1\n const domainMin = rawMin - pad\n const domainMax = rawMax + pad\n\n const yScale = (v: number) =>\n innerHeight - ((v - domainMin) / (domainMax - domainMin)) * innerHeight\n\n const candleSpacing = innerWidth / candles.length\n const candleWidth = Math.min(candleSpacing * 0.7, 20)\n\n const isTruncated = (data as unknown[]).length > MAX_CANDLES\n\n return (\n <div ref={containerRef} className=\"dc:relative dc:w-full\" style={{ height }}>\n <svg\n width=\"100%\"\n height={isTruncated ? 'calc(100% - 20px)' : '100%'}\n viewBox={`0 0 ${containerWidth} ${typeof containerHeight === 'number' ? containerHeight : 400}`}\n data-testid=\"candlestick-svg\"\n >\n <g transform={`translate(${margin.left}, ${margin.top})`}>\n <YAxisTicks\n domainMin={domainMin}\n domainMax={domainMax}\n innerHeight={innerHeight}\n tickCount={5}\n format={yAxisFormat ? (v) => formatAxisValue(v, yAxisFormat) : undefined}\n />\n\n {candles.map((candle, i) => {\n const cx = candleSpacing * i + candleSpacing / 2\n return (\n <g\n key={candle.label + i}\n onClick={(event: React.MouseEvent) => {\n if (onDataPointClick && drillEnabled) {\n onDataPointClick({\n dataPoint: { ...candle },\n clickedField: xField ?? '',\n xValue: candle.label,\n position: { x: event.clientX, y: event.clientY },\n nativeEvent: event,\n })\n }\n }}\n cursor={drillEnabled ? 'pointer' : undefined}\n >\n <title>{`${candle.label}: O=${candle.open} H=${candle.high} L=${candle.low} C=${candle.close}`}</title>\n <Candle\n x={cx}\n candleWidth={candleWidth}\n openY={yScale(candle.open)}\n closeY={yScale(candle.close)}\n highY={yScale(candle.high)}\n lowY={yScale(candle.low)}\n isBullish={candle.isBullish}\n bullColor={bullColor}\n bearColor={bearColor}\n showWicks={showWicks}\n label={candle.label}\n />\n <text\n x={cx}\n y={innerHeight + 20}\n textAnchor=\"middle\"\n fontSize={10}\n fill=\"currentColor\"\n className=\"text-dc-text-secondary\"\n data-testid={`x-label-${candle.label}`}\n >\n {candle.label}\n </text>\n </g>\n )\n })}\n </g>\n </svg>\n {isTruncated && (\n <div className=\"dc:text-xs text-dc-warning dc:text-center dc:mt-1\">\n {t('chart.runtime.candlestick.truncated', {\n max: MAX_CANDLES,\n total: (data as unknown[]).length\n })}\n </div>\n )}\n </div>\n )\n } catch (error) {\n return (\n <div className=\"dc:flex dc:flex-col dc:items-center dc:justify-center dc:w-full text-dc-error dc:p-4\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">{t('chart.runtime.chartError', { chartType: 'Candlestick Chart' })}</div>\n <div className=\"dc:text-xs dc:mb-2\">{error instanceof Error ? error.message : t('chart.runtime.unknownError')}</div>\n <div className=\"dc:text-xs text-dc-text-muted\">{t('chart.runtime.checkConfig')}</div>\n </div>\n </div>\n )\n }\n})\n\nexport default CandlestickChart\n"],"mappings":"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"}
|
|
@@ -4,6 +4,13 @@ var t = /* @__PURE__ */ e({ activityGridChartConfig: () => n }), n = {
|
|
|
4
4
|
label: "chart.activityGrid.label",
|
|
5
5
|
description: "chart.activityGrid.description",
|
|
6
6
|
useCase: "chart.activityGrid.useCase",
|
|
7
|
+
isAvailable: ({ measureCount: e, timeDimensionCount: t }) => e < 1 ? {
|
|
8
|
+
available: !1,
|
|
9
|
+
reason: "chart.availability.requiresMeasure"
|
|
10
|
+
} : t < 1 ? {
|
|
11
|
+
available: !1,
|
|
12
|
+
reason: "chart.availability.requiresTimeDimension"
|
|
13
|
+
} : { available: !0 },
|
|
7
14
|
dropZones: [{
|
|
8
15
|
key: "dateField",
|
|
9
16
|
label: "chart.configText.time_dimension",
|
|
@@ -48,4 +55,4 @@ var t = /* @__PURE__ */ e({ activityGridChartConfig: () => n }), n = {
|
|
|
48
55
|
//#endregion
|
|
49
56
|
export { n, t };
|
|
50
57
|
|
|
51
|
-
//# sourceMappingURL=chart-config-activity-grid-
|
|
58
|
+
//# sourceMappingURL=chart-config-activity-grid-Dssynumw.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-config-activity-grid-Dssynumw.js","names":[],"sources":["../../../src/client/components/charts/ActivityGridChart.config.ts"],"sourcesContent":["import type { ChartTypeConfig } from '../../charts/chartConfigs'\n\n/**\n * Configuration for the activity grid chart type\n */\nexport const activityGridChartConfig: ChartTypeConfig = {\n label: 'chart.activityGrid.label',\n description: 'chart.activityGrid.description',\n useCase: 'chart.activityGrid.useCase',\n isAvailable: ({ measureCount, timeDimensionCount }) => {\n if (measureCount < 1) return { available: false, reason: 'chart.availability.requiresMeasure' }\n if (timeDimensionCount < 1) return { available: false, reason: 'chart.availability.requiresTimeDimension' }\n return { available: true }\n },\n dropZones: [\n {\n key: 'dateField',\n label: 'chart.configText.time_dimension',\n description: 'chart.configText.time_field_that_determines_grid_structure_granularity_affects_layout',\n mandatory: true,\n maxItems: 1,\n acceptTypes: ['timeDimension'],\n emptyText: 'chart.activityGrid.dropZone.dateField.empty'\n },\n {\n key: 'valueField',\n label: 'chart.configText.activity_measure',\n description: 'chart.configText.measure_used_for_activity_intensity_color_coding',\n mandatory: true,\n maxItems: 1,\n acceptTypes: ['measure'],\n emptyText: 'chart.activityGrid.dropZone.valueField.empty'\n }\n ],\n displayOptions: ['showLabels', 'showTooltip', 'hideHeader'],\n displayOptionsConfig: [\n {\n key: 'fitToWidth',\n label: 'chart.option.fitToWidth.label',\n type: 'boolean',\n defaultValue: false,\n description: 'chart.option.fitToWidth.description'\n }\n ],\n validate: (config) => {\n const { dateField, valueField } = config\n\n if (!dateField || (Array.isArray(dateField) && dateField.length === 0)) {\n return {\n isValid: false,\n message: 'chart.activityGrid.validation.timeDimensionRequired'\n }\n }\n\n if (!valueField || (Array.isArray(valueField) && valueField.length === 0)) {\n return {\n isValid: false,\n message: 'chart.activityGrid.validation.measureRequired'\n }\n }\n\n return { isValid: true }\n },\n clickableElements: { cell: true }\n}"],"mappings":";;iEAKa,IAA2C;CACtD,OAAO;CACP,aAAa;CACb,SAAS;CACT,cAAc,EAAE,iBAAc,4BACxB,IAAe,IAAU;EAAE,WAAW;EAAO,QAAQ;EAAsC,GAC3F,IAAqB,IAAU;EAAE,WAAW;EAAO,QAAQ;EAA4C,GACpG,EAAE,WAAW,IAAM;CAE5B,WAAW,CACT;EACE,KAAK;EACL,OAAO;EACP,aAAa;EACb,WAAW;EACX,UAAU;EACV,aAAa,CAAC,gBAAgB;EAC9B,WAAW;EACZ,EACD;EACE,KAAK;EACL,OAAO;EACP,aAAa;EACb,WAAW;EACX,UAAU;EACV,aAAa,CAAC,UAAU;EACxB,WAAW;EACZ,CACF;CACD,gBAAgB;EAAC;EAAc;EAAe;EAAa;CAC3D,sBAAsB,CACpB;EACE,KAAK;EACL,OAAO;EACP,MAAM;EACN,cAAc;EACd,aAAa;EACd,CACF;CACD,WAAW,MAAW;EACpB,IAAM,EAAE,cAAW,kBAAe;AAgBlC,SAdI,CAAC,KAAc,MAAM,QAAQ,EAAU,IAAI,EAAU,WAAW,IAC3D;GACL,SAAS;GACT,SAAS;GACV,GAGC,CAAC,KAAe,MAAM,QAAQ,EAAW,IAAI,EAAW,WAAW,IAC9D;GACL,SAAS;GACT,SAAS;GACV,GAGI,EAAE,SAAS,IAAM;;CAE1B,mBAAmB,EAAE,MAAM,IAAM"}
|
|
@@ -4,6 +4,13 @@ var t = /* @__PURE__ */ e({ areaChartConfig: () => n }), n = {
|
|
|
4
4
|
label: "chart.area.label",
|
|
5
5
|
description: "chart.area.description",
|
|
6
6
|
useCase: "chart.area.useCase",
|
|
7
|
+
isAvailable: ({ measureCount: e, dimensionCount: t }) => e < 1 ? {
|
|
8
|
+
available: !1,
|
|
9
|
+
reason: "chart.availability.requiresMeasure"
|
|
10
|
+
} : t < 1 ? {
|
|
11
|
+
available: !1,
|
|
12
|
+
reason: "chart.availability.requiresDimension"
|
|
13
|
+
} : { available: !0 },
|
|
7
14
|
dropZones: [
|
|
8
15
|
{
|
|
9
16
|
key: "xAxis",
|
|
@@ -90,4 +97,4 @@ var t = /* @__PURE__ */ e({ areaChartConfig: () => n }), n = {
|
|
|
90
97
|
//#endregion
|
|
91
98
|
export { n, t };
|
|
92
99
|
|
|
93
|
-
//# sourceMappingURL=chart-config-area-
|
|
100
|
+
//# sourceMappingURL=chart-config-area-40fbx2Ah.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-config-area-40fbx2Ah.js","names":[],"sources":["../../../src/client/components/charts/AreaChart.config.ts"],"sourcesContent":["import type { ChartTypeConfig } from '../../charts/chartConfigs'\n\n/**\n * Configuration for the area chart type\n */\nexport const areaChartConfig: ChartTypeConfig = {\n label: 'chart.area.label',\n description: 'chart.area.description',\n useCase: 'chart.area.useCase',\n isAvailable: ({ measureCount, dimensionCount }) => {\n if (measureCount < 1) return { available: false, reason: 'chart.availability.requiresMeasure' }\n if (dimensionCount < 1) return { available: false, reason: 'chart.availability.requiresDimension' }\n return { available: true }\n },\n dropZones: [\n {\n key: 'xAxis',\n label: 'chart.configText.x_axis_time_categories',\n description: 'chart.configText.time_dimensions_or_dimensions_for_x_axis',\n mandatory: true,\n acceptTypes: ['dimension', 'timeDimension'],\n emptyText: 'chart.area.dropZone.xAxis.empty'\n },\n {\n key: 'yAxis',\n label: 'chart.dropZone.yAxis.label',\n description: 'chart.configText.measures_for_area_values',\n mandatory: true,\n acceptTypes: ['measure'],\n emptyText: 'chart.area.dropZone.yAxis.empty',\n enableDualAxis: true\n },\n {\n key: 'series',\n label: 'chart.configText.series_stack_areas',\n description: 'chart.configText.dimensions_to_create_stacked_areas',\n mandatory: false,\n acceptTypes: ['dimension'],\n emptyText: 'chart.area.dropZone.series.empty'\n }\n ],\n displayOptions: ['showLegend', 'showGrid', 'showTooltip', 'hideHeader'],\n displayOptionsConfig: [\n {\n key: 'stackType',\n label: 'chart.option.stacking.label',\n type: 'select',\n defaultValue: 'none',\n options: [\n { value: 'none', label: 'chart.option.accentBorder.none' },\n { value: 'normal', label: 'chart.option.stacking.stacked' },\n { value: 'percent', label: 'chart.option.stacking.percent' }\n ],\n description: 'chart.configText.how_to_stack_multiple_area_series'\n },\n {\n key: 'connectNulls',\n label: 'chart.option.connectNulls.label',\n type: 'boolean',\n defaultValue: false,\n description: 'chart.option.connectNulls.description'\n },\n {\n key: 'target',\n label: 'chart.option.target.label',\n type: 'string',\n placeholder: 'e.g., 100 or 50,75 for spread',\n description: 'chart.option.target.description'\n },\n {\n key: 'leftYAxisFormat',\n label: 'chart.option.leftYAxisFormat.label',\n type: 'axisFormat',\n description: 'chart.option.leftYAxisFormat.description'\n },\n {\n key: 'rightYAxisFormat',\n label: 'chart.option.rightYAxisFormat.label',\n type: 'axisFormat',\n description: 'chart.option.rightYAxisFormat.description'\n }\n ]\n}"],"mappings":";;yDAKa,IAAmC;CAC9C,OAAO;CACP,aAAa;CACb,SAAS;CACT,cAAc,EAAE,iBAAc,wBACxB,IAAe,IAAU;EAAE,WAAW;EAAO,QAAQ;EAAsC,GAC3F,IAAiB,IAAU;EAAE,WAAW;EAAO,QAAQ;EAAwC,GAC5F,EAAE,WAAW,IAAM;CAE5B,WAAW;EACT;GACE,KAAK;GACL,OAAO;GACP,aAAa;GACb,WAAW;GACX,aAAa,CAAC,aAAa,gBAAgB;GAC3C,WAAW;GACZ;EACD;GACE,KAAK;GACL,OAAO;GACP,aAAa;GACb,WAAW;GACX,aAAa,CAAC,UAAU;GACxB,WAAW;GACX,gBAAgB;GACjB;EACD;GACE,KAAK;GACL,OAAO;GACP,aAAa;GACb,WAAW;GACX,aAAa,CAAC,YAAY;GAC1B,WAAW;GACZ;EACF;CACD,gBAAgB;EAAC;EAAc;EAAY;EAAe;EAAa;CACvE,sBAAsB;EACpB;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,cAAc;GACd,SAAS;IACP;KAAE,OAAO;KAAQ,OAAO;KAAkC;IAC1D;KAAE,OAAO;KAAU,OAAO;KAAiC;IAC3D;KAAE,OAAO;KAAW,OAAO;KAAiC;IAC7D;GACD,aAAa;GACd;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,cAAc;GACd,aAAa;GACd;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,aAAa;GACd;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACd;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACd;EACF"}
|
|
@@ -5,6 +5,13 @@ var t = /* @__PURE__ */ e({ barChartConfig: () => n }), n = {
|
|
|
5
5
|
description: "chart.bar.description",
|
|
6
6
|
useCase: "chart.bar.useCase",
|
|
7
7
|
clickableElements: { bar: !0 },
|
|
8
|
+
isAvailable: ({ measureCount: e, dimensionCount: t }) => e < 1 ? {
|
|
9
|
+
available: !1,
|
|
10
|
+
reason: "chart.availability.requiresMeasure"
|
|
11
|
+
} : t < 1 ? {
|
|
12
|
+
available: !1,
|
|
13
|
+
reason: "chart.availability.requiresDimension"
|
|
14
|
+
} : { available: !0 },
|
|
8
15
|
dropZones: [
|
|
9
16
|
{
|
|
10
17
|
key: "xAxis",
|
|
@@ -84,4 +91,4 @@ var t = /* @__PURE__ */ e({ barChartConfig: () => n }), n = {
|
|
|
84
91
|
//#endregion
|
|
85
92
|
export { n, t };
|
|
86
93
|
|
|
87
|
-
//# sourceMappingURL=chart-config-bar-
|
|
94
|
+
//# sourceMappingURL=chart-config-bar-CUWHwOPN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-config-bar-CUWHwOPN.js","names":[],"sources":["../../../src/client/components/charts/BarChart.config.ts"],"sourcesContent":["import type { ChartTypeConfig } from '../../charts/chartConfigs'\n\n/**\n * Configuration for the bar chart type\n */\nexport const barChartConfig: ChartTypeConfig = {\n label: 'chart.bar.label',\n description: 'chart.bar.description',\n useCase: 'chart.bar.useCase',\n clickableElements: { bar: true },\n isAvailable: ({ measureCount, dimensionCount }) => {\n if (measureCount < 1) return { available: false, reason: 'chart.availability.requiresMeasure' }\n if (dimensionCount < 1) return { available: false, reason: 'chart.availability.requiresDimension' }\n return { available: true }\n },\n dropZones: [\n {\n key: 'xAxis',\n label: 'chart.dropZone.xAxis.label',\n description: 'chart.dropZone.xAxis.description',\n mandatory: false,\n acceptTypes: ['dimension', 'timeDimension'],\n emptyText: 'chart.bar.dropZone.xAxis.empty'\n },\n {\n key: 'yAxis',\n label: 'chart.dropZone.yAxis.label',\n description: 'chart.configText.measures_for_bar_heights',\n mandatory: true,\n acceptTypes: ['measure'],\n emptyText: 'chart.bar.dropZone.yAxis.empty',\n enableDualAxis: true\n },\n {\n key: 'series',\n label: 'chart.dropZone.series.label',\n description: 'chart.dropZone.series.description',\n mandatory: false,\n acceptTypes: ['dimension'],\n emptyText: 'chart.bar.dropZone.series.empty'\n }\n ],\n displayOptions: ['showLegend', 'showGrid', 'showTooltip', 'hideHeader'],\n displayOptionsConfig: [\n {\n key: 'stackType',\n label: 'chart.option.stacking.label',\n type: 'select',\n defaultValue: 'none',\n options: [\n { value: 'none', label: 'chart.option.accentBorder.none' },\n { value: 'normal', label: 'chart.option.stacking.stacked' },\n { value: 'percent', label: 'chart.option.stacking.percent' }\n ],\n description: 'chart.configText.how_to_stack_multiple_bar_series'\n },\n {\n key: 'target',\n label: 'chart.option.target.label',\n type: 'string',\n placeholder: 'e.g., 100 or 50,75 for spread',\n description: 'chart.option.target.description'\n },\n {\n key: 'leftYAxisFormat',\n label: 'chart.option.leftYAxisFormat.label',\n type: 'axisFormat',\n description: 'chart.option.leftYAxisFormat.description'\n },\n {\n key: 'rightYAxisFormat',\n label: 'chart.option.rightYAxisFormat.label',\n type: 'axisFormat',\n description: 'chart.option.rightYAxisFormat.description'\n }\n ]\n}"],"mappings":";;wDAKa,IAAkC;CAC7C,OAAO;CACP,aAAa;CACb,SAAS;CACT,mBAAmB,EAAE,KAAK,IAAM;CAChC,cAAc,EAAE,iBAAc,wBACxB,IAAe,IAAU;EAAE,WAAW;EAAO,QAAQ;EAAsC,GAC3F,IAAiB,IAAU;EAAE,WAAW;EAAO,QAAQ;EAAwC,GAC5F,EAAE,WAAW,IAAM;CAE5B,WAAW;EACT;GACE,KAAK;GACL,OAAO;GACP,aAAa;GACb,WAAW;GACX,aAAa,CAAC,aAAa,gBAAgB;GAC3C,WAAW;GACZ;EACD;GACE,KAAK;GACL,OAAO;GACP,aAAa;GACb,WAAW;GACX,aAAa,CAAC,UAAU;GACxB,WAAW;GACX,gBAAgB;GACjB;EACD;GACE,KAAK;GACL,OAAO;GACP,aAAa;GACb,WAAW;GACX,aAAa,CAAC,YAAY;GAC1B,WAAW;GACZ;EACF;CACD,gBAAgB;EAAC;EAAc;EAAY;EAAe;EAAa;CACvE,sBAAsB;EACpB;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,cAAc;GACd,SAAS;IACP;KAAE,OAAO;KAAQ,OAAO;KAAkC;IAC1D;KAAE,OAAO;KAAU,OAAO;KAAiC;IAC3D;KAAE,OAAO;KAAW,OAAO;KAAiC;IAC7D;GACD,aAAa;GACd;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,aAAa;GACd;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACd;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACd;EACF"}
|
package/dist/client/chunks/{chart-config-box-plot-Dwj7sEbU.js → chart-config-box-plot-D3Y0ien3.js}
RENAMED
|
@@ -4,6 +4,13 @@ var t = /* @__PURE__ */ e({ boxPlotChartConfig: () => n }), n = {
|
|
|
4
4
|
label: "chart.boxPlot.label",
|
|
5
5
|
description: "chart.boxPlot.description",
|
|
6
6
|
useCase: "chart.boxPlot.useCase",
|
|
7
|
+
isAvailable: ({ measureCount: e, dimensionCount: t }) => e < 1 ? {
|
|
8
|
+
available: !1,
|
|
9
|
+
reason: "chart.availability.requiresMeasure"
|
|
10
|
+
} : t < 1 ? {
|
|
11
|
+
available: !1,
|
|
12
|
+
reason: "chart.availability.requiresDimension"
|
|
13
|
+
} : { available: !0 },
|
|
7
14
|
displayOptions: ["hideHeader"],
|
|
8
15
|
dropZones: [{
|
|
9
16
|
key: "xAxis",
|
|
@@ -32,4 +39,4 @@ var t = /* @__PURE__ */ e({ boxPlotChartConfig: () => n }), n = {
|
|
|
32
39
|
//#endregion
|
|
33
40
|
export { n, t };
|
|
34
41
|
|
|
35
|
-
//# sourceMappingURL=chart-config-box-plot-
|
|
42
|
+
//# sourceMappingURL=chart-config-box-plot-D3Y0ien3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-config-box-plot-D3Y0ien3.js","names":[],"sources":["../../../src/client/components/charts/BoxPlotChart.config.ts"],"sourcesContent":["import type { ChartTypeConfig } from '../../charts/chartConfigs'\n\n/**\n * Configuration for the box plot chart type\n */\nexport const boxPlotChartConfig: ChartTypeConfig = {\n label: 'chart.boxPlot.label',\n description: 'chart.boxPlot.description',\n useCase: 'chart.boxPlot.useCase',\n isAvailable: ({ measureCount, dimensionCount }) => {\n if (measureCount < 1) return { available: false, reason: 'chart.availability.requiresMeasure' }\n if (dimensionCount < 1) return { available: false, reason: 'chart.availability.requiresDimension' }\n return { available: true }\n },\n displayOptions: ['hideHeader'],\n dropZones: [\n {\n key: 'xAxis',\n label: 'chart.configText.x_axis_groups',\n description: 'chart.configText.dimension_to_group_boxes_by_e_g_symbol_platform',\n mandatory: true,\n maxItems: 1,\n acceptTypes: ['dimension', 'timeDimension'],\n emptyText: 'chart.boxPlot.dropZone.xAxis.empty',\n },\n {\n key: 'yAxis',\n label: 'chart.configText.y_axis_measures',\n description: 'chart.configText.drop_1_measure_for_auto_mode_3_for_avg_stddev_median_mode_or_5_for_min_q',\n mandatory: true,\n maxItems: 5,\n acceptTypes: ['measure'],\n emptyText: 'chart.boxPlot.dropZone.yAxis.empty',\n },\n ],\n displayOptionsConfig: [\n {\n key: 'leftYAxisFormat',\n label: 'chart.option.yAxisFormat.label',\n type: 'axisFormat',\n description: 'chart.configText.number_formatting_for_the_value_axis',\n },\n ],\n}\n"],"mappings":";;4DAKa,IAAsC;CACjD,OAAO;CACP,aAAa;CACb,SAAS;CACT,cAAc,EAAE,iBAAc,wBACxB,IAAe,IAAU;EAAE,WAAW;EAAO,QAAQ;EAAsC,GAC3F,IAAiB,IAAU;EAAE,WAAW;EAAO,QAAQ;EAAwC,GAC5F,EAAE,WAAW,IAAM;CAE5B,gBAAgB,CAAC,aAAa;CAC9B,WAAW,CACT;EACE,KAAK;EACL,OAAO;EACP,aAAa;EACb,WAAW;EACX,UAAU;EACV,aAAa,CAAC,aAAa,gBAAgB;EAC3C,WAAW;EACZ,EACD;EACE,KAAK;EACL,OAAO;EACP,aAAa;EACb,WAAW;EACX,UAAU;EACV,aAAa,CAAC,UAAU;EACxB,WAAW;EACZ,CACF;CACD,sBAAsB,CACpB;EACE,KAAK;EACL,OAAO;EACP,MAAM;EACN,aAAa;EACd,CACF;CACF"}
|
package/dist/client/chunks/{chart-config-bubble-B0w0ZVp4.js → chart-config-bubble-BXSTKLn-.js}
RENAMED
|
@@ -4,6 +4,13 @@ var t = /* @__PURE__ */ e({ bubbleChartConfig: () => n }), n = {
|
|
|
4
4
|
label: "chart.bubble.label",
|
|
5
5
|
description: "chart.bubble.description",
|
|
6
6
|
useCase: "chart.bubble.useCase",
|
|
7
|
+
isAvailable: ({ measureCount: e, dimensionCount: t }) => e < 2 ? {
|
|
8
|
+
available: !1,
|
|
9
|
+
reason: "chart.availability.requiresTwoMeasures"
|
|
10
|
+
} : t < 1 ? {
|
|
11
|
+
available: !1,
|
|
12
|
+
reason: "chart.availability.bubble"
|
|
13
|
+
} : { available: !0 },
|
|
7
14
|
dropZones: [
|
|
8
15
|
{
|
|
9
16
|
key: "xAxis",
|
|
@@ -79,4 +86,4 @@ var t = /* @__PURE__ */ e({ bubbleChartConfig: () => n }), n = {
|
|
|
79
86
|
//#endregion
|
|
80
87
|
export { n, t };
|
|
81
88
|
|
|
82
|
-
//# sourceMappingURL=chart-config-bubble-
|
|
89
|
+
//# sourceMappingURL=chart-config-bubble-BXSTKLn-.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-config-bubble-BXSTKLn-.js","names":[],"sources":["../../../src/client/components/charts/BubbleChart.config.ts"],"sourcesContent":["import type { ChartTypeConfig } from '../../charts/chartConfigs'\n\n/**\n * Configuration for the bubble chart type\n */\nexport const bubbleChartConfig: ChartTypeConfig = {\n label: 'chart.bubble.label',\n description: 'chart.bubble.description',\n useCase: 'chart.bubble.useCase',\n isAvailable: ({ measureCount, dimensionCount }) => {\n if (measureCount < 2) return { available: false, reason: 'chart.availability.requiresTwoMeasures' }\n if (dimensionCount < 1) return { available: false, reason: 'chart.availability.bubble' }\n return { available: true }\n },\n dropZones: [\n {\n key: 'xAxis',\n label: 'chart.runtime.axisFormat.xAxis',\n description: 'chart.configText.horizontal_axis_position',\n mandatory: true,\n maxItems: 1,\n acceptTypes: ['dimension', 'timeDimension', 'measure'],\n emptyText: 'chart.bubble.dropZone.xAxis.empty'\n },\n {\n key: 'yAxis',\n label: 'chart.configText.y_axis', \n description: 'chart.configText.vertical_axis_position',\n mandatory: true,\n maxItems: 1,\n acceptTypes: ['measure'],\n emptyText: 'chart.bubble.dropZone.yAxis.empty'\n },\n {\n key: 'sizeField',\n label: 'chart.configText.bubble_radius',\n description: 'chart.configText.size_of_bubbles_based_on_this_measure',\n mandatory: true,\n maxItems: 1,\n acceptTypes: ['measure'],\n emptyText: 'chart.bubble.dropZone.sizeField.empty'\n },\n {\n key: 'series',\n label: 'chart.configText.bubble_labels',\n description: 'chart.configText.field_to_use_for_bubble_labels_and_identification',\n mandatory: true,\n maxItems: 1,\n acceptTypes: ['dimension'],\n emptyText: 'chart.bubble.dropZone.series.empty'\n },\n {\n key: 'colorField',\n label: 'chart.configText.bubble_colour',\n description: 'chart.configText.color_bubbles_by_this_field_optional',\n mandatory: false,\n maxItems: 1,\n acceptTypes: ['dimension', 'measure'],\n emptyText: 'chart.bubble.dropZone.colorField.empty'\n }\n ],\n displayOptions: ['showLegend', 'showGrid', 'showTooltip', 'minBubbleSize', 'maxBubbleSize', 'bubbleOpacity', 'hideHeader'],\n displayOptionsConfig: [\n {\n key: 'xAxisFormat',\n label: 'chart.option.xAxisFormat.label',\n type: 'axisFormat',\n description: 'chart.option.xAxisFormat.description'\n },\n {\n key: 'leftYAxisFormat',\n label: 'chart.option.yAxisFormat.label',\n type: 'axisFormat',\n description: 'chart.configText.number_formatting_for_y_axis_and_values'\n }\n ]\n}"],"mappings":";;2DAKa,IAAqC;CAChD,OAAO;CACP,aAAa;CACb,SAAS;CACT,cAAc,EAAE,iBAAc,wBACxB,IAAe,IAAU;EAAE,WAAW;EAAO,QAAQ;EAA0C,GAC/F,IAAiB,IAAU;EAAE,WAAW;EAAO,QAAQ;EAA6B,GACjF,EAAE,WAAW,IAAM;CAE5B,WAAW;EACT;GACE,KAAK;GACL,OAAO;GACP,aAAa;GACb,WAAW;GACX,UAAU;GACV,aAAa;IAAC;IAAa;IAAiB;IAAU;GACtD,WAAW;GACZ;EACD;GACE,KAAK;GACL,OAAO;GACP,aAAa;GACb,WAAW;GACX,UAAU;GACV,aAAa,CAAC,UAAU;GACxB,WAAW;GACZ;EACD;GACE,KAAK;GACL,OAAO;GACP,aAAa;GACb,WAAW;GACX,UAAU;GACV,aAAa,CAAC,UAAU;GACxB,WAAW;GACZ;EACD;GACE,KAAK;GACL,OAAO;GACP,aAAa;GACb,WAAW;GACX,UAAU;GACV,aAAa,CAAC,YAAY;GAC1B,WAAW;GACZ;EACD;GACE,KAAK;GACL,OAAO;GACP,aAAa;GACb,WAAW;GACX,UAAU;GACV,aAAa,CAAC,aAAa,UAAU;GACrC,WAAW;GACZ;EACF;CACD,gBAAgB;EAAC;EAAc;EAAY;EAAe;EAAiB;EAAiB;EAAiB;EAAa;CAC1H,sBAAsB,CACpB;EACE,KAAK;EACL,OAAO;EACP,MAAM;EACN,aAAa;EACd,EACD;EACE,KAAK;EACL,OAAO;EACP,MAAM;EACN,aAAa;EACd,CACF"}
|
|
@@ -6,6 +6,13 @@ var t = /* @__PURE__ */ e({ candlestickChartConfig: () => n }), n = {
|
|
|
6
6
|
useCase: "chart.candlestick.useCase",
|
|
7
7
|
clickableElements: { bar: !0 },
|
|
8
8
|
displayOptions: ["hideHeader"],
|
|
9
|
+
isAvailable: ({ measureCount: e, dimensionCount: t }) => e < 2 ? {
|
|
10
|
+
available: !1,
|
|
11
|
+
reason: "chart.availability.requiresTwoMeasures"
|
|
12
|
+
} : t < 1 ? {
|
|
13
|
+
available: !1,
|
|
14
|
+
reason: "chart.availability.requiresDimension"
|
|
15
|
+
} : { available: !0 },
|
|
9
16
|
dropZones: [{
|
|
10
17
|
key: "xAxis",
|
|
11
18
|
label: "chart.configText.x_axis_time_category",
|
|
@@ -69,4 +76,4 @@ var t = /* @__PURE__ */ e({ candlestickChartConfig: () => n }), n = {
|
|
|
69
76
|
//#endregion
|
|
70
77
|
export { n, t };
|
|
71
78
|
|
|
72
|
-
//# sourceMappingURL=chart-config-candlestick-
|
|
79
|
+
//# sourceMappingURL=chart-config-candlestick-DEuD2Av0.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-config-candlestick-DEuD2Av0.js","names":[],"sources":["../../../src/client/components/charts/CandlestickChart.config.ts"],"sourcesContent":["import type { ChartTypeConfig } from '../../charts/chartConfigs'\n\n/**\n * Configuration for the candlestick chart type\n */\nexport const candlestickChartConfig: ChartTypeConfig = {\n label: 'chart.candlestick.label',\n description: 'chart.candlestick.description',\n useCase: 'chart.candlestick.useCase',\n clickableElements: { bar: true },\n displayOptions: ['hideHeader'],\n isAvailable: ({ measureCount, dimensionCount }) => {\n if (measureCount < 2) return { available: false, reason: 'chart.availability.requiresTwoMeasures' }\n if (dimensionCount < 1) return { available: false, reason: 'chart.availability.requiresDimension' }\n return { available: true }\n },\n dropZones: [\n {\n key: 'xAxis',\n label: 'chart.configText.x_axis_time_category',\n description: 'chart.configText.time_dimension_or_category_for_each_candle_e_g_date_symbol',\n mandatory: true,\n maxItems: 1,\n acceptTypes: ['timeDimension', 'dimension'],\n emptyText: 'chart.candlestick.dropZone.xAxis.empty',\n },\n {\n key: 'yAxis',\n label: 'chart.configText.ohlc_measures_open_close_high_low',\n description: 'chart.configText.drop_2_4_measures_in_order_open_close_high_low_ohlc_mode_for_range_mode_',\n mandatory: true,\n acceptTypes: ['measure'],\n emptyText: 'chart.candlestick.dropZone.yAxis.empty',\n },\n ],\n displayOptionsConfig: [\n {\n key: 'rangeMode',\n label: 'chart.option.rangeMode.label',\n type: 'select',\n defaultValue: 'ohlc',\n options: [\n { value: 'ohlc', label: 'chart.option.rangeMode.ohlc' },\n { value: 'range', label: 'chart.option.rangeMode.range' },\n ],\n description: 'chart.option.rangeMode.description',\n },\n {\n key: 'bullColor',\n label: 'chart.option.bullColor.label',\n type: 'color',\n defaultValue: '#22c55e',\n description: 'chart.option.bullColor.description',\n },\n {\n key: 'bearColor',\n label: 'chart.option.bearColor.label',\n type: 'color',\n defaultValue: '#ef4444',\n description: 'chart.option.bearColor.description',\n },\n {\n key: 'showWicks',\n label: 'chart.option.showWicks.label',\n type: 'boolean',\n defaultValue: true,\n description: 'chart.option.showWicks.description',\n },\n {\n key: 'leftYAxisFormat',\n label: 'chart.option.yAxisFormat.label',\n type: 'axisFormat',\n description: 'chart.configText.number_formatting_for_the_price_axis',\n },\n ],\n}\n"],"mappings":";;gEAKa,IAA0C;CACrD,OAAO;CACP,aAAa;CACb,SAAS;CACT,mBAAmB,EAAE,KAAK,IAAM;CAChC,gBAAgB,CAAC,aAAa;CAC9B,cAAc,EAAE,iBAAc,wBACxB,IAAe,IAAU;EAAE,WAAW;EAAO,QAAQ;EAA0C,GAC/F,IAAiB,IAAU;EAAE,WAAW;EAAO,QAAQ;EAAwC,GAC5F,EAAE,WAAW,IAAM;CAE5B,WAAW,CACT;EACE,KAAK;EACL,OAAO;EACP,aAAa;EACb,WAAW;EACX,UAAU;EACV,aAAa,CAAC,iBAAiB,YAAY;EAC3C,WAAW;EACZ,EACD;EACE,KAAK;EACL,OAAO;EACP,aAAa;EACb,WAAW;EACX,aAAa,CAAC,UAAU;EACxB,WAAW;EACZ,CACF;CACD,sBAAsB;EACpB;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,cAAc;GACd,SAAS,CACP;IAAE,OAAO;IAAQ,OAAO;IAA+B,EACvD;IAAE,OAAO;IAAS,OAAO;IAAgC,CAC1D;GACD,aAAa;GACd;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,cAAc;GACd,aAAa;GACd;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,cAAc;GACd,aAAa;GACd;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,cAAc;GACd,aAAa;GACd;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACd;EACF;CACF"}
|
package/dist/client/chunks/{chart-config-gauge-C5ZiyZy7.js → chart-config-gauge-CCva3FfA.js}
RENAMED
|
@@ -6,6 +6,10 @@ var t = /* @__PURE__ */ e({ gaugeChartConfig: () => n }), n = {
|
|
|
6
6
|
useCase: "chart.gauge.useCase",
|
|
7
7
|
clickableElements: {},
|
|
8
8
|
displayOptions: ["hideHeader"],
|
|
9
|
+
isAvailable: ({ measureCount: e }) => e < 1 ? {
|
|
10
|
+
available: !1,
|
|
11
|
+
reason: "chart.availability.requiresMeasure"
|
|
12
|
+
} : { available: !0 },
|
|
9
13
|
dropZones: [{
|
|
10
14
|
key: "yAxis",
|
|
11
15
|
label: "chart.configText.value_measure",
|
|
@@ -61,4 +65,4 @@ var t = /* @__PURE__ */ e({ gaugeChartConfig: () => n }), n = {
|
|
|
61
65
|
//#endregion
|
|
62
66
|
export { n, t };
|
|
63
67
|
|
|
64
|
-
//# sourceMappingURL=chart-config-gauge-
|
|
68
|
+
//# sourceMappingURL=chart-config-gauge-CCva3FfA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-config-gauge-CCva3FfA.js","names":[],"sources":["../../../src/client/components/charts/GaugeChart.config.ts"],"sourcesContent":["import type { ChartTypeConfig } from '../../charts/chartConfigs'\n\n/**\n * Configuration for the gauge chart type\n */\nexport const gaugeChartConfig: ChartTypeConfig = {\n label: 'chart.gauge.label',\n description: 'chart.gauge.description',\n useCase: 'chart.gauge.useCase',\n clickableElements: {},\n displayOptions: ['hideHeader'],\n isAvailable: ({ measureCount }) => {\n if (measureCount < 1) return { available: false, reason: 'chart.availability.requiresMeasure' }\n return { available: true }\n },\n dropZones: [\n {\n key: 'yAxis',\n label: 'chart.configText.value_measure',\n description: 'chart.configText.current_value_to_display_on_the_gauge_e_g_current_equity_margin_used',\n mandatory: true,\n maxItems: 2,\n acceptTypes: ['measure'],\n emptyText: 'chart.gauge.dropZone.yAxis.empty',\n },\n ],\n displayOptionsConfig: [\n {\n key: 'minValue',\n label: 'chart.option.minValue.label',\n type: 'number',\n defaultValue: 0,\n description: 'chart.option.minValue.description',\n },\n {\n key: 'maxValue',\n label: 'chart.option.maxValue.label',\n type: 'number',\n description: 'chart.option.maxValue.description',\n },\n {\n key: 'thresholds',\n label: 'chart.configText.threshold_bands',\n type: 'string',\n placeholder: '[{\"value\":0.33,\"color\":\"#22c55e\"},{\"value\":0.66,\"color\":\"#f59e0b\"},{\"value\":1,\"color\":\"#ef4444\"}]',\n description: 'chart.configText.array_of_value_0_1_fraction_color_bands_shown_as_outer_arc_markers',\n },\n {\n key: 'showCenterLabel',\n label: 'chart.option.showCentreLabel.label',\n type: 'boolean',\n defaultValue: true,\n description: 'chart.option.showCentreLabel.description',\n },\n {\n key: 'showPercentage',\n label: 'chart.option.showPercentage.label',\n type: 'boolean',\n defaultValue: false,\n description: 'chart.option.showPercentage.description',\n },\n {\n key: 'leftYAxisFormat',\n label: 'chart.option.valueFormat.label',\n type: 'axisFormat',\n description: 'chart.configText.number_formatting_for_the_displayed_value_and_axis_labels',\n },\n ],\n}\n"],"mappings":";;0DAKa,IAAoC;CAC/C,OAAO;CACP,aAAa;CACb,SAAS;CACT,mBAAmB,EAAE;CACrB,gBAAgB,CAAC,aAAa;CAC9B,cAAc,EAAE,sBACV,IAAe,IAAU;EAAE,WAAW;EAAO,QAAQ;EAAsC,GACxF,EAAE,WAAW,IAAM;CAE5B,WAAW,CACT;EACE,KAAK;EACL,OAAO;EACP,aAAa;EACb,WAAW;EACX,UAAU;EACV,aAAa,CAAC,UAAU;EACxB,WAAW;EACZ,CACF;CACD,sBAAsB;EACpB;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,cAAc;GACd,aAAa;GACd;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACd;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,aAAa;GACd;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,cAAc;GACd,aAAa;GACd;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,cAAc;GACd,aAAa;GACd;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACd;EACF;CACF"}
|
package/dist/client/chunks/{chart-config-heat-map-Cv8qNnVP.js → chart-config-heat-map-Db4Z8UUn.js}
RENAMED
|
@@ -4,6 +4,13 @@ var t = /* @__PURE__ */ e({ heatmapChartConfig: () => n }), n = {
|
|
|
4
4
|
label: "chart.heatmap.label",
|
|
5
5
|
description: "chart.heatmap.description",
|
|
6
6
|
useCase: "chart.heatmap.useCase",
|
|
7
|
+
isAvailable: ({ measureCount: e, dimensionCount: t }) => e < 1 ? {
|
|
8
|
+
available: !1,
|
|
9
|
+
reason: "chart.availability.requiresMeasure"
|
|
10
|
+
} : t < 2 ? {
|
|
11
|
+
available: !1,
|
|
12
|
+
reason: "chart.availability.requiresTwoDimensions"
|
|
13
|
+
} : { available: !0 },
|
|
7
14
|
dropZones: [
|
|
8
15
|
{
|
|
9
16
|
key: "xAxis",
|
|
@@ -88,4 +95,4 @@ var t = /* @__PURE__ */ e({ heatmapChartConfig: () => n }), n = {
|
|
|
88
95
|
//#endregion
|
|
89
96
|
export { n, t };
|
|
90
97
|
|
|
91
|
-
//# sourceMappingURL=chart-config-heat-map-
|
|
98
|
+
//# sourceMappingURL=chart-config-heat-map-Db4Z8UUn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-config-heat-map-Db4Z8UUn.js","names":[],"sources":["../../../src/client/components/charts/HeatMapChart.config.ts"],"sourcesContent":["import type { ChartTypeConfig } from '../../charts/chartConfigs'\n\n/**\n * Configuration for the heatmap chart type\n *\n * Heatmap charts visualize intensity across two dimensions as a color matrix.\n * Best for showing patterns in matrix data like correlations, schedules, or category comparisons.\n */\nexport const heatmapChartConfig: ChartTypeConfig = {\n label: 'chart.heatmap.label',\n description: 'chart.heatmap.description',\n useCase: 'chart.heatmap.useCase',\n isAvailable: ({ measureCount, dimensionCount }) => {\n if (measureCount < 1) return { available: false, reason: 'chart.availability.requiresMeasure' }\n if (dimensionCount < 2) return { available: false, reason: 'chart.availability.requiresTwoDimensions' }\n return { available: true }\n },\n dropZones: [\n {\n key: 'xAxis',\n label: 'chart.configText.columns_x_axis',\n description: 'chart.configText.dimension_for_column_categories',\n mandatory: true,\n maxItems: 1,\n acceptTypes: ['dimension'],\n emptyText: 'chart.heatmap.dropZone.xAxis.empty',\n },\n {\n key: 'yAxis',\n label: 'chart.configText.rows_y_axis',\n description: 'chart.configText.dimension_for_row_categories',\n mandatory: true,\n maxItems: 1,\n acceptTypes: ['dimension'],\n emptyText: 'chart.heatmap.dropZone.yAxis.empty',\n },\n {\n key: 'valueField',\n label: 'chart.configText.value_color_intensity',\n description: 'chart.configText.measure_that_determines_cell_color',\n mandatory: true,\n maxItems: 1,\n acceptTypes: ['measure'],\n emptyText: 'chart.heatmap.dropZone.valueField.empty',\n },\n ],\n displayOptions: ['showLegend', 'showTooltip'],\n displayOptionsConfig: [\n {\n key: 'showLabels',\n label: 'chart.option.showLabels.label',\n type: 'boolean',\n defaultValue: false,\n description: 'chart.option.showLabels.description',\n },\n {\n key: 'cellShape',\n label: 'chart.option.cellShape.label',\n type: 'select',\n defaultValue: 'rect',\n options: [\n { value: 'rect', label: 'chart.option.cellShape.rectangle' },\n { value: 'circle', label: 'chart.option.cellShape.circle' },\n ],\n },\n {\n key: 'xAxisFormat',\n label: 'chart.option.xAxisFormat.label',\n type: 'axisFormat',\n description: 'chart.configText.number_formatting_for_x_axis_labels',\n },\n {\n key: 'yAxisFormat',\n label: 'chart.option.yAxisFormat.label',\n type: 'axisFormat',\n description: 'chart.configText.number_formatting_for_y_axis_labels',\n },\n {\n key: 'valueFormat',\n label: 'chart.option.valueFormat.label',\n type: 'axisFormat',\n description: 'chart.configText.number_formatting_for_cell_values_and_legend',\n },\n ],\n validate: (config) => {\n if (!config.xAxis?.length) return { isValid: false, message: 'chart.heatmap.validation.xAxisRequired' }\n if (!config.yAxis?.length) return { isValid: false, message: 'chart.heatmap.validation.yAxisRequired' }\n if (!config.valueField?.length) return { isValid: false, message: 'chart.heatmap.validation.valueRequired' }\n return { isValid: true }\n },\n}\n"],"mappings":";;4DAQa,IAAsC;CACjD,OAAO;CACP,aAAa;CACb,SAAS;CACT,cAAc,EAAE,iBAAc,wBACxB,IAAe,IAAU;EAAE,WAAW;EAAO,QAAQ;EAAsC,GAC3F,IAAiB,IAAU;EAAE,WAAW;EAAO,QAAQ;EAA4C,GAChG,EAAE,WAAW,IAAM;CAE5B,WAAW;EACT;GACE,KAAK;GACL,OAAO;GACP,aAAa;GACb,WAAW;GACX,UAAU;GACV,aAAa,CAAC,YAAY;GAC1B,WAAW;GACZ;EACD;GACE,KAAK;GACL,OAAO;GACP,aAAa;GACb,WAAW;GACX,UAAU;GACV,aAAa,CAAC,YAAY;GAC1B,WAAW;GACZ;EACD;GACE,KAAK;GACL,OAAO;GACP,aAAa;GACb,WAAW;GACX,UAAU;GACV,aAAa,CAAC,UAAU;GACxB,WAAW;GACZ;EACF;CACD,gBAAgB,CAAC,cAAc,cAAc;CAC7C,sBAAsB;EACpB;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,cAAc;GACd,aAAa;GACd;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,cAAc;GACd,SAAS,CACP;IAAE,OAAO;IAAQ,OAAO;IAAoC,EAC5D;IAAE,OAAO;IAAU,OAAO;IAAiC,CAC5D;GACF;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACd;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACd;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACd;EACF;CACD,WAAW,MACJ,EAAO,OAAO,SACd,EAAO,OAAO,SACd,EAAO,YAAY,SACjB,EAAE,SAAS,IAAM,GADe;EAAE,SAAS;EAAO,SAAS;EAA0C,GAD1E;EAAE,SAAS;EAAO,SAAS;EAA0C,GADrE;EAAE,SAAS;EAAO,SAAS;EAA0C;CAK1G"}
|
package/dist/client/chunks/{chart-config-kpi-delta-BraHQc2E.js → chart-config-kpi-delta-BfLf3iyi.js}
RENAMED
|
@@ -4,6 +4,13 @@ var t = /* @__PURE__ */ e({ kpiDeltaConfig: () => n }), n = {
|
|
|
4
4
|
label: "chart.kpiDelta.label",
|
|
5
5
|
description: "chart.kpiDelta.description",
|
|
6
6
|
useCase: "chart.kpiDelta.useCase",
|
|
7
|
+
isAvailable: ({ measureCount: e, dimensionCount: t }) => e < 1 ? {
|
|
8
|
+
available: !1,
|
|
9
|
+
reason: "chart.availability.requiresMeasure"
|
|
10
|
+
} : t < 1 ? {
|
|
11
|
+
available: !1,
|
|
12
|
+
reason: "chart.availability.requiresDimension"
|
|
13
|
+
} : { available: !0 },
|
|
7
14
|
dropZones: [{
|
|
8
15
|
key: "yAxis",
|
|
9
16
|
label: "chart.configText.value",
|
|
@@ -91,4 +98,4 @@ var t = /* @__PURE__ */ e({ kpiDeltaConfig: () => n }), n = {
|
|
|
91
98
|
//#endregion
|
|
92
99
|
export { n, t };
|
|
93
100
|
|
|
94
|
-
//# sourceMappingURL=chart-config-kpi-delta-
|
|
101
|
+
//# sourceMappingURL=chart-config-kpi-delta-BfLf3iyi.js.map
|