drizzle-cube 0.4.21 → 0.4.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/package.json +1 -1
package/dist/client/chunks/{chart-data-table-BsAjHe7o.js.map → chart-data-table-DJZPkArt.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-data-table-BsAjHe7o.js","sources":["../../../src/client/utils/pivotUtils.ts","../../../src/client/components/charts/DataTable.tsx"],"sourcesContent":["/**\n * Pivot utilities for DataTable time dimension pivoting\n *\n * When a query includes a time dimension with granularity, transforms flat data\n * into a pivoted structure with time periods as columns.\n */\n\nimport type { CubeQuery, CubeMeta } from '../types'\nimport { formatTimeValue } from './chartUtils'\n\n/**\n * Derives ordered column list from a CubeQuery object.\n * Order: dimensions, timeDimensions (as field names), measures\n *\n * @param queryObject The CubeQuery object\n * @returns Array of field names in order\n */\nexport function getOrderedColumnsFromQuery(queryObject?: CubeQuery): string[] {\n if (!queryObject) return []\n\n const columns: string[] = []\n\n // Add regular dimensions first\n if (queryObject.dimensions) {\n columns.push(...queryObject.dimensions)\n }\n\n // Add time dimensions\n if (queryObject.timeDimensions) {\n queryObject.timeDimensions.forEach(td => {\n if (!columns.includes(td.dimension)) {\n columns.push(td.dimension)\n }\n })\n }\n\n // Add measures last\n if (queryObject.measures) {\n columns.push(...queryObject.measures)\n }\n\n return columns\n}\n\n/**\n * Configuration for pivoting based on query structure\n */\nexport interface PivotConfig {\n /** Time dimension field name (e.g., \"Sales.date\") */\n timeDimension: string\n /** Time granularity (e.g., \"month\", \"day\", \"year\") */\n granularity: string\n /** Non-time dimension fields */\n dimensions: string[]\n /** Measure fields */\n measures: string[]\n}\n\n/**\n * Column definition for pivoted table\n */\nexport interface PivotColumn {\n /** Column key for data access */\n key: string\n /** Display label for column header */\n label: string\n /** Whether this is a time column (vs row identifier column) */\n isTimeColumn: boolean\n /** Whether this is the measure column */\n isMeasureColumn?: boolean\n}\n\n/**\n * Row in the pivoted table\n */\nexport interface PivotRow {\n /** Unique row identifier */\n id: string\n /** The measure field name (for icon lookup) */\n measureField: string\n /** Values keyed by column key */\n values: Record<string, any>\n /** Whether this is the first row in a dimension group (for row spanning) */\n isFirstInGroup?: boolean\n /** Number of rows to span for dimension cells (only set on first row in group) */\n dimensionRowSpan?: number\n}\n\n/**\n * Result of pivoting table data\n */\nexport interface PivotedTableData {\n /** Whether data was pivoted (has time dimension with granularity) */\n isPivoted: boolean\n /** Column definitions for the pivoted table */\n columns: PivotColumn[]\n /** Rows of pivoted data */\n rows: PivotRow[]\n}\n\n/**\n * Determines if a query has a time dimension with granularity that should trigger pivoting\n * @param queryObject The CubeQuery object\n * @param xAxisOverride Optional array of fields to use for filtering dimensions and measures\n * (for respecting chartConfig.xAxis configuration)\n * @returns PivotConfig if pivoting should occur, null otherwise\n */\nexport function hasTimeDimensionForPivot(\n queryObject?: CubeQuery,\n xAxisOverride?: string[]\n): PivotConfig | null {\n if (!queryObject?.timeDimensions?.length) return null\n\n // Find the first time dimension with granularity\n const timeDim = queryObject.timeDimensions.find(td => td.granularity)\n if (!timeDim?.granularity) return null\n\n // Must have at least one measure to pivot\n if (!queryObject.measures?.length) return null\n\n let dimensions: string[]\n let measures: string[]\n\n if (xAxisOverride && xAxisOverride.length > 0) {\n // Filter dimensions from xAxisOverride (excluding time dimension and measures)\n dimensions = xAxisOverride.filter(field => {\n // Exclude the time dimension being pivoted (it becomes columns)\n if (field === timeDim.dimension) return false\n // Exclude measures (they become row values, not dimension columns)\n if (queryObject.measures?.includes(field)) return false\n return true\n })\n\n // Filter measures from xAxisOverride - only show measures that are in xAxis\n const measuresInXAxis = xAxisOverride.filter(field =>\n queryObject.measures?.includes(field)\n )\n // If xAxis contains measures, use only those; otherwise fall back to all measures\n measures = measuresInXAxis.length > 0 ? measuresInXAxis : queryObject.measures\n } else {\n dimensions = queryObject.dimensions || []\n measures = queryObject.measures\n }\n\n // Must have at least one measure after filtering\n if (measures.length === 0) return null\n\n return {\n timeDimension: timeDim.dimension,\n granularity: timeDim.granularity,\n dimensions,\n measures\n }\n}\n\n/**\n * Extracts unique time values from data and sorts them chronologically\n */\nfunction extractAndSortTimeValues(\n data: any[],\n timeDimension: string,\n granularity: string\n): string[] {\n const timeSet = new Set<string>()\n\n data.forEach(row => {\n const rawTime = row[timeDimension]\n if (rawTime != null) {\n const formattedTime = formatTimeValue(rawTime, granularity)\n timeSet.add(formattedTime)\n }\n })\n\n // Sort chronologically - ISO date strings sort correctly alphabetically\n return Array.from(timeSet).sort()\n}\n\n/**\n * Builds column definitions for pivoted table\n * Order: Measure (if multiple) -> Dimensions -> Time columns\n */\nfunction buildColumns(\n config: PivotConfig,\n timeValues: string[],\n getFieldLabel: (field: string) => string\n): PivotColumn[] {\n const columns: PivotColumn[] = []\n\n // Add measure column first (if multiple measures)\n if (config.measures.length > 1) {\n columns.push({\n key: '__measure__',\n label: 'Measure',\n isTimeColumn: false,\n isMeasureColumn: true\n })\n }\n\n // Add dimension columns\n config.dimensions.forEach(dim => {\n columns.push({\n key: dim,\n label: getFieldLabel(dim),\n isTimeColumn: false\n })\n })\n\n // Add time columns (already sorted chronologically)\n timeValues.forEach(timeVal => {\n columns.push({\n key: timeVal,\n label: timeVal,\n isTimeColumn: true\n })\n })\n\n return columns\n}\n\n/**\n * Groups data by dimension values, then by time period\n * Returns Map<dimensionKey, Map<formattedTime, dataRow>>\n */\nfunction groupByDimensions(\n data: any[],\n config: PivotConfig\n): Map<string, Map<string, any>> {\n const grouped = new Map<string, Map<string, any>>()\n\n data.forEach(row => {\n // Build dimension key from all dimension values\n const dimKey = config.dimensions.length > 0\n ? config.dimensions.map(dim => String(row[dim] ?? '')).join('|')\n : '__all__'\n\n // Get or create time map for this dimension combo\n if (!grouped.has(dimKey)) {\n grouped.set(dimKey, new Map())\n }\n\n // Store data point by formatted time value\n const rawTime = row[config.timeDimension]\n if (rawTime != null) {\n const formattedTime = formatTimeValue(rawTime, config.granularity)\n grouped.get(dimKey)!.set(formattedTime, row)\n }\n })\n\n return grouped\n}\n\n/**\n * Builds pivoted rows from grouped data\n * Rows are grouped by measure first (all Revenue rows together, all Quantity rows together)\n * Then within each measure group, rows are ordered by dimension values\n */\nfunction buildPivotedRows(\n data: any[],\n config: PivotConfig,\n timeValues: string[],\n getFieldLabel: (field: string) => string\n): PivotRow[] {\n // Group data by dimensions and time\n const grouped = groupByDimensions(data, config)\n const dimensionKeys = Array.from(grouped.keys())\n\n const rows: PivotRow[] = []\n const measureCount = config.measures.length\n const dimensionCount = dimensionKeys.length\n\n // Iterate over measures first, then dimensions\n // This groups all rows for one measure together\n config.measures.forEach((measure) => {\n dimensionKeys.forEach((dimensionKey, dimIndex) => {\n const timeData = grouped.get(dimensionKey)!\n const rowId = measureCount > 1\n ? `${measure}|${dimensionKey}`\n : dimensionKey\n\n const values: Record<string, any> = {}\n\n // Add dimension values\n const dimValues = dimensionKey === '__all__' ? [] : dimensionKey.split('|')\n config.dimensions.forEach((dim, idx) => {\n values[dim] = dimValues[idx] ?? ''\n })\n\n // Add measure name if multiple measures (for display in Measure column)\n if (measureCount > 1) {\n values['__measure__'] = getFieldLabel(measure)\n }\n\n // Add time period values\n timeValues.forEach(timeVal => {\n const dataPoint = timeData.get(timeVal)\n values[timeVal] = dataPoint?.[measure] ?? null\n })\n\n // Track grouping for row spanning (when multiple measures)\n // First row of each measure group should span all dimension rows\n const isFirstInGroup = dimIndex === 0\n const measureRowSpan = isFirstInGroup && measureCount > 1 ? dimensionCount : undefined\n\n rows.push({\n id: rowId,\n measureField: measure,\n values,\n isFirstInGroup,\n dimensionRowSpan: measureRowSpan\n })\n })\n })\n\n return rows\n}\n\n/**\n * Pivots flat data into time-columned table structure\n *\n * @param data Raw data array from query result\n * @param config Pivot configuration\n * @param getFieldLabel Function to get display label for a field\n * @param meta Optional cube metadata for looking up measure types\n * @returns Pivoted table data structure\n */\nexport function pivotTableData(\n data: any[],\n config: PivotConfig,\n getFieldLabel: (field: string) => string,\n _meta?: CubeMeta | null\n): PivotedTableData {\n if (!data || data.length === 0) {\n return { isPivoted: true, columns: [], rows: [] }\n }\n\n // Extract unique time values and sort chronologically\n const timeValues = extractAndSortTimeValues(data, config.timeDimension, config.granularity)\n\n // Build column definitions\n const columns = buildColumns(config, timeValues, getFieldLabel)\n\n // Build pivoted rows\n const rows = buildPivotedRows(data, config, timeValues, getFieldLabel)\n\n return { isPivoted: true, columns, rows }\n}\n\n/**\n * Looks up the measure type from metadata\n *\n * @param measureField The fully qualified measure field name (e.g., \"Sales.revenue\")\n * @param meta Cube metadata\n * @returns The measure type (e.g., \"sum\", \"count\", \"avg\") or undefined\n */\nexport function getMeasureType(measureField: string, meta: CubeMeta | null): string | undefined {\n if (!meta?.cubes) return undefined\n\n for (const cube of meta.cubes) {\n const measure = cube.measures.find(m => m.name === measureField)\n if (measure) {\n return measure.type\n }\n }\n\n return undefined\n}\n","/**\n * Data Table component with time dimension pivoting\n *\n * When a query includes a time dimension with granularity, the table\n * automatically pivots to show time periods as columns.\n */\n\nimport React, { useMemo } from 'react'\nimport { useCubeMeta } from '../../providers/CubeProvider'\nimport { getMeasureTypeIcon } from '../../icons'\nimport {\n hasTimeDimensionForPivot,\n pivotTableData,\n getMeasureType,\n getOrderedColumnsFromQuery,\n type PivotedTableData,\n type PivotColumn,\n type PivotRow\n} from '../../utils/pivotUtils'\nimport { formatAxisValue } from '../../utils/chartUtils'\nimport type { ChartProps, AxisFormatConfig } from '../../types'\n\nconst DataTable = React.memo(function DataTable({\n data,\n chartConfig,\n displayConfig = {},\n queryObject,\n height = 300\n}: ChartProps) {\n const { getFieldLabel, meta } = useCubeMeta()\n\n // Detect if we should pivot based on query structure\n // Pass chartConfig.xAxis to respect user-configured column ordering\n const pivotConfig = useMemo(\n () => hasTimeDimensionForPivot(queryObject, chartConfig?.xAxis),\n [queryObject, chartConfig?.xAxis]\n )\n\n // Check if pivoting is enabled (default: true when time dimension present)\n const enablePivot = displayConfig?.pivotTimeDimension !== false\n\n // Compute pivoted data if applicable\n const pivotedData = useMemo<PivotedTableData | null>(() => {\n if (!pivotConfig || !enablePivot) return null\n return pivotTableData(data, pivotConfig, getFieldLabel, meta)\n }, [data, pivotConfig, enablePivot, getFieldLabel, meta])\n\n // Empty state\n if (!data || data.length === 0) {\n return (\n <div\n className=\"dc:flex dc:items-center dc:justify-center dc:w-full\"\n style={{ height }}\n >\n <div className=\"dc:text-center text-dc-text-muted\">\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 to display in table</div>\n </div>\n </div>\n )\n }\n\n // Render pivoted table if applicable\n if (pivotedData?.isPivoted && pivotedData.columns.length > 0) {\n return (\n <PivotedTable\n pivotedData={pivotedData}\n height={height}\n meta={meta}\n leftYAxisFormat={displayConfig?.leftYAxisFormat}\n />\n )\n }\n\n // Fallback to flat table rendering\n return (\n <FlatTable\n data={data}\n chartConfig={chartConfig}\n queryObject={queryObject}\n height={height}\n getFieldLabel={getFieldLabel}\n leftYAxisFormat={displayConfig?.leftYAxisFormat}\n />\n )\n})\n\nexport default DataTable\n\n/**\n * Pivoted table component - renders time dimension as columns\n */\nfunction PivotedTable({\n pivotedData,\n height,\n meta,\n leftYAxisFormat\n}: {\n pivotedData: PivotedTableData\n height: number | string\n meta: any\n leftYAxisFormat?: AxisFormatConfig\n}) {\n const { columns, rows } = pivotedData\n\n if (columns.length === 0 || rows.length === 0) {\n return (\n <div\n className=\"dc:flex dc:items-center dc:justify-center dc:w-full\"\n style={{ height }}\n >\n <div className=\"dc:text-center text-dc-text-muted\">\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 to display in table</div>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"dc:w-full dc:overflow-auto\" style={{ height }}>\n <table className=\"dc:min-w-full dc:divide-y border-dc-border\">\n <thead className=\"bg-dc-surface-secondary dc:sticky dc:top-0\">\n <tr>\n {columns.map((col: PivotColumn) => (\n <th\n key={col.key}\n className={`dc:px-3 dc:py-2 dc:text-xs dc:font-medium text-dc-text-muted dc:uppercase dc:tracking-wider dc:whitespace-nowrap ${\n col.isTimeColumn ? 'dc:text-right' : 'dc:text-left'\n }`}\n >\n {col.label}\n </th>\n ))}\n </tr>\n </thead>\n <tbody className=\"bg-dc-surface dc:divide-y border-dc-border\">\n {rows.map((row: PivotRow) => (\n <PivotedTableRow\n key={row.id}\n row={row}\n columns={columns}\n meta={meta}\n leftYAxisFormat={leftYAxisFormat}\n />\n ))}\n </tbody>\n </table>\n </div>\n )\n}\n\n/**\n * Single row in the pivoted table\n * Supports row spanning for measure cells when grouped by measure\n */\nfunction PivotedTableRow({\n row,\n columns,\n meta,\n leftYAxisFormat\n}: {\n row: PivotRow\n columns: PivotColumn[]\n meta: any\n leftYAxisFormat?: AxisFormatConfig\n}) {\n // Get measure icon for this row\n const measureType = getMeasureType(row.measureField, meta)\n const MeasureIcon = getMeasureTypeIcon(measureType)\n\n return (\n <tr className=\"hover:bg-dc-surface-secondary\">\n {columns.map((col: PivotColumn) => {\n const value = row.values[col.key]\n\n // Measure column - show icon + label with row spanning\n if (col.isMeasureColumn) {\n // Skip this cell if not first in measure group\n if (row.isFirstInGroup === false) {\n return null\n }\n\n return (\n <td\n key={col.key}\n className=\"dc:px-3 dc:py-2 dc:whitespace-nowrap dc:text-sm text-dc-text dc:align-top\"\n rowSpan={row.dimensionRowSpan}\n >\n <div className=\"dc:flex dc:items-center\">\n <MeasureIcon className=\"dc:w-3.5 dc:h-3.5 dc:mr-1.5 text-dc-text-muted dc:shrink-0\" />\n <span>{value}</span>\n </div>\n </td>\n )\n }\n\n // Time column - right-aligned, formatted values (these are measure values)\n if (col.isTimeColumn) {\n return (\n <td\n key={col.key}\n className=\"dc:px-3 dc:py-2 dc:whitespace-nowrap dc:text-sm dc:text-right text-dc-text\"\n >\n {formatPivotCellValue(value, leftYAxisFormat)}\n </td>\n )\n }\n\n // Dimension column - left-aligned (no row spanning) - no number formatting\n return (\n <td\n key={col.key}\n className=\"dc:px-3 dc:py-2 dc:whitespace-nowrap dc:text-sm text-dc-text\"\n >\n {formatPivotCellValue(value)}\n </td>\n )\n })}\n </tr>\n )\n}\n\n/**\n * Format cell value for pivoted table display\n * Shows \"-\" for null/undefined values\n */\nfunction formatPivotCellValue(value: any, formatConfig?: AxisFormatConfig): string {\n if (value === null || value === undefined) return '-'\n if (typeof value === 'number') {\n // Use formatAxisValue if config provided\n if (formatConfig) {\n return formatAxisValue(value, formatConfig)\n }\n // Format with locale and up to 2 decimal places\n if (Number.isInteger(value)) {\n return value.toLocaleString()\n }\n return parseFloat(value.toFixed(2)).toLocaleString()\n }\n if (typeof value === 'boolean') {\n return value ? 'Yes' : 'No'\n }\n return String(value)\n}\n\n/**\n * Flat table component - original non-pivoted table rendering\n */\nfunction FlatTable({\n data,\n chartConfig,\n queryObject,\n height,\n getFieldLabel,\n leftYAxisFormat\n}: {\n data: any[]\n chartConfig?: { xAxis?: string[] }\n queryObject?: ChartProps['queryObject']\n height: number | string\n getFieldLabel: (field: string) => string\n leftYAxisFormat?: AxisFormatConfig\n}) {\n // Get all columns available in data\n const allColumns = Object.keys(data[0] || {})\n\n // Determine column order with proper fallback:\n // 1. If xAxis is configured, use that order\n // 2. Otherwise, derive order from queryObject (dimensions + timeDimensions + measures)\n // 3. Fallback: Object.keys order\n const columns = useMemo(() => {\n // If xAxis is configured, use that order (filtered to existing columns)\n if (chartConfig?.xAxis && chartConfig.xAxis.length > 0) {\n return chartConfig.xAxis.filter(col => allColumns.includes(col))\n }\n\n // Derive order from queryObject\n const queryOrder = getOrderedColumnsFromQuery(queryObject)\n if (queryOrder.length > 0) {\n // Filter to only columns that exist in data\n const ordered = queryOrder.filter(col => allColumns.includes(col))\n // Add any columns in data that weren't in query (edge case)\n const remaining = allColumns.filter(col => !ordered.includes(col))\n return [...ordered, ...remaining]\n }\n\n // Final fallback: Object.keys order\n return allColumns\n }, [chartConfig?.xAxis, queryObject, allColumns])\n\n if (columns.length === 0) {\n return (\n <div\n className=\"dc:flex dc:items-center dc:justify-center dc:w-full\"\n style={{ height }}\n >\n <div className=\"dc:text-center text-dc-text-muted\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">No columns available</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">Data structure is invalid</div>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"dc:w-full dc:overflow-auto\" style={{ height }}>\n <table className=\"dc:min-w-full dc:divide-y border-dc-border\">\n <thead className=\"bg-dc-surface-secondary dc:sticky dc:top-0\">\n <tr>\n {columns.map((column) => (\n <th\n key={column}\n className=\"dc:px-3 dc:py-2 dc:text-left dc:text-xs dc:font-medium text-dc-text-muted dc:uppercase dc:tracking-wider\"\n >\n {getFieldLabel(column)}\n </th>\n ))}\n </tr>\n </thead>\n <tbody className=\"bg-dc-surface dc:divide-y border-dc-border\">\n {data.map((row, index) => (\n <tr key={index} className=\"hover:bg-dc-surface-secondary\">\n {columns.map((column) => (\n <td\n key={column}\n className=\"dc:px-3 dc:py-2 dc:whitespace-nowrap dc:text-sm text-dc-text\"\n >\n {formatCellValue(row[column], leftYAxisFormat)}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )\n}\n\n/**\n * Format cell value for flat table display\n */\nfunction formatCellValue(value: any, formatConfig?: AxisFormatConfig): string {\n if (value == null) return ''\n if (typeof value === 'number') {\n // Use formatAxisValue if config provided\n if (formatConfig) {\n return formatAxisValue(value, formatConfig)\n }\n return value.toLocaleString()\n }\n if (typeof value === 'boolean') {\n return value ? 'Yes' : 'No'\n }\n return String(value)\n}\n"],"names":["getOrderedColumnsFromQuery","queryObject","columns","td","hasTimeDimensionForPivot","xAxisOverride","timeDim","dimensions","measures","field","measuresInXAxis","extractAndSortTimeValues","data","timeDimension","granularity","timeSet","row","rawTime","formattedTime","formatTimeValue","buildColumns","config","timeValues","getFieldLabel","dim","timeVal","groupByDimensions","grouped","dimKey","buildPivotedRows","dimensionKeys","rows","measureCount","dimensionCount","measure","dimensionKey","dimIndex","timeData","rowId","values","dimValues","idx","dataPoint","isFirstInGroup","measureRowSpan","pivotTableData","_meta","getMeasureType","measureField","meta","cube","m","DataTable","React","chartConfig","displayConfig","height","useCubeMeta","pivotConfig","useMemo","enablePivot","pivotedData","jsx","jsxs","PivotedTable","FlatTable","leftYAxisFormat","col","PivotedTableRow","measureType","MeasureIcon","getMeasureTypeIcon","value","formatPivotCellValue","formatConfig","formatAxisValue","allColumns","queryOrder","ordered","remaining","column","index","formatCellValue"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"chart-data-table-DJZPkArt.js","sources":["../../../src/client/utils/pivotUtils.ts","../../../src/client/components/charts/DataTable.tsx"],"sourcesContent":["/**\n * Pivot utilities for DataTable time dimension pivoting\n *\n * When a query includes a time dimension with granularity, transforms flat data\n * into a pivoted structure with time periods as columns.\n */\n\nimport type { CubeQuery, CubeMeta } from '../types'\nimport { formatTimeValue } from './chartUtils'\n\n/**\n * Derives ordered column list from a CubeQuery object.\n * Order: dimensions, timeDimensions (as field names), measures\n *\n * @param queryObject The CubeQuery object\n * @returns Array of field names in order\n */\nexport function getOrderedColumnsFromQuery(queryObject?: CubeQuery): string[] {\n if (!queryObject) return []\n\n const columns: string[] = []\n\n // Add regular dimensions first\n if (queryObject.dimensions) {\n columns.push(...queryObject.dimensions)\n }\n\n // Add time dimensions\n if (queryObject.timeDimensions) {\n queryObject.timeDimensions.forEach(td => {\n if (!columns.includes(td.dimension)) {\n columns.push(td.dimension)\n }\n })\n }\n\n // Add measures last\n if (queryObject.measures) {\n columns.push(...queryObject.measures)\n }\n\n return columns\n}\n\n/**\n * Configuration for pivoting based on query structure\n */\nexport interface PivotConfig {\n /** Time dimension field name (e.g., \"Sales.date\") */\n timeDimension: string\n /** Time granularity (e.g., \"month\", \"day\", \"year\") */\n granularity: string\n /** Non-time dimension fields */\n dimensions: string[]\n /** Measure fields */\n measures: string[]\n}\n\n/**\n * Column definition for pivoted table\n */\nexport interface PivotColumn {\n /** Column key for data access */\n key: string\n /** Display label for column header */\n label: string\n /** Whether this is a time column (vs row identifier column) */\n isTimeColumn: boolean\n /** Whether this is the measure column */\n isMeasureColumn?: boolean\n}\n\n/**\n * Row in the pivoted table\n */\nexport interface PivotRow {\n /** Unique row identifier */\n id: string\n /** The measure field name (for icon lookup) */\n measureField: string\n /** Values keyed by column key */\n values: Record<string, any>\n /** Whether this is the first row in a dimension group (for row spanning) */\n isFirstInGroup?: boolean\n /** Number of rows to span for dimension cells (only set on first row in group) */\n dimensionRowSpan?: number\n}\n\n/**\n * Result of pivoting table data\n */\nexport interface PivotedTableData {\n /** Whether data was pivoted (has time dimension with granularity) */\n isPivoted: boolean\n /** Column definitions for the pivoted table */\n columns: PivotColumn[]\n /** Rows of pivoted data */\n rows: PivotRow[]\n}\n\n/**\n * Determines if a query has a time dimension with granularity that should trigger pivoting\n * @param queryObject The CubeQuery object\n * @param xAxisOverride Optional array of fields to use for filtering dimensions and measures\n * (for respecting chartConfig.xAxis configuration)\n * @returns PivotConfig if pivoting should occur, null otherwise\n */\nexport function hasTimeDimensionForPivot(\n queryObject?: CubeQuery,\n xAxisOverride?: string[]\n): PivotConfig | null {\n if (!queryObject?.timeDimensions?.length) return null\n\n // Find the first time dimension with granularity\n const timeDim = queryObject.timeDimensions.find(td => td.granularity)\n if (!timeDim?.granularity) return null\n\n // Must have at least one measure to pivot\n if (!queryObject.measures?.length) return null\n\n let dimensions: string[]\n let measures: string[]\n\n if (xAxisOverride && xAxisOverride.length > 0) {\n // Filter dimensions from xAxisOverride (excluding time dimension and measures)\n dimensions = xAxisOverride.filter(field => {\n // Exclude the time dimension being pivoted (it becomes columns)\n if (field === timeDim.dimension) return false\n // Exclude measures (they become row values, not dimension columns)\n if (queryObject.measures?.includes(field)) return false\n return true\n })\n\n // Filter measures from xAxisOverride - only show measures that are in xAxis\n const measuresInXAxis = xAxisOverride.filter(field =>\n queryObject.measures?.includes(field)\n )\n // If xAxis contains measures, use only those; otherwise fall back to all measures\n measures = measuresInXAxis.length > 0 ? measuresInXAxis : queryObject.measures\n } else {\n dimensions = queryObject.dimensions || []\n measures = queryObject.measures\n }\n\n // Must have at least one measure after filtering\n if (measures.length === 0) return null\n\n return {\n timeDimension: timeDim.dimension,\n granularity: timeDim.granularity,\n dimensions,\n measures\n }\n}\n\n/**\n * Extracts unique time values from data and sorts them chronologically\n */\nfunction extractAndSortTimeValues(\n data: any[],\n timeDimension: string,\n granularity: string\n): string[] {\n const timeSet = new Set<string>()\n\n data.forEach(row => {\n const rawTime = row[timeDimension]\n if (rawTime != null) {\n const formattedTime = formatTimeValue(rawTime, granularity)\n timeSet.add(formattedTime)\n }\n })\n\n // Sort chronologically - ISO date strings sort correctly alphabetically\n return Array.from(timeSet).sort()\n}\n\n/**\n * Builds column definitions for pivoted table\n * Order: Measure (if multiple) -> Dimensions -> Time columns\n */\nfunction buildColumns(\n config: PivotConfig,\n timeValues: string[],\n getFieldLabel: (field: string) => string\n): PivotColumn[] {\n const columns: PivotColumn[] = []\n\n // Add measure column first (if multiple measures)\n if (config.measures.length > 1) {\n columns.push({\n key: '__measure__',\n label: 'Measure',\n isTimeColumn: false,\n isMeasureColumn: true\n })\n }\n\n // Add dimension columns\n config.dimensions.forEach(dim => {\n columns.push({\n key: dim,\n label: getFieldLabel(dim),\n isTimeColumn: false\n })\n })\n\n // Add time columns (already sorted chronologically)\n timeValues.forEach(timeVal => {\n columns.push({\n key: timeVal,\n label: timeVal,\n isTimeColumn: true\n })\n })\n\n return columns\n}\n\n/**\n * Groups data by dimension values, then by time period\n * Returns Map<dimensionKey, Map<formattedTime, dataRow>>\n */\nfunction groupByDimensions(\n data: any[],\n config: PivotConfig\n): Map<string, Map<string, any>> {\n const grouped = new Map<string, Map<string, any>>()\n\n data.forEach(row => {\n // Build dimension key from all dimension values\n const dimKey = config.dimensions.length > 0\n ? config.dimensions.map(dim => String(row[dim] ?? '')).join('|')\n : '__all__'\n\n // Get or create time map for this dimension combo\n if (!grouped.has(dimKey)) {\n grouped.set(dimKey, new Map())\n }\n\n // Store data point by formatted time value\n const rawTime = row[config.timeDimension]\n if (rawTime != null) {\n const formattedTime = formatTimeValue(rawTime, config.granularity)\n grouped.get(dimKey)!.set(formattedTime, row)\n }\n })\n\n return grouped\n}\n\n/**\n * Builds pivoted rows from grouped data\n * Rows are grouped by measure first (all Revenue rows together, all Quantity rows together)\n * Then within each measure group, rows are ordered by dimension values\n */\nfunction buildPivotedRows(\n data: any[],\n config: PivotConfig,\n timeValues: string[],\n getFieldLabel: (field: string) => string\n): PivotRow[] {\n // Group data by dimensions and time\n const grouped = groupByDimensions(data, config)\n const dimensionKeys = Array.from(grouped.keys())\n\n const rows: PivotRow[] = []\n const measureCount = config.measures.length\n const dimensionCount = dimensionKeys.length\n\n // Iterate over measures first, then dimensions\n // This groups all rows for one measure together\n config.measures.forEach((measure) => {\n dimensionKeys.forEach((dimensionKey, dimIndex) => {\n const timeData = grouped.get(dimensionKey)!\n const rowId = measureCount > 1\n ? `${measure}|${dimensionKey}`\n : dimensionKey\n\n const values: Record<string, any> = {}\n\n // Add dimension values\n const dimValues = dimensionKey === '__all__' ? [] : dimensionKey.split('|')\n config.dimensions.forEach((dim, idx) => {\n values[dim] = dimValues[idx] ?? ''\n })\n\n // Add measure name if multiple measures (for display in Measure column)\n if (measureCount > 1) {\n values['__measure__'] = getFieldLabel(measure)\n }\n\n // Add time period values\n timeValues.forEach(timeVal => {\n const dataPoint = timeData.get(timeVal)\n values[timeVal] = dataPoint?.[measure] ?? null\n })\n\n // Track grouping for row spanning (when multiple measures)\n // First row of each measure group should span all dimension rows\n const isFirstInGroup = dimIndex === 0\n const measureRowSpan = isFirstInGroup && measureCount > 1 ? dimensionCount : undefined\n\n rows.push({\n id: rowId,\n measureField: measure,\n values,\n isFirstInGroup,\n dimensionRowSpan: measureRowSpan\n })\n })\n })\n\n return rows\n}\n\n/**\n * Pivots flat data into time-columned table structure\n *\n * @param data Raw data array from query result\n * @param config Pivot configuration\n * @param getFieldLabel Function to get display label for a field\n * @param meta Optional cube metadata for looking up measure types\n * @returns Pivoted table data structure\n */\nexport function pivotTableData(\n data: any[],\n config: PivotConfig,\n getFieldLabel: (field: string) => string,\n _meta?: CubeMeta | null\n): PivotedTableData {\n if (!data || data.length === 0) {\n return { isPivoted: true, columns: [], rows: [] }\n }\n\n // Extract unique time values and sort chronologically\n const timeValues = extractAndSortTimeValues(data, config.timeDimension, config.granularity)\n\n // Build column definitions\n const columns = buildColumns(config, timeValues, getFieldLabel)\n\n // Build pivoted rows\n const rows = buildPivotedRows(data, config, timeValues, getFieldLabel)\n\n return { isPivoted: true, columns, rows }\n}\n\n/**\n * Looks up the measure type from metadata\n *\n * @param measureField The fully qualified measure field name (e.g., \"Sales.revenue\")\n * @param meta Cube metadata\n * @returns The measure type (e.g., \"sum\", \"count\", \"avg\") or undefined\n */\nexport function getMeasureType(measureField: string, meta: CubeMeta | null): string | undefined {\n if (!meta?.cubes) return undefined\n\n for (const cube of meta.cubes) {\n const measure = cube.measures.find(m => m.name === measureField)\n if (measure) {\n return measure.type\n }\n }\n\n return undefined\n}\n","/**\n * Data Table component with time dimension pivoting\n *\n * When a query includes a time dimension with granularity, the table\n * automatically pivots to show time periods as columns.\n */\n\nimport React, { useMemo } from 'react'\nimport { useCubeMeta } from '../../providers/CubeProvider'\nimport { getMeasureTypeIcon } from '../../icons'\nimport {\n hasTimeDimensionForPivot,\n pivotTableData,\n getMeasureType,\n getOrderedColumnsFromQuery,\n type PivotedTableData,\n type PivotColumn,\n type PivotRow\n} from '../../utils/pivotUtils'\nimport { formatAxisValue } from '../../utils/chartUtils'\nimport type { ChartProps, AxisFormatConfig } from '../../types'\n\nconst DataTable = React.memo(function DataTable({\n data,\n chartConfig,\n displayConfig = {},\n queryObject,\n height = 300\n}: ChartProps) {\n const { getFieldLabel, meta } = useCubeMeta()\n\n // Detect if we should pivot based on query structure\n // Pass chartConfig.xAxis to respect user-configured column ordering\n const pivotConfig = useMemo(\n () => hasTimeDimensionForPivot(queryObject, chartConfig?.xAxis),\n [queryObject, chartConfig?.xAxis]\n )\n\n // Check if pivoting is enabled (default: true when time dimension present)\n const enablePivot = displayConfig?.pivotTimeDimension !== false\n\n // Compute pivoted data if applicable\n const pivotedData = useMemo<PivotedTableData | null>(() => {\n if (!pivotConfig || !enablePivot) return null\n return pivotTableData(data, pivotConfig, getFieldLabel, meta)\n }, [data, pivotConfig, enablePivot, getFieldLabel, meta])\n\n // Empty state\n if (!data || data.length === 0) {\n return (\n <div\n className=\"dc:flex dc:items-center dc:justify-center dc:w-full\"\n style={{ height }}\n >\n <div className=\"dc:text-center text-dc-text-muted\">\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 to display in table</div>\n </div>\n </div>\n )\n }\n\n // Render pivoted table if applicable\n if (pivotedData?.isPivoted && pivotedData.columns.length > 0) {\n return (\n <PivotedTable\n pivotedData={pivotedData}\n height={height}\n meta={meta}\n leftYAxisFormat={displayConfig?.leftYAxisFormat}\n />\n )\n }\n\n // Fallback to flat table rendering\n return (\n <FlatTable\n data={data}\n chartConfig={chartConfig}\n queryObject={queryObject}\n height={height}\n getFieldLabel={getFieldLabel}\n leftYAxisFormat={displayConfig?.leftYAxisFormat}\n />\n )\n})\n\nexport default DataTable\n\n/**\n * Pivoted table component - renders time dimension as columns\n */\nfunction PivotedTable({\n pivotedData,\n height,\n meta,\n leftYAxisFormat\n}: {\n pivotedData: PivotedTableData\n height: number | string\n meta: any\n leftYAxisFormat?: AxisFormatConfig\n}) {\n const { columns, rows } = pivotedData\n\n if (columns.length === 0 || rows.length === 0) {\n return (\n <div\n className=\"dc:flex dc:items-center dc:justify-center dc:w-full\"\n style={{ height }}\n >\n <div className=\"dc:text-center text-dc-text-muted\">\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 to display in table</div>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"dc:w-full dc:overflow-auto\" style={{ height }}>\n <table className=\"dc:min-w-full dc:divide-y border-dc-border\">\n <thead className=\"bg-dc-surface-secondary dc:sticky dc:top-0\">\n <tr>\n {columns.map((col: PivotColumn) => (\n <th\n key={col.key}\n className={`dc:px-3 dc:py-2 dc:text-xs dc:font-medium text-dc-text-muted dc:uppercase dc:tracking-wider dc:whitespace-nowrap ${\n col.isTimeColumn ? 'dc:text-right' : 'dc:text-left'\n }`}\n >\n {col.label}\n </th>\n ))}\n </tr>\n </thead>\n <tbody className=\"bg-dc-surface dc:divide-y border-dc-border\">\n {rows.map((row: PivotRow) => (\n <PivotedTableRow\n key={row.id}\n row={row}\n columns={columns}\n meta={meta}\n leftYAxisFormat={leftYAxisFormat}\n />\n ))}\n </tbody>\n </table>\n </div>\n )\n}\n\n/**\n * Single row in the pivoted table\n * Supports row spanning for measure cells when grouped by measure\n */\nfunction PivotedTableRow({\n row,\n columns,\n meta,\n leftYAxisFormat\n}: {\n row: PivotRow\n columns: PivotColumn[]\n meta: any\n leftYAxisFormat?: AxisFormatConfig\n}) {\n // Get measure icon for this row\n const measureType = getMeasureType(row.measureField, meta)\n const MeasureIcon = getMeasureTypeIcon(measureType)\n\n return (\n <tr className=\"hover:bg-dc-surface-secondary\">\n {columns.map((col: PivotColumn) => {\n const value = row.values[col.key]\n\n // Measure column - show icon + label with row spanning\n if (col.isMeasureColumn) {\n // Skip this cell if not first in measure group\n if (row.isFirstInGroup === false) {\n return null\n }\n\n return (\n <td\n key={col.key}\n className=\"dc:px-3 dc:py-2 dc:whitespace-nowrap dc:text-sm text-dc-text dc:align-top\"\n rowSpan={row.dimensionRowSpan}\n >\n <div className=\"dc:flex dc:items-center\">\n <MeasureIcon className=\"dc:w-3.5 dc:h-3.5 dc:mr-1.5 text-dc-text-muted dc:shrink-0\" />\n <span>{value}</span>\n </div>\n </td>\n )\n }\n\n // Time column - right-aligned, formatted values (these are measure values)\n if (col.isTimeColumn) {\n return (\n <td\n key={col.key}\n className=\"dc:px-3 dc:py-2 dc:whitespace-nowrap dc:text-sm dc:text-right text-dc-text\"\n >\n {formatPivotCellValue(value, leftYAxisFormat)}\n </td>\n )\n }\n\n // Dimension column - left-aligned (no row spanning) - no number formatting\n return (\n <td\n key={col.key}\n className=\"dc:px-3 dc:py-2 dc:whitespace-nowrap dc:text-sm text-dc-text\"\n >\n {formatPivotCellValue(value)}\n </td>\n )\n })}\n </tr>\n )\n}\n\n/**\n * Format cell value for pivoted table display\n * Shows \"-\" for null/undefined values\n */\nfunction formatPivotCellValue(value: any, formatConfig?: AxisFormatConfig): string {\n if (value === null || value === undefined) return '-'\n if (typeof value === 'number') {\n // Use formatAxisValue if config provided\n if (formatConfig) {\n return formatAxisValue(value, formatConfig)\n }\n // Format with locale and up to 2 decimal places\n if (Number.isInteger(value)) {\n return value.toLocaleString()\n }\n return parseFloat(value.toFixed(2)).toLocaleString()\n }\n if (typeof value === 'boolean') {\n return value ? 'Yes' : 'No'\n }\n return String(value)\n}\n\n/**\n * Flat table component - original non-pivoted table rendering\n */\nfunction FlatTable({\n data,\n chartConfig,\n queryObject,\n height,\n getFieldLabel,\n leftYAxisFormat\n}: {\n data: any[]\n chartConfig?: { xAxis?: string[] }\n queryObject?: ChartProps['queryObject']\n height: number | string\n getFieldLabel: (field: string) => string\n leftYAxisFormat?: AxisFormatConfig\n}) {\n // Get all columns available in data\n const allColumns = Object.keys(data[0] || {})\n\n // Determine column order with proper fallback:\n // 1. If xAxis is configured, use that order\n // 2. Otherwise, derive order from queryObject (dimensions + timeDimensions + measures)\n // 3. Fallback: Object.keys order\n const columns = useMemo(() => {\n // If xAxis is configured, use that order (filtered to existing columns)\n if (chartConfig?.xAxis && chartConfig.xAxis.length > 0) {\n return chartConfig.xAxis.filter(col => allColumns.includes(col))\n }\n\n // Derive order from queryObject\n const queryOrder = getOrderedColumnsFromQuery(queryObject)\n if (queryOrder.length > 0) {\n // Filter to only columns that exist in data\n const ordered = queryOrder.filter(col => allColumns.includes(col))\n // Add any columns in data that weren't in query (edge case)\n const remaining = allColumns.filter(col => !ordered.includes(col))\n return [...ordered, ...remaining]\n }\n\n // Final fallback: Object.keys order\n return allColumns\n }, [chartConfig?.xAxis, queryObject, allColumns])\n\n if (columns.length === 0) {\n return (\n <div\n className=\"dc:flex dc:items-center dc:justify-center dc:w-full\"\n style={{ height }}\n >\n <div className=\"dc:text-center text-dc-text-muted\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">No columns available</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">Data structure is invalid</div>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"dc:w-full dc:overflow-auto\" style={{ height }}>\n <table className=\"dc:min-w-full dc:divide-y border-dc-border\">\n <thead className=\"bg-dc-surface-secondary dc:sticky dc:top-0\">\n <tr>\n {columns.map((column) => (\n <th\n key={column}\n className=\"dc:px-3 dc:py-2 dc:text-left dc:text-xs dc:font-medium text-dc-text-muted dc:uppercase dc:tracking-wider\"\n >\n {getFieldLabel(column)}\n </th>\n ))}\n </tr>\n </thead>\n <tbody className=\"bg-dc-surface dc:divide-y border-dc-border\">\n {data.map((row, index) => (\n <tr key={index} className=\"hover:bg-dc-surface-secondary\">\n {columns.map((column) => (\n <td\n key={column}\n className=\"dc:px-3 dc:py-2 dc:whitespace-nowrap dc:text-sm text-dc-text\"\n >\n {formatCellValue(row[column], leftYAxisFormat)}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )\n}\n\n/**\n * Format cell value for flat table display\n */\nfunction formatCellValue(value: any, formatConfig?: AxisFormatConfig): string {\n if (value == null) return ''\n if (typeof value === 'number') {\n // Use formatAxisValue if config provided\n if (formatConfig) {\n return formatAxisValue(value, formatConfig)\n }\n return value.toLocaleString()\n }\n if (typeof value === 'boolean') {\n return value ? 'Yes' : 'No'\n }\n return String(value)\n}\n"],"names":["getOrderedColumnsFromQuery","queryObject","columns","td","hasTimeDimensionForPivot","xAxisOverride","timeDim","dimensions","measures","field","measuresInXAxis","extractAndSortTimeValues","data","timeDimension","granularity","timeSet","row","rawTime","formattedTime","formatTimeValue","buildColumns","config","timeValues","getFieldLabel","dim","timeVal","groupByDimensions","grouped","dimKey","buildPivotedRows","dimensionKeys","rows","measureCount","dimensionCount","measure","dimensionKey","dimIndex","timeData","rowId","values","dimValues","idx","dataPoint","isFirstInGroup","measureRowSpan","pivotTableData","_meta","getMeasureType","measureField","meta","cube","m","DataTable","React","chartConfig","displayConfig","height","useCubeMeta","pivotConfig","useMemo","enablePivot","pivotedData","jsx","jsxs","PivotedTable","FlatTable","leftYAxisFormat","col","PivotedTableRow","measureType","MeasureIcon","getMeasureTypeIcon","value","formatPivotCellValue","formatConfig","formatAxisValue","allColumns","queryOrder","ordered","remaining","column","index","formatCellValue"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as e, jsxs as t } from "react/jsx-runtime";
|
|
2
2
|
import R, { useMemo as k } from "react";
|
|
3
3
|
import { ResponsiveContainer as A, FunnelChart as D, Tooltip as P, Funnel as z, Cell as B, LabelList as j } from "recharts";
|
|
4
|
-
import { c as E } from "./charts-core-
|
|
4
|
+
import { c as E } from "./charts-core-B4Rbfdcn.js";
|
|
5
5
|
import { f as y } from "./funnel-utils-CyonoNeC.js";
|
|
6
6
|
const K = [
|
|
7
7
|
"#3B82F6",
|
|
@@ -256,4 +256,4 @@ const J = R.memo(function({
|
|
|
256
256
|
export {
|
|
257
257
|
J as default
|
|
258
258
|
};
|
|
259
|
-
//# sourceMappingURL=chart-funnel-
|
|
259
|
+
//# sourceMappingURL=chart-funnel-CE9x0Io9.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-funnel-dofnhD24.js","sources":["../../../src/client/components/charts/FunnelChart.tsx"],"sourcesContent":["/**\n * FunnelChart Component\n *\n * Visualizes funnel data showing conversion rates between steps.\n * Uses horizontal bars with percentage widths to represent the funnel shape.\n * Works with data from useFunnelQuery hook which provides FunnelChartData.\n *\n * When displayConfig.showFunnelTimeMetrics is enabled, displays time-to-convert\n * metrics from server-side funnel execution (avg, median, P90 seconds).\n */\n\nimport React, { useMemo } from 'react'\nimport { FunnelChart as RechartsFunnelChart, Funnel, LabelList, Tooltip, Cell, ResponsiveContainer } from 'recharts'\nimport { CHART_COLORS } from '../../utils/chartConstants'\nimport type { ChartProps } from '../../types'\nimport type { FunnelChartData } from '../../types/funnel'\nimport { formatDuration } from '../../utils/funnelExecution'\n\n// Color gradient for funnel steps (darker to lighter)\nconst FUNNEL_COLORS = [\n '#3B82F6', // blue-500\n '#60A5FA', // blue-400\n '#93C5FD', // blue-300\n '#BFDBFE', // blue-200\n '#DBEAFE', // blue-100\n]\n\n/**\n * Get color for a funnel step\n */\nfunction getStepColor(index: number, colorPalette?: string[]): string {\n const colors = colorPalette || FUNNEL_COLORS\n return colors[index % colors.length]\n}\n\n/**\n * Check if data is funnel data format\n */\nfunction isFunnelData(data: unknown[]): data is FunnelChartData[] {\n if (!data || data.length === 0) return false\n const first = data[0]\n return (\n typeof first === 'object' &&\n first !== null &&\n 'name' in first &&\n 'value' in first &&\n 'percentage' in first\n )\n}\n\n/**\n * Render time metrics based on config options - returns array of lines for vertical stacking\n */\nfunction getTimeMetricsLines(\n step: FunnelChartData,\n showAvg: boolean,\n showMedian: boolean,\n showP90: boolean\n): string[] {\n const lines: string[] = []\n if (showAvg && step.avgSecondsToConvert != null) {\n lines.push(`Avg: ${formatDuration(step.avgSecondsToConvert)}`)\n }\n if (showMedian && step.medianSecondsToConvert != null) {\n lines.push(`Med: ${formatDuration(step.medianSecondsToConvert)}`)\n }\n if (showP90 && step.p90SecondsToConvert != null) {\n lines.push(`P90: ${formatDuration(step.p90SecondsToConvert)}`)\n }\n return lines\n}\n\n/**\n * FunnelChart Component\n *\n * Renders a funnel visualization from FunnelChartData array.\n * Shows each step as a horizontal bar with width proportional to count.\n * Displays conversion rates between steps.\n */\nconst FunnelChart = React.memo(function FunnelChart({\n data,\n height = '100%',\n colorPalette,\n displayConfig,\n}: ChartProps) {\n // Get display config options\n const customStepLabels = displayConfig?.funnelStepLabels\n const orientation = displayConfig?.funnelOrientation || 'horizontal'\n const isVertical = orientation === 'vertical'\n const funnelStyle = displayConfig?.funnelStyle ?? 'bars'\n const showConversion = displayConfig?.showFunnelConversion ?? true\n\n // Time metrics - individual toggles with backward compat for showFunnelTimeMetrics\n const showAvgTime = displayConfig?.showFunnelAvgTime ??\n (displayConfig?.showFunnelTimeMetrics ?? false) // backward compat\n const showMedianTime = displayConfig?.showFunnelMedianTime ?? false\n const showP90Time = displayConfig?.showFunnelP90Time ?? false\n\n // Transform data if needed\n const funnelData = useMemo<FunnelChartData[]>(() => {\n if (!data || data.length === 0) return []\n\n // If already funnel data format, use directly\n if (isFunnelData(data)) {\n return data\n }\n\n // Try to convert from raw query results\n // Look for common patterns: step/name, count/value, percentage\n return data.map((row, index) => {\n const record = row as Record<string, unknown>\n\n // Find name field\n const nameField = Object.keys(record).find(\n (k) => k.toLowerCase().includes('step') || k.toLowerCase().includes('name') || k === '__stepName'\n )\n const name = nameField ? String(record[nameField]) : `Step ${index + 1}`\n\n // Find value field\n const valueField = Object.keys(record).find(\n (k) => k.toLowerCase().includes('count') || k.toLowerCase().includes('value') || k === '__count'\n )\n const value = valueField ? Number(record[valueField]) || 0 : 0\n\n // Find percentage field\n const percentField = Object.keys(record).find(\n (k) => k.toLowerCase().includes('percent') || k === '__percentage'\n )\n const percentage = percentField ? Number(record[percentField]) || 0 : 0\n\n // Find conversion rate field\n const convRateField = Object.keys(record).find(\n (k) => k.toLowerCase().includes('conversion') || k === '__conversionRate'\n )\n const conversionRate = convRateField ? Number(record[convRateField]) || null : null\n\n return {\n name,\n value,\n percentage,\n conversionRate,\n stepIndex: index,\n }\n })\n }, [data])\n\n // Calculate first step value for percentage calculations\n const firstStepValue = funnelData[0]?.value || 0\n\n // Handle no data\n if (!data || data.length === 0 || funnelData.length === 0) {\n return (\n <div\n className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-text-muted\"\n style={{ height }}\n >\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">No funnel data</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">\n Configure a funnel with at least 2 steps and a binding key\n </div>\n </div>\n </div>\n )\n }\n\n const paletteColors = colorPalette?.colors || CHART_COLORS\n\n // Render Recharts Funnel style (trapezoid shape)\n if (funnelStyle === 'funnel') {\n // Recharts FunnelChart layout: 'horizontal' = funnel flows left-to-right, 'vertical' = top-to-bottom (default)\n // Our config: 'horizontal' orientation = standard top-to-bottom funnel\n // 'vertical' orientation = left-to-right funnel\n const rechartsLayout: 'horizontal' | 'vertical' = isVertical ? 'horizontal' : 'vertical'\n\n return (\n <div className=\"dc:relative dc:w-full dc:h-full dc:flex dc:flex-col\" style={{ height }}>\n <div className=\"dc:flex-1\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsFunnelChart layout={rechartsLayout} accessibilityLayer={false}>\n <Tooltip\n formatter={(value) => typeof value === 'number' ? value.toLocaleString() : String(value)}\n contentStyle={{\n backgroundColor: 'var(--dc-surface)',\n border: '1px solid var(--dc-border)',\n borderRadius: '4px',\n }}\n />\n <Funnel\n dataKey=\"value\"\n nameKey=\"name\"\n data={funnelData}\n isAnimationActive\n >\n {funnelData.map((_, index) => (\n <Cell key={`cell-${index}`} fill={getStepColor(index, paletteColors)} />\n ))}\n <LabelList\n position=\"right\"\n dataKey=\"name\"\n fill=\"var(--dc-text)\"\n style={{ fontSize: '12px' }}\n />\n <LabelList\n position=\"center\"\n dataKey=\"percentage\"\n formatter={(v) => typeof v === 'number' ? `${v.toFixed(1)}%` : String(v)}\n fill=\"#fff\"\n style={{ fontSize: '11px', fontWeight: 500 }}\n />\n </Funnel>\n </RechartsFunnelChart>\n </ResponsiveContainer>\n </div>\n {/* Summary Footer */}\n {!displayConfig?.hideSummaryFooter && (\n <div className=\"dc:flex-shrink-0 dc:px-4 dc:py-2 dc:border-t border-dc-border bg-dc-surface-secondary\">\n <div className=\"dc:flex dc:items-center dc:justify-between dc:text-sm\">\n <div className=\"text-dc-text-muted\">\n <span className=\"dc:font-medium\">{funnelData.length}</span> steps\n </div>\n <div className=\"text-dc-text\">\n <span className=\"text-dc-text-muted\">Overall:</span>{' '}\n <span className=\"dc:font-medium\">\n {firstStepValue > 0\n ? `${((funnelData[funnelData.length - 1]?.value || 0) / firstStepValue * 100).toFixed(1)}%`\n : '0%'}\n </span>\n </div>\n <div className=\"text-dc-text-muted\">\n {funnelData[funnelData.length - 1]?.value.toLocaleString() || 0} / {firstStepValue.toLocaleString()} completed\n </div>\n </div>\n </div>\n )}\n </div>\n )\n }\n\n // Render vertical orientation (bars grow from bottom to top, steps laid out horizontally)\n if (isVertical) {\n return (\n <div className=\"dc:relative dc:w-full dc:h-full dc:flex dc:flex-col\" style={{ height }}>\n {/* Funnel Steps - Vertical Layout */}\n <div className=\"dc:flex-1 dc:flex dc:items-end dc:justify-center dc:gap-4 dc:px-4 dc:py-3 dc:overflow-hidden\">\n {funnelData.map((step, index) => {\n const heightPercent = firstStepValue > 0 ? (step.value / firstStepValue) * 100 : 0\n const prevStep = index > 0 ? funnelData[index - 1] : null\n const stepConversionRate = prevStep && prevStep.value > 0\n ? (step.value / prevStep.value) * 100\n : null\n\n // Use custom label if provided, otherwise fall back to step name\n const displayName = customStepLabels?.[index] || step.name\n\n const timeMetricsLines = getTimeMetricsLines(step, showAvgTime, showMedianTime, showP90Time)\n const metricsCount = timeMetricsLines.length\n\n return (\n <div key={step.name} className=\"dc:flex dc:flex-col dc:items-center dc:gap-2 dc:flex-1 dc:max-w-32 dc:h-full\">\n {/* Conversion Rate from Previous (top) */}\n <div className={`${metricsCount > 0 ? (metricsCount > 1 ? 'dc:min-h-16' : 'dc:min-h-10') : 'dc:h-5'} dc:flex-shrink-0 dc:text-center`}>\n {stepConversionRate !== null ? (\n <div className=\"dc:text-xs text-dc-text-secondary\">\n {showConversion && <span>→ {stepConversionRate.toFixed(1)}%</span>}\n {/* Time metrics (when enabled) */}\n {metricsCount > 0 && (\n <div className=\"text-dc-text-muted dc:mt-0.5 dc:space-y-0.5\">\n {timeMetricsLines.map((line, i) => (\n <div key={i}>⏱ {line}</div>\n ))}\n </div>\n )}\n </div>\n ) : (\n <div className=\"dc:text-xs text-dc-text-muted\">—</div>\n )}\n </div>\n\n {/* Bar Container */}\n <div className=\"dc:flex-1 dc:w-full dc:relative dc:min-h-12\">\n {/* Background Track */}\n <div className=\"dc:absolute dc:inset-0 bg-dc-surface-secondary dc:rounded-sm\" />\n\n {/* Filled Bar (grows from bottom) */}\n <div\n className=\"dc:absolute dc:bottom-0 dc:left-0 dc:right-0 dc:rounded-sm dc:transition-all dc:duration-300\"\n style={{\n height: `${Math.max(heightPercent, 5)}%`,\n backgroundColor: getStepColor(index, paletteColors),\n }}\n />\n\n {/* Percentage Label on Bar */}\n <div\n className=\"dc:absolute dc:bottom-0 dc:left-0 dc:right-0 dc:flex dc:items-end dc:justify-center dc:pb-1 dc:pointer-events-none\"\n style={{ height: `${Math.max(heightPercent, 20)}%` }}\n >\n <span className=\"dc:text-xs dc:font-medium text-white dc:drop-shadow-sm\">\n {step.percentage?.toFixed(1) ?? heightPercent.toFixed(1)}%\n </span>\n </div>\n </div>\n\n {/* Step Label (bottom) */}\n <div className=\"dc:flex-shrink-0 dc:text-center\">\n <div className=\"dc:text-sm dc:font-medium text-dc-text dc:truncate\" title={displayName}>\n {displayName}\n </div>\n <div className=\"dc:text-xs text-dc-text-muted\">\n {step.value.toLocaleString()}\n </div>\n </div>\n </div>\n )\n })}\n </div>\n\n {/* Summary Footer */}\n {!displayConfig?.hideSummaryFooter && (\n <div className=\"dc:flex-shrink-0 dc:px-4 dc:py-2 dc:border-t border-dc-border bg-dc-surface-secondary\">\n <div className=\"dc:flex dc:items-center dc:justify-between dc:text-sm\">\n <div className=\"text-dc-text-muted\">\n <span className=\"dc:font-medium\">{funnelData.length}</span> steps\n </div>\n <div className=\"text-dc-text\">\n <span className=\"text-dc-text-muted\">Overall:</span>{' '}\n <span className=\"dc:font-medium\">\n {firstStepValue > 0\n ? `${((funnelData[funnelData.length - 1]?.value || 0) / firstStepValue * 100).toFixed(1)}%`\n : '0%'}\n </span>\n </div>\n <div className=\"text-dc-text-muted\">\n {funnelData[funnelData.length - 1]?.value.toLocaleString() || 0} / {firstStepValue.toLocaleString()} completed\n </div>\n </div>\n </div>\n )}\n </div>\n )\n }\n\n // Render horizontal orientation (default - bars grow left to right, steps stacked vertically)\n return (\n <div className=\"dc:relative dc:w-full dc:h-full dc:flex dc:flex-col\" style={{ height }}>\n {/* Funnel Steps - Horizontal Layout */}\n <div className=\"dc:flex-1 dc:flex dc:flex-col dc:justify-center dc:gap-2 dc:px-4 dc:py-3 dc:overflow-hidden\">\n {funnelData.map((step, index) => {\n const widthPercent = firstStepValue > 0 ? (step.value / firstStepValue) * 100 : 0\n const prevStep = index > 0 ? funnelData[index - 1] : null\n const stepConversionRate = prevStep && prevStep.value > 0\n ? (step.value / prevStep.value) * 100\n : null\n\n // Use custom label if provided, otherwise fall back to step name\n const displayName = customStepLabels?.[index] || step.name\n const timeMetricsLines = getTimeMetricsLines(step, showAvgTime, showMedianTime, showP90Time)\n const metricsCount = timeMetricsLines.length\n\n return (\n <div key={step.name} className=\"dc:flex dc:items-center dc:gap-3\">\n {/* Step Label */}\n <div className=\"dc:w-24 dc:flex-shrink-0 dc:text-right\">\n <div className=\"dc:text-sm dc:font-medium text-dc-text dc:truncate\" title={displayName}>\n {displayName}\n </div>\n <div className=\"dc:text-xs text-dc-text-muted\">\n {step.value.toLocaleString()}\n </div>\n </div>\n\n {/* Bar Container */}\n <div className=\"dc:flex-1 dc:relative\">\n {/* Background Track */}\n <div className=\"dc:w-full dc:h-8 bg-dc-surface-secondary dc:rounded-sm\" />\n\n {/* Filled Bar */}\n <div\n className=\"dc:absolute dc:top-0 dc:left-0 dc:h-8 dc:rounded-sm dc:transition-all dc:duration-300\"\n style={{\n width: `${Math.max(widthPercent, 2)}%`,\n backgroundColor: getStepColor(index, paletteColors),\n }}\n />\n\n {/* Percentage Label on Bar */}\n <div\n className=\"dc:absolute dc:top-0 dc:left-0 dc:h-8 dc:flex dc:items-center dc:px-2 dc:pointer-events-none\"\n style={{ width: `${Math.max(widthPercent, 20)}%` }}\n >\n <span className=\"dc:text-xs dc:font-medium text-white dc:drop-shadow-sm\">\n {step.percentage?.toFixed(1) ?? widthPercent.toFixed(1)}%\n </span>\n </div>\n </div>\n\n {/* Conversion Rate from Previous */}\n <div className={`${metricsCount > 0 ? (metricsCount > 1 ? 'dc:w-36' : 'dc:w-28') : 'dc:w-16'} dc:flex-shrink-0 dc:text-left`}>\n {stepConversionRate !== null ? (\n <div className=\"dc:text-xs text-dc-text-secondary\">\n {showConversion && <span>↓ {stepConversionRate.toFixed(1)}%</span>}\n {/* Time metrics (when enabled) */}\n {metricsCount > 0 && (\n <div className=\"text-dc-text-muted dc:mt-0.5 dc:space-y-0.5\">\n {timeMetricsLines.map((line, i) => (\n <div key={i}>⏱ {line}</div>\n ))}\n </div>\n )}\n </div>\n ) : (\n <div className=\"dc:text-xs text-dc-text-muted\">—</div>\n )}\n </div>\n </div>\n )\n })}\n </div>\n\n {/* Summary Footer */}\n {!displayConfig?.hideSummaryFooter && (\n <div className=\"dc:flex-shrink-0 dc:px-4 dc:py-2 dc:border-t border-dc-border bg-dc-surface-secondary\">\n <div className=\"dc:flex dc:items-center dc:justify-between dc:text-sm\">\n <div className=\"text-dc-text-muted\">\n <span className=\"dc:font-medium\">{funnelData.length}</span> steps\n </div>\n <div className=\"text-dc-text\">\n <span className=\"text-dc-text-muted\">Overall:</span>{' '}\n <span className=\"dc:font-medium\">\n {firstStepValue > 0\n ? `${((funnelData[funnelData.length - 1]?.value || 0) / firstStepValue * 100).toFixed(1)}%`\n : '0%'}\n </span>\n </div>\n <div className=\"text-dc-text-muted\">\n {funnelData[funnelData.length - 1]?.value.toLocaleString() || 0} / {firstStepValue.toLocaleString()} completed\n </div>\n </div>\n </div>\n )}\n </div>\n )\n})\n\nexport default FunnelChart\n"],"names":["FUNNEL_COLORS","getStepColor","index","colorPalette","colors","isFunnelData","data","first","getTimeMetricsLines","step","showAvg","showMedian","showP90","lines","formatDuration","FunnelChart","React","height","displayConfig","customStepLabels","isVertical","funnelStyle","showConversion","showAvgTime","showMedianTime","showP90Time","funnelData","useMemo","row","record","nameField","k","name","valueField","value","percentField","percentage","convRateField","conversionRate","firstStepValue","jsx","jsxs","paletteColors","CHART_COLORS","ResponsiveContainer","RechartsFunnelChart","Tooltip","Funnel","_","Cell","LabelList","v","heightPercent","prevStep","stepConversionRate","displayName","timeMetricsLines","metricsCount","line","i","widthPercent"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"chart-funnel-CE9x0Io9.js","sources":["../../../src/client/components/charts/FunnelChart.tsx"],"sourcesContent":["/**\n * FunnelChart Component\n *\n * Visualizes funnel data showing conversion rates between steps.\n * Uses horizontal bars with percentage widths to represent the funnel shape.\n * Works with data from useFunnelQuery hook which provides FunnelChartData.\n *\n * When displayConfig.showFunnelTimeMetrics is enabled, displays time-to-convert\n * metrics from server-side funnel execution (avg, median, P90 seconds).\n */\n\nimport React, { useMemo } from 'react'\nimport { FunnelChart as RechartsFunnelChart, Funnel, LabelList, Tooltip, Cell, ResponsiveContainer } from 'recharts'\nimport { CHART_COLORS } from '../../utils/chartConstants'\nimport type { ChartProps } from '../../types'\nimport type { FunnelChartData } from '../../types/funnel'\nimport { formatDuration } from '../../utils/funnelExecution'\n\n// Color gradient for funnel steps (darker to lighter)\nconst FUNNEL_COLORS = [\n '#3B82F6', // blue-500\n '#60A5FA', // blue-400\n '#93C5FD', // blue-300\n '#BFDBFE', // blue-200\n '#DBEAFE', // blue-100\n]\n\n/**\n * Get color for a funnel step\n */\nfunction getStepColor(index: number, colorPalette?: string[]): string {\n const colors = colorPalette || FUNNEL_COLORS\n return colors[index % colors.length]\n}\n\n/**\n * Check if data is funnel data format\n */\nfunction isFunnelData(data: unknown[]): data is FunnelChartData[] {\n if (!data || data.length === 0) return false\n const first = data[0]\n return (\n typeof first === 'object' &&\n first !== null &&\n 'name' in first &&\n 'value' in first &&\n 'percentage' in first\n )\n}\n\n/**\n * Render time metrics based on config options - returns array of lines for vertical stacking\n */\nfunction getTimeMetricsLines(\n step: FunnelChartData,\n showAvg: boolean,\n showMedian: boolean,\n showP90: boolean\n): string[] {\n const lines: string[] = []\n if (showAvg && step.avgSecondsToConvert != null) {\n lines.push(`Avg: ${formatDuration(step.avgSecondsToConvert)}`)\n }\n if (showMedian && step.medianSecondsToConvert != null) {\n lines.push(`Med: ${formatDuration(step.medianSecondsToConvert)}`)\n }\n if (showP90 && step.p90SecondsToConvert != null) {\n lines.push(`P90: ${formatDuration(step.p90SecondsToConvert)}`)\n }\n return lines\n}\n\n/**\n * FunnelChart Component\n *\n * Renders a funnel visualization from FunnelChartData array.\n * Shows each step as a horizontal bar with width proportional to count.\n * Displays conversion rates between steps.\n */\nconst FunnelChart = React.memo(function FunnelChart({\n data,\n height = '100%',\n colorPalette,\n displayConfig,\n}: ChartProps) {\n // Get display config options\n const customStepLabels = displayConfig?.funnelStepLabels\n const orientation = displayConfig?.funnelOrientation || 'horizontal'\n const isVertical = orientation === 'vertical'\n const funnelStyle = displayConfig?.funnelStyle ?? 'bars'\n const showConversion = displayConfig?.showFunnelConversion ?? true\n\n // Time metrics - individual toggles with backward compat for showFunnelTimeMetrics\n const showAvgTime = displayConfig?.showFunnelAvgTime ??\n (displayConfig?.showFunnelTimeMetrics ?? false) // backward compat\n const showMedianTime = displayConfig?.showFunnelMedianTime ?? false\n const showP90Time = displayConfig?.showFunnelP90Time ?? false\n\n // Transform data if needed\n const funnelData = useMemo<FunnelChartData[]>(() => {\n if (!data || data.length === 0) return []\n\n // If already funnel data format, use directly\n if (isFunnelData(data)) {\n return data\n }\n\n // Try to convert from raw query results\n // Look for common patterns: step/name, count/value, percentage\n return data.map((row, index) => {\n const record = row as Record<string, unknown>\n\n // Find name field\n const nameField = Object.keys(record).find(\n (k) => k.toLowerCase().includes('step') || k.toLowerCase().includes('name') || k === '__stepName'\n )\n const name = nameField ? String(record[nameField]) : `Step ${index + 1}`\n\n // Find value field\n const valueField = Object.keys(record).find(\n (k) => k.toLowerCase().includes('count') || k.toLowerCase().includes('value') || k === '__count'\n )\n const value = valueField ? Number(record[valueField]) || 0 : 0\n\n // Find percentage field\n const percentField = Object.keys(record).find(\n (k) => k.toLowerCase().includes('percent') || k === '__percentage'\n )\n const percentage = percentField ? Number(record[percentField]) || 0 : 0\n\n // Find conversion rate field\n const convRateField = Object.keys(record).find(\n (k) => k.toLowerCase().includes('conversion') || k === '__conversionRate'\n )\n const conversionRate = convRateField ? Number(record[convRateField]) || null : null\n\n return {\n name,\n value,\n percentage,\n conversionRate,\n stepIndex: index,\n }\n })\n }, [data])\n\n // Calculate first step value for percentage calculations\n const firstStepValue = funnelData[0]?.value || 0\n\n // Handle no data\n if (!data || data.length === 0 || funnelData.length === 0) {\n return (\n <div\n className=\"dc:flex dc:items-center dc:justify-center dc:w-full text-dc-text-muted\"\n style={{ height }}\n >\n <div className=\"dc:text-center\">\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1\">No funnel data</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">\n Configure a funnel with at least 2 steps and a binding key\n </div>\n </div>\n </div>\n )\n }\n\n const paletteColors = colorPalette?.colors || CHART_COLORS\n\n // Render Recharts Funnel style (trapezoid shape)\n if (funnelStyle === 'funnel') {\n // Recharts FunnelChart layout: 'horizontal' = funnel flows left-to-right, 'vertical' = top-to-bottom (default)\n // Our config: 'horizontal' orientation = standard top-to-bottom funnel\n // 'vertical' orientation = left-to-right funnel\n const rechartsLayout: 'horizontal' | 'vertical' = isVertical ? 'horizontal' : 'vertical'\n\n return (\n <div className=\"dc:relative dc:w-full dc:h-full dc:flex dc:flex-col\" style={{ height }}>\n <div className=\"dc:flex-1\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsFunnelChart layout={rechartsLayout} accessibilityLayer={false}>\n <Tooltip\n formatter={(value) => typeof value === 'number' ? value.toLocaleString() : String(value)}\n contentStyle={{\n backgroundColor: 'var(--dc-surface)',\n border: '1px solid var(--dc-border)',\n borderRadius: '4px',\n }}\n />\n <Funnel\n dataKey=\"value\"\n nameKey=\"name\"\n data={funnelData}\n isAnimationActive\n >\n {funnelData.map((_, index) => (\n <Cell key={`cell-${index}`} fill={getStepColor(index, paletteColors)} />\n ))}\n <LabelList\n position=\"right\"\n dataKey=\"name\"\n fill=\"var(--dc-text)\"\n style={{ fontSize: '12px' }}\n />\n <LabelList\n position=\"center\"\n dataKey=\"percentage\"\n formatter={(v) => typeof v === 'number' ? `${v.toFixed(1)}%` : String(v)}\n fill=\"#fff\"\n style={{ fontSize: '11px', fontWeight: 500 }}\n />\n </Funnel>\n </RechartsFunnelChart>\n </ResponsiveContainer>\n </div>\n {/* Summary Footer */}\n {!displayConfig?.hideSummaryFooter && (\n <div className=\"dc:flex-shrink-0 dc:px-4 dc:py-2 dc:border-t border-dc-border bg-dc-surface-secondary\">\n <div className=\"dc:flex dc:items-center dc:justify-between dc:text-sm\">\n <div className=\"text-dc-text-muted\">\n <span className=\"dc:font-medium\">{funnelData.length}</span> steps\n </div>\n <div className=\"text-dc-text\">\n <span className=\"text-dc-text-muted\">Overall:</span>{' '}\n <span className=\"dc:font-medium\">\n {firstStepValue > 0\n ? `${((funnelData[funnelData.length - 1]?.value || 0) / firstStepValue * 100).toFixed(1)}%`\n : '0%'}\n </span>\n </div>\n <div className=\"text-dc-text-muted\">\n {funnelData[funnelData.length - 1]?.value.toLocaleString() || 0} / {firstStepValue.toLocaleString()} completed\n </div>\n </div>\n </div>\n )}\n </div>\n )\n }\n\n // Render vertical orientation (bars grow from bottom to top, steps laid out horizontally)\n if (isVertical) {\n return (\n <div className=\"dc:relative dc:w-full dc:h-full dc:flex dc:flex-col\" style={{ height }}>\n {/* Funnel Steps - Vertical Layout */}\n <div className=\"dc:flex-1 dc:flex dc:items-end dc:justify-center dc:gap-4 dc:px-4 dc:py-3 dc:overflow-hidden\">\n {funnelData.map((step, index) => {\n const heightPercent = firstStepValue > 0 ? (step.value / firstStepValue) * 100 : 0\n const prevStep = index > 0 ? funnelData[index - 1] : null\n const stepConversionRate = prevStep && prevStep.value > 0\n ? (step.value / prevStep.value) * 100\n : null\n\n // Use custom label if provided, otherwise fall back to step name\n const displayName = customStepLabels?.[index] || step.name\n\n const timeMetricsLines = getTimeMetricsLines(step, showAvgTime, showMedianTime, showP90Time)\n const metricsCount = timeMetricsLines.length\n\n return (\n <div key={step.name} className=\"dc:flex dc:flex-col dc:items-center dc:gap-2 dc:flex-1 dc:max-w-32 dc:h-full\">\n {/* Conversion Rate from Previous (top) */}\n <div className={`${metricsCount > 0 ? (metricsCount > 1 ? 'dc:min-h-16' : 'dc:min-h-10') : 'dc:h-5'} dc:flex-shrink-0 dc:text-center`}>\n {stepConversionRate !== null ? (\n <div className=\"dc:text-xs text-dc-text-secondary\">\n {showConversion && <span>→ {stepConversionRate.toFixed(1)}%</span>}\n {/* Time metrics (when enabled) */}\n {metricsCount > 0 && (\n <div className=\"text-dc-text-muted dc:mt-0.5 dc:space-y-0.5\">\n {timeMetricsLines.map((line, i) => (\n <div key={i}>⏱ {line}</div>\n ))}\n </div>\n )}\n </div>\n ) : (\n <div className=\"dc:text-xs text-dc-text-muted\">—</div>\n )}\n </div>\n\n {/* Bar Container */}\n <div className=\"dc:flex-1 dc:w-full dc:relative dc:min-h-12\">\n {/* Background Track */}\n <div className=\"dc:absolute dc:inset-0 bg-dc-surface-secondary dc:rounded-sm\" />\n\n {/* Filled Bar (grows from bottom) */}\n <div\n className=\"dc:absolute dc:bottom-0 dc:left-0 dc:right-0 dc:rounded-sm dc:transition-all dc:duration-300\"\n style={{\n height: `${Math.max(heightPercent, 5)}%`,\n backgroundColor: getStepColor(index, paletteColors),\n }}\n />\n\n {/* Percentage Label on Bar */}\n <div\n className=\"dc:absolute dc:bottom-0 dc:left-0 dc:right-0 dc:flex dc:items-end dc:justify-center dc:pb-1 dc:pointer-events-none\"\n style={{ height: `${Math.max(heightPercent, 20)}%` }}\n >\n <span className=\"dc:text-xs dc:font-medium text-white dc:drop-shadow-sm\">\n {step.percentage?.toFixed(1) ?? heightPercent.toFixed(1)}%\n </span>\n </div>\n </div>\n\n {/* Step Label (bottom) */}\n <div className=\"dc:flex-shrink-0 dc:text-center\">\n <div className=\"dc:text-sm dc:font-medium text-dc-text dc:truncate\" title={displayName}>\n {displayName}\n </div>\n <div className=\"dc:text-xs text-dc-text-muted\">\n {step.value.toLocaleString()}\n </div>\n </div>\n </div>\n )\n })}\n </div>\n\n {/* Summary Footer */}\n {!displayConfig?.hideSummaryFooter && (\n <div className=\"dc:flex-shrink-0 dc:px-4 dc:py-2 dc:border-t border-dc-border bg-dc-surface-secondary\">\n <div className=\"dc:flex dc:items-center dc:justify-between dc:text-sm\">\n <div className=\"text-dc-text-muted\">\n <span className=\"dc:font-medium\">{funnelData.length}</span> steps\n </div>\n <div className=\"text-dc-text\">\n <span className=\"text-dc-text-muted\">Overall:</span>{' '}\n <span className=\"dc:font-medium\">\n {firstStepValue > 0\n ? `${((funnelData[funnelData.length - 1]?.value || 0) / firstStepValue * 100).toFixed(1)}%`\n : '0%'}\n </span>\n </div>\n <div className=\"text-dc-text-muted\">\n {funnelData[funnelData.length - 1]?.value.toLocaleString() || 0} / {firstStepValue.toLocaleString()} completed\n </div>\n </div>\n </div>\n )}\n </div>\n )\n }\n\n // Render horizontal orientation (default - bars grow left to right, steps stacked vertically)\n return (\n <div className=\"dc:relative dc:w-full dc:h-full dc:flex dc:flex-col\" style={{ height }}>\n {/* Funnel Steps - Horizontal Layout */}\n <div className=\"dc:flex-1 dc:flex dc:flex-col dc:justify-center dc:gap-2 dc:px-4 dc:py-3 dc:overflow-hidden\">\n {funnelData.map((step, index) => {\n const widthPercent = firstStepValue > 0 ? (step.value / firstStepValue) * 100 : 0\n const prevStep = index > 0 ? funnelData[index - 1] : null\n const stepConversionRate = prevStep && prevStep.value > 0\n ? (step.value / prevStep.value) * 100\n : null\n\n // Use custom label if provided, otherwise fall back to step name\n const displayName = customStepLabels?.[index] || step.name\n const timeMetricsLines = getTimeMetricsLines(step, showAvgTime, showMedianTime, showP90Time)\n const metricsCount = timeMetricsLines.length\n\n return (\n <div key={step.name} className=\"dc:flex dc:items-center dc:gap-3\">\n {/* Step Label */}\n <div className=\"dc:w-24 dc:flex-shrink-0 dc:text-right\">\n <div className=\"dc:text-sm dc:font-medium text-dc-text dc:truncate\" title={displayName}>\n {displayName}\n </div>\n <div className=\"dc:text-xs text-dc-text-muted\">\n {step.value.toLocaleString()}\n </div>\n </div>\n\n {/* Bar Container */}\n <div className=\"dc:flex-1 dc:relative\">\n {/* Background Track */}\n <div className=\"dc:w-full dc:h-8 bg-dc-surface-secondary dc:rounded-sm\" />\n\n {/* Filled Bar */}\n <div\n className=\"dc:absolute dc:top-0 dc:left-0 dc:h-8 dc:rounded-sm dc:transition-all dc:duration-300\"\n style={{\n width: `${Math.max(widthPercent, 2)}%`,\n backgroundColor: getStepColor(index, paletteColors),\n }}\n />\n\n {/* Percentage Label on Bar */}\n <div\n className=\"dc:absolute dc:top-0 dc:left-0 dc:h-8 dc:flex dc:items-center dc:px-2 dc:pointer-events-none\"\n style={{ width: `${Math.max(widthPercent, 20)}%` }}\n >\n <span className=\"dc:text-xs dc:font-medium text-white dc:drop-shadow-sm\">\n {step.percentage?.toFixed(1) ?? widthPercent.toFixed(1)}%\n </span>\n </div>\n </div>\n\n {/* Conversion Rate from Previous */}\n <div className={`${metricsCount > 0 ? (metricsCount > 1 ? 'dc:w-36' : 'dc:w-28') : 'dc:w-16'} dc:flex-shrink-0 dc:text-left`}>\n {stepConversionRate !== null ? (\n <div className=\"dc:text-xs text-dc-text-secondary\">\n {showConversion && <span>↓ {stepConversionRate.toFixed(1)}%</span>}\n {/* Time metrics (when enabled) */}\n {metricsCount > 0 && (\n <div className=\"text-dc-text-muted dc:mt-0.5 dc:space-y-0.5\">\n {timeMetricsLines.map((line, i) => (\n <div key={i}>⏱ {line}</div>\n ))}\n </div>\n )}\n </div>\n ) : (\n <div className=\"dc:text-xs text-dc-text-muted\">—</div>\n )}\n </div>\n </div>\n )\n })}\n </div>\n\n {/* Summary Footer */}\n {!displayConfig?.hideSummaryFooter && (\n <div className=\"dc:flex-shrink-0 dc:px-4 dc:py-2 dc:border-t border-dc-border bg-dc-surface-secondary\">\n <div className=\"dc:flex dc:items-center dc:justify-between dc:text-sm\">\n <div className=\"text-dc-text-muted\">\n <span className=\"dc:font-medium\">{funnelData.length}</span> steps\n </div>\n <div className=\"text-dc-text\">\n <span className=\"text-dc-text-muted\">Overall:</span>{' '}\n <span className=\"dc:font-medium\">\n {firstStepValue > 0\n ? `${((funnelData[funnelData.length - 1]?.value || 0) / firstStepValue * 100).toFixed(1)}%`\n : '0%'}\n </span>\n </div>\n <div className=\"text-dc-text-muted\">\n {funnelData[funnelData.length - 1]?.value.toLocaleString() || 0} / {firstStepValue.toLocaleString()} completed\n </div>\n </div>\n </div>\n )}\n </div>\n )\n})\n\nexport default FunnelChart\n"],"names":["FUNNEL_COLORS","getStepColor","index","colorPalette","colors","isFunnelData","data","first","getTimeMetricsLines","step","showAvg","showMedian","showP90","lines","formatDuration","FunnelChart","React","height","displayConfig","customStepLabels","isVertical","funnelStyle","showConversion","showAvgTime","showMedianTime","showP90Time","funnelData","useMemo","row","record","nameField","k","name","valueField","value","percentField","percentage","convRateField","conversionRate","firstStepValue","jsx","jsxs","paletteColors","CHART_COLORS","ResponsiveContainer","RechartsFunnelChart","Tooltip","Funnel","_","Cell","LabelList","v","heightPercent","prevStep","stepConversionRate","displayName","timeMetricsLines","metricsCount","line","i","widthPercent"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as v, jsxs as O } from "react/jsx-runtime";
|
|
2
2
|
import Mt, { useRef as _t, useState as At, useLayoutEffect as bt, useMemo as mt } from "react";
|
|
3
|
-
import { u as Nt, f as lt } from "./charts-core-
|
|
3
|
+
import { u as Nt, f as lt } from "./charts-core-B4Rbfdcn.js";
|
|
4
4
|
function k(n) {
|
|
5
5
|
return function() {
|
|
6
6
|
return n;
|
|
@@ -371,4 +371,4 @@ const Yt = Mt.memo(function({
|
|
|
371
371
|
export {
|
|
372
372
|
Yt as default
|
|
373
373
|
};
|
|
374
|
-
//# sourceMappingURL=chart-gauge-
|
|
374
|
+
//# sourceMappingURL=chart-gauge-Djs5FWxB.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-gauge-CKJJ8m3b.js","sources":["../../../node_modules/d3-shape/src/constant.js","../../../node_modules/d3-shape/src/math.js","../../../node_modules/d3-path/src/path.js","../../../node_modules/d3-shape/src/path.js","../../../node_modules/d3-shape/src/arc.js","../../../src/client/components/charts/GaugeChart.tsx"],"sourcesContent":["export default function(x) {\n return function constant() {\n return x;\n };\n}\n","export const abs = Math.abs;\nexport const atan2 = Math.atan2;\nexport const cos = Math.cos;\nexport const max = Math.max;\nexport const min = Math.min;\nexport const sin = Math.sin;\nexport const sqrt = Math.sqrt;\n\nexport const epsilon = 1e-12;\nexport const pi = Math.PI;\nexport const halfPi = pi / 2;\nexport const tau = 2 * pi;\n\nexport function acos(x) {\n return x > 1 ? 0 : x < -1 ? pi : Math.acos(x);\n}\n\nexport function asin(x) {\n return x >= 1 ? halfPi : x <= -1 ? -halfPi : Math.asin(x);\n}\n","const pi = Math.PI,\n tau = 2 * pi,\n epsilon = 1e-6,\n tauEpsilon = tau - epsilon;\n\nfunction append(strings) {\n this._ += strings[0];\n for (let i = 1, n = strings.length; i < n; ++i) {\n this._ += arguments[i] + strings[i];\n }\n}\n\nfunction appendRound(digits) {\n let d = Math.floor(digits);\n if (!(d >= 0)) throw new Error(`invalid digits: ${digits}`);\n if (d > 15) return append;\n const k = 10 ** d;\n return function(strings) {\n this._ += strings[0];\n for (let i = 1, n = strings.length; i < n; ++i) {\n this._ += Math.round(arguments[i] * k) / k + strings[i];\n }\n };\n}\n\nexport class Path {\n constructor(digits) {\n this._x0 = this._y0 = // start of current subpath\n this._x1 = this._y1 = null; // end of current subpath\n this._ = \"\";\n this._append = digits == null ? append : appendRound(digits);\n }\n moveTo(x, y) {\n this._append`M${this._x0 = this._x1 = +x},${this._y0 = this._y1 = +y}`;\n }\n closePath() {\n if (this._x1 !== null) {\n this._x1 = this._x0, this._y1 = this._y0;\n this._append`Z`;\n }\n }\n lineTo(x, y) {\n this._append`L${this._x1 = +x},${this._y1 = +y}`;\n }\n quadraticCurveTo(x1, y1, x, y) {\n this._append`Q${+x1},${+y1},${this._x1 = +x},${this._y1 = +y}`;\n }\n bezierCurveTo(x1, y1, x2, y2, x, y) {\n this._append`C${+x1},${+y1},${+x2},${+y2},${this._x1 = +x},${this._y1 = +y}`;\n }\n arcTo(x1, y1, x2, y2, r) {\n x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(`negative radius: ${r}`);\n\n let x0 = this._x1,\n y0 = this._y1,\n x21 = x2 - x1,\n y21 = y2 - y1,\n x01 = x0 - x1,\n y01 = y0 - y1,\n l01_2 = x01 * x01 + y01 * y01;\n\n // Is this path empty? Move to (x1,y1).\n if (this._x1 === null) {\n this._append`M${this._x1 = x1},${this._y1 = y1}`;\n }\n\n // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.\n else if (!(l01_2 > epsilon));\n\n // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?\n // Equivalently, is (x1,y1) coincident with (x2,y2)?\n // Or, is the radius zero? Line to (x1,y1).\n else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) {\n this._append`L${this._x1 = x1},${this._y1 = y1}`;\n }\n\n // Otherwise, draw an arc!\n else {\n let x20 = x2 - x0,\n y20 = y2 - y0,\n l21_2 = x21 * x21 + y21 * y21,\n l20_2 = x20 * x20 + y20 * y20,\n l21 = Math.sqrt(l21_2),\n l01 = Math.sqrt(l01_2),\n l = r * Math.tan((pi - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),\n t01 = l / l01,\n t21 = l / l21;\n\n // If the start tangent is not coincident with (x0,y0), line to.\n if (Math.abs(t01 - 1) > epsilon) {\n this._append`L${x1 + t01 * x01},${y1 + t01 * y01}`;\n }\n\n this._append`A${r},${r},0,0,${+(y01 * x20 > x01 * y20)},${this._x1 = x1 + t21 * x21},${this._y1 = y1 + t21 * y21}`;\n }\n }\n arc(x, y, r, a0, a1, ccw) {\n x = +x, y = +y, r = +r, ccw = !!ccw;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(`negative radius: ${r}`);\n\n let dx = r * Math.cos(a0),\n dy = r * Math.sin(a0),\n x0 = x + dx,\n y0 = y + dy,\n cw = 1 ^ ccw,\n da = ccw ? a0 - a1 : a1 - a0;\n\n // Is this path empty? Move to (x0,y0).\n if (this._x1 === null) {\n this._append`M${x0},${y0}`;\n }\n\n // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).\n else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) {\n this._append`L${x0},${y0}`;\n }\n\n // Is this arc empty? We’re done.\n if (!r) return;\n\n // Does the angle go the wrong way? Flip the direction.\n if (da < 0) da = da % tau + tau;\n\n // Is this a complete circle? Draw two arcs to complete the circle.\n if (da > tauEpsilon) {\n this._append`A${r},${r},0,1,${cw},${x - dx},${y - dy}A${r},${r},0,1,${cw},${this._x1 = x0},${this._y1 = y0}`;\n }\n\n // Is this arc non-empty? Draw an arc!\n else if (da > epsilon) {\n this._append`A${r},${r},0,${+(da >= pi)},${cw},${this._x1 = x + r * Math.cos(a1)},${this._y1 = y + r * Math.sin(a1)}`;\n }\n }\n rect(x, y, w, h) {\n this._append`M${this._x0 = this._x1 = +x},${this._y0 = this._y1 = +y}h${w = +w}v${+h}h${-w}Z`;\n }\n toString() {\n return this._;\n }\n}\n\nexport function path() {\n return new Path;\n}\n\n// Allow instanceof d3.path\npath.prototype = Path.prototype;\n\nexport function pathRound(digits = 3) {\n return new Path(+digits);\n}\n","import {Path} from \"d3-path\";\n\nexport function withPath(shape) {\n let digits = 3;\n\n shape.digits = function(_) {\n if (!arguments.length) return digits;\n if (_ == null) {\n digits = null;\n } else {\n const d = Math.floor(_);\n if (!(d >= 0)) throw new RangeError(`invalid digits: ${_}`);\n digits = d;\n }\n return shape;\n };\n\n return () => new Path(digits);\n}\n","import constant from \"./constant.js\";\nimport {abs, acos, asin, atan2, cos, epsilon, halfPi, max, min, pi, sin, sqrt, tau} from \"./math.js\";\nimport {withPath} from \"./path.js\";\n\nfunction arcInnerRadius(d) {\n return d.innerRadius;\n}\n\nfunction arcOuterRadius(d) {\n return d.outerRadius;\n}\n\nfunction arcStartAngle(d) {\n return d.startAngle;\n}\n\nfunction arcEndAngle(d) {\n return d.endAngle;\n}\n\nfunction arcPadAngle(d) {\n return d && d.padAngle; // Note: optional!\n}\n\nfunction intersect(x0, y0, x1, y1, x2, y2, x3, y3) {\n var x10 = x1 - x0, y10 = y1 - y0,\n x32 = x3 - x2, y32 = y3 - y2,\n t = y32 * x10 - x32 * y10;\n if (t * t < epsilon) return;\n t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / t;\n return [x0 + t * x10, y0 + t * y10];\n}\n\n// Compute perpendicular offset line of length rc.\n// http://mathworld.wolfram.com/Circle-LineIntersection.html\nfunction cornerTangents(x0, y0, x1, y1, r1, rc, cw) {\n var x01 = x0 - x1,\n y01 = y0 - y1,\n lo = (cw ? rc : -rc) / sqrt(x01 * x01 + y01 * y01),\n ox = lo * y01,\n oy = -lo * x01,\n x11 = x0 + ox,\n y11 = y0 + oy,\n x10 = x1 + ox,\n y10 = y1 + oy,\n x00 = (x11 + x10) / 2,\n y00 = (y11 + y10) / 2,\n dx = x10 - x11,\n dy = y10 - y11,\n d2 = dx * dx + dy * dy,\n r = r1 - rc,\n D = x11 * y10 - x10 * y11,\n d = (dy < 0 ? -1 : 1) * sqrt(max(0, r * r * d2 - D * D)),\n cx0 = (D * dy - dx * d) / d2,\n cy0 = (-D * dx - dy * d) / d2,\n cx1 = (D * dy + dx * d) / d2,\n cy1 = (-D * dx + dy * d) / d2,\n dx0 = cx0 - x00,\n dy0 = cy0 - y00,\n dx1 = cx1 - x00,\n dy1 = cy1 - y00;\n\n // Pick the closer of the two intersection points.\n // TODO Is there a faster way to determine which intersection to use?\n if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;\n\n return {\n cx: cx0,\n cy: cy0,\n x01: -ox,\n y01: -oy,\n x11: cx0 * (r1 / r - 1),\n y11: cy0 * (r1 / r - 1)\n };\n}\n\nexport default function() {\n var innerRadius = arcInnerRadius,\n outerRadius = arcOuterRadius,\n cornerRadius = constant(0),\n padRadius = null,\n startAngle = arcStartAngle,\n endAngle = arcEndAngle,\n padAngle = arcPadAngle,\n context = null,\n path = withPath(arc);\n\n function arc() {\n var buffer,\n r,\n r0 = +innerRadius.apply(this, arguments),\n r1 = +outerRadius.apply(this, arguments),\n a0 = startAngle.apply(this, arguments) - halfPi,\n a1 = endAngle.apply(this, arguments) - halfPi,\n da = abs(a1 - a0),\n cw = a1 > a0;\n\n if (!context) context = buffer = path();\n\n // Ensure that the outer radius is always larger than the inner radius.\n if (r1 < r0) r = r1, r1 = r0, r0 = r;\n\n // Is it a point?\n if (!(r1 > epsilon)) context.moveTo(0, 0);\n\n // Or is it a circle or annulus?\n else if (da > tau - epsilon) {\n context.moveTo(r1 * cos(a0), r1 * sin(a0));\n context.arc(0, 0, r1, a0, a1, !cw);\n if (r0 > epsilon) {\n context.moveTo(r0 * cos(a1), r0 * sin(a1));\n context.arc(0, 0, r0, a1, a0, cw);\n }\n }\n\n // Or is it a circular or annular sector?\n else {\n var a01 = a0,\n a11 = a1,\n a00 = a0,\n a10 = a1,\n da0 = da,\n da1 = da,\n ap = padAngle.apply(this, arguments) / 2,\n rp = (ap > epsilon) && (padRadius ? +padRadius.apply(this, arguments) : sqrt(r0 * r0 + r1 * r1)),\n rc = min(abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments)),\n rc0 = rc,\n rc1 = rc,\n t0,\n t1;\n\n // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0.\n if (rp > epsilon) {\n var p0 = asin(rp / r0 * sin(ap)),\n p1 = asin(rp / r1 * sin(ap));\n if ((da0 -= p0 * 2) > epsilon) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0;\n else da0 = 0, a00 = a10 = (a0 + a1) / 2;\n if ((da1 -= p1 * 2) > epsilon) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1;\n else da1 = 0, a01 = a11 = (a0 + a1) / 2;\n }\n\n var x01 = r1 * cos(a01),\n y01 = r1 * sin(a01),\n x10 = r0 * cos(a10),\n y10 = r0 * sin(a10);\n\n // Apply rounded corners?\n if (rc > epsilon) {\n var x11 = r1 * cos(a11),\n y11 = r1 * sin(a11),\n x00 = r0 * cos(a00),\n y00 = r0 * sin(a00),\n oc;\n\n // Restrict the corner radius according to the sector angle. If this\n // intersection fails, it’s probably because the arc is too small, so\n // disable the corner radius entirely.\n if (da < pi) {\n if (oc = intersect(x01, y01, x00, y00, x11, y11, x10, y10)) {\n var ax = x01 - oc[0],\n ay = y01 - oc[1],\n bx = x11 - oc[0],\n by = y11 - oc[1],\n kc = 1 / sin(acos((ax * bx + ay * by) / (sqrt(ax * ax + ay * ay) * sqrt(bx * bx + by * by))) / 2),\n lc = sqrt(oc[0] * oc[0] + oc[1] * oc[1]);\n rc0 = min(rc, (r0 - lc) / (kc - 1));\n rc1 = min(rc, (r1 - lc) / (kc + 1));\n } else {\n rc0 = rc1 = 0;\n }\n }\n }\n\n // Is the sector collapsed to a line?\n if (!(da1 > epsilon)) context.moveTo(x01, y01);\n\n // Does the sector’s outer ring have rounded corners?\n else if (rc1 > epsilon) {\n t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw);\n t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw);\n\n context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01);\n\n // Have the corners merged?\n if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw);\n\n // Otherwise, draw the two corners and the ring.\n else {\n context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw);\n context.arc(0, 0, r1, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), !cw);\n context.arc(t1.cx, t1.cy, rc1, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw);\n }\n }\n\n // Or is the outer ring just a circular arc?\n else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw);\n\n // Is there no inner ring, and it’s a circular sector?\n // Or perhaps it’s an annular sector collapsed due to padding?\n if (!(r0 > epsilon) || !(da0 > epsilon)) context.lineTo(x10, y10);\n\n // Does the sector’s inner ring (or point) have rounded corners?\n else if (rc0 > epsilon) {\n t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw);\n t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw);\n\n context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01);\n\n // Have the corners merged?\n if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw);\n\n // Otherwise, draw the two corners and the ring.\n else {\n context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw);\n context.arc(0, 0, r0, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), cw);\n context.arc(t1.cx, t1.cy, rc0, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw);\n }\n }\n\n // Or is the inner ring just a circular arc?\n else context.arc(0, 0, r0, a10, a00, cw);\n }\n\n context.closePath();\n\n if (buffer) return context = null, buffer + \"\" || null;\n }\n\n arc.centroid = function() {\n var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2,\n a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi / 2;\n return [cos(a) * r, sin(a) * r];\n };\n\n arc.innerRadius = function(_) {\n return arguments.length ? (innerRadius = typeof _ === \"function\" ? _ : constant(+_), arc) : innerRadius;\n };\n\n arc.outerRadius = function(_) {\n return arguments.length ? (outerRadius = typeof _ === \"function\" ? _ : constant(+_), arc) : outerRadius;\n };\n\n arc.cornerRadius = function(_) {\n return arguments.length ? (cornerRadius = typeof _ === \"function\" ? _ : constant(+_), arc) : cornerRadius;\n };\n\n arc.padRadius = function(_) {\n return arguments.length ? (padRadius = _ == null ? null : typeof _ === \"function\" ? _ : constant(+_), arc) : padRadius;\n };\n\n arc.startAngle = function(_) {\n return arguments.length ? (startAngle = typeof _ === \"function\" ? _ : constant(+_), arc) : startAngle;\n };\n\n arc.endAngle = function(_) {\n return arguments.length ? (endAngle = typeof _ === \"function\" ? _ : constant(+_), arc) : endAngle;\n };\n\n arc.padAngle = function(_) {\n return arguments.length ? (padAngle = typeof _ === \"function\" ? _ : constant(+_), arc) : padAngle;\n };\n\n arc.context = function(_) {\n return arguments.length ? ((context = _ == null ? null : _), arc) : context;\n };\n\n return arc;\n}\n","import React, { useLayoutEffect, useMemo, useRef, useState } from 'react'\nimport { arc } from 'd3-shape'\nimport { formatAxisValue } from '../../utils/chartUtils'\nimport { useCubeFieldLabel } from '../../hooks/useCubeFieldLabel'\nimport type { ChartProps, ThresholdBand } from '../../types'\n\nconst START_ANGLE = -Math.PI * 0.75\nconst END_ANGLE = Math.PI * 0.75\nconst TRACK_COLOR = '#e2e8f0'\nconst DEFAULT_FILL = '#6366f1'\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 clamp(v: number, lo: number, hi: number): number {\n return Math.max(lo, Math.min(hi, v))\n}\n\nfunction valueToAngle(value: number, min: number, max: number): number {\n const span = max === min ? 1 : max - min\n const t = clamp((value - min) / span, 0, 1)\n return START_ANGLE + t * (END_ANGLE - START_ANGLE)\n}\n\nfunction resolveColor(fraction: number, thresholds: ThresholdBand[]): string {\n const sorted = [...thresholds].sort((a, b) => a.value - b.value)\n let color = DEFAULT_FILL\n for (const t of sorted) {\n if (fraction >= t.value) color = t.color\n }\n return color\n}\n\nfunction buildArcPath(\n innerRadius: number,\n outerRadius: number,\n startAngle: number,\n endAngle: number\n): string {\n const pathFn = arc()\n return pathFn({ innerRadius, outerRadius, startAngle, endAngle }) ?? ''\n}\n\nfunction Needle({ angle, radius }: { angle: number; radius: number }) {\n const needleLen = radius * 0.72\n const needleBase = radius * 0.06\n const x = Math.cos(angle - Math.PI / 2) * needleLen\n const y = Math.sin(angle - Math.PI / 2) * needleLen\n return (\n <g data-testid=\"gauge-needle\">\n <circle r={needleBase} fill=\"currentColor\" className=\"text-dc-text-secondary\" />\n <line\n x1={0}\n y1={0}\n x2={x}\n y2={y}\n stroke=\"currentColor\"\n strokeWidth={3}\n strokeLinecap=\"round\"\n className=\"text-dc-text-secondary\"\n />\n </g>\n )\n}\n\nconst GaugeChart = React.memo(function GaugeChart({\n data,\n chartConfig,\n displayConfig = {},\n height = '100%',\n}: ChartProps) {\n const getFieldLabel = useCubeFieldLabel()\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 { valueField, maxField, configError } = useMemo(() => {\n const yAxis: string[] = Array.isArray(chartConfig?.yAxis)\n ? chartConfig.yAxis\n : []\n\n const valueField = yAxis[0] ?? ''\n const maxField = yAxis[1] ?? ''\n\n if (!valueField) {\n return { valueField, maxField, configError: 'Gauge requires at least 1 measure in Y-Axis (current value)' }\n }\n return { valueField, maxField, configError: null }\n }, [chartConfig])\n\n const thresholds: ThresholdBand[] = useMemo(() => {\n const raw = displayConfig?.thresholds\n let arr: unknown[] | null = null\n if (Array.isArray(raw)) {\n arr = raw\n } else if (typeof raw === 'string' && raw.trim()) {\n try {\n const parsed = JSON.parse(raw)\n if (Array.isArray(parsed)) arr = parsed\n } catch (e) {\n console.warn('GaugeChart: invalid threshold JSON', e)\n return []\n }\n }\n if (!arr) return []\n return arr.filter(\n (entry): entry is ThresholdBand =>\n entry !== null &&\n typeof entry === 'object' &&\n typeof (entry as ThresholdBand).value === 'number' &&\n typeof (entry as ThresholdBand).color === 'string'\n )\n }, [displayConfig?.thresholds])\n\n const thresholdBands = thresholds.length === 0\n ? []\n : [...thresholds].sort((a, b) => a.value - b.value).map((t, i, sorted) => {\n const bandStart = i === 0 ? START_ANGLE : valueToAngle(sorted[i - 1].value, 0, 1)\n const bandEnd = valueToAngle(t.value, 0, 1)\n return { color: t.color, start: bandStart, end: bandEnd }\n })\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 gauge 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 const row = (data as Record<string, unknown>[])[0]\n const rawValue = parseNum(row[valueField])\n if (rawValue === null) {\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\">Gauge value is not a valid number</div>\n </div>\n </div>\n )\n }\n const minValue = displayConfig?.minValue ?? 0\n const maxFieldValue = maxField ? parseNum(row[maxField]) : null\n const maxValue = displayConfig?.maxValue ?? (maxFieldValue ?? 100)\n\n const effectiveMax = maxValue === minValue ? minValue + 1 : maxValue\n const clampedValue = clamp(rawValue, minValue, effectiveMax)\n const fraction = (clampedValue - minValue) / (effectiveMax - minValue)\n\n const fillColor = thresholds.length > 0 ? resolveColor(fraction, thresholds) : DEFAULT_FILL\n\n const showCenterLabel = displayConfig?.showCenterLabel ?? true\n const showPercentage = displayConfig?.showPercentage ?? false\n const yAxisFormat = displayConfig?.leftYAxisFormat\n\n const containerW = dimensions.width || 300\n const containerH = typeof height === 'number' ? height : (dimensions.height || 200)\n\n const radius = Math.min(containerW / 2, containerH * 0.9) * 0.85\n const outerR = radius\n const innerR = radius * 0.6\n const cx = containerW / 2\n const cy = containerH * 0.7\n\n const trackPath = buildArcPath(innerR, outerR, START_ANGLE, END_ANGLE)\n const fillAngle = valueToAngle(clampedValue, minValue, effectiveMax)\n const fillPath = buildArcPath(innerR, outerR, START_ANGLE, fillAngle)\n\n const needleAngle = valueToAngle(clampedValue, minValue, effectiveMax)\n\n const displayValue = yAxisFormat\n ? formatAxisValue(rawValue, yAxisFormat)\n : rawValue.toLocaleString()\n\n const valueLabel = showPercentage\n ? `${(fraction * 100).toFixed(1)}%`\n : displayValue\n\n const fieldLabel = getFieldLabel(valueField)\n return (\n <div ref={containerRef} className=\"dc:relative dc:w-full\" style={{ height }}>\n <svg\n width=\"100%\"\n height=\"100%\"\n viewBox={`0 0 ${containerW} ${containerH}`}\n preserveAspectRatio=\"xMidYMid meet\"\n data-testid=\"gauge-svg\"\n >\n <g transform={`translate(${cx}, ${cy})`}>\n <path\n d={trackPath}\n fill={TRACK_COLOR}\n data-testid=\"gauge-track\"\n />\n\n {thresholdBands.map((band, i) => (\n <path\n key={i}\n d={buildArcPath(outerR + 4, outerR + 8, band.start, band.end)}\n fill={band.color}\n data-testid={`gauge-band-${i}`}\n />\n ))}\n\n <path\n d={fillPath}\n fill={fillColor}\n data-testid=\"gauge-fill\"\n data-fraction={fraction.toFixed(4)}\n />\n\n <Needle angle={needleAngle} radius={radius} />\n\n {showCenterLabel && (\n <g data-testid=\"gauge-label\">\n <text\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n fontSize={radius * 0.22}\n fontWeight=\"bold\"\n fill=\"currentColor\"\n dy={radius * 0.12}\n data-testid=\"gauge-value-text\"\n >\n {valueLabel}\n </text>\n <text\n textAnchor=\"middle\"\n fontSize={radius * 0.13}\n fill=\"currentColor\"\n className=\"text-dc-text-secondary\"\n dy={radius * 0.34}\n >\n {fieldLabel}\n </text>\n </g>\n )}\n\n <text\n x={Math.cos(START_ANGLE - Math.PI / 2) * (outerR + 14)}\n y={Math.sin(START_ANGLE - Math.PI / 2) * (outerR + 14)}\n textAnchor=\"middle\"\n fontSize={radius * 0.12}\n fill=\"currentColor\"\n className=\"text-dc-text-secondary\"\n data-testid=\"gauge-min-label\"\n >\n {yAxisFormat ? formatAxisValue(minValue, yAxisFormat) : minValue.toLocaleString()}\n </text>\n <text\n x={Math.cos(END_ANGLE - Math.PI / 2) * (outerR + 14)}\n y={Math.sin(END_ANGLE - Math.PI / 2) * (outerR + 14)}\n textAnchor=\"middle\"\n fontSize={radius * 0.12}\n fill=\"currentColor\"\n className=\"text-dc-text-secondary\"\n data-testid=\"gauge-max-label\"\n >\n {yAxisFormat ? formatAxisValue(effectiveMax, yAxisFormat) : effectiveMax.toLocaleString()}\n </text>\n </g>\n </svg>\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\">Gauge 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 GaugeChart\n"],"names":["constant","x","abs","atan2","cos","max","min","sin","sqrt","epsilon","pi","halfPi","tau","acos","asin","tauEpsilon","append","strings","i","n","appendRound","digits","d","k","Path","y","x1","y1","x2","y2","r","x0","y0","x21","y21","x01","y01","l01_2","x20","y20","l21_2","l20_2","l21","l01","l","t01","t21","a0","a1","ccw","dx","dy","cw","da","w","h","withPath","shape","_","arcInnerRadius","arcOuterRadius","arcStartAngle","arcEndAngle","arcPadAngle","intersect","x3","y3","x10","y10","x32","y32","t","cornerTangents","r1","rc","lo","ox","oy","x11","y11","x00","y00","d2","D","cx0","cy0","cx1","cy1","dx0","dy0","dx1","dy1","arc","innerRadius","outerRadius","cornerRadius","padRadius","startAngle","endAngle","padAngle","context","path","buffer","r0","a01","a11","a00","a10","da0","da1","ap","rp","rc0","rc1","t0","t1","p0","p1","oc","ax","ay","bx","by","kc","lc","a","START_ANGLE","END_ANGLE","TRACK_COLOR","DEFAULT_FILL","parseNum","v","clamp","hi","valueToAngle","value","span","resolveColor","fraction","thresholds","sorted","b","color","buildArcPath","Needle","angle","radius","needleLen","needleBase","jsxs","jsx","GaugeChart","React","data","chartConfig","displayConfig","height","getFieldLabel","useCubeFieldLabel","containerRef","useRef","dimensions","setDimensions","useState","useLayoutEffect","el","observer","entries","entry","width","rect","valueField","maxField","configError","useMemo","yAxis","raw","arr","parsed","e","thresholdBands","bandStart","bandEnd","row","rawValue","minValue","maxFieldValue","maxValue","effectiveMax","clampedValue","fillColor","showCenterLabel","showPercentage","yAxisFormat","containerW","containerH","outerR","innerR","cx","cy","trackPath","fillAngle","fillPath","needleAngle","displayValue","formatAxisValue","valueLabel","fieldLabel","band","error"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4]}
|
|
1
|
+
{"version":3,"file":"chart-gauge-Djs5FWxB.js","sources":["../../../node_modules/d3-shape/src/constant.js","../../../node_modules/d3-shape/src/math.js","../../../node_modules/d3-path/src/path.js","../../../node_modules/d3-shape/src/path.js","../../../node_modules/d3-shape/src/arc.js","../../../src/client/components/charts/GaugeChart.tsx"],"sourcesContent":["export default function(x) {\n return function constant() {\n return x;\n };\n}\n","export const abs = Math.abs;\nexport const atan2 = Math.atan2;\nexport const cos = Math.cos;\nexport const max = Math.max;\nexport const min = Math.min;\nexport const sin = Math.sin;\nexport const sqrt = Math.sqrt;\n\nexport const epsilon = 1e-12;\nexport const pi = Math.PI;\nexport const halfPi = pi / 2;\nexport const tau = 2 * pi;\n\nexport function acos(x) {\n return x > 1 ? 0 : x < -1 ? pi : Math.acos(x);\n}\n\nexport function asin(x) {\n return x >= 1 ? halfPi : x <= -1 ? -halfPi : Math.asin(x);\n}\n","const pi = Math.PI,\n tau = 2 * pi,\n epsilon = 1e-6,\n tauEpsilon = tau - epsilon;\n\nfunction append(strings) {\n this._ += strings[0];\n for (let i = 1, n = strings.length; i < n; ++i) {\n this._ += arguments[i] + strings[i];\n }\n}\n\nfunction appendRound(digits) {\n let d = Math.floor(digits);\n if (!(d >= 0)) throw new Error(`invalid digits: ${digits}`);\n if (d > 15) return append;\n const k = 10 ** d;\n return function(strings) {\n this._ += strings[0];\n for (let i = 1, n = strings.length; i < n; ++i) {\n this._ += Math.round(arguments[i] * k) / k + strings[i];\n }\n };\n}\n\nexport class Path {\n constructor(digits) {\n this._x0 = this._y0 = // start of current subpath\n this._x1 = this._y1 = null; // end of current subpath\n this._ = \"\";\n this._append = digits == null ? append : appendRound(digits);\n }\n moveTo(x, y) {\n this._append`M${this._x0 = this._x1 = +x},${this._y0 = this._y1 = +y}`;\n }\n closePath() {\n if (this._x1 !== null) {\n this._x1 = this._x0, this._y1 = this._y0;\n this._append`Z`;\n }\n }\n lineTo(x, y) {\n this._append`L${this._x1 = +x},${this._y1 = +y}`;\n }\n quadraticCurveTo(x1, y1, x, y) {\n this._append`Q${+x1},${+y1},${this._x1 = +x},${this._y1 = +y}`;\n }\n bezierCurveTo(x1, y1, x2, y2, x, y) {\n this._append`C${+x1},${+y1},${+x2},${+y2},${this._x1 = +x},${this._y1 = +y}`;\n }\n arcTo(x1, y1, x2, y2, r) {\n x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(`negative radius: ${r}`);\n\n let x0 = this._x1,\n y0 = this._y1,\n x21 = x2 - x1,\n y21 = y2 - y1,\n x01 = x0 - x1,\n y01 = y0 - y1,\n l01_2 = x01 * x01 + y01 * y01;\n\n // Is this path empty? Move to (x1,y1).\n if (this._x1 === null) {\n this._append`M${this._x1 = x1},${this._y1 = y1}`;\n }\n\n // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.\n else if (!(l01_2 > epsilon));\n\n // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?\n // Equivalently, is (x1,y1) coincident with (x2,y2)?\n // Or, is the radius zero? Line to (x1,y1).\n else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) {\n this._append`L${this._x1 = x1},${this._y1 = y1}`;\n }\n\n // Otherwise, draw an arc!\n else {\n let x20 = x2 - x0,\n y20 = y2 - y0,\n l21_2 = x21 * x21 + y21 * y21,\n l20_2 = x20 * x20 + y20 * y20,\n l21 = Math.sqrt(l21_2),\n l01 = Math.sqrt(l01_2),\n l = r * Math.tan((pi - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),\n t01 = l / l01,\n t21 = l / l21;\n\n // If the start tangent is not coincident with (x0,y0), line to.\n if (Math.abs(t01 - 1) > epsilon) {\n this._append`L${x1 + t01 * x01},${y1 + t01 * y01}`;\n }\n\n this._append`A${r},${r},0,0,${+(y01 * x20 > x01 * y20)},${this._x1 = x1 + t21 * x21},${this._y1 = y1 + t21 * y21}`;\n }\n }\n arc(x, y, r, a0, a1, ccw) {\n x = +x, y = +y, r = +r, ccw = !!ccw;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(`negative radius: ${r}`);\n\n let dx = r * Math.cos(a0),\n dy = r * Math.sin(a0),\n x0 = x + dx,\n y0 = y + dy,\n cw = 1 ^ ccw,\n da = ccw ? a0 - a1 : a1 - a0;\n\n // Is this path empty? Move to (x0,y0).\n if (this._x1 === null) {\n this._append`M${x0},${y0}`;\n }\n\n // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).\n else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) {\n this._append`L${x0},${y0}`;\n }\n\n // Is this arc empty? We’re done.\n if (!r) return;\n\n // Does the angle go the wrong way? Flip the direction.\n if (da < 0) da = da % tau + tau;\n\n // Is this a complete circle? Draw two arcs to complete the circle.\n if (da > tauEpsilon) {\n this._append`A${r},${r},0,1,${cw},${x - dx},${y - dy}A${r},${r},0,1,${cw},${this._x1 = x0},${this._y1 = y0}`;\n }\n\n // Is this arc non-empty? Draw an arc!\n else if (da > epsilon) {\n this._append`A${r},${r},0,${+(da >= pi)},${cw},${this._x1 = x + r * Math.cos(a1)},${this._y1 = y + r * Math.sin(a1)}`;\n }\n }\n rect(x, y, w, h) {\n this._append`M${this._x0 = this._x1 = +x},${this._y0 = this._y1 = +y}h${w = +w}v${+h}h${-w}Z`;\n }\n toString() {\n return this._;\n }\n}\n\nexport function path() {\n return new Path;\n}\n\n// Allow instanceof d3.path\npath.prototype = Path.prototype;\n\nexport function pathRound(digits = 3) {\n return new Path(+digits);\n}\n","import {Path} from \"d3-path\";\n\nexport function withPath(shape) {\n let digits = 3;\n\n shape.digits = function(_) {\n if (!arguments.length) return digits;\n if (_ == null) {\n digits = null;\n } else {\n const d = Math.floor(_);\n if (!(d >= 0)) throw new RangeError(`invalid digits: ${_}`);\n digits = d;\n }\n return shape;\n };\n\n return () => new Path(digits);\n}\n","import constant from \"./constant.js\";\nimport {abs, acos, asin, atan2, cos, epsilon, halfPi, max, min, pi, sin, sqrt, tau} from \"./math.js\";\nimport {withPath} from \"./path.js\";\n\nfunction arcInnerRadius(d) {\n return d.innerRadius;\n}\n\nfunction arcOuterRadius(d) {\n return d.outerRadius;\n}\n\nfunction arcStartAngle(d) {\n return d.startAngle;\n}\n\nfunction arcEndAngle(d) {\n return d.endAngle;\n}\n\nfunction arcPadAngle(d) {\n return d && d.padAngle; // Note: optional!\n}\n\nfunction intersect(x0, y0, x1, y1, x2, y2, x3, y3) {\n var x10 = x1 - x0, y10 = y1 - y0,\n x32 = x3 - x2, y32 = y3 - y2,\n t = y32 * x10 - x32 * y10;\n if (t * t < epsilon) return;\n t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / t;\n return [x0 + t * x10, y0 + t * y10];\n}\n\n// Compute perpendicular offset line of length rc.\n// http://mathworld.wolfram.com/Circle-LineIntersection.html\nfunction cornerTangents(x0, y0, x1, y1, r1, rc, cw) {\n var x01 = x0 - x1,\n y01 = y0 - y1,\n lo = (cw ? rc : -rc) / sqrt(x01 * x01 + y01 * y01),\n ox = lo * y01,\n oy = -lo * x01,\n x11 = x0 + ox,\n y11 = y0 + oy,\n x10 = x1 + ox,\n y10 = y1 + oy,\n x00 = (x11 + x10) / 2,\n y00 = (y11 + y10) / 2,\n dx = x10 - x11,\n dy = y10 - y11,\n d2 = dx * dx + dy * dy,\n r = r1 - rc,\n D = x11 * y10 - x10 * y11,\n d = (dy < 0 ? -1 : 1) * sqrt(max(0, r * r * d2 - D * D)),\n cx0 = (D * dy - dx * d) / d2,\n cy0 = (-D * dx - dy * d) / d2,\n cx1 = (D * dy + dx * d) / d2,\n cy1 = (-D * dx + dy * d) / d2,\n dx0 = cx0 - x00,\n dy0 = cy0 - y00,\n dx1 = cx1 - x00,\n dy1 = cy1 - y00;\n\n // Pick the closer of the two intersection points.\n // TODO Is there a faster way to determine which intersection to use?\n if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;\n\n return {\n cx: cx0,\n cy: cy0,\n x01: -ox,\n y01: -oy,\n x11: cx0 * (r1 / r - 1),\n y11: cy0 * (r1 / r - 1)\n };\n}\n\nexport default function() {\n var innerRadius = arcInnerRadius,\n outerRadius = arcOuterRadius,\n cornerRadius = constant(0),\n padRadius = null,\n startAngle = arcStartAngle,\n endAngle = arcEndAngle,\n padAngle = arcPadAngle,\n context = null,\n path = withPath(arc);\n\n function arc() {\n var buffer,\n r,\n r0 = +innerRadius.apply(this, arguments),\n r1 = +outerRadius.apply(this, arguments),\n a0 = startAngle.apply(this, arguments) - halfPi,\n a1 = endAngle.apply(this, arguments) - halfPi,\n da = abs(a1 - a0),\n cw = a1 > a0;\n\n if (!context) context = buffer = path();\n\n // Ensure that the outer radius is always larger than the inner radius.\n if (r1 < r0) r = r1, r1 = r0, r0 = r;\n\n // Is it a point?\n if (!(r1 > epsilon)) context.moveTo(0, 0);\n\n // Or is it a circle or annulus?\n else if (da > tau - epsilon) {\n context.moveTo(r1 * cos(a0), r1 * sin(a0));\n context.arc(0, 0, r1, a0, a1, !cw);\n if (r0 > epsilon) {\n context.moveTo(r0 * cos(a1), r0 * sin(a1));\n context.arc(0, 0, r0, a1, a0, cw);\n }\n }\n\n // Or is it a circular or annular sector?\n else {\n var a01 = a0,\n a11 = a1,\n a00 = a0,\n a10 = a1,\n da0 = da,\n da1 = da,\n ap = padAngle.apply(this, arguments) / 2,\n rp = (ap > epsilon) && (padRadius ? +padRadius.apply(this, arguments) : sqrt(r0 * r0 + r1 * r1)),\n rc = min(abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments)),\n rc0 = rc,\n rc1 = rc,\n t0,\n t1;\n\n // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0.\n if (rp > epsilon) {\n var p0 = asin(rp / r0 * sin(ap)),\n p1 = asin(rp / r1 * sin(ap));\n if ((da0 -= p0 * 2) > epsilon) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0;\n else da0 = 0, a00 = a10 = (a0 + a1) / 2;\n if ((da1 -= p1 * 2) > epsilon) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1;\n else da1 = 0, a01 = a11 = (a0 + a1) / 2;\n }\n\n var x01 = r1 * cos(a01),\n y01 = r1 * sin(a01),\n x10 = r0 * cos(a10),\n y10 = r0 * sin(a10);\n\n // Apply rounded corners?\n if (rc > epsilon) {\n var x11 = r1 * cos(a11),\n y11 = r1 * sin(a11),\n x00 = r0 * cos(a00),\n y00 = r0 * sin(a00),\n oc;\n\n // Restrict the corner radius according to the sector angle. If this\n // intersection fails, it’s probably because the arc is too small, so\n // disable the corner radius entirely.\n if (da < pi) {\n if (oc = intersect(x01, y01, x00, y00, x11, y11, x10, y10)) {\n var ax = x01 - oc[0],\n ay = y01 - oc[1],\n bx = x11 - oc[0],\n by = y11 - oc[1],\n kc = 1 / sin(acos((ax * bx + ay * by) / (sqrt(ax * ax + ay * ay) * sqrt(bx * bx + by * by))) / 2),\n lc = sqrt(oc[0] * oc[0] + oc[1] * oc[1]);\n rc0 = min(rc, (r0 - lc) / (kc - 1));\n rc1 = min(rc, (r1 - lc) / (kc + 1));\n } else {\n rc0 = rc1 = 0;\n }\n }\n }\n\n // Is the sector collapsed to a line?\n if (!(da1 > epsilon)) context.moveTo(x01, y01);\n\n // Does the sector’s outer ring have rounded corners?\n else if (rc1 > epsilon) {\n t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw);\n t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw);\n\n context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01);\n\n // Have the corners merged?\n if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw);\n\n // Otherwise, draw the two corners and the ring.\n else {\n context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw);\n context.arc(0, 0, r1, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), !cw);\n context.arc(t1.cx, t1.cy, rc1, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw);\n }\n }\n\n // Or is the outer ring just a circular arc?\n else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw);\n\n // Is there no inner ring, and it’s a circular sector?\n // Or perhaps it’s an annular sector collapsed due to padding?\n if (!(r0 > epsilon) || !(da0 > epsilon)) context.lineTo(x10, y10);\n\n // Does the sector’s inner ring (or point) have rounded corners?\n else if (rc0 > epsilon) {\n t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw);\n t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw);\n\n context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01);\n\n // Have the corners merged?\n if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw);\n\n // Otherwise, draw the two corners and the ring.\n else {\n context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw);\n context.arc(0, 0, r0, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), cw);\n context.arc(t1.cx, t1.cy, rc0, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw);\n }\n }\n\n // Or is the inner ring just a circular arc?\n else context.arc(0, 0, r0, a10, a00, cw);\n }\n\n context.closePath();\n\n if (buffer) return context = null, buffer + \"\" || null;\n }\n\n arc.centroid = function() {\n var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2,\n a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi / 2;\n return [cos(a) * r, sin(a) * r];\n };\n\n arc.innerRadius = function(_) {\n return arguments.length ? (innerRadius = typeof _ === \"function\" ? _ : constant(+_), arc) : innerRadius;\n };\n\n arc.outerRadius = function(_) {\n return arguments.length ? (outerRadius = typeof _ === \"function\" ? _ : constant(+_), arc) : outerRadius;\n };\n\n arc.cornerRadius = function(_) {\n return arguments.length ? (cornerRadius = typeof _ === \"function\" ? _ : constant(+_), arc) : cornerRadius;\n };\n\n arc.padRadius = function(_) {\n return arguments.length ? (padRadius = _ == null ? null : typeof _ === \"function\" ? _ : constant(+_), arc) : padRadius;\n };\n\n arc.startAngle = function(_) {\n return arguments.length ? (startAngle = typeof _ === \"function\" ? _ : constant(+_), arc) : startAngle;\n };\n\n arc.endAngle = function(_) {\n return arguments.length ? (endAngle = typeof _ === \"function\" ? _ : constant(+_), arc) : endAngle;\n };\n\n arc.padAngle = function(_) {\n return arguments.length ? (padAngle = typeof _ === \"function\" ? _ : constant(+_), arc) : padAngle;\n };\n\n arc.context = function(_) {\n return arguments.length ? ((context = _ == null ? null : _), arc) : context;\n };\n\n return arc;\n}\n","import React, { useLayoutEffect, useMemo, useRef, useState } from 'react'\nimport { arc } from 'd3-shape'\nimport { formatAxisValue } from '../../utils/chartUtils'\nimport { useCubeFieldLabel } from '../../hooks/useCubeFieldLabel'\nimport type { ChartProps, ThresholdBand } from '../../types'\n\nconst START_ANGLE = -Math.PI * 0.75\nconst END_ANGLE = Math.PI * 0.75\nconst TRACK_COLOR = '#e2e8f0'\nconst DEFAULT_FILL = '#6366f1'\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 clamp(v: number, lo: number, hi: number): number {\n return Math.max(lo, Math.min(hi, v))\n}\n\nfunction valueToAngle(value: number, min: number, max: number): number {\n const span = max === min ? 1 : max - min\n const t = clamp((value - min) / span, 0, 1)\n return START_ANGLE + t * (END_ANGLE - START_ANGLE)\n}\n\nfunction resolveColor(fraction: number, thresholds: ThresholdBand[]): string {\n const sorted = [...thresholds].sort((a, b) => a.value - b.value)\n let color = DEFAULT_FILL\n for (const t of sorted) {\n if (fraction >= t.value) color = t.color\n }\n return color\n}\n\nfunction buildArcPath(\n innerRadius: number,\n outerRadius: number,\n startAngle: number,\n endAngle: number\n): string {\n const pathFn = arc()\n return pathFn({ innerRadius, outerRadius, startAngle, endAngle }) ?? ''\n}\n\nfunction Needle({ angle, radius }: { angle: number; radius: number }) {\n const needleLen = radius * 0.72\n const needleBase = radius * 0.06\n const x = Math.cos(angle - Math.PI / 2) * needleLen\n const y = Math.sin(angle - Math.PI / 2) * needleLen\n return (\n <g data-testid=\"gauge-needle\">\n <circle r={needleBase} fill=\"currentColor\" className=\"text-dc-text-secondary\" />\n <line\n x1={0}\n y1={0}\n x2={x}\n y2={y}\n stroke=\"currentColor\"\n strokeWidth={3}\n strokeLinecap=\"round\"\n className=\"text-dc-text-secondary\"\n />\n </g>\n )\n}\n\nconst GaugeChart = React.memo(function GaugeChart({\n data,\n chartConfig,\n displayConfig = {},\n height = '100%',\n}: ChartProps) {\n const getFieldLabel = useCubeFieldLabel()\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 { valueField, maxField, configError } = useMemo(() => {\n const yAxis: string[] = Array.isArray(chartConfig?.yAxis)\n ? chartConfig.yAxis\n : []\n\n const valueField = yAxis[0] ?? ''\n const maxField = yAxis[1] ?? ''\n\n if (!valueField) {\n return { valueField, maxField, configError: 'Gauge requires at least 1 measure in Y-Axis (current value)' }\n }\n return { valueField, maxField, configError: null }\n }, [chartConfig])\n\n const thresholds: ThresholdBand[] = useMemo(() => {\n const raw = displayConfig?.thresholds\n let arr: unknown[] | null = null\n if (Array.isArray(raw)) {\n arr = raw\n } else if (typeof raw === 'string' && raw.trim()) {\n try {\n const parsed = JSON.parse(raw)\n if (Array.isArray(parsed)) arr = parsed\n } catch (e) {\n console.warn('GaugeChart: invalid threshold JSON', e)\n return []\n }\n }\n if (!arr) return []\n return arr.filter(\n (entry): entry is ThresholdBand =>\n entry !== null &&\n typeof entry === 'object' &&\n typeof (entry as ThresholdBand).value === 'number' &&\n typeof (entry as ThresholdBand).color === 'string'\n )\n }, [displayConfig?.thresholds])\n\n const thresholdBands = thresholds.length === 0\n ? []\n : [...thresholds].sort((a, b) => a.value - b.value).map((t, i, sorted) => {\n const bandStart = i === 0 ? START_ANGLE : valueToAngle(sorted[i - 1].value, 0, 1)\n const bandEnd = valueToAngle(t.value, 0, 1)\n return { color: t.color, start: bandStart, end: bandEnd }\n })\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 gauge 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 const row = (data as Record<string, unknown>[])[0]\n const rawValue = parseNum(row[valueField])\n if (rawValue === null) {\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\">Gauge value is not a valid number</div>\n </div>\n </div>\n )\n }\n const minValue = displayConfig?.minValue ?? 0\n const maxFieldValue = maxField ? parseNum(row[maxField]) : null\n const maxValue = displayConfig?.maxValue ?? (maxFieldValue ?? 100)\n\n const effectiveMax = maxValue === minValue ? minValue + 1 : maxValue\n const clampedValue = clamp(rawValue, minValue, effectiveMax)\n const fraction = (clampedValue - minValue) / (effectiveMax - minValue)\n\n const fillColor = thresholds.length > 0 ? resolveColor(fraction, thresholds) : DEFAULT_FILL\n\n const showCenterLabel = displayConfig?.showCenterLabel ?? true\n const showPercentage = displayConfig?.showPercentage ?? false\n const yAxisFormat = displayConfig?.leftYAxisFormat\n\n const containerW = dimensions.width || 300\n const containerH = typeof height === 'number' ? height : (dimensions.height || 200)\n\n const radius = Math.min(containerW / 2, containerH * 0.9) * 0.85\n const outerR = radius\n const innerR = radius * 0.6\n const cx = containerW / 2\n const cy = containerH * 0.7\n\n const trackPath = buildArcPath(innerR, outerR, START_ANGLE, END_ANGLE)\n const fillAngle = valueToAngle(clampedValue, minValue, effectiveMax)\n const fillPath = buildArcPath(innerR, outerR, START_ANGLE, fillAngle)\n\n const needleAngle = valueToAngle(clampedValue, minValue, effectiveMax)\n\n const displayValue = yAxisFormat\n ? formatAxisValue(rawValue, yAxisFormat)\n : rawValue.toLocaleString()\n\n const valueLabel = showPercentage\n ? `${(fraction * 100).toFixed(1)}%`\n : displayValue\n\n const fieldLabel = getFieldLabel(valueField)\n return (\n <div ref={containerRef} className=\"dc:relative dc:w-full\" style={{ height }}>\n <svg\n width=\"100%\"\n height=\"100%\"\n viewBox={`0 0 ${containerW} ${containerH}`}\n preserveAspectRatio=\"xMidYMid meet\"\n data-testid=\"gauge-svg\"\n >\n <g transform={`translate(${cx}, ${cy})`}>\n <path\n d={trackPath}\n fill={TRACK_COLOR}\n data-testid=\"gauge-track\"\n />\n\n {thresholdBands.map((band, i) => (\n <path\n key={i}\n d={buildArcPath(outerR + 4, outerR + 8, band.start, band.end)}\n fill={band.color}\n data-testid={`gauge-band-${i}`}\n />\n ))}\n\n <path\n d={fillPath}\n fill={fillColor}\n data-testid=\"gauge-fill\"\n data-fraction={fraction.toFixed(4)}\n />\n\n <Needle angle={needleAngle} radius={radius} />\n\n {showCenterLabel && (\n <g data-testid=\"gauge-label\">\n <text\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n fontSize={radius * 0.22}\n fontWeight=\"bold\"\n fill=\"currentColor\"\n dy={radius * 0.12}\n data-testid=\"gauge-value-text\"\n >\n {valueLabel}\n </text>\n <text\n textAnchor=\"middle\"\n fontSize={radius * 0.13}\n fill=\"currentColor\"\n className=\"text-dc-text-secondary\"\n dy={radius * 0.34}\n >\n {fieldLabel}\n </text>\n </g>\n )}\n\n <text\n x={Math.cos(START_ANGLE - Math.PI / 2) * (outerR + 14)}\n y={Math.sin(START_ANGLE - Math.PI / 2) * (outerR + 14)}\n textAnchor=\"middle\"\n fontSize={radius * 0.12}\n fill=\"currentColor\"\n className=\"text-dc-text-secondary\"\n data-testid=\"gauge-min-label\"\n >\n {yAxisFormat ? formatAxisValue(minValue, yAxisFormat) : minValue.toLocaleString()}\n </text>\n <text\n x={Math.cos(END_ANGLE - Math.PI / 2) * (outerR + 14)}\n y={Math.sin(END_ANGLE - Math.PI / 2) * (outerR + 14)}\n textAnchor=\"middle\"\n fontSize={radius * 0.12}\n fill=\"currentColor\"\n className=\"text-dc-text-secondary\"\n data-testid=\"gauge-max-label\"\n >\n {yAxisFormat ? formatAxisValue(effectiveMax, yAxisFormat) : effectiveMax.toLocaleString()}\n </text>\n </g>\n </svg>\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\">Gauge 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 GaugeChart\n"],"names":["constant","x","abs","atan2","cos","max","min","sin","sqrt","epsilon","pi","halfPi","tau","acos","asin","tauEpsilon","append","strings","i","n","appendRound","digits","d","k","Path","y","x1","y1","x2","y2","r","x0","y0","x21","y21","x01","y01","l01_2","x20","y20","l21_2","l20_2","l21","l01","l","t01","t21","a0","a1","ccw","dx","dy","cw","da","w","h","withPath","shape","_","arcInnerRadius","arcOuterRadius","arcStartAngle","arcEndAngle","arcPadAngle","intersect","x3","y3","x10","y10","x32","y32","t","cornerTangents","r1","rc","lo","ox","oy","x11","y11","x00","y00","d2","D","cx0","cy0","cx1","cy1","dx0","dy0","dx1","dy1","arc","innerRadius","outerRadius","cornerRadius","padRadius","startAngle","endAngle","padAngle","context","path","buffer","r0","a01","a11","a00","a10","da0","da1","ap","rp","rc0","rc1","t0","t1","p0","p1","oc","ax","ay","bx","by","kc","lc","a","START_ANGLE","END_ANGLE","TRACK_COLOR","DEFAULT_FILL","parseNum","v","clamp","hi","valueToAngle","value","span","resolveColor","fraction","thresholds","sorted","b","color","buildArcPath","Needle","angle","radius","needleLen","needleBase","jsxs","jsx","GaugeChart","React","data","chartConfig","displayConfig","height","getFieldLabel","useCubeFieldLabel","containerRef","useRef","dimensions","setDimensions","useState","useLayoutEffect","el","observer","entries","entry","width","rect","valueField","maxField","configError","useMemo","yAxis","raw","arr","parsed","e","thresholdBands","bandStart","bandEnd","row","rawValue","minValue","maxFieldValue","maxValue","effectiveMax","clampedValue","fillColor","showCenterLabel","showPercentage","yAxisFormat","containerW","containerH","outerR","innerR","cx","cy","trackPath","fillAngle","fillPath","needleAngle","displayValue","formatAxisValue","valueLabel","fieldLabel","band","error"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4]}
|