drizzle-cube 0.4.21 → 0.4.23
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 +2 -2
- package/dist/adapters/fastify/index.cjs +1 -1
- package/dist/adapters/fastify/index.js +2 -2
- package/dist/adapters/{handler-B-tEntiU.cjs → handler-C3hT7g2W.cjs} +1 -1
- package/dist/adapters/{handler-9Rdn7zM2.js → handler-t7Qd1IYi.js} +1 -1
- package/dist/adapters/hono/index.cjs +6 -6
- package/dist/adapters/hono/index.d.ts +13 -6
- package/dist/adapters/hono/index.js +65 -65
- package/dist/adapters/{mcp-transport-m1X1GtwG.js → mcp-transport-B6ZudTSk.js} +7 -0
- package/dist/adapters/{mcp-transport-8u9G5oNa.cjs → mcp-transport-DCiSGtp1.cjs} +1 -1
- package/dist/adapters/nextjs/index.cjs +2 -2
- package/dist/adapters/nextjs/index.js +2 -2
- package/dist/client/charts.js +12 -12
- package/dist/client/chunks/{RetentionCombinedChart-CLq89aOJ.js → RetentionCombinedChart-BK3NPsHP.js} +2 -2
- package/dist/client/chunks/{RetentionCombinedChart-CLq89aOJ.js.map → RetentionCombinedChart-BK3NPsHP.js.map} +1 -1
- package/dist/client/chunks/{analysis-builder-3z9fHE2F.js → analysis-builder-DVrv9Q4n.js} +9 -9
- package/dist/client/chunks/{analysis-builder-3z9fHE2F.js.map → analysis-builder-DVrv9Q4n.js.map} +1 -1
- package/dist/client/chunks/{analysis-builder-shared-Da-vlQa_.js → analysis-builder-shared-CrENEvEk.js} +6 -6
- package/dist/client/chunks/{analysis-builder-shared-Da-vlQa_.js.map → analysis-builder-shared-CrENEvEk.js.map} +1 -1
- package/dist/client/chunks/{chart-activity-grid-CPGcTSuh.js → chart-activity-grid-OG6he4YS.js} +2 -2
- package/dist/client/chunks/{chart-activity-grid-CPGcTSuh.js.map → chart-activity-grid-OG6he4YS.js.map} +1 -1
- package/dist/client/chunks/{chart-area-ByJQ7NZd.js → chart-area-TawAd2k9.js} +3 -3
- package/dist/client/chunks/{chart-area-ByJQ7NZd.js.map → chart-area-TawAd2k9.js.map} +1 -1
- package/dist/client/chunks/{chart-bar-dj14frMt.js → chart-bar-D3vtCNQG.js} +2 -2
- package/dist/client/chunks/{chart-bar-dj14frMt.js.map → chart-bar-D3vtCNQG.js.map} +1 -1
- package/dist/client/chunks/{chart-box-plot-ZatBpatq.js → chart-box-plot-BXwN2rO5.js} +2 -2
- package/dist/client/chunks/{chart-box-plot-ZatBpatq.js.map → chart-box-plot-BXwN2rO5.js.map} +1 -1
- package/dist/client/chunks/{chart-bubble-CemotLx-.js → chart-bubble-ZfNe8t5k.js} +2 -2
- package/dist/client/chunks/{chart-bubble-CemotLx-.js.map → chart-bubble-ZfNe8t5k.js.map} +1 -1
- package/dist/client/chunks/{chart-candlestick-BIR4uGGt.js → chart-candlestick-DmF3haFu.js} +2 -2
- package/dist/client/chunks/{chart-candlestick-BIR4uGGt.js.map → chart-candlestick-DmF3haFu.js.map} +1 -1
- package/dist/client/chunks/{chart-data-table-BsAjHe7o.js → chart-data-table-DJZPkArt.js} +4 -4
- package/dist/client/chunks/{chart-data-table-BsAjHe7o.js.map → chart-data-table-DJZPkArt.js.map} +1 -1
- package/dist/client/chunks/{chart-funnel-dofnhD24.js → chart-funnel-CE9x0Io9.js} +2 -2
- package/dist/client/chunks/{chart-funnel-dofnhD24.js.map → chart-funnel-CE9x0Io9.js.map} +1 -1
- package/dist/client/chunks/{chart-gauge-CKJJ8m3b.js → chart-gauge-Djs5FWxB.js} +2 -2
- package/dist/client/chunks/{chart-gauge-CKJJ8m3b.js.map → chart-gauge-Djs5FWxB.js.map} +1 -1
- package/dist/client/chunks/{chart-heat-map-BVuPUKHT.js → chart-heat-map-CqtMkdxd.js} +2 -2
- package/dist/client/chunks/{chart-heat-map-BVuPUKHT.js.map → chart-heat-map-CqtMkdxd.js.map} +1 -1
- package/dist/client/chunks/{chart-kpi-delta-DUD3f8vL.js → chart-kpi-delta-DEzA74cL.js} +4 -4
- package/dist/client/chunks/{chart-kpi-delta-DUD3f8vL.js.map → chart-kpi-delta-DEzA74cL.js.map} +1 -1
- package/dist/client/chunks/{chart-kpi-number-iJh-PzsM.js → chart-kpi-number-Bab-BZtX.js} +3 -3
- package/dist/client/chunks/{chart-kpi-number-iJh-PzsM.js.map → chart-kpi-number-Bab-BZtX.js.map} +1 -1
- package/dist/client/chunks/{chart-kpi-text-x6pV9v9Q.js → chart-kpi-text-BkTgckDJ.js} +3 -3
- package/dist/client/chunks/{chart-kpi-text-x6pV9v9Q.js.map → chart-kpi-text-BkTgckDJ.js.map} +1 -1
- package/dist/client/chunks/{chart-line-DzyZkugh.js → chart-line-DhM-Hvu0.js} +3 -3
- package/dist/client/chunks/{chart-line-DzyZkugh.js.map → chart-line-DhM-Hvu0.js.map} +1 -1
- package/dist/client/chunks/{chart-measure-profile-C2IkBG3V.js → chart-measure-profile-4vQxFm69.js} +3 -3
- package/dist/client/chunks/{chart-measure-profile-C2IkBG3V.js.map → chart-measure-profile-4vQxFm69.js.map} +1 -1
- package/dist/client/chunks/{chart-pie-akbfRfb9.js → chart-pie-B86KRcHI.js} +2 -2
- package/dist/client/chunks/{chart-pie-akbfRfb9.js.map → chart-pie-B86KRcHI.js.map} +1 -1
- package/dist/client/chunks/{chart-radar-BaN-Kjww.js → chart-radar-BhDBmJRh.js} +2 -2
- package/dist/client/chunks/{chart-radar-BaN-Kjww.js.map → chart-radar-BhDBmJRh.js.map} +1 -1
- package/dist/client/chunks/{chart-radial-bar-DpptEL3s.js → chart-radial-bar-Brugya8X.js} +2 -2
- package/dist/client/chunks/{chart-radial-bar-DpptEL3s.js.map → chart-radial-bar-Brugya8X.js.map} +1 -1
- package/dist/client/chunks/{chart-sankey-CG-3hHmX.js → chart-sankey-D2L8ympI.js} +2 -2
- package/dist/client/chunks/{chart-sankey-CG-3hHmX.js.map → chart-sankey-D2L8ympI.js.map} +1 -1
- package/dist/client/chunks/{chart-scatter-l_yTVxF3.js → chart-scatter-CAkbBDkK.js} +2 -2
- package/dist/client/chunks/{chart-scatter-l_yTVxF3.js.map → chart-scatter-CAkbBDkK.js.map} +1 -1
- package/dist/client/chunks/{chart-sunburst-KhDcKhmZ.js → chart-sunburst-DaxJ-cob.js} +2 -2
- package/dist/client/chunks/{chart-sunburst-KhDcKhmZ.js.map → chart-sunburst-DaxJ-cob.js.map} +1 -1
- package/dist/client/chunks/{chart-tree-map-CBbiaBXV.js → chart-tree-map-CrDJAvZU.js} +2 -2
- package/dist/client/chunks/{chart-tree-map-CBbiaBXV.js.map → chart-tree-map-CrDJAvZU.js.map} +1 -1
- package/dist/client/chunks/{chart-waterfall-CX3vx_lI.js → chart-waterfall-BBwSfEKT.js} +3 -3
- package/dist/client/chunks/{chart-waterfall-CX3vx_lI.js.map → chart-waterfall-BBwSfEKT.js.map} +1 -1
- package/dist/client/chunks/{charts-core-CU9u_HtL.js → charts-core-B4Rbfdcn.js} +2 -2
- package/dist/client/chunks/{charts-core-CU9u_HtL.js.map → charts-core-B4Rbfdcn.js.map} +1 -1
- package/dist/client/chunks/{charts-loader-B3tt5oKG.js → charts-loader-DbrwgvCK.js} +25 -25
- package/dist/client/chunks/{charts-loader-B3tt5oKG.js.map → charts-loader-DbrwgvCK.js.map} +1 -1
- package/dist/client/chunks/{components-CMGGxqOB.js → components-GzooQM5J.js} +9 -9
- package/dist/client/chunks/{components-CMGGxqOB.js.map → components-GzooQM5J.js.map} +1 -1
- package/dist/client/chunks/{core-D_8mkGpQ.js → core-Y9e-sNfb.js} +2 -2
- package/dist/client/chunks/{core-D_8mkGpQ.js.map → core-Y9e-sNfb.js.map} +1 -1
- package/dist/client/chunks/{icons-M7shurcH.js → icons-DFJw-2HU.js} +6 -6
- package/dist/client/chunks/{icons-M7shurcH.js.map → icons-DFJw-2HU.js.map} +1 -1
- package/dist/client/chunks/{providers-CgxXm6Ll.js → providers-CCw8Kjlc.js} +2 -2
- package/dist/client/chunks/{providers-CgxXm6Ll.js.map → providers-CCw8Kjlc.js.map} +1 -1
- package/dist/client/chunks/{syntaxHighlighting-BQfjio-i.js → syntaxHighlighting-DAMSW_A6.js} +2 -2
- package/dist/client/chunks/{syntaxHighlighting-BQfjio-i.js.map → syntaxHighlighting-DAMSW_A6.js.map} +1 -1
- package/dist/client/chunks/{useDirtyStateTracking-Cu1HSjmo.js → useDirtyStateTracking-CjhwBXRw.js} +20 -20
- package/dist/client/chunks/{useDirtyStateTracking-Cu1HSjmo.js.map → useDirtyStateTracking-CjhwBXRw.js.map} +1 -1
- package/dist/client/chunks/useExplainAI-IiW55BaQ.js +182 -0
- package/dist/client/chunks/useExplainAI-IiW55BaQ.js.map +1 -0
- package/dist/client/chunks/{vendor-AVsJ2ni0.js → vendor-B2EH3V58.js} +7 -7
- package/dist/client/chunks/{vendor-AVsJ2ni0.js.map → vendor-B2EH3V58.js.map} +1 -1
- package/dist/client/components.js +1 -1
- package/dist/client/hooks/useNotebookLayout.d.ts +8 -0
- package/dist/client/hooks.d.ts +2 -0
- package/dist/client/hooks.js +51 -190
- package/dist/client/hooks.js.map +1 -1
- package/dist/client/icons.js +1 -1
- package/dist/client/index.js +871 -742
- package/dist/client/index.js.map +1 -1
- package/dist/client/providers.js +1 -1
- package/dist/client/styles.css +1 -1
- package/dist/client/utils.js +7 -7
- package/dist/client-bundle-stats.html +1 -1
- package/dist/server/index.cjs +1 -1
- package/dist/server/index.d.ts +5 -0
- package/dist/server/index.js +7 -0
- package/package.json +1 -1
package/dist/client/chunks/{chart-box-plot-ZatBpatq.js.map → chart-box-plot-BXwN2rO5.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-box-plot-ZatBpatq.js","sources":["../../../src/client/components/charts/BoxPlotChart.tsx"],"sourcesContent":["import React, { useLayoutEffect, useMemo, useRef, useState } from 'react'\nimport { CHART_COLORS } from '../../utils/chartConstants'\nimport { formatAxisValue } from '../../utils/chartUtils'\nimport type { ChartProps } from '../../types'\n\nconst MAX_BOXES = 50\n\ninterface BoxStats {\n label: string\n min: number\n q1: number\n median: number\n q3: number\n max: number\n color: string\n}\n\nfunction parseNumeric(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 buildFrom5Measures(\n row: Record<string, unknown>,\n minField: string,\n q1Field: string,\n medianField: string,\n q3Field: string,\n maxField: string,\n label: string,\n color: string\n): BoxStats | null {\n const min = parseNumeric(row[minField])\n const q1 = parseNumeric(row[q1Field])\n const median = parseNumeric(row[medianField])\n const q3 = parseNumeric(row[q3Field])\n const max = parseNumeric(row[maxField])\n if (min === null || q1 === null || median === null || q3 === null || max === null) return null\n return { label, min, q1, median, q3, max, color }\n}\n\n/** Build approximate box stats assuming normality: Q1/Q3 at ±1σ, whiskers at ±2σ */\nfunction buildFrom3Measures(\n row: Record<string, unknown>,\n avgField: string,\n stddevField: string,\n medianField: string,\n label: string,\n color: string\n): BoxStats | null {\n const avg = parseNumeric(row[avgField])\n const sd = parseNumeric(row[stddevField])\n const median = parseNumeric(row[medianField])\n if (avg === null || sd === null || median === null) return null\n const absSd = Math.abs(sd)\n return {\n label,\n min: avg - 2 * absSd,\n q1: avg - absSd,\n median,\n q3: avg + absSd,\n max: avg + 2 * absSd,\n color,\n }\n}\n\nfunction BoxElement({\n x,\n boxWidth,\n minY,\n q1Y,\n medianY,\n q3Y,\n maxY,\n color,\n label,\n}: {\n x: number\n boxWidth: number\n minY: number\n q1Y: number\n medianY: number\n q3Y: number\n maxY: number\n color: string\n label: string\n}) {\n const halfWidth = boxWidth / 2\n const whiskerX = x\n const capWidth = boxWidth * 0.4\n\n return (\n <g data-testid={`box-${label}`}>\n {/* Whisker line (min to max) */}\n <line x1={whiskerX} y1={minY} x2={whiskerX} y2={maxY} stroke={color} strokeWidth={1.5} />\n {/* Min cap */}\n <line\n x1={whiskerX - capWidth / 2}\n y1={minY}\n x2={whiskerX + capWidth / 2}\n y2={minY}\n stroke={color}\n strokeWidth={1.5}\n />\n {/* Max cap */}\n <line\n x1={whiskerX - capWidth / 2}\n y1={maxY}\n x2={whiskerX + capWidth / 2}\n y2={maxY}\n stroke={color}\n strokeWidth={1.5}\n />\n {/* IQR Box (Q1 to Q3) */}\n <rect\n x={whiskerX - halfWidth}\n y={Math.min(q1Y, q3Y)}\n width={boxWidth}\n height={Math.abs(q3Y - q1Y) || 2}\n fill={color}\n fillOpacity={0.3}\n stroke={color}\n strokeWidth={1.5}\n />\n {/* Median line */}\n <line\n x1={whiskerX - halfWidth}\n y1={medianY}\n x2={whiskerX + halfWidth}\n y2={medianY}\n stroke={color}\n strokeWidth={2.5}\n data-testid={`median-${label}`}\n />\n </g>\n )\n}\n\nfunction YAxis({\n scale,\n domainMin,\n domainMax,\n width,\n tickCount = 5,\n format,\n}: {\n scale: (v: number) => number\n domainMin: number\n domainMax: number\n width: number\n tickCount?: number\n format?: (v: number) => string\n}) {\n const ticks = useMemo(() => {\n const range = domainMax - domainMin\n if (range === 0) return [domainMin]\n const step = range / (tickCount - 1)\n return Array.from({ length: tickCount }, (_, i) => domainMin + i * step)\n }, [domainMin, domainMax, tickCount])\n\n return (\n <g data-testid=\"y-axis\">\n {ticks.map((tick, i) => (\n <g key={i} transform={`translate(0, ${scale(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={width} stroke=\"currentColor\" strokeOpacity={0.1} strokeWidth={1} />\n </g>\n ))}\n <line y1={scale(ticks[0])} y2={scale(ticks[ticks.length - 1])} stroke=\"currentColor\" strokeWidth={1} />\n </g>\n )\n}\n\nconst BoxPlotChart = React.memo(function BoxPlotChart({\n data,\n chartConfig,\n displayConfig = {},\n height = '100%',\n colorPalette,\n onDataPointClick,\n drillEnabled,\n}: ChartProps) {\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 yAxisFormat = displayConfig?.leftYAxisFormat\n\n const { xField, mode, fields, 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 if (!xField || yAxisFields.length === 0) {\n return {\n xField,\n mode: 'none' as const,\n fields: {},\n configError: 'BoxPlot requires an X-Axis dimension and at least one measure in Y-Axis',\n }\n }\n\n // 5-measure mode: yAxis = [min, q1, median, q3, max]\n if (yAxisFields.length >= 5) {\n return {\n xField,\n mode: '5measure' as const,\n fields: {\n minField: yAxisFields[0],\n q1Field: yAxisFields[1],\n medianField: yAxisFields[2],\n q3Field: yAxisFields[3],\n maxField: yAxisFields[4],\n },\n configError: null,\n }\n }\n\n // 3-measure mode: yAxis = [avg, stddev, median]\n if (yAxisFields.length >= 3) {\n return {\n xField,\n mode: '3measure' as const,\n fields: {\n avgField: yAxisFields[0],\n stddevField: yAxisFields[1],\n medianField: yAxisFields[2],\n },\n configError: null,\n }\n }\n\n if (yAxisFields.length === 2) {\n return {\n xField,\n mode: 'none' as const,\n fields: {},\n configError: 'BoxPlot requires 1 measure (auto), 3 (avg/stddev/median), or 5 (min/q1/median/q3/max)',\n }\n }\n\n // Auto mode: use yAxis[0] as the value field (treated as median/value)\n return {\n xField,\n mode: 'auto' as const,\n fields: { valueField: yAxisFields[0] },\n configError: null,\n }\n }, [chartConfig])\n\n const boxes: BoxStats[] = useMemo(() => {\n if (configError || !data || data.length === 0 || mode === 'none') return []\n const rows = (data as Record<string, unknown>[]).slice(0, MAX_BOXES)\n const palette = colorPalette?.colors ?? CHART_COLORS\n\n const results: BoxStats[] = []\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i]\n const label = xField ? String(row[xField] ?? `Row ${i + 1}`) : `Row ${i + 1}`\n const color = palette[i % palette.length]\n\n let box: BoxStats | null = null\n if (mode === '5measure') {\n box = buildFrom5Measures(\n row,\n fields.minField!,\n fields.q1Field!,\n fields.medianField!,\n fields.q3Field!,\n fields.maxField!,\n label,\n color\n )\n } else if (mode === '3measure') {\n box = buildFrom3Measures(row, fields.avgField!, fields.stddevField!, fields.medianField!, label, color)\n } else {\n // Auto: use value as median, build minimal box (value ± 0)\n const v = parseNumeric(row[fields.valueField!])\n if (v !== null) {\n box = { label, min: v, q1: v, median: v, q3: v, max: v, color }\n }\n }\n if (box) results.push(box)\n }\n return results\n }, [data, xField, mode, fields, colorPalette, configError])\n\n if (!data || data.length === 0) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">No data available</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">No data points to display in box plot chart</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\">Configuration Error</div>\n <div className=\"dc:text-xs\">{configError}</div>\n </div>\n </div>\n )\n }\n\n if (boxes.length === 0) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">No valid data</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">\n Could not compute box plot statistics from the provided data\n </div>\n </div>\n </div>\n )\n }\n\n try {\n const margin = { top: 20, right: 20, bottom: 60, left: 60 }\n const containerWidth = dimensions.width || 600\n const containerHeight = typeof height === 'number' ? height : (dimensions.height || 400)\n const innerWidth = Math.max(containerWidth - margin.left - margin.right, 50)\n const innerHeight = Math.max(containerHeight - margin.top - margin.bottom, 50)\n\n const allValues = boxes.flatMap((b) => [b.min, b.max])\n const rawMin = Math.min(...allValues)\n const rawMax = Math.max(...allValues)\n const padding = (rawMax - rawMin) * 0.1 || 1\n const domainMin = rawMin - padding\n const domainMax = rawMax + padding\n\n const domainRange = domainMax - domainMin\n const yScale = (v: number) =>\n domainRange === 0 ? innerHeight / 2 : innerHeight - ((v - domainMin) / domainRange) * innerHeight\n\n const boxSpacing = innerWidth / boxes.length\n const boxWidth = Math.min(boxSpacing * 0.6, 40)\n\n const isTruncated = (data as unknown[]).length > MAX_BOXES\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 preserveAspectRatio=\"none\"\n data-testid=\"boxplot-svg\"\n >\n <g transform={`translate(${margin.left}, ${margin.top})`}>\n <YAxis\n scale={yScale}\n domainMin={domainMin}\n domainMax={domainMax}\n width={innerWidth}\n tickCount={5}\n format={yAxisFormat ? (v) => formatAxisValue(v, yAxisFormat) : undefined}\n />\n\n {boxes.map((box, i) => {\n const cx = boxSpacing * i + boxSpacing / 2\n return (\n <g\n key={`${box.label}-${i}`}\n onClick={(event: React.MouseEvent) => {\n if (onDataPointClick && drillEnabled) {\n onDataPointClick({\n dataPoint: { ...box },\n clickedField: xField ?? '',\n xValue: box.label,\n position: { x: event.clientX, y: event.clientY },\n nativeEvent: event,\n })\n }\n }}\n cursor={drillEnabled ? 'pointer' : undefined}\n >\n <title>{`${box.label}: min=${box.min}, Q1=${box.q1}, median=${box.median}, Q3=${box.q3}, max=${box.max}`}</title>\n <BoxElement\n x={cx}\n boxWidth={boxWidth}\n minY={yScale(box.min)}\n q1Y={yScale(box.q1)}\n medianY={yScale(box.median)}\n q3Y={yScale(box.q3)}\n maxY={yScale(box.max)}\n color={box.color}\n label={box.label}\n />\n <text\n x={cx}\n y={innerHeight + 20}\n textAnchor=\"middle\"\n fontSize={11}\n fill=\"currentColor\"\n className=\"text-dc-text-secondary\"\n data-testid={`x-label-${box.label}`}\n >\n {box.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 Data truncated to {MAX_BOXES} groups (original: {(data as unknown[]).length})\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\">Box Plot Chart Error</div>\n <div className=\"dc:text-xs dc:mb-2\">{error instanceof Error ? error.message : 'Unknown rendering error'}</div>\n <div className=\"dc:text-xs text-dc-text-muted\">Check the data and configuration</div>\n </div>\n </div>\n )\n }\n})\n\nexport default BoxPlotChart\n"],"names":["MAX_BOXES","parseNumeric","v","buildFrom5Measures","row","minField","q1Field","medianField","q3Field","maxField","label","color","min","q1","median","q3","max","buildFrom3Measures","avgField","stddevField","avg","sd","absSd","BoxElement","x","boxWidth","minY","q1Y","medianY","q3Y","maxY","halfWidth","whiskerX","capWidth","jsxs","jsx","YAxis","scale","domainMin","domainMax","width","tickCount","format","ticks","useMemo","range","step","_","i","tick","BoxPlotChart","React","data","chartConfig","displayConfig","height","colorPalette","onDataPointClick","drillEnabled","containerRef","useRef","dimensions","setDimensions","useState","useLayoutEffect","el","observer","entries","entry","h","rect","yAxisFormat","xField","mode","fields","configError","yAxisFields","boxes","rows","palette","CHART_COLORS","results","box","margin","containerWidth","containerHeight","innerWidth","innerHeight","allValues","b","rawMin","rawMax","padding","domainRange","yScale","boxSpacing","isTruncated","formatAxisValue","cx","event","error"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"chart-box-plot-BXwN2rO5.js","sources":["../../../src/client/components/charts/BoxPlotChart.tsx"],"sourcesContent":["import React, { useLayoutEffect, useMemo, useRef, useState } from 'react'\nimport { CHART_COLORS } from '../../utils/chartConstants'\nimport { formatAxisValue } from '../../utils/chartUtils'\nimport type { ChartProps } from '../../types'\n\nconst MAX_BOXES = 50\n\ninterface BoxStats {\n label: string\n min: number\n q1: number\n median: number\n q3: number\n max: number\n color: string\n}\n\nfunction parseNumeric(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 buildFrom5Measures(\n row: Record<string, unknown>,\n minField: string,\n q1Field: string,\n medianField: string,\n q3Field: string,\n maxField: string,\n label: string,\n color: string\n): BoxStats | null {\n const min = parseNumeric(row[minField])\n const q1 = parseNumeric(row[q1Field])\n const median = parseNumeric(row[medianField])\n const q3 = parseNumeric(row[q3Field])\n const max = parseNumeric(row[maxField])\n if (min === null || q1 === null || median === null || q3 === null || max === null) return null\n return { label, min, q1, median, q3, max, color }\n}\n\n/** Build approximate box stats assuming normality: Q1/Q3 at ±1σ, whiskers at ±2σ */\nfunction buildFrom3Measures(\n row: Record<string, unknown>,\n avgField: string,\n stddevField: string,\n medianField: string,\n label: string,\n color: string\n): BoxStats | null {\n const avg = parseNumeric(row[avgField])\n const sd = parseNumeric(row[stddevField])\n const median = parseNumeric(row[medianField])\n if (avg === null || sd === null || median === null) return null\n const absSd = Math.abs(sd)\n return {\n label,\n min: avg - 2 * absSd,\n q1: avg - absSd,\n median,\n q3: avg + absSd,\n max: avg + 2 * absSd,\n color,\n }\n}\n\nfunction BoxElement({\n x,\n boxWidth,\n minY,\n q1Y,\n medianY,\n q3Y,\n maxY,\n color,\n label,\n}: {\n x: number\n boxWidth: number\n minY: number\n q1Y: number\n medianY: number\n q3Y: number\n maxY: number\n color: string\n label: string\n}) {\n const halfWidth = boxWidth / 2\n const whiskerX = x\n const capWidth = boxWidth * 0.4\n\n return (\n <g data-testid={`box-${label}`}>\n {/* Whisker line (min to max) */}\n <line x1={whiskerX} y1={minY} x2={whiskerX} y2={maxY} stroke={color} strokeWidth={1.5} />\n {/* Min cap */}\n <line\n x1={whiskerX - capWidth / 2}\n y1={minY}\n x2={whiskerX + capWidth / 2}\n y2={minY}\n stroke={color}\n strokeWidth={1.5}\n />\n {/* Max cap */}\n <line\n x1={whiskerX - capWidth / 2}\n y1={maxY}\n x2={whiskerX + capWidth / 2}\n y2={maxY}\n stroke={color}\n strokeWidth={1.5}\n />\n {/* IQR Box (Q1 to Q3) */}\n <rect\n x={whiskerX - halfWidth}\n y={Math.min(q1Y, q3Y)}\n width={boxWidth}\n height={Math.abs(q3Y - q1Y) || 2}\n fill={color}\n fillOpacity={0.3}\n stroke={color}\n strokeWidth={1.5}\n />\n {/* Median line */}\n <line\n x1={whiskerX - halfWidth}\n y1={medianY}\n x2={whiskerX + halfWidth}\n y2={medianY}\n stroke={color}\n strokeWidth={2.5}\n data-testid={`median-${label}`}\n />\n </g>\n )\n}\n\nfunction YAxis({\n scale,\n domainMin,\n domainMax,\n width,\n tickCount = 5,\n format,\n}: {\n scale: (v: number) => number\n domainMin: number\n domainMax: number\n width: number\n tickCount?: number\n format?: (v: number) => string\n}) {\n const ticks = useMemo(() => {\n const range = domainMax - domainMin\n if (range === 0) return [domainMin]\n const step = range / (tickCount - 1)\n return Array.from({ length: tickCount }, (_, i) => domainMin + i * step)\n }, [domainMin, domainMax, tickCount])\n\n return (\n <g data-testid=\"y-axis\">\n {ticks.map((tick, i) => (\n <g key={i} transform={`translate(0, ${scale(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={width} stroke=\"currentColor\" strokeOpacity={0.1} strokeWidth={1} />\n </g>\n ))}\n <line y1={scale(ticks[0])} y2={scale(ticks[ticks.length - 1])} stroke=\"currentColor\" strokeWidth={1} />\n </g>\n )\n}\n\nconst BoxPlotChart = React.memo(function BoxPlotChart({\n data,\n chartConfig,\n displayConfig = {},\n height = '100%',\n colorPalette,\n onDataPointClick,\n drillEnabled,\n}: ChartProps) {\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 yAxisFormat = displayConfig?.leftYAxisFormat\n\n const { xField, mode, fields, 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 if (!xField || yAxisFields.length === 0) {\n return {\n xField,\n mode: 'none' as const,\n fields: {},\n configError: 'BoxPlot requires an X-Axis dimension and at least one measure in Y-Axis',\n }\n }\n\n // 5-measure mode: yAxis = [min, q1, median, q3, max]\n if (yAxisFields.length >= 5) {\n return {\n xField,\n mode: '5measure' as const,\n fields: {\n minField: yAxisFields[0],\n q1Field: yAxisFields[1],\n medianField: yAxisFields[2],\n q3Field: yAxisFields[3],\n maxField: yAxisFields[4],\n },\n configError: null,\n }\n }\n\n // 3-measure mode: yAxis = [avg, stddev, median]\n if (yAxisFields.length >= 3) {\n return {\n xField,\n mode: '3measure' as const,\n fields: {\n avgField: yAxisFields[0],\n stddevField: yAxisFields[1],\n medianField: yAxisFields[2],\n },\n configError: null,\n }\n }\n\n if (yAxisFields.length === 2) {\n return {\n xField,\n mode: 'none' as const,\n fields: {},\n configError: 'BoxPlot requires 1 measure (auto), 3 (avg/stddev/median), or 5 (min/q1/median/q3/max)',\n }\n }\n\n // Auto mode: use yAxis[0] as the value field (treated as median/value)\n return {\n xField,\n mode: 'auto' as const,\n fields: { valueField: yAxisFields[0] },\n configError: null,\n }\n }, [chartConfig])\n\n const boxes: BoxStats[] = useMemo(() => {\n if (configError || !data || data.length === 0 || mode === 'none') return []\n const rows = (data as Record<string, unknown>[]).slice(0, MAX_BOXES)\n const palette = colorPalette?.colors ?? CHART_COLORS\n\n const results: BoxStats[] = []\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i]\n const label = xField ? String(row[xField] ?? `Row ${i + 1}`) : `Row ${i + 1}`\n const color = palette[i % palette.length]\n\n let box: BoxStats | null = null\n if (mode === '5measure') {\n box = buildFrom5Measures(\n row,\n fields.minField!,\n fields.q1Field!,\n fields.medianField!,\n fields.q3Field!,\n fields.maxField!,\n label,\n color\n )\n } else if (mode === '3measure') {\n box = buildFrom3Measures(row, fields.avgField!, fields.stddevField!, fields.medianField!, label, color)\n } else {\n // Auto: use value as median, build minimal box (value ± 0)\n const v = parseNumeric(row[fields.valueField!])\n if (v !== null) {\n box = { label, min: v, q1: v, median: v, q3: v, max: v, color }\n }\n }\n if (box) results.push(box)\n }\n return results\n }, [data, xField, mode, fields, colorPalette, configError])\n\n if (!data || data.length === 0) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">No data available</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">No data points to display in box plot chart</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\">Configuration Error</div>\n <div className=\"dc:text-xs\">{configError}</div>\n </div>\n </div>\n )\n }\n\n if (boxes.length === 0) {\n return (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">No valid data</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">\n Could not compute box plot statistics from the provided data\n </div>\n </div>\n </div>\n )\n }\n\n try {\n const margin = { top: 20, right: 20, bottom: 60, left: 60 }\n const containerWidth = dimensions.width || 600\n const containerHeight = typeof height === 'number' ? height : (dimensions.height || 400)\n const innerWidth = Math.max(containerWidth - margin.left - margin.right, 50)\n const innerHeight = Math.max(containerHeight - margin.top - margin.bottom, 50)\n\n const allValues = boxes.flatMap((b) => [b.min, b.max])\n const rawMin = Math.min(...allValues)\n const rawMax = Math.max(...allValues)\n const padding = (rawMax - rawMin) * 0.1 || 1\n const domainMin = rawMin - padding\n const domainMax = rawMax + padding\n\n const domainRange = domainMax - domainMin\n const yScale = (v: number) =>\n domainRange === 0 ? innerHeight / 2 : innerHeight - ((v - domainMin) / domainRange) * innerHeight\n\n const boxSpacing = innerWidth / boxes.length\n const boxWidth = Math.min(boxSpacing * 0.6, 40)\n\n const isTruncated = (data as unknown[]).length > MAX_BOXES\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 preserveAspectRatio=\"none\"\n data-testid=\"boxplot-svg\"\n >\n <g transform={`translate(${margin.left}, ${margin.top})`}>\n <YAxis\n scale={yScale}\n domainMin={domainMin}\n domainMax={domainMax}\n width={innerWidth}\n tickCount={5}\n format={yAxisFormat ? (v) => formatAxisValue(v, yAxisFormat) : undefined}\n />\n\n {boxes.map((box, i) => {\n const cx = boxSpacing * i + boxSpacing / 2\n return (\n <g\n key={`${box.label}-${i}`}\n onClick={(event: React.MouseEvent) => {\n if (onDataPointClick && drillEnabled) {\n onDataPointClick({\n dataPoint: { ...box },\n clickedField: xField ?? '',\n xValue: box.label,\n position: { x: event.clientX, y: event.clientY },\n nativeEvent: event,\n })\n }\n }}\n cursor={drillEnabled ? 'pointer' : undefined}\n >\n <title>{`${box.label}: min=${box.min}, Q1=${box.q1}, median=${box.median}, Q3=${box.q3}, max=${box.max}`}</title>\n <BoxElement\n x={cx}\n boxWidth={boxWidth}\n minY={yScale(box.min)}\n q1Y={yScale(box.q1)}\n medianY={yScale(box.median)}\n q3Y={yScale(box.q3)}\n maxY={yScale(box.max)}\n color={box.color}\n label={box.label}\n />\n <text\n x={cx}\n y={innerHeight + 20}\n textAnchor=\"middle\"\n fontSize={11}\n fill=\"currentColor\"\n className=\"text-dc-text-secondary\"\n data-testid={`x-label-${box.label}`}\n >\n {box.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 Data truncated to {MAX_BOXES} groups (original: {(data as unknown[]).length})\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\">Box Plot Chart Error</div>\n <div className=\"dc:text-xs dc:mb-2\">{error instanceof Error ? error.message : 'Unknown rendering error'}</div>\n <div className=\"dc:text-xs text-dc-text-muted\">Check the data and configuration</div>\n </div>\n </div>\n )\n }\n})\n\nexport default BoxPlotChart\n"],"names":["MAX_BOXES","parseNumeric","v","buildFrom5Measures","row","minField","q1Field","medianField","q3Field","maxField","label","color","min","q1","median","q3","max","buildFrom3Measures","avgField","stddevField","avg","sd","absSd","BoxElement","x","boxWidth","minY","q1Y","medianY","q3Y","maxY","halfWidth","whiskerX","capWidth","jsxs","jsx","YAxis","scale","domainMin","domainMax","width","tickCount","format","ticks","useMemo","range","step","_","i","tick","BoxPlotChart","React","data","chartConfig","displayConfig","height","colorPalette","onDataPointClick","drillEnabled","containerRef","useRef","dimensions","setDimensions","useState","useLayoutEffect","el","observer","entries","entry","h","rect","yAxisFormat","xField","mode","fields","configError","yAxisFields","boxes","rows","palette","CHART_COLORS","results","box","margin","containerWidth","containerHeight","innerWidth","innerHeight","allValues","b","rawMin","rawMax","padding","domainRange","yScale","boxSpacing","isTruncated","formatAxisValue","cx","event","error"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as y, jsxs as te } from "react/jsx-runtime";
|
|
2
2
|
import Ae, { useSyncExternalStore as Fe, useCallback as Se, useRef as ne, useState as oe, useMemo as we, useLayoutEffect as ve, useEffect as ce } from "react";
|
|
3
3
|
import { select as D, scaleLinear as de, extent as ue, scaleSqrt as ze, max as Te, scaleQuantize as $e, scaleOrdinal as me, axisBottom as xe, axisLeft as fe } from "d3";
|
|
4
|
-
import { u as Ne, g as ke, d as ye, i as Ye, e as he, C as pe, h as ge, c as se, f as N } from "./charts-core-
|
|
4
|
+
import { u as Ne, g as ke, d as ye, i as Ye, e as he, C as pe, h as ge, c as se, f as N } from "./charts-core-B4Rbfdcn.js";
|
|
5
5
|
import { g as be, s as Re, w as Ve } from "./theme-Dp3hFed1.js";
|
|
6
6
|
const H = {
|
|
7
7
|
listeners: /* @__PURE__ */ new Set(),
|
|
@@ -246,4 +246,4 @@ export {
|
|
|
246
246
|
He as B,
|
|
247
247
|
Be as u
|
|
248
248
|
};
|
|
249
|
-
//# sourceMappingURL=chart-bubble-
|
|
249
|
+
//# sourceMappingURL=chart-bubble-ZfNe8t5k.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-bubble-CemotLx-.js","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 { 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 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\">No data available</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">No data points to display in bubble chart</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\">Configuration Required</div>\n <div className=\"dc:text-xs\">Bubble chart requires xAxis, yAxis, series, and sizeField dimensions</div>\n <div className=\"dc:text-xs dc:mt-1\">Optional: colorField for bubble coloring</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\">Measuring chart dimensions...</div>\n </div>\n )}\n </div>\n </div>\n )\n})\n\nexport default BubbleChart"],"names":["themeStore","listener","watchThemeChanges","useTheme","theme","useSyncExternalStore","getTheme","setTheme","useCallback","newTheme","setThemeUtil","BubbleChart","React","data","chartConfig","displayConfig","queryObject","height","colorPalette","svgRef","useRef","containerRef","dimensions","setDimensions","useState","dimensionsReady","setDimensionsReady","getFieldLabel","useCubeFieldLabel","safeDisplayConfig","useMemo","useLayoutEffect","retryCount","maxRetries","rafId","timeoutId","updateDimensions","width","retryWithRaf","useEffect","resizeObserver","entries","entry","select","xAxisField","yAxisField","seriesField","sizeFieldName","colorFieldName","xGranularity","getFieldGranularity","isTimeDimension","td","bubbleData","item","rawXValue","xNum","xLabel","dateStr","date","isoStr","formatTimeValue","formattedValue","yValue","parseNumericValue","sizeValue","seriesValue","isValidNumericValue","d","margin","CHART_MARGINS","chartHeight","svg","g","xScale","scaleLinear","extent","yScale","sizeScale","scaleSqrt","max","colorScale","isNumericColorField","uniqueColors","colorValues","value","val","minValue","maxValue","scaleQuantize","CHART_COLORS_GRADIENT","scaleOrdinal","CHART_COLORS","getThemeColor","varName","fallback","isDark","textColor","gridColor","xGrid","axisBottom","yGrid","axisLeft","xAxisGenerator","q","formatAxisValue","xAxis","yAxisGenerator","yAxis","tooltip","bubbles","event","tooltipContent","_event","legend","gradient","gradientColors","color","i","legendItems","legendItem","_d","legendKey","jsx","jsxs"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"chart-bubble-ZfNe8t5k.js","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 { 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 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\">No data available</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">No data points to display in bubble chart</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\">Configuration Required</div>\n <div className=\"dc:text-xs\">Bubble chart requires xAxis, yAxis, series, and sizeField dimensions</div>\n <div className=\"dc:text-xs dc:mt-1\">Optional: colorField for bubble coloring</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\">Measuring chart dimensions...</div>\n </div>\n )}\n </div>\n </div>\n )\n})\n\nexport default BubbleChart"],"names":["themeStore","listener","watchThemeChanges","useTheme","theme","useSyncExternalStore","getTheme","setTheme","useCallback","newTheme","setThemeUtil","BubbleChart","React","data","chartConfig","displayConfig","queryObject","height","colorPalette","svgRef","useRef","containerRef","dimensions","setDimensions","useState","dimensionsReady","setDimensionsReady","getFieldLabel","useCubeFieldLabel","safeDisplayConfig","useMemo","useLayoutEffect","retryCount","maxRetries","rafId","timeoutId","updateDimensions","width","retryWithRaf","useEffect","resizeObserver","entries","entry","select","xAxisField","yAxisField","seriesField","sizeFieldName","colorFieldName","xGranularity","getFieldGranularity","isTimeDimension","td","bubbleData","item","rawXValue","xNum","xLabel","dateStr","date","isoStr","formatTimeValue","formattedValue","yValue","parseNumericValue","sizeValue","seriesValue","isValidNumericValue","d","margin","CHART_MARGINS","chartHeight","svg","g","xScale","scaleLinear","extent","yScale","sizeScale","scaleSqrt","max","colorScale","isNumericColorField","uniqueColors","colorValues","value","val","minValue","maxValue","scaleQuantize","CHART_COLORS_GRADIENT","scaleOrdinal","CHART_COLORS","getThemeColor","varName","fallback","isDark","textColor","gridColor","xGrid","axisBottom","yGrid","axisLeft","xAxisGenerator","q","formatAxisValue","xAxis","yAxisGenerator","yAxis","tooltip","bubbles","event","tooltipContent","_event","legend","gradient","gradientColors","color","i","legendItems","legendItem","_d","legendKey","jsx","jsxs"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as r, jsxs as w, Fragment as X } from "react/jsx-runtime";
|
|
2
2
|
import K, { useRef as G, useState as J, useLayoutEffect as P, useMemo as T } from "react";
|
|
3
|
-
import { f as Q } from "./charts-core-
|
|
3
|
+
import { f as Q } from "./charts-core-B4Rbfdcn.js";
|
|
4
4
|
const Z = "#22c55e", ee = "#ef4444", I = "#94a3b8", j = 200;
|
|
5
5
|
function S(n) {
|
|
6
6
|
if (n == null) return null;
|
|
@@ -266,4 +266,4 @@ const oe = K.memo(function({
|
|
|
266
266
|
export {
|
|
267
267
|
oe as default
|
|
268
268
|
};
|
|
269
|
-
//# sourceMappingURL=chart-candlestick-
|
|
269
|
+
//# sourceMappingURL=chart-candlestick-DmF3haFu.js.map
|
package/dist/client/chunks/{chart-candlestick-BIR4uGGt.js.map → chart-candlestick-DmF3haFu.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-candlestick-BIR4uGGt.js","sources":["../../../src/client/components/charts/CandlestickChart.tsx"],"sourcesContent":["import React, { useLayoutEffect, useMemo, useRef, useState } from 'react'\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 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\">No data available</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">No data points to display in candlestick chart</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\">Configuration Error</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 Showing first {MAX_CANDLES} candles (total: {(data as unknown[]).length})\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\">Candlestick Chart Error</div>\n <div className=\"dc:text-xs dc:mb-2\">{error instanceof Error ? error.message : 'Unknown rendering error'}</div>\n <div className=\"dc:text-xs text-dc-text-muted\">Check the data and configuration</div>\n </div>\n </div>\n )\n }\n})\n\nexport default CandlestickChart\n"],"names":["BULL_COLOR_DEFAULT","BEAR_COLOR_DEFAULT","WICK_COLOR","MAX_CANDLES","parseNum","v","n","Candle","x","candleWidth","openY","closeY","highY","lowY","isBullish","bullColor","bearColor","showWicks","label","fill","bodyTop","bodyBottom","bodyHeight","halfWidth","jsxs","jsx","Fragment","YAxisTicks","domainMin","domainMax","innerHeight","tickCount","format","ticks","useMemo","step","_","i","yScale","tick","CandlestickChart","React","data","chartConfig","displayConfig","height","onDataPointClick","drillEnabled","containerRef","useRef","dimensions","setDimensions","useState","useLayoutEffect","el","observer","entries","entry","width","h","rect","rangeMode","yAxisFormat","xField","openField","closeField","highField","lowField","configError","yAxisFields","candles","rows","result","row","rawOpen","rawClose","open","close","high","low","margin","containerWidth","containerHeight","innerWidth","allValues","c","rawMin","rawMax","pad","candleSpacing","isTruncated","formatAxisValue","candle","cx","event","error"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"chart-candlestick-DmF3haFu.js","sources":["../../../src/client/components/charts/CandlestickChart.tsx"],"sourcesContent":["import React, { useLayoutEffect, useMemo, useRef, useState } from 'react'\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 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\">No data available</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">No data points to display in candlestick chart</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\">Configuration Error</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 Showing first {MAX_CANDLES} candles (total: {(data as unknown[]).length})\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\">Candlestick Chart Error</div>\n <div className=\"dc:text-xs dc:mb-2\">{error instanceof Error ? error.message : 'Unknown rendering error'}</div>\n <div className=\"dc:text-xs text-dc-text-muted\">Check the data and configuration</div>\n </div>\n </div>\n )\n }\n})\n\nexport default CandlestickChart\n"],"names":["BULL_COLOR_DEFAULT","BEAR_COLOR_DEFAULT","WICK_COLOR","MAX_CANDLES","parseNum","v","n","Candle","x","candleWidth","openY","closeY","highY","lowY","isBullish","bullColor","bearColor","showWicks","label","fill","bodyTop","bodyBottom","bodyHeight","halfWidth","jsxs","jsx","Fragment","YAxisTicks","domainMin","domainMax","innerHeight","tickCount","format","ticks","useMemo","step","_","i","yScale","tick","CandlestickChart","React","data","chartConfig","displayConfig","height","onDataPointClick","drillEnabled","containerRef","useRef","dimensions","setDimensions","useState","useLayoutEffect","el","observer","entries","entry","width","h","rect","rangeMode","yAxisFormat","xField","openField","closeField","highField","lowField","configError","yAxisFields","candles","rows","result","row","rawOpen","rawClose","open","close","high","low","margin","containerWidth","containerHeight","innerWidth","allValues","c","rawMin","rawMax","pad","candleSpacing","isTruncated","formatAxisValue","candle","cx","event","error"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx as c, jsxs as u } from "react/jsx-runtime";
|
|
2
2
|
import k, { useMemo as y } from "react";
|
|
3
|
-
import { u as S } from "./providers-
|
|
4
|
-
import { d as g, f as w } from "./charts-core-
|
|
5
|
-
import { g as F } from "./icons-
|
|
3
|
+
import { u as S } from "./providers-CCw8Kjlc.js";
|
|
4
|
+
import { d as g, f as w } from "./charts-core-B4Rbfdcn.js";
|
|
5
|
+
import { g as F } from "./icons-DFJw-2HU.js";
|
|
6
6
|
function A(e) {
|
|
7
7
|
if (!e) return [];
|
|
8
8
|
const t = [];
|
|
@@ -290,4 +290,4 @@ export {
|
|
|
290
290
|
M as h,
|
|
291
291
|
R as p
|
|
292
292
|
};
|
|
293
|
-
//# sourceMappingURL=chart-data-table-
|
|
293
|
+
//# sourceMappingURL=chart-data-table-DJZPkArt.js.map
|