drizzle-cube 0.2.0 → 0.2.1
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 +11 -11
- package/dist/client/chunks/{chart-activitygridchart-BRk9BNnp.js → chart-activitygridchart-B5OqLgbD.js} +7 -7
- package/dist/client/chunks/{chart-activitygridchart-BRk9BNnp.js.map → chart-activitygridchart-B5OqLgbD.js.map} +1 -1
- package/dist/client/chunks/{chart-areachart-Beu8sO9v.js → chart-areachart-CTzUpR0_.js} +3 -3
- package/dist/client/chunks/{chart-areachart-Beu8sO9v.js.map → chart-areachart-CTzUpR0_.js.map} +1 -1
- package/dist/client/chunks/{chart-barchart-BzoejYkT.js → chart-barchart-CKF8FnMs.js} +4 -4
- package/dist/client/chunks/{chart-barchart-BzoejYkT.js.map → chart-barchart-CKF8FnMs.js.map} +1 -1
- package/dist/client/chunks/{chart-bubblechart-Dg7sT_Mm.js → chart-bubblechart-5Z0hPYwn.js} +2 -2
- package/dist/client/chunks/{chart-bubblechart-Dg7sT_Mm.js.map → chart-bubblechart-5Z0hPYwn.js.map} +1 -1
- package/dist/client/chunks/{chart-charttooltip-NrFVM1cJ.js → chart-charttooltip-CqtjUW2V.js} +2 -2
- package/dist/client/chunks/{chart-charttooltip-NrFVM1cJ.js.map → chart-charttooltip-CqtjUW2V.js.map} +1 -1
- package/dist/client/chunks/{chart-datatable-BvV7gLPZ.js → chart-datatable-uFzkh18f.js} +2 -2
- package/dist/client/chunks/{chart-datatable-BvV7gLPZ.js.map → chart-datatable-uFzkh18f.js.map} +1 -1
- package/dist/client/chunks/{chart-kpidelta-p1lVVG5v.js → chart-kpidelta-B1zg2dTx.js} +2 -2
- package/dist/client/chunks/{chart-kpidelta-p1lVVG5v.js.map → chart-kpidelta-B1zg2dTx.js.map} +1 -1
- package/dist/client/chunks/{chart-kpinumber-BFtxFeqq.js → chart-kpinumber-CHcSqthc.js} +4 -4
- package/dist/client/chunks/{chart-kpinumber-BFtxFeqq.js.map → chart-kpinumber-CHcSqthc.js.map} +1 -1
- package/dist/client/chunks/{chart-kpitext-CX1s1u8B.js → chart-kpitext-BrapZkRe.js} +3 -3
- package/dist/client/chunks/{chart-kpitext-CX1s1u8B.js.map → chart-kpitext-BrapZkRe.js.map} +1 -1
- package/dist/client/chunks/{chart-linechart-Dgb10zbj.js → chart-linechart-DqZU4vH8.js} +4 -4
- package/dist/client/chunks/{chart-linechart-Dgb10zbj.js.map → chart-linechart-DqZU4vH8.js.map} +1 -1
- package/dist/client/chunks/{chart-piechart-B-0BQh-d.js → chart-piechart-Dsxs70px.js} +3 -3
- package/dist/client/chunks/{chart-piechart-B-0BQh-d.js.map → chart-piechart-Dsxs70px.js.map} +1 -1
- package/dist/client/chunks/{chart-radarchart-BwZM1yTd.js → chart-radarchart-2qnrlYCv.js} +3 -3
- package/dist/client/chunks/{chart-radarchart-BwZM1yTd.js.map → chart-radarchart-2qnrlYCv.js.map} +1 -1
- package/dist/client/chunks/{chart-radialbarchart-CythI1zx.js → chart-radialbarchart-DPi9fYc7.js} +3 -3
- package/dist/client/chunks/{chart-radialbarchart-CythI1zx.js.map → chart-radialbarchart-DPi9fYc7.js.map} +1 -1
- package/dist/client/chunks/{chart-scatterchart-om9-qmtE.js → chart-scatterchart-DNleJCr4.js} +2 -2
- package/dist/client/chunks/{chart-scatterchart-om9-qmtE.js.map → chart-scatterchart-DNleJCr4.js.map} +1 -1
- package/dist/client/chunks/{chart-treemapchart-Dc35Miif.js → chart-treemapchart-B2-Qr28e.js} +3 -3
- package/dist/client/chunks/{chart-treemapchart-Dc35Miif.js.map → chart-treemapchart-B2-Qr28e.js.map} +1 -1
- package/dist/client/chunks/{charts-DL9XOlaK.js → charts-BmpuCBGG.js} +25 -25
- package/dist/client/chunks/{charts-DL9XOlaK.js.map → charts-BmpuCBGG.js.map} +1 -1
- package/dist/client/chunks/{index-DpEuGmcW.js → index-EfJ-vN-5.js} +2 -2
- package/dist/client/chunks/{index-DpEuGmcW.js.map → index-EfJ-vN-5.js.map} +1 -1
- package/dist/client/components.js +1 -1
- package/dist/client/hooks.js +9 -9
- package/dist/client/index.js +748 -748
- package/dist/client/index.js.map +1 -1
- package/dist/client/providers.d.ts +1 -0
- package/dist/client/providers.js +8 -4
- package/dist/client/providers.js.map +1 -1
- package/dist/client-bundle-stats.html +1 -1
- package/package.json +1 -1
|
@@ -2,8 +2,8 @@ import { jsx as t, jsxs as d, Fragment as D } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState as L } from "react";
|
|
3
3
|
import { ComposedChart as M, CartesianGrid as O, XAxis as V, YAxis as E, Legend as G, Area as $, Line as b } from "recharts";
|
|
4
4
|
import { C as I } from "./chart-chartcontainer-CdwzIKP1.js";
|
|
5
|
-
import { C } from "./chart-charttooltip-
|
|
6
|
-
import { u as R, t as W, C as H, f as g, a as N } from "./chart-activitygridchart-
|
|
5
|
+
import { C } from "./chart-charttooltip-CqtjUW2V.js";
|
|
6
|
+
import { u as R, t as W, C as H, f as g, a as N } from "./chart-activitygridchart-B5OqLgbD.js";
|
|
7
7
|
function K(r) {
|
|
8
8
|
if (!r || typeof r != "string")
|
|
9
9
|
return [];
|
|
@@ -201,4 +201,4 @@ export {
|
|
|
201
201
|
K as p,
|
|
202
202
|
X as s
|
|
203
203
|
};
|
|
204
|
-
//# sourceMappingURL=chart-areachart-
|
|
204
|
+
//# sourceMappingURL=chart-areachart-CTzUpR0_.js.map
|
package/dist/client/chunks/{chart-areachart-Beu8sO9v.js.map → chart-areachart-CTzUpR0_.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-areachart-Beu8sO9v.js","sources":["../../../src/client/utils/targetUtils.ts","../../../src/client/components/charts/AreaChart.tsx"],"sourcesContent":["/**\n * Utility functions for handling target values in charts\n */\n\n/**\n * Parse target values from string format\n * @param targetString - String containing target values (e.g., \"100\" or \"50,75,100\")\n * @returns Array of numeric target values\n */\nexport function parseTargetValues(targetString: string): number[] {\n if (!targetString || typeof targetString !== 'string') {\n return []\n }\n\n const trimmed = targetString.trim()\n if (!trimmed) {\n return []\n }\n\n try {\n // Split by comma and parse each value\n const values = trimmed\n .split(',')\n .map(val => val.trim())\n .filter(val => val !== '')\n .map(val => {\n const num = parseFloat(val)\n if (isNaN(num)) {\n throw new Error(`Invalid numeric value: ${val}`)\n }\n return num\n })\n\n return values.length > 0 ? values : []\n } catch (error) {\n console.warn('Failed to parse target values:', error)\n return []\n }\n}\n\n/**\n * Spread target values across data points\n * @param targets - Array of target values\n * @param dataLength - Number of data points to spread across\n * @returns Array of target values for each data point\n */\nexport function spreadTargetValues(targets: number[], dataLength: number): number[] {\n if (targets.length === 0 || dataLength <= 0) {\n return []\n }\n\n // If only one target value, repeat for all data points\n if (targets.length === 1) {\n return new Array(dataLength).fill(targets[0])\n }\n\n // If we have multiple targets, spread them evenly across data points\n const result: number[] = []\n const baseGroupSize = Math.floor(dataLength / targets.length)\n const remainder = dataLength % targets.length\n\n let currentIndex = 0\n \n for (let i = 0; i < targets.length; i++) {\n // Calculate group size for this target\n // First 'remainder' groups get an extra item\n const groupSize = baseGroupSize + (i < remainder ? 1 : 0)\n \n // Fill this group with the current target value\n for (let j = 0; j < groupSize; j++) {\n result[currentIndex++] = targets[i]\n }\n }\n\n return result\n}\n\n/**\n * Calculate variance between actual and target values\n * @param actual - Actual value\n * @param target - Target value\n * @returns Variance as percentage\n */\nexport function calculateVariance(actual: number, target: number): number {\n if (target === 0) {\n return actual === 0 ? 0 : (actual > 0 ? 100 : -100)\n }\n return ((actual - target) / target) * 100\n}\n\n/**\n * Format variance as percentage string with appropriate sign and color indication\n * @param variance - Variance percentage\n * @param decimals - Number of decimal places (default: 1)\n * @returns Formatted variance string (e.g., \"+12.5%\" or \"-8.3%\")\n */\nexport function formatVariance(variance: number, decimals: number = 1): string {\n const sign = variance >= 0 ? '+' : ''\n return `${sign}${variance.toFixed(decimals)}%`\n}\n\n/**\n * Get unique target values for reference lines\n * @param targets - Array of target values (may contain duplicates)\n * @returns Array of unique target values\n */\nexport function getUniqueTargets(targets: number[]): number[] {\n return [...new Set(targets)].sort((a, b) => a - b)\n}","import { useState } from 'react'\nimport { ComposedChart, Area, Line, XAxis, YAxis, CartesianGrid, Legend } from 'recharts'\nimport ChartContainer from './ChartContainer'\nimport ChartTooltip from './ChartTooltip'\nimport { CHART_COLORS, CHART_MARGINS } from '../../utils/chartConstants'\nimport { transformChartDataWithSeries, formatNumericValue } from '../../utils/chartUtils'\nimport { parseTargetValues, spreadTargetValues } from '../../utils/targetUtils'\nimport { useCubeContext } from '../../providers/CubeProvider'\nimport type { ChartProps } from '../../types'\n\nexport default function AreaChart({ \n data, \n chartConfig, \n displayConfig = {},\n queryObject,\n height = \"100%\",\n colorPalette\n}: ChartProps) {\n const [hoveredLegend, setHoveredLegend] = useState<string | null>(null)\n const { labelMap, getFieldLabel } = useCubeContext()\n \n try {\n // Determine stacking from stackType (new) or stacked (legacy)\n const stackType = displayConfig?.stackType ?? (displayConfig?.stacked ? 'normal' : 'none')\n const shouldStack = stackType !== 'none'\n const isPercentStack = stackType === 'percent'\n\n const safeDisplayConfig = {\n showLegend: displayConfig?.showLegend ?? true,\n showGrid: displayConfig?.showGrid ?? true,\n showTooltip: displayConfig?.showTooltip ?? true,\n connectNulls: displayConfig?.connectNulls ?? false\n }\n\n if (!data || data.length === 0) {\n return (\n <div className=\"flex items-center justify-center w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">No data available</div>\n <div className=\"text-xs text-dc-text-secondary\">No data points to display in area chart</div>\n </div>\n </div>\n )\n }\n\n // Validate chartConfig - support both legacy and new formats\n let xAxisField: string\n let yAxisFields: string[]\n let seriesFields: string[] = []\n \n if (chartConfig?.xAxis && chartConfig?.yAxis) {\n // New format\n xAxisField = Array.isArray(chartConfig.xAxis) ? chartConfig.xAxis[0] : chartConfig.xAxis\n yAxisFields = Array.isArray(chartConfig.yAxis) ? chartConfig.yAxis : [chartConfig.yAxis]\n seriesFields = chartConfig.series || []\n } else if (chartConfig?.x && chartConfig?.y) {\n // Legacy format\n xAxisField = chartConfig.x\n yAxisFields = Array.isArray(chartConfig.y) ? chartConfig.y : [chartConfig.y]\n } else {\n return (\n <div className=\"flex items-center justify-center w-full text-yellow-600\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">Configuration Error</div>\n <div className=\"text-xs\">Invalid or missing chart axis configuration</div>\n </div>\n </div>\n )\n }\n\n if (!xAxisField || !yAxisFields || yAxisFields.length === 0) {\n return (\n <div className=\"flex items-center justify-center w-full text-yellow-600\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">Configuration Error</div>\n <div className=\"text-xs\">Missing required X-axis or Y-axis fields</div>\n </div>\n </div>\n )\n }\n\n // Use shared function to transform data and handle series\n const { data: chartData, seriesKeys } = transformChartDataWithSeries(\n data, \n xAxisField, \n yAxisFields, \n queryObject,\n seriesFields,\n labelMap\n )\n \n // Determine if legend will be shown\n const showLegend = safeDisplayConfig.showLegend\n \n // Use custom chart margins with extra left space for Y-axis label\n const chartMargins = {\n ...CHART_MARGINS,\n left: 40 // Increased from 20 to 40 for Y-axis label space\n }\n \n // Process target values and add to chart data\n const targetValues = parseTargetValues(displayConfig?.target || '')\n const spreadTargets = spreadTargetValues(targetValues, chartData.length)\n \n // Add target data to chart data if targets exist\n let enhancedChartData = chartData\n if (spreadTargets.length > 0) {\n enhancedChartData = chartData.map((dataPoint, index) => ({\n ...dataPoint,\n __target: spreadTargets[index] || null\n }))\n }\n \n // Validate transformed data\n if (!chartData || chartData.length === 0) {\n return (\n <div className=\"flex items-center justify-center w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">No valid data</div>\n <div className=\"text-xs text-dc-text-secondary\">No valid data points for area chart after transformation</div>\n </div>\n </div>\n )\n }\n\n // Determine stack offset for percentage stacking\n const stackOffset = isPercentStack ? 'expand' as const : undefined\n\n return (\n <ChartContainer height={height}>\n <ComposedChart data={enhancedChartData} margin={chartMargins} stackOffset={stackOffset}>\n {safeDisplayConfig.showGrid && (\n <CartesianGrid strokeDasharray=\"3 3\" />\n )}\n <XAxis\n dataKey=\"name\"\n tick={{ fontSize: 12 }}\n angle={-45}\n textAnchor=\"end\"\n height={60}\n />\n <YAxis\n tick={{ fontSize: 12 }}\n tickFormatter={isPercentStack ? (v) => `${(v * 100).toFixed(0)}%` : undefined}\n domain={isPercentStack ? [0, 1] : undefined}\n label={isPercentStack ? undefined : { value: getFieldLabel(yAxisFields[0]), angle: -90, position: 'left', style: { textAnchor: 'middle', fontSize: '12px' } }}\n />\n {safeDisplayConfig.showTooltip && (\n <ChartTooltip\n formatter={(value: any, name: any) => {\n // Handle null values in tooltip\n if (value === null || value === undefined) {\n return ['No data', name]\n }\n if (name === 'Target') {\n return [formatNumericValue(value), 'Target Value']\n }\n // Format as percentage when using percent stacking\n if (isPercentStack && typeof value === 'number') {\n return [`${(value * 100).toFixed(1)}%`, name]\n }\n return [formatNumericValue(value), name]\n }}\n />\n )}\n {showLegend && (\n <Legend \n wrapperStyle={{ fontSize: '12px', paddingTop: '10px' }}\n iconType=\"rect\"\n iconSize={8}\n layout=\"horizontal\"\n align=\"center\"\n verticalAlign=\"bottom\"\n onMouseEnter={(o) => setHoveredLegend(String(o.dataKey || ''))}\n onMouseLeave={() => setHoveredLegend(null)}\n />\n )}\n {seriesKeys.map((seriesKey, index) => (\n <Area\n key={seriesKey}\n type=\"monotone\"\n dataKey={seriesKey}\n stackId={shouldStack ? \"stack\" : undefined}\n stroke={(colorPalette?.colors && colorPalette.colors[index % colorPalette.colors.length]) || CHART_COLORS[index % CHART_COLORS.length]}\n fill={(colorPalette?.colors && colorPalette.colors[index % colorPalette.colors.length]) || CHART_COLORS[index % CHART_COLORS.length]}\n fillOpacity={hoveredLegend ? (hoveredLegend === seriesKey ? 0.6 : 0.1) : 0.3}\n strokeWidth={2}\n strokeOpacity={hoveredLegend ? (hoveredLegend === seriesKey ? 1 : 0.3) : 1}\n connectNulls={safeDisplayConfig.connectNulls}\n />\n ))}\n {spreadTargets.length > 0 && (\n <>\n {/* White background line */}\n <Line\n type=\"monotone\"\n dataKey=\"__target\"\n stroke=\"#ffffff\"\n strokeWidth={2}\n dot={false}\n activeDot={false}\n connectNulls={false}\n />\n {/* Grey dashed line on top */}\n <Line\n type=\"monotone\"\n dataKey=\"__target\"\n name=\"Target\"\n stroke=\"#8B5CF6\"\n strokeWidth={2}\n strokeDasharray=\"2 3\"\n dot={false}\n activeDot={false}\n connectNulls={false}\n />\n </>\n )}\n </ComposedChart>\n </ChartContainer>\n )\n } catch (error) {\n // 'AreaChart rendering error\n return (\n <div className=\"flex flex-col items-center justify-center w-full text-red-500 p-4\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">Area Chart Error</div>\n <div className=\"text-xs mb-2\">{error instanceof Error ? error.message : 'Unknown rendering error'}</div>\n <div className=\"text-xs text-dc-text-muted\">Check the data and configuration</div>\n </div>\n </div>\n )\n }\n}"],"names":["parseTargetValues","targetString","trimmed","values","val","num","error","spreadTargetValues","targets","dataLength","result","baseGroupSize","remainder","currentIndex","groupSize","j","calculateVariance","actual","target","formatVariance","variance","decimals","AreaChart","data","chartConfig","displayConfig","queryObject","height","colorPalette","hoveredLegend","setHoveredLegend","useState","labelMap","getFieldLabel","useCubeContext","stackType","shouldStack","isPercentStack","safeDisplayConfig","jsx","jsxs","xAxisField","yAxisFields","seriesFields","chartData","seriesKeys","transformChartDataWithSeries","showLegend","chartMargins","CHART_MARGINS","targetValues","spreadTargets","enhancedChartData","dataPoint","index","ChartContainer","ComposedChart","CartesianGrid","XAxis","YAxis","v","ChartTooltip","value","name","formatNumericValue","Legend","o","seriesKey","Area","CHART_COLORS","Fragment","Line"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"chart-areachart-CTzUpR0_.js","sources":["../../../src/client/utils/targetUtils.ts","../../../src/client/components/charts/AreaChart.tsx"],"sourcesContent":["/**\n * Utility functions for handling target values in charts\n */\n\n/**\n * Parse target values from string format\n * @param targetString - String containing target values (e.g., \"100\" or \"50,75,100\")\n * @returns Array of numeric target values\n */\nexport function parseTargetValues(targetString: string): number[] {\n if (!targetString || typeof targetString !== 'string') {\n return []\n }\n\n const trimmed = targetString.trim()\n if (!trimmed) {\n return []\n }\n\n try {\n // Split by comma and parse each value\n const values = trimmed\n .split(',')\n .map(val => val.trim())\n .filter(val => val !== '')\n .map(val => {\n const num = parseFloat(val)\n if (isNaN(num)) {\n throw new Error(`Invalid numeric value: ${val}`)\n }\n return num\n })\n\n return values.length > 0 ? values : []\n } catch (error) {\n console.warn('Failed to parse target values:', error)\n return []\n }\n}\n\n/**\n * Spread target values across data points\n * @param targets - Array of target values\n * @param dataLength - Number of data points to spread across\n * @returns Array of target values for each data point\n */\nexport function spreadTargetValues(targets: number[], dataLength: number): number[] {\n if (targets.length === 0 || dataLength <= 0) {\n return []\n }\n\n // If only one target value, repeat for all data points\n if (targets.length === 1) {\n return new Array(dataLength).fill(targets[0])\n }\n\n // If we have multiple targets, spread them evenly across data points\n const result: number[] = []\n const baseGroupSize = Math.floor(dataLength / targets.length)\n const remainder = dataLength % targets.length\n\n let currentIndex = 0\n \n for (let i = 0; i < targets.length; i++) {\n // Calculate group size for this target\n // First 'remainder' groups get an extra item\n const groupSize = baseGroupSize + (i < remainder ? 1 : 0)\n \n // Fill this group with the current target value\n for (let j = 0; j < groupSize; j++) {\n result[currentIndex++] = targets[i]\n }\n }\n\n return result\n}\n\n/**\n * Calculate variance between actual and target values\n * @param actual - Actual value\n * @param target - Target value\n * @returns Variance as percentage\n */\nexport function calculateVariance(actual: number, target: number): number {\n if (target === 0) {\n return actual === 0 ? 0 : (actual > 0 ? 100 : -100)\n }\n return ((actual - target) / target) * 100\n}\n\n/**\n * Format variance as percentage string with appropriate sign and color indication\n * @param variance - Variance percentage\n * @param decimals - Number of decimal places (default: 1)\n * @returns Formatted variance string (e.g., \"+12.5%\" or \"-8.3%\")\n */\nexport function formatVariance(variance: number, decimals: number = 1): string {\n const sign = variance >= 0 ? '+' : ''\n return `${sign}${variance.toFixed(decimals)}%`\n}\n\n/**\n * Get unique target values for reference lines\n * @param targets - Array of target values (may contain duplicates)\n * @returns Array of unique target values\n */\nexport function getUniqueTargets(targets: number[]): number[] {\n return [...new Set(targets)].sort((a, b) => a - b)\n}","import { useState } from 'react'\nimport { ComposedChart, Area, Line, XAxis, YAxis, CartesianGrid, Legend } from 'recharts'\nimport ChartContainer from './ChartContainer'\nimport ChartTooltip from './ChartTooltip'\nimport { CHART_COLORS, CHART_MARGINS } from '../../utils/chartConstants'\nimport { transformChartDataWithSeries, formatNumericValue } from '../../utils/chartUtils'\nimport { parseTargetValues, spreadTargetValues } from '../../utils/targetUtils'\nimport { useCubeContext } from '../../providers/CubeProvider'\nimport type { ChartProps } from '../../types'\n\nexport default function AreaChart({ \n data, \n chartConfig, \n displayConfig = {},\n queryObject,\n height = \"100%\",\n colorPalette\n}: ChartProps) {\n const [hoveredLegend, setHoveredLegend] = useState<string | null>(null)\n const { labelMap, getFieldLabel } = useCubeContext()\n \n try {\n // Determine stacking from stackType (new) or stacked (legacy)\n const stackType = displayConfig?.stackType ?? (displayConfig?.stacked ? 'normal' : 'none')\n const shouldStack = stackType !== 'none'\n const isPercentStack = stackType === 'percent'\n\n const safeDisplayConfig = {\n showLegend: displayConfig?.showLegend ?? true,\n showGrid: displayConfig?.showGrid ?? true,\n showTooltip: displayConfig?.showTooltip ?? true,\n connectNulls: displayConfig?.connectNulls ?? false\n }\n\n if (!data || data.length === 0) {\n return (\n <div className=\"flex items-center justify-center w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">No data available</div>\n <div className=\"text-xs text-dc-text-secondary\">No data points to display in area chart</div>\n </div>\n </div>\n )\n }\n\n // Validate chartConfig - support both legacy and new formats\n let xAxisField: string\n let yAxisFields: string[]\n let seriesFields: string[] = []\n \n if (chartConfig?.xAxis && chartConfig?.yAxis) {\n // New format\n xAxisField = Array.isArray(chartConfig.xAxis) ? chartConfig.xAxis[0] : chartConfig.xAxis\n yAxisFields = Array.isArray(chartConfig.yAxis) ? chartConfig.yAxis : [chartConfig.yAxis]\n seriesFields = chartConfig.series || []\n } else if (chartConfig?.x && chartConfig?.y) {\n // Legacy format\n xAxisField = chartConfig.x\n yAxisFields = Array.isArray(chartConfig.y) ? chartConfig.y : [chartConfig.y]\n } else {\n return (\n <div className=\"flex items-center justify-center w-full text-yellow-600\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">Configuration Error</div>\n <div className=\"text-xs\">Invalid or missing chart axis configuration</div>\n </div>\n </div>\n )\n }\n\n if (!xAxisField || !yAxisFields || yAxisFields.length === 0) {\n return (\n <div className=\"flex items-center justify-center w-full text-yellow-600\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">Configuration Error</div>\n <div className=\"text-xs\">Missing required X-axis or Y-axis fields</div>\n </div>\n </div>\n )\n }\n\n // Use shared function to transform data and handle series\n const { data: chartData, seriesKeys } = transformChartDataWithSeries(\n data, \n xAxisField, \n yAxisFields, \n queryObject,\n seriesFields,\n labelMap\n )\n \n // Determine if legend will be shown\n const showLegend = safeDisplayConfig.showLegend\n \n // Use custom chart margins with extra left space for Y-axis label\n const chartMargins = {\n ...CHART_MARGINS,\n left: 40 // Increased from 20 to 40 for Y-axis label space\n }\n \n // Process target values and add to chart data\n const targetValues = parseTargetValues(displayConfig?.target || '')\n const spreadTargets = spreadTargetValues(targetValues, chartData.length)\n \n // Add target data to chart data if targets exist\n let enhancedChartData = chartData\n if (spreadTargets.length > 0) {\n enhancedChartData = chartData.map((dataPoint, index) => ({\n ...dataPoint,\n __target: spreadTargets[index] || null\n }))\n }\n \n // Validate transformed data\n if (!chartData || chartData.length === 0) {\n return (\n <div className=\"flex items-center justify-center w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">No valid data</div>\n <div className=\"text-xs text-dc-text-secondary\">No valid data points for area chart after transformation</div>\n </div>\n </div>\n )\n }\n\n // Determine stack offset for percentage stacking\n const stackOffset = isPercentStack ? 'expand' as const : undefined\n\n return (\n <ChartContainer height={height}>\n <ComposedChart data={enhancedChartData} margin={chartMargins} stackOffset={stackOffset}>\n {safeDisplayConfig.showGrid && (\n <CartesianGrid strokeDasharray=\"3 3\" />\n )}\n <XAxis\n dataKey=\"name\"\n tick={{ fontSize: 12 }}\n angle={-45}\n textAnchor=\"end\"\n height={60}\n />\n <YAxis\n tick={{ fontSize: 12 }}\n tickFormatter={isPercentStack ? (v) => `${(v * 100).toFixed(0)}%` : undefined}\n domain={isPercentStack ? [0, 1] : undefined}\n label={isPercentStack ? undefined : { value: getFieldLabel(yAxisFields[0]), angle: -90, position: 'left', style: { textAnchor: 'middle', fontSize: '12px' } }}\n />\n {safeDisplayConfig.showTooltip && (\n <ChartTooltip\n formatter={(value: any, name: any) => {\n // Handle null values in tooltip\n if (value === null || value === undefined) {\n return ['No data', name]\n }\n if (name === 'Target') {\n return [formatNumericValue(value), 'Target Value']\n }\n // Format as percentage when using percent stacking\n if (isPercentStack && typeof value === 'number') {\n return [`${(value * 100).toFixed(1)}%`, name]\n }\n return [formatNumericValue(value), name]\n }}\n />\n )}\n {showLegend && (\n <Legend \n wrapperStyle={{ fontSize: '12px', paddingTop: '10px' }}\n iconType=\"rect\"\n iconSize={8}\n layout=\"horizontal\"\n align=\"center\"\n verticalAlign=\"bottom\"\n onMouseEnter={(o) => setHoveredLegend(String(o.dataKey || ''))}\n onMouseLeave={() => setHoveredLegend(null)}\n />\n )}\n {seriesKeys.map((seriesKey, index) => (\n <Area\n key={seriesKey}\n type=\"monotone\"\n dataKey={seriesKey}\n stackId={shouldStack ? \"stack\" : undefined}\n stroke={(colorPalette?.colors && colorPalette.colors[index % colorPalette.colors.length]) || CHART_COLORS[index % CHART_COLORS.length]}\n fill={(colorPalette?.colors && colorPalette.colors[index % colorPalette.colors.length]) || CHART_COLORS[index % CHART_COLORS.length]}\n fillOpacity={hoveredLegend ? (hoveredLegend === seriesKey ? 0.6 : 0.1) : 0.3}\n strokeWidth={2}\n strokeOpacity={hoveredLegend ? (hoveredLegend === seriesKey ? 1 : 0.3) : 1}\n connectNulls={safeDisplayConfig.connectNulls}\n />\n ))}\n {spreadTargets.length > 0 && (\n <>\n {/* White background line */}\n <Line\n type=\"monotone\"\n dataKey=\"__target\"\n stroke=\"#ffffff\"\n strokeWidth={2}\n dot={false}\n activeDot={false}\n connectNulls={false}\n />\n {/* Grey dashed line on top */}\n <Line\n type=\"monotone\"\n dataKey=\"__target\"\n name=\"Target\"\n stroke=\"#8B5CF6\"\n strokeWidth={2}\n strokeDasharray=\"2 3\"\n dot={false}\n activeDot={false}\n connectNulls={false}\n />\n </>\n )}\n </ComposedChart>\n </ChartContainer>\n )\n } catch (error) {\n // 'AreaChart rendering error\n return (\n <div className=\"flex flex-col items-center justify-center w-full text-red-500 p-4\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">Area Chart Error</div>\n <div className=\"text-xs mb-2\">{error instanceof Error ? error.message : 'Unknown rendering error'}</div>\n <div className=\"text-xs text-dc-text-muted\">Check the data and configuration</div>\n </div>\n </div>\n )\n }\n}"],"names":["parseTargetValues","targetString","trimmed","values","val","num","error","spreadTargetValues","targets","dataLength","result","baseGroupSize","remainder","currentIndex","groupSize","j","calculateVariance","actual","target","formatVariance","variance","decimals","AreaChart","data","chartConfig","displayConfig","queryObject","height","colorPalette","hoveredLegend","setHoveredLegend","useState","labelMap","getFieldLabel","useCubeContext","stackType","shouldStack","isPercentStack","safeDisplayConfig","jsx","jsxs","xAxisField","yAxisFields","seriesFields","chartData","seriesKeys","transformChartDataWithSeries","showLegend","chartMargins","CHART_MARGINS","targetValues","spreadTargets","enhancedChartData","dataPoint","index","ChartContainer","ComposedChart","CartesianGrid","XAxis","YAxis","v","ChartTooltip","value","name","formatNumericValue","Legend","o","seriesKey","Area","CHART_COLORS","Fragment","Line"],"mappings":"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"}
|
|
@@ -2,9 +2,9 @@ import { jsx as e, jsxs as a, Fragment as R } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState as B, useMemo as H } from "react";
|
|
3
3
|
import { ComposedChart as W, CartesianGrid as $, XAxis as K, YAxis as P, Legend as X, Bar as Y, Cell as q, Line as S } from "recharts";
|
|
4
4
|
import { C as U } from "./chart-chartcontainer-CdwzIKP1.js";
|
|
5
|
-
import { C as J } from "./chart-charttooltip-
|
|
6
|
-
import { u as Q, t as Z, i as ee, C as te, f as C, N as se, P as D, a as F } from "./chart-activitygridchart-
|
|
7
|
-
import { p as re, s as ae } from "./chart-areachart-
|
|
5
|
+
import { C as J } from "./chart-charttooltip-CqtjUW2V.js";
|
|
6
|
+
import { u as Q, t as Z, i as ee, C as te, f as C, N as se, P as D, a as F } from "./chart-activitygridchart-B5OqLgbD.js";
|
|
7
|
+
import { p as re, s as ae } from "./chart-areachart-CTzUpR0_.js";
|
|
8
8
|
function xe({
|
|
9
9
|
data: h,
|
|
10
10
|
chartConfig: s,
|
|
@@ -174,4 +174,4 @@ function xe({
|
|
|
174
174
|
export {
|
|
175
175
|
xe as default
|
|
176
176
|
};
|
|
177
|
-
//# sourceMappingURL=chart-barchart-
|
|
177
|
+
//# sourceMappingURL=chart-barchart-CKF8FnMs.js.map
|
package/dist/client/chunks/{chart-barchart-BzoejYkT.js.map → chart-barchart-CKF8FnMs.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-barchart-BzoejYkT.js","sources":["../../../src/client/components/charts/BarChart.tsx"],"sourcesContent":["import { useState, useMemo } from 'react'\nimport { ComposedChart, Bar, Line, XAxis, YAxis, CartesianGrid, Cell, Legend } from 'recharts'\nimport ChartContainer from './ChartContainer'\nimport ChartTooltip from './ChartTooltip'\nimport { CHART_COLORS, POSITIVE_COLOR, NEGATIVE_COLOR, CHART_MARGINS } from '../../utils/chartConstants'\nimport { transformChartDataWithSeries, isValidNumericValue, formatNumericValue } from '../../utils/chartUtils'\nimport { parseTargetValues, spreadTargetValues } from '../../utils/targetUtils'\nimport { useCubeContext } from '../../providers/CubeProvider'\nimport type { ChartProps } from '../../types'\n\nexport default function BarChart({ \n data, \n chartConfig, \n displayConfig = {},\n queryObject,\n height = \"100%\",\n colorPalette\n}: ChartProps) {\n const [hoveredLegend, setHoveredLegend] = useState<string | null>(null)\n const { labelMap, getFieldLabel: contextGetFieldLabel } = useCubeContext()\n \n try {\n // Determine stacking from stackType (new) or stacked (legacy)\n const stackType = displayConfig?.stackType ?? (displayConfig?.stacked ? 'normal' : 'none')\n const shouldStack = stackType !== 'none'\n const isPercentStack = stackType === 'percent'\n\n const safeDisplayConfig = {\n showLegend: displayConfig?.showLegend ?? true,\n showGrid: displayConfig?.showGrid ?? true,\n showTooltip: displayConfig?.showTooltip ?? true\n }\n\n if (!data || data.length === 0) {\n return (\n <div className=\"flex items-center justify-center w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">No data available</div>\n <div className=\"text-xs text-dc-text-secondary\">No data points to display in bar chart</div>\n </div>\n </div>\n )\n }\n\n // Validate chartConfig - support both legacy and new formats\n let xAxisField: string\n let yAxisFields: string[]\n let seriesFields: string[] = []\n \n if (chartConfig?.xAxis && chartConfig?.yAxis) {\n // New format\n xAxisField = Array.isArray(chartConfig.xAxis) ? chartConfig.xAxis[0] : chartConfig.xAxis\n yAxisFields = Array.isArray(chartConfig.yAxis) ? chartConfig.yAxis : [chartConfig.yAxis]\n seriesFields = chartConfig.series || []\n } else if (chartConfig?.x && chartConfig?.y) {\n // Legacy format\n xAxisField = chartConfig.x\n yAxisFields = Array.isArray(chartConfig.y) ? chartConfig.y : [chartConfig.y]\n } else {\n return (\n <div className=\"flex items-center justify-center w-full text-yellow-600\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">Configuration Error</div>\n <div className=\"text-xs\">Invalid or missing chart axis configuration</div>\n </div>\n </div>\n )\n }\n\n if (!xAxisField || !yAxisFields || yAxisFields.length === 0) {\n return (\n <div className=\"flex items-center justify-center w-full text-yellow-600\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">Configuration Error</div>\n <div className=\"text-xs\">Missing required X-axis or Y-axis fields</div>\n </div>\n </div>\n )\n }\n\n // Use shared function to transform data and handle series\n const { data: transformedData, seriesKeys } = transformChartDataWithSeries(\n data,\n xAxisField,\n yAxisFields,\n queryObject,\n seriesFields,\n labelMap\n )\n\n // Null handling: Filter out data points where ALL measure values are null\n // This prevents rendering empty bars and makes the chart clearer\n const { chartData, skippedCount } = useMemo(() => {\n const filtered = transformedData.filter(row => {\n // Keep the row if at least one series has a valid numeric value\n return seriesKeys.some(key => isValidNumericValue(row[key]))\n })\n const skipped = transformedData.length - filtered.length\n return { chartData: filtered, skippedCount: skipped }\n }, [transformedData, seriesKeys])\n\n // Determine stack offset for percentage stacking\n const stackOffset = isPercentStack ? 'expand' as const : undefined\n \n // Check if we should use positive/negative coloring\n // This is enabled when we have single series data with mixed positive/negative values\n const usePositiveNegativeColoring = seriesKeys.length === 1 && chartData.some(row => {\n const value = row[seriesKeys[0]]\n return typeof value === 'number' && value < 0\n })\n \n // Determine if legend will be shown\n const showLegend = safeDisplayConfig.showLegend\n \n // Use custom chart margins with extra left space for Y-axis label\n const chartMargins = {\n ...CHART_MARGINS,\n left: 40 // Increased from 20 to 40 for Y-axis label space\n }\n \n // Process target values and add to chart data\n const targetValues = parseTargetValues(displayConfig?.target || '')\n const spreadTargets = spreadTargetValues(targetValues, chartData.length)\n \n // Add target data to chart data if targets exist\n let enhancedChartData = chartData\n if (spreadTargets.length > 0) {\n enhancedChartData = chartData.map((dataPoint, index) => ({\n ...dataPoint,\n __target: spreadTargets[index] || null\n }))\n }\n \n // Validate transformed data\n if (!chartData || chartData.length === 0) {\n return (\n <div className=\"flex items-center justify-center w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">No valid data</div>\n <div className=\"text-xs text-dc-text-secondary\">No valid data points for bar chart after transformation</div>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"relative w-full\" style={{ height }}>\n <ChartContainer height={skippedCount > 0 ? `calc(100% - 20px)` : \"100%\"}>\n <ComposedChart data={enhancedChartData} margin={chartMargins} stackOffset={stackOffset}>\n {safeDisplayConfig.showGrid && (\n <CartesianGrid strokeDasharray=\"3 3\" />\n )}\n <XAxis\n dataKey=\"name\"\n tick={{ fontSize: 12 }}\n angle={-45}\n textAnchor=\"end\"\n height={60}\n />\n <YAxis\n tick={{ fontSize: 12 }}\n tickFormatter={isPercentStack ? (v) => `${(v * 100).toFixed(0)}%` : undefined}\n domain={isPercentStack ? [0, 1] : undefined}\n label={isPercentStack ? undefined : { value: contextGetFieldLabel(yAxisFields[0]), angle: -90, position: 'left', style: { textAnchor: 'middle', fontSize: '12px' } }}\n />\n {safeDisplayConfig.showTooltip && (\n <ChartTooltip\n formatter={(value: any, name: any) => {\n // Handle null values in tooltip\n if (value === null || value === undefined) {\n return ['No data', name]\n }\n if (name === 'Target') {\n return [formatNumericValue(value), 'Target Value']\n }\n // Format as percentage when using percent stacking\n if (isPercentStack && typeof value === 'number') {\n return [`${(value * 100).toFixed(1)}%`, name]\n }\n return [formatNumericValue(value), name]\n }}\n />\n )}\n {showLegend && (\n <Legend \n wrapperStyle={{ fontSize: '12px', paddingTop: '25px' }}\n iconType=\"rect\"\n iconSize={8}\n layout=\"horizontal\"\n align=\"center\"\n verticalAlign=\"bottom\"\n onMouseEnter={(o) => setHoveredLegend(String(o.dataKey || ''))}\n onMouseLeave={() => setHoveredLegend(null)}\n />\n )}\n {seriesKeys.map((seriesKey, index) => (\n <Bar\n key={seriesKey}\n dataKey={seriesKey}\n stackId={shouldStack ? \"stack\" : undefined}\n fill={usePositiveNegativeColoring ? POSITIVE_COLOR : ((colorPalette?.colors && colorPalette.colors[index % colorPalette.colors.length]) || CHART_COLORS[index % CHART_COLORS.length])}\n fillOpacity={hoveredLegend ? (hoveredLegend === seriesKey ? 1 : 0.3) : 1}\n >\n {usePositiveNegativeColoring && chartData.map((entry, entryIndex) => {\n const value = entry[seriesKey]\n const fillColor = typeof value === 'number' && value < 0 ? NEGATIVE_COLOR : POSITIVE_COLOR\n return (\n <Cell \n key={`cell-${entryIndex}`} \n fill={fillColor}\n fillOpacity={hoveredLegend ? (hoveredLegend === seriesKey ? 1 : 0.3) : 1}\n />\n )\n })}\n </Bar>\n ))}\n {spreadTargets.length > 0 && (\n <>\n {/* White background line */}\n <Line\n type=\"monotone\"\n dataKey=\"__target\"\n stroke=\"#ffffff\"\n strokeWidth={2}\n dot={false}\n activeDot={false}\n connectNulls={false}\n />\n {/* Grey dashed line on top */}\n <Line\n type=\"monotone\"\n dataKey=\"__target\"\n name=\"Target\"\n stroke=\"#8B5CF6\"\n strokeWidth={2}\n strokeDasharray=\"2 3\"\n dot={false}\n activeDot={false}\n connectNulls={false}\n />\n </>\n )}\n </ComposedChart>\n </ChartContainer>\n {skippedCount > 0 && (\n <div className=\"text-xs text-dc-text-muted text-center mt-1\">\n {skippedCount} data point{skippedCount !== 1 ? 's' : ''} with no values hidden\n </div>\n )}\n </div>\n )\n } catch (error) {\n // 'BarChart rendering error\n return (\n <div className=\"flex flex-col items-center justify-center w-full text-red-500 p-4\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">Bar Chart Error</div>\n <div className=\"text-xs mb-2\">{error instanceof Error ? error.message : 'Unknown rendering error'}</div>\n <div className=\"text-xs text-dc-text-muted\">Check the data and configuration</div>\n </div>\n </div>\n )\n }\n}"],"names":["BarChart","data","chartConfig","displayConfig","queryObject","height","colorPalette","hoveredLegend","setHoveredLegend","useState","labelMap","contextGetFieldLabel","useCubeContext","stackType","shouldStack","isPercentStack","safeDisplayConfig","jsx","jsxs","xAxisField","yAxisFields","seriesFields","transformedData","seriesKeys","transformChartDataWithSeries","chartData","skippedCount","useMemo","filtered","row","key","isValidNumericValue","skipped","stackOffset","usePositiveNegativeColoring","value","showLegend","chartMargins","CHART_MARGINS","targetValues","parseTargetValues","spreadTargets","spreadTargetValues","enhancedChartData","dataPoint","index","ChartContainer","ComposedChart","CartesianGrid","XAxis","YAxis","v","ChartTooltip","name","formatNumericValue","Legend","o","seriesKey","Bar","POSITIVE_COLOR","CHART_COLORS","entry","entryIndex","fillColor","NEGATIVE_COLOR","Cell","Fragment","Line","error"],"mappings":";;;;;;;AAUA,SAAwBA,GAAS;AAAA,EAC/B,MAAAC;AAAA,EACA,aAAAC;AAAA,EACA,eAAAC,IAAgB,CAAA;AAAA,EAChB,aAAAC;AAAA,EACA,QAAAC,IAAS;AAAA,EACT,cAAAC;AACF,GAAe;AACb,QAAM,CAACC,GAAeC,CAAgB,IAAIC,EAAwB,IAAI,GAChE,EAAE,UAAAC,GAAU,eAAeC,EAAA,IAAyBC,EAAA;AAE1D,MAAI;AAEF,UAAMC,IAAYV,GAAe,cAAcA,GAAe,UAAU,WAAW,SAC7EW,IAAcD,MAAc,QAC5BE,IAAiBF,MAAc,WAE/BG,IAAoB;AAAA,MACxB,YAAYb,GAAe,cAAc;AAAA,MACzC,UAAUA,GAAe,YAAY;AAAA,MACrC,aAAaA,GAAe,eAAe;AAAA,IAAA;AAG7C,QAAI,CAACF,KAAQA,EAAK,WAAW;AAC3B,aACE,gBAAAgB,EAAC,OAAA,EAAI,WAAU,8DAA6D,OAAO,EAAE,QAAAZ,EAAA,GACnF,UAAA,gBAAAa,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,QAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,qBAAiB;AAAA,QAC7D,gBAAAA,EAAC,OAAA,EAAI,WAAU,kCAAiC,UAAA,yCAAA,CAAsC;AAAA,MAAA,EAAA,CACxF,EAAA,CACF;AAKJ,QAAIE,GACAC,GACAC,IAAyB,CAAA;AAE7B,QAAInB,GAAa,SAASA,GAAa;AAErC,MAAAiB,IAAa,MAAM,QAAQjB,EAAY,KAAK,IAAIA,EAAY,MAAM,CAAC,IAAIA,EAAY,OACnFkB,IAAc,MAAM,QAAQlB,EAAY,KAAK,IAAIA,EAAY,QAAQ,CAACA,EAAY,KAAK,GACvFmB,IAAenB,EAAY,UAAU,CAAA;AAAA,aAC5BA,GAAa,KAAKA,GAAa;AAExC,MAAAiB,IAAajB,EAAY,GACzBkB,IAAc,MAAM,QAAQlB,EAAY,CAAC,IAAIA,EAAY,IAAI,CAACA,EAAY,CAAC;AAAA;AAE3E,aACE,gBAAAe,EAAC,OAAA,EAAI,WAAU,2DAA0D,OAAO,EAAE,QAAAZ,EAAA,GAChF,UAAA,gBAAAa,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,QAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,uBAAmB;AAAA,QAC/D,gBAAAA,EAAC,OAAA,EAAI,WAAU,WAAU,UAAA,8CAAA,CAA2C;AAAA,MAAA,EAAA,CACtE,EAAA,CACF;AAIJ,QAAI,CAACE,KAAc,CAACC,KAAeA,EAAY,WAAW;AACxD,aACE,gBAAAH,EAAC,OAAA,EAAI,WAAU,2DAA0D,OAAO,EAAE,QAAAZ,EAAA,GAChF,UAAA,gBAAAa,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,QAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,uBAAmB;AAAA,QAC/D,gBAAAA,EAAC,OAAA,EAAI,WAAU,WAAU,UAAA,2CAAA,CAAwC;AAAA,MAAA,EAAA,CACnE,EAAA,CACF;AAKJ,UAAM,EAAE,MAAMK,GAAiB,YAAAC,EAAA,IAAeC;AAAA,MAC5CvB;AAAA,MACAkB;AAAA,MACAC;AAAA,MACAhB;AAAA,MACAiB;AAAA,MACAX;AAAA,IAAA,GAKI,EAAE,WAAAe,GAAW,cAAAC,EAAA,IAAiBC,EAAQ,MAAM;AAChD,YAAMC,IAAWN,EAAgB,OAAO,CAAAO,MAE/BN,EAAW,KAAK,CAAAO,MAAOC,GAAoBF,EAAIC,CAAG,CAAC,CAAC,CAC5D,GACKE,IAAUV,EAAgB,SAASM,EAAS;AAClD,aAAO,EAAE,WAAWA,GAAU,cAAcI,EAAA;AAAA,IAC9C,GAAG,CAACV,GAAiBC,CAAU,CAAC,GAG1BU,IAAclB,IAAiB,WAAoB,QAInDmB,IAA8BX,EAAW,WAAW,KAAKE,EAAU,KAAK,CAAAI,MAAO;AACnF,YAAMM,IAAQN,EAAIN,EAAW,CAAC,CAAC;AAC/B,aAAO,OAAOY,KAAU,YAAYA,IAAQ;AAAA,IAC9C,CAAC,GAGKC,IAAapB,EAAkB,YAG/BqB,IAAe;AAAA,MACnB,GAAGC;AAAA,MACH,MAAM;AAAA;AAAA,IAAA,GAIFC,IAAeC,GAAkBrC,GAAe,UAAU,EAAE,GAC5DsC,IAAgBC,GAAmBH,GAAcd,EAAU,MAAM;AAGvE,QAAIkB,IAAoBlB;AASxB,WARIgB,EAAc,SAAS,MACzBE,IAAoBlB,EAAU,IAAI,CAACmB,GAAWC,OAAW;AAAA,MACvD,GAAGD;AAAA,MACH,UAAUH,EAAcI,CAAK,KAAK;AAAA,IAAA,EAClC,IAIA,CAACpB,KAAaA,EAAU,WAAW,IAEnC,gBAAAR,EAAC,OAAA,EAAI,WAAU,8DAA6D,OAAO,EAAE,QAAAZ,EAAA,GACnF,UAAA,gBAAAa,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,MAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,iBAAa;AAAA,MACzD,gBAAAA,EAAC,OAAA,EAAI,WAAU,kCAAiC,UAAA,0DAAA,CAAuD;AAAA,IAAA,EAAA,CACzG,EAAA,CACF,sBAKD,OAAA,EAAI,WAAU,mBAAkB,OAAO,EAAE,QAAAZ,KACxC,UAAA;AAAA,MAAA,gBAAAY,EAAC6B,GAAA,EAAe,QAAQpB,IAAe,IAAI,sBAAsB,QAC/D,UAAA,gBAAAR,EAAC6B,GAAA,EAAc,MAAMJ,GAAmB,QAAQN,GAAc,aAAAJ,GAC7D,UAAA;AAAA,QAAAjB,EAAkB,YACjB,gBAAAC,EAAC+B,GAAA,EAAc,iBAAgB,OAAM;AAAA,QAEvC,gBAAA/B;AAAA,UAACgC;AAAA,UAAA;AAAA,YACC,SAAQ;AAAA,YACR,MAAM,EAAE,UAAU,GAAA;AAAA,YAClB,OAAO;AAAA,YACP,YAAW;AAAA,YACX,QAAQ;AAAA,UAAA;AAAA,QAAA;AAAA,QAEV,gBAAAhC;AAAA,UAACiC;AAAA,UAAA;AAAA,YACC,MAAM,EAAE,UAAU,GAAA;AAAA,YAClB,eAAenC,IAAiB,CAACoC,MAAM,IAAIA,IAAI,KAAK,QAAQ,CAAC,CAAC,MAAM;AAAA,YACpE,QAAQpC,IAAiB,CAAC,GAAG,CAAC,IAAI;AAAA,YAClC,OAAOA,IAAiB,SAAY,EAAE,OAAOJ,EAAqBS,EAAY,CAAC,CAAC,GAAG,OAAO,KAAK,UAAU,QAAQ,OAAO,EAAE,YAAY,UAAU,UAAU,SAAO;AAAA,UAAE;AAAA,QAAA;AAAA,QAEpKJ,EAAkB,eACjB,gBAAAC;AAAA,UAACmC;AAAA,UAAA;AAAA,YACC,WAAW,CAACjB,GAAYkB,MAElBlB,KAAU,OACL,CAAC,WAAWkB,CAAI,IAErBA,MAAS,WACJ,CAACC,EAAmBnB,CAAK,GAAG,cAAc,IAG/CpB,KAAkB,OAAOoB,KAAU,WAC9B,CAAC,IAAIA,IAAQ,KAAK,QAAQ,CAAC,CAAC,KAAKkB,CAAI,IAEvC,CAACC,EAAmBnB,CAAK,GAAGkB,CAAI;AAAA,UACzC;AAAA,QAAA;AAAA,QAGHjB,KACC,gBAAAnB;AAAA,UAACsC;AAAA,UAAA;AAAA,YACC,cAAc,EAAE,UAAU,QAAQ,YAAY,OAAA;AAAA,YAC9C,UAAS;AAAA,YACT,UAAU;AAAA,YACV,QAAO;AAAA,YACP,OAAM;AAAA,YACN,eAAc;AAAA,YACd,cAAc,CAACC,MAAMhD,EAAiB,OAAOgD,EAAE,WAAW,EAAE,CAAC;AAAA,YAC7D,cAAc,MAAMhD,EAAiB,IAAI;AAAA,UAAA;AAAA,QAAA;AAAA,QAG5Ce,EAAW,IAAI,CAACkC,GAAWZ,MAC1B,gBAAA5B;AAAA,UAACyC;AAAA,UAAA;AAAA,YAEC,SAASD;AAAA,YACT,SAAS3C,IAAc,UAAU;AAAA,YACjC,MAAMoB,IAA8ByB,IAAmBrD,GAAc,UAAUA,EAAa,OAAOuC,IAAQvC,EAAa,OAAO,MAAM,KAAMsD,EAAaf,IAAQe,EAAa,MAAM;AAAA,YACnL,aAAarD,IAAiBA,MAAkBkD,IAAY,IAAI,MAAO;AAAA,YAEtE,UAAAvB,KAA+BT,EAAU,IAAI,CAACoC,GAAOC,MAAe;AACnE,oBAAM3B,IAAQ0B,EAAMJ,CAAS,GACvBM,IAAY,OAAO5B,KAAU,YAAYA,IAAQ,IAAI6B,KAAiBL;AAC5E,qBACE,gBAAA1C;AAAA,gBAACgD;AAAA,gBAAA;AAAA,kBAEC,MAAMF;AAAA,kBACN,aAAaxD,IAAiBA,MAAkBkD,IAAY,IAAI,MAAO;AAAA,gBAAA;AAAA,gBAFlE,QAAQK,CAAU;AAAA,cAAA;AAAA,YAK7B,CAAC;AAAA,UAAA;AAAA,UAhBIL;AAAA,QAAA,CAkBR;AAAA,QACAhB,EAAc,SAAS,KACtB,gBAAAvB,EAAAgD,GAAA,EAEE,UAAA;AAAA,UAAA,gBAAAjD;AAAA,YAACkD;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,QAAO;AAAA,cACP,aAAa;AAAA,cACb,KAAK;AAAA,cACL,WAAW;AAAA,cACX,cAAc;AAAA,YAAA;AAAA,UAAA;AAAA,UAGhB,gBAAAlD;AAAA,YAACkD;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,QAAO;AAAA,cACP,aAAa;AAAA,cACb,iBAAgB;AAAA,cAChB,KAAK;AAAA,cACL,WAAW;AAAA,cACX,cAAc;AAAA,YAAA;AAAA,UAAA;AAAA,QAChB,EAAA,CACF;AAAA,MAAA,EAAA,CAEF,EAAA,CACF;AAAA,MACCzC,IAAe,KACd,gBAAAR,EAAC,OAAA,EAAI,WAAU,+CACZ,UAAA;AAAA,QAAAQ;AAAA,QAAa;AAAA,QAAYA,MAAiB,IAAI,MAAM;AAAA,QAAG;AAAA,MAAA,EAAA,CAC1D;AAAA,IAAA,GAEJ;AAAA,EAEJ,SAAS0C,GAAO;AAEd,WACE,gBAAAnD,EAAC,OAAA,EAAI,WAAU,qEAAoE,OAAO,EAAE,QAAAZ,EAAA,GAC1F,UAAA,gBAAAa,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,MAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,mBAAe;AAAA,MAC3D,gBAAAA,EAAC,SAAI,WAAU,gBAAgB,uBAAiB,QAAQmD,EAAM,UAAU,0BAAA,CAA0B;AAAA,MAClG,gBAAAnD,EAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,mCAAA,CAAgC;AAAA,IAAA,EAAA,CAC9E,EAAA,CACF;AAAA,EAEJ;AACF;"}
|
|
1
|
+
{"version":3,"file":"chart-barchart-CKF8FnMs.js","sources":["../../../src/client/components/charts/BarChart.tsx"],"sourcesContent":["import { useState, useMemo } from 'react'\nimport { ComposedChart, Bar, Line, XAxis, YAxis, CartesianGrid, Cell, Legend } from 'recharts'\nimport ChartContainer from './ChartContainer'\nimport ChartTooltip from './ChartTooltip'\nimport { CHART_COLORS, POSITIVE_COLOR, NEGATIVE_COLOR, CHART_MARGINS } from '../../utils/chartConstants'\nimport { transformChartDataWithSeries, isValidNumericValue, formatNumericValue } from '../../utils/chartUtils'\nimport { parseTargetValues, spreadTargetValues } from '../../utils/targetUtils'\nimport { useCubeContext } from '../../providers/CubeProvider'\nimport type { ChartProps } from '../../types'\n\nexport default function BarChart({ \n data, \n chartConfig, \n displayConfig = {},\n queryObject,\n height = \"100%\",\n colorPalette\n}: ChartProps) {\n const [hoveredLegend, setHoveredLegend] = useState<string | null>(null)\n const { labelMap, getFieldLabel: contextGetFieldLabel } = useCubeContext()\n \n try {\n // Determine stacking from stackType (new) or stacked (legacy)\n const stackType = displayConfig?.stackType ?? (displayConfig?.stacked ? 'normal' : 'none')\n const shouldStack = stackType !== 'none'\n const isPercentStack = stackType === 'percent'\n\n const safeDisplayConfig = {\n showLegend: displayConfig?.showLegend ?? true,\n showGrid: displayConfig?.showGrid ?? true,\n showTooltip: displayConfig?.showTooltip ?? true\n }\n\n if (!data || data.length === 0) {\n return (\n <div className=\"flex items-center justify-center w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">No data available</div>\n <div className=\"text-xs text-dc-text-secondary\">No data points to display in bar chart</div>\n </div>\n </div>\n )\n }\n\n // Validate chartConfig - support both legacy and new formats\n let xAxisField: string\n let yAxisFields: string[]\n let seriesFields: string[] = []\n \n if (chartConfig?.xAxis && chartConfig?.yAxis) {\n // New format\n xAxisField = Array.isArray(chartConfig.xAxis) ? chartConfig.xAxis[0] : chartConfig.xAxis\n yAxisFields = Array.isArray(chartConfig.yAxis) ? chartConfig.yAxis : [chartConfig.yAxis]\n seriesFields = chartConfig.series || []\n } else if (chartConfig?.x && chartConfig?.y) {\n // Legacy format\n xAxisField = chartConfig.x\n yAxisFields = Array.isArray(chartConfig.y) ? chartConfig.y : [chartConfig.y]\n } else {\n return (\n <div className=\"flex items-center justify-center w-full text-yellow-600\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">Configuration Error</div>\n <div className=\"text-xs\">Invalid or missing chart axis configuration</div>\n </div>\n </div>\n )\n }\n\n if (!xAxisField || !yAxisFields || yAxisFields.length === 0) {\n return (\n <div className=\"flex items-center justify-center w-full text-yellow-600\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">Configuration Error</div>\n <div className=\"text-xs\">Missing required X-axis or Y-axis fields</div>\n </div>\n </div>\n )\n }\n\n // Use shared function to transform data and handle series\n const { data: transformedData, seriesKeys } = transformChartDataWithSeries(\n data,\n xAxisField,\n yAxisFields,\n queryObject,\n seriesFields,\n labelMap\n )\n\n // Null handling: Filter out data points where ALL measure values are null\n // This prevents rendering empty bars and makes the chart clearer\n const { chartData, skippedCount } = useMemo(() => {\n const filtered = transformedData.filter(row => {\n // Keep the row if at least one series has a valid numeric value\n return seriesKeys.some(key => isValidNumericValue(row[key]))\n })\n const skipped = transformedData.length - filtered.length\n return { chartData: filtered, skippedCount: skipped }\n }, [transformedData, seriesKeys])\n\n // Determine stack offset for percentage stacking\n const stackOffset = isPercentStack ? 'expand' as const : undefined\n \n // Check if we should use positive/negative coloring\n // This is enabled when we have single series data with mixed positive/negative values\n const usePositiveNegativeColoring = seriesKeys.length === 1 && chartData.some(row => {\n const value = row[seriesKeys[0]]\n return typeof value === 'number' && value < 0\n })\n \n // Determine if legend will be shown\n const showLegend = safeDisplayConfig.showLegend\n \n // Use custom chart margins with extra left space for Y-axis label\n const chartMargins = {\n ...CHART_MARGINS,\n left: 40 // Increased from 20 to 40 for Y-axis label space\n }\n \n // Process target values and add to chart data\n const targetValues = parseTargetValues(displayConfig?.target || '')\n const spreadTargets = spreadTargetValues(targetValues, chartData.length)\n \n // Add target data to chart data if targets exist\n let enhancedChartData = chartData\n if (spreadTargets.length > 0) {\n enhancedChartData = chartData.map((dataPoint, index) => ({\n ...dataPoint,\n __target: spreadTargets[index] || null\n }))\n }\n \n // Validate transformed data\n if (!chartData || chartData.length === 0) {\n return (\n <div className=\"flex items-center justify-center w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">No valid data</div>\n <div className=\"text-xs text-dc-text-secondary\">No valid data points for bar chart after transformation</div>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"relative w-full\" style={{ height }}>\n <ChartContainer height={skippedCount > 0 ? `calc(100% - 20px)` : \"100%\"}>\n <ComposedChart data={enhancedChartData} margin={chartMargins} stackOffset={stackOffset}>\n {safeDisplayConfig.showGrid && (\n <CartesianGrid strokeDasharray=\"3 3\" />\n )}\n <XAxis\n dataKey=\"name\"\n tick={{ fontSize: 12 }}\n angle={-45}\n textAnchor=\"end\"\n height={60}\n />\n <YAxis\n tick={{ fontSize: 12 }}\n tickFormatter={isPercentStack ? (v) => `${(v * 100).toFixed(0)}%` : undefined}\n domain={isPercentStack ? [0, 1] : undefined}\n label={isPercentStack ? undefined : { value: contextGetFieldLabel(yAxisFields[0]), angle: -90, position: 'left', style: { textAnchor: 'middle', fontSize: '12px' } }}\n />\n {safeDisplayConfig.showTooltip && (\n <ChartTooltip\n formatter={(value: any, name: any) => {\n // Handle null values in tooltip\n if (value === null || value === undefined) {\n return ['No data', name]\n }\n if (name === 'Target') {\n return [formatNumericValue(value), 'Target Value']\n }\n // Format as percentage when using percent stacking\n if (isPercentStack && typeof value === 'number') {\n return [`${(value * 100).toFixed(1)}%`, name]\n }\n return [formatNumericValue(value), name]\n }}\n />\n )}\n {showLegend && (\n <Legend \n wrapperStyle={{ fontSize: '12px', paddingTop: '25px' }}\n iconType=\"rect\"\n iconSize={8}\n layout=\"horizontal\"\n align=\"center\"\n verticalAlign=\"bottom\"\n onMouseEnter={(o) => setHoveredLegend(String(o.dataKey || ''))}\n onMouseLeave={() => setHoveredLegend(null)}\n />\n )}\n {seriesKeys.map((seriesKey, index) => (\n <Bar\n key={seriesKey}\n dataKey={seriesKey}\n stackId={shouldStack ? \"stack\" : undefined}\n fill={usePositiveNegativeColoring ? POSITIVE_COLOR : ((colorPalette?.colors && colorPalette.colors[index % colorPalette.colors.length]) || CHART_COLORS[index % CHART_COLORS.length])}\n fillOpacity={hoveredLegend ? (hoveredLegend === seriesKey ? 1 : 0.3) : 1}\n >\n {usePositiveNegativeColoring && chartData.map((entry, entryIndex) => {\n const value = entry[seriesKey]\n const fillColor = typeof value === 'number' && value < 0 ? NEGATIVE_COLOR : POSITIVE_COLOR\n return (\n <Cell \n key={`cell-${entryIndex}`} \n fill={fillColor}\n fillOpacity={hoveredLegend ? (hoveredLegend === seriesKey ? 1 : 0.3) : 1}\n />\n )\n })}\n </Bar>\n ))}\n {spreadTargets.length > 0 && (\n <>\n {/* White background line */}\n <Line\n type=\"monotone\"\n dataKey=\"__target\"\n stroke=\"#ffffff\"\n strokeWidth={2}\n dot={false}\n activeDot={false}\n connectNulls={false}\n />\n {/* Grey dashed line on top */}\n <Line\n type=\"monotone\"\n dataKey=\"__target\"\n name=\"Target\"\n stroke=\"#8B5CF6\"\n strokeWidth={2}\n strokeDasharray=\"2 3\"\n dot={false}\n activeDot={false}\n connectNulls={false}\n />\n </>\n )}\n </ComposedChart>\n </ChartContainer>\n {skippedCount > 0 && (\n <div className=\"text-xs text-dc-text-muted text-center mt-1\">\n {skippedCount} data point{skippedCount !== 1 ? 's' : ''} with no values hidden\n </div>\n )}\n </div>\n )\n } catch (error) {\n // 'BarChart rendering error\n return (\n <div className=\"flex flex-col items-center justify-center w-full text-red-500 p-4\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">Bar Chart Error</div>\n <div className=\"text-xs mb-2\">{error instanceof Error ? error.message : 'Unknown rendering error'}</div>\n <div className=\"text-xs text-dc-text-muted\">Check the data and configuration</div>\n </div>\n </div>\n )\n }\n}"],"names":["BarChart","data","chartConfig","displayConfig","queryObject","height","colorPalette","hoveredLegend","setHoveredLegend","useState","labelMap","contextGetFieldLabel","useCubeContext","stackType","shouldStack","isPercentStack","safeDisplayConfig","jsx","jsxs","xAxisField","yAxisFields","seriesFields","transformedData","seriesKeys","transformChartDataWithSeries","chartData","skippedCount","useMemo","filtered","row","key","isValidNumericValue","skipped","stackOffset","usePositiveNegativeColoring","value","showLegend","chartMargins","CHART_MARGINS","targetValues","parseTargetValues","spreadTargets","spreadTargetValues","enhancedChartData","dataPoint","index","ChartContainer","ComposedChart","CartesianGrid","XAxis","YAxis","v","ChartTooltip","name","formatNumericValue","Legend","o","seriesKey","Bar","POSITIVE_COLOR","CHART_COLORS","entry","entryIndex","fillColor","NEGATIVE_COLOR","Cell","Fragment","Line","error"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as p, jsxs as K } from "react/jsx-runtime";
|
|
2
2
|
import { useRef as ae, useState as O, useEffect as P, useLayoutEffect as ge } from "react";
|
|
3
|
-
import { u as fe, g as be, w as we, s as D, b as Se, c as oe, i as Ae, p as ce, C as de, l as ue, e as me, d as ve, m as ze, q as Te, h as ye, o as pe, a as ee, j as xe, k as he } from "./chart-activitygridchart-
|
|
3
|
+
import { u as fe, g as be, w as we, s as D, b as Se, c as oe, i as Ae, p as ce, C as de, l as ue, e as me, d as ve, m as ze, q as Te, h as ye, o as pe, a as ee, j as xe, k as he } from "./chart-activitygridchart-B5OqLgbD.js";
|
|
4
4
|
function Re({
|
|
5
5
|
data: $,
|
|
6
6
|
chartConfig: s,
|
|
@@ -207,4 +207,4 @@ function Re({
|
|
|
207
207
|
export {
|
|
208
208
|
Re as default
|
|
209
209
|
};
|
|
210
|
-
//# sourceMappingURL=chart-bubblechart-
|
|
210
|
+
//# sourceMappingURL=chart-bubblechart-5Z0hPYwn.js.map
|
package/dist/client/chunks/{chart-bubblechart-Dg7sT_Mm.js.map → chart-bubblechart-5Z0hPYwn.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-bubblechart-Dg7sT_Mm.js","sources":["../../../src/client/components/charts/BubbleChart.tsx"],"sourcesContent":["import { useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport { select, scaleLinear, scaleSqrt, scaleOrdinal, scaleQuantize, extent, max, axisBottom, axisLeft, type ScaleOrdinal, type ScaleQuantize } from 'd3'\nimport { CHART_COLORS, CHART_COLORS_GRADIENT, CHART_MARGINS } from '../../utils/chartConstants'\nimport { formatTimeValue, getFieldGranularity, parseNumericValue, isValidNumericValue } from '../../utils/chartUtils'\nimport { useCubeContext } from '../../providers/CubeProvider'\nimport { getTheme, watchThemeChanges, type Theme } from '../../theme'\nimport type { ChartProps } from '../../types'\n\ninterface BubbleData {\n x: number\n xLabel?: string // Formatted label for time dimensions\n y: number\n size: number\n color?: string | number\n label: string\n series?: string\n}\n\nexport default function BubbleChart({\n data,\n chartConfig,\n displayConfig = {},\n queryObject,\n height = \"100%\",\n colorPalette\n}: ChartProps) {\n const svgRef = useRef<SVGSVGElement | null>(null)\n const containerRef = useRef<HTMLDivElement | null>(null)\n const [, setHoveredBubble] = useState<string | null>(null)\n const [dimensions, setDimensions] = useState({ width: 0, height: 0 })\n const [dimensionsReady, setDimensionsReady] = useState(false)\n const [currentTheme, setCurrentTheme] = useState<Theme>('light')\n const { getFieldLabel } = useCubeContext()\n\n // Watch for theme changes\n useEffect(() => {\n setCurrentTheme(getTheme())\n const unwatch = watchThemeChanges((theme) => {\n setCurrentTheme(theme)\n })\n return unwatch\n }, [])\n\n const safeDisplayConfig = {\n showLegend: displayConfig?.showLegend ?? true,\n showGrid: displayConfig?.showGrid ?? true,\n showTooltip: displayConfig?.showTooltip ?? true,\n minBubbleSize: displayConfig?.minBubbleSize ?? 5,\n maxBubbleSize: displayConfig?.maxBubbleSize ?? 50,\n bubbleOpacity: displayConfig?.bubbleOpacity ?? 0.7\n }\n\n // Enhanced dimension measurement with retry mechanism\n useLayoutEffect(() => {\n let retryCount = 0\n const maxRetries = 10\n let rafId: number\n let timeoutId: NodeJS.Timeout\n \n const updateDimensions = () => {\n if (containerRef.current) {\n const { width, height } = containerRef.current.getBoundingClientRect()\n \n if (width > 0 && height > 0) {\n setDimensions({ width, height })\n setDimensionsReady(true)\n return true\n }\n }\n return false\n }\n \n // Immediate measurement\n const success = updateDimensions()\n \n if (!success && retryCount < maxRetries) {\n // Retry with requestAnimationFrame\n const retryWithRaf = () => {\n const rafSuccess = updateDimensions()\n \n if (!rafSuccess && retryCount < maxRetries) {\n retryCount++\n // Use setTimeout for additional retries with increasing delays\n timeoutId = setTimeout(() => {\n rafId = requestAnimationFrame(retryWithRaf)\n }, 50 * retryCount) // Increasing delay: 50ms, 100ms, 150ms, etc.\n }\n }\n \n rafId = requestAnimationFrame(retryWithRaf)\n }\n \n return () => {\n if (rafId) cancelAnimationFrame(rafId)\n if (timeoutId) clearTimeout(timeoutId)\n }\n }, [])\n\n // Enhanced ResizeObserver for dynamic resizing with immediate initialization\n useEffect(() => {\n let resizeObserver: ResizeObserver | null = null\n \n const updateDimensions = () => {\n if (containerRef.current) {\n const { width, height } = containerRef.current.getBoundingClientRect()\n if (width > 0 && height > 0) {\n setDimensions({ width, height })\n if (!dimensionsReady) {\n setDimensionsReady(true)\n }\n }\n }\n }\n \n // Initialize ResizeObserver immediately\n if (containerRef.current) {\n resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const { width, height } = entry.contentRect\n if (width > 0 && height > 0) {\n setDimensions({ width, height })\n if (!dimensionsReady) {\n setDimensionsReady(true)\n }\n }\n }\n })\n \n resizeObserver.observe(containerRef.current)\n \n // Also try immediate measurement as fallback\n updateDimensions()\n }\n\n // Window resize as additional fallback\n window.addEventListener('resize', updateDimensions)\n \n return () => {\n if (resizeObserver) {\n resizeObserver.disconnect()\n }\n window.removeEventListener('resize', updateDimensions)\n }\n }, [dimensionsReady])\n\n useEffect(() => {\n if (!data || data.length === 0 || !svgRef.current || !dimensionsReady || dimensions.width === 0) {\n return\n }\n\n // Clear previous chart\n select(svgRef.current).selectAll('*').remove()\n\n\n // Validate chartConfig - only new format supported\n if (!chartConfig?.xAxis || !chartConfig?.yAxis || !chartConfig?.series) {\n return\n }\n\n const xAxisField = Array.isArray(chartConfig.xAxis) ? chartConfig.xAxis[0] : chartConfig.xAxis\n const yAxisField = Array.isArray(chartConfig.yAxis) ? chartConfig.yAxis[0] : chartConfig.yAxis\n const seriesField = Array.isArray(chartConfig.series) ? chartConfig.series[0] : chartConfig.series\n const sizeFieldName = Array.isArray(chartConfig.sizeField) ? chartConfig.sizeField[0] : chartConfig.sizeField || yAxisField\n const colorFieldName = Array.isArray(chartConfig.colorField) ? chartConfig.colorField[0] : chartConfig.colorField\n\n\n if (!xAxisField || !yAxisField || !seriesField || !sizeFieldName) {\n return\n }\n\n // Transform data for bubble chart\n // Null handling: Filter out bubbles where x, y, or size are null\n const xGranularity = getFieldGranularity(queryObject, xAxisField)\n\n // Check if x-axis field is a time dimension\n const isTimeDimension = queryObject?.timeDimensions?.some(\n (td: { dimension: string }) => td.dimension === xAxisField\n ) || false\n\n const bubbleData: BubbleData[] = data\n .map(item => {\n const rawXValue = item[xAxisField]\n let xNum: number\n let xLabel: string\n\n if (isTimeDimension && rawXValue) {\n // For time dimensions, convert to timestamp for proper numeric positioning\n const dateStr = String(rawXValue)\n // Try to parse as date - handle ISO format and PostgreSQL format\n let date: Date\n if (dateStr.match(/^\\d{4}-\\d{2}-\\d{2}[T ]/)) {\n // Full timestamp format\n let isoStr = dateStr\n if (dateStr.includes(' ')) {\n isoStr = dateStr.replace(' ', 'T').replace('+00', 'Z').replace(/\\+\\d{2}:\\d{2}$/, 'Z')\n }\n if (!isoStr.endsWith('Z') && !isoStr.includes('+')) {\n isoStr = isoStr + 'Z'\n }\n date = new Date(isoStr)\n } else {\n date = new Date(dateStr)\n }\n\n xNum = isNaN(date.getTime()) ? parseFloat(dateStr) : date.getTime()\n xLabel = formatTimeValue(rawXValue, xGranularity)\n } else {\n // Non-time value - use as-is\n const formattedValue = formatTimeValue(rawXValue, xGranularity) || rawXValue\n xNum = typeof formattedValue === 'string' ? parseFloat(formattedValue) : formattedValue\n xLabel = String(formattedValue)\n }\n\n const yValue = parseNumericValue(item[yAxisField])\n const sizeValue = parseNumericValue(item[sizeFieldName])\n const seriesValue = item[seriesField]\n\n return {\n x: xNum,\n xLabel, // Store formatted label for tooltip display\n y: yValue as number, // Type assertion: filter below ensures this is never null\n size: sizeValue !== null ? Math.abs(sizeValue) : 0, // Ensure positive size\n color: colorFieldName ? item[colorFieldName] : seriesValue,\n series: seriesValue,\n label: `${seriesValue || 'Unknown'}`,\n isValid: isValidNumericValue(xNum) && yValue !== null && sizeValue !== null && sizeValue > 0\n }\n })\n .filter(d => d.isValid && d.size > 0) // Filter out bubbles with invalid coordinates or no size\n\n if (bubbleData.length === 0) return\n\n const margin = { \n ...CHART_MARGINS, \n left: CHART_MARGINS.left + 30, // Add extra 30px left margin for Y-axis label\n bottom: (safeDisplayConfig.showLegend && colorFieldName) ? 100 : 40 // Add extra space for legend\n }\n const width = dimensions.width - margin.left - margin.right\n const chartHeight = dimensions.height - margin.top - margin.bottom\n\n const svg = select(svgRef.current)\n .attr('width', dimensions.width)\n .attr('height', dimensions.height)\n\n const g = svg.append('g')\n .attr('transform', `translate(${margin.left},${margin.top})`)\n\n // Set up scales\n const xScale = scaleLinear()\n .domain(extent(bubbleData, d => d.x) as [number, number])\n .range([0, width])\n .nice()\n\n const yScale = scaleLinear()\n .domain(extent(bubbleData, d => d.y) as [number, number])\n .range([chartHeight, 0])\n .nice()\n\n const sizeScale = scaleSqrt()\n .domain([0, max(bubbleData, d => d.size) as number])\n .range([safeDisplayConfig.minBubbleSize, safeDisplayConfig.maxBubbleSize])\n\n // Set up color scale\n let colorScale: ScaleOrdinal<string, string> | ScaleQuantize<string>\n let isNumericColorField = false\n let uniqueColors: string[] = []\n \n if (colorFieldName && bubbleData.length > 0) {\n // Check if color field is numeric for color scaling (same logic as TreeMapChart)\n const colorValues = bubbleData.map(item => {\n const value = item.color\n return typeof value === 'string' ? parseFloat(value) : value\n }).filter((val): val is number => !isNaN(val as number))\n \n isNumericColorField = colorValues.length === bubbleData.length && colorValues.every(val => typeof val === 'number')\n \n if (isNumericColorField) {\n // Use D3 quantize scale for better color distribution with small ranges\n const minValue = Math.min(...colorValues)\n const maxValue = Math.max(...colorValues)\n \n // Create D3 quantize color scale - maps continuous data to discrete color bands\n colorScale = scaleQuantize<string>()\n .domain([minValue, maxValue])\n .range(colorPalette?.gradient || CHART_COLORS_GRADIENT)\n } else {\n // Categorical color field - use series colors\n uniqueColors = [...new Set(bubbleData.map(d => String(d.color)))]\n colorScale = scaleOrdinal<string>()\n .domain(uniqueColors)\n .range(colorPalette?.colors || CHART_COLORS)\n }\n } else {\n // Single color for all bubbles\n colorScale = scaleOrdinal<string>()\n .domain(['default'])\n .range([CHART_COLORS[0]])\n }\n\n // Get theme colors from CSS variables\n const getThemeColor = (varName: string, fallback: string) => {\n const value = getComputedStyle(document.documentElement).getPropertyValue(varName).trim()\n return value || fallback\n }\n\n const isDark = currentTheme !== 'light'\n const textColor = isDark\n ? getThemeColor('--dc-text-muted', '#cbd5e1') // Lighter text for dark mode\n : getThemeColor('--dc-text-secondary', '#374151') // Darker text for light mode\n const gridColor = isDark\n ? getThemeColor('--dc-border', '#475569') // Lighter grid for dark mode\n : '#9ca3af' // Much darker gray for light mode visibility\n\n // Add grid\n if (safeDisplayConfig.showGrid) {\n // X-axis grid\n const xGrid = g.append('g')\n .attr('class', 'grid')\n .attr('transform', `translate(0,${chartHeight})`)\n .call(axisBottom(xScale)\n .tickSize(-chartHeight)\n .tickFormat(() => '')\n )\n\n xGrid.selectAll('line')\n .style('stroke', gridColor)\n .style('stroke-dasharray', '3,3')\n .style('opacity', 0.3)\n\n xGrid.select('.domain')\n .style('stroke', 'none')\n\n // Y-axis grid\n const yGrid = g.append('g')\n .attr('class', 'grid')\n .call(axisLeft(yScale)\n .tickSize(-width)\n .tickFormat(() => '')\n )\n\n yGrid.selectAll('line')\n .style('stroke', gridColor)\n .style('stroke-dasharray', '3,3')\n .style('opacity', 0.3)\n\n yGrid.select('.domain')\n .style('stroke', 'none')\n }\n\n // Add X axis with proper time formatting if needed\n const xAxisGenerator = axisBottom(xScale)\n\n // If it's a time dimension, format the tick labels\n if (isTimeDimension) {\n xAxisGenerator.tickFormat((d) => {\n const date = new Date(d as number)\n if (isNaN(date.getTime())) return String(d)\n\n // Format based on granularity\n switch (xGranularity?.toLowerCase()) {\n case 'year':\n return String(date.getUTCFullYear())\n case 'quarter': {\n const q = Math.floor(date.getUTCMonth() / 3) + 1\n return `${date.getUTCFullYear()}-Q${q}`\n }\n case 'month':\n return `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, '0')}`\n case 'week':\n case 'day':\n return `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, '0')}-${String(date.getUTCDate()).padStart(2, '0')}`\n case 'hour':\n return `${String(date.getUTCMonth() + 1).padStart(2, '0')}-${String(date.getUTCDate()).padStart(2, '0')} ${String(date.getUTCHours()).padStart(2, '0')}:00`\n default:\n return `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, '0')}`\n }\n })\n }\n\n const xAxis = g.append('g')\n .attr('transform', `translate(0,${chartHeight})`)\n .call(xAxisGenerator)\n\n xAxis.selectAll('text')\n .style('fill', textColor)\n\n xAxis.selectAll('line, path')\n .style('stroke', gridColor)\n\n xAxis.append('text')\n .attr('x', width / 2)\n .attr('y', 35)\n .attr('fill', textColor)\n .style('text-anchor', 'middle')\n .style('font-size', '12px')\n .text(getFieldLabel(xAxisField))\n\n // Add Y axis\n const yAxis = g.append('g')\n .call(axisLeft(yScale))\n\n yAxis.selectAll('text')\n .style('fill', textColor)\n\n yAxis.selectAll('line, path')\n .style('stroke', gridColor)\n\n yAxis.append('text')\n .attr('transform', 'rotate(-90)')\n .attr('y', -35)\n .attr('x', -chartHeight / 2)\n .attr('fill', textColor)\n .style('text-anchor', 'middle')\n .style('font-size', '12px')\n .text(getFieldLabel(yAxisField))\n\n // Create tooltip\n const tooltip = select('body').append('div')\n .attr('class', 'bubble-chart-tooltip')\n .style('position', 'absolute')\n .style('padding', '8px')\n .style('background', 'rgba(0, 0, 0, 0.8)')\n .style('color', 'white')\n .style('border-radius', '4px')\n .style('font-size', '12px')\n .style('pointer-events', 'none')\n .style('opacity', 0)\n .style('z-index', 1000)\n\n // Add bubbles\n const bubbles = g.selectAll('.bubble')\n .data(bubbleData)\n .enter().append('circle')\n .attr('class', 'bubble')\n .attr('cx', d => xScale(d.x))\n .attr('cy', d => yScale(d.y))\n .attr('r', d => sizeScale(d.size))\n .style('fill', d => {\n if (colorFieldName && d.color !== undefined) {\n return isNumericColorField\n ? (colorScale as ScaleQuantize<string>)(d.color as number)\n : (colorScale as ScaleOrdinal<string, string>)(String(d.color))\n }\n return CHART_COLORS[0]\n })\n .style('opacity', safeDisplayConfig.bubbleOpacity)\n .style('stroke', '#fff')\n .style('stroke-width', 1)\n .style('cursor', 'pointer')\n\n // Add hover effects\n if (safeDisplayConfig.showTooltip) {\n bubbles\n .on('mouseover', function(event, d) {\n select(this)\n .transition()\n .duration(200)\n .style('opacity', 1)\n .attr('r', sizeScale(d.size) * 1.1)\n\n const tooltipContent = [\n `<strong>${d.series || 'Unknown'}</strong>`,\n `${getFieldLabel(xAxisField)}: ${d.xLabel || d.x}`,\n `${getFieldLabel(yAxisField)}: ${d.y}`,\n `${getFieldLabel(sizeFieldName)}: ${d.size}`,\n colorFieldName && d.color ? `${getFieldLabel(colorFieldName)}: ${d.color}` : ''\n ].filter(Boolean).join('<br>')\n\n tooltip\n .html(tooltipContent)\n .style('left', (event.pageX + 10) + 'px')\n .style('top', (event.pageY - 10) + 'px')\n .transition()\n .duration(200)\n .style('opacity', 1)\n\n setHoveredBubble(d.label)\n })\n .on('mousemove', function(event) {\n tooltip\n .style('left', (event.pageX + 10) + 'px')\n .style('top', (event.pageY - 10) + 'px')\n })\n .on('mouseout', function(_event, d) {\n select(this)\n .transition()\n .duration(200)\n .style('opacity', safeDisplayConfig.bubbleOpacity)\n .attr('r', sizeScale(d.size))\n\n tooltip\n .transition()\n .duration(200)\n .style('opacity', 0)\n\n setHoveredBubble(null)\n })\n }\n\n // Add legend if needed\n if (safeDisplayConfig.showLegend && colorFieldName) {\n if (isNumericColorField) {\n // Create gradient legend for numeric color field\n const legendWidth = 200\n const legendHeight = 20\n const minValue = Math.min(...bubbleData.map(d => d.color as number))\n const maxValue = Math.max(...bubbleData.map(d => d.color as number))\n \n const legend = g.append('g')\n .attr('class', 'color-legend')\n .attr('transform', `translate(${width / 2 - legendWidth / 2}, ${chartHeight + 60})`)\n\n // Create gradient definition\n const defs = svg.append('defs')\n const gradient = defs.append('linearGradient')\n .attr('id', 'color-scale-gradient')\n .attr('x1', '0%')\n .attr('y1', '0%')\n .attr('x2', '100%')\n .attr('y2', '0%')\n\n // Add color stops for the gradient\n const gradientColors = colorPalette?.gradient || CHART_COLORS_GRADIENT\n gradientColors.forEach((color, i) => {\n gradient.append('stop')\n .attr('offset', `${(i / (gradientColors.length - 1)) * 100}%`)\n .attr('stop-color', color)\n })\n\n // Add the gradient rectangle\n legend.append('rect')\n .attr('width', legendWidth)\n .attr('height', legendHeight)\n .style('fill', 'url(#color-scale-gradient)')\n .style('stroke', '#ccc')\n .style('stroke-width', 1)\n\n // Add min value label\n legend.append('text')\n .attr('x', 0)\n .attr('y', legendHeight + 15)\n .attr('text-anchor', 'start')\n .style('font-size', '11px')\n .style('fill', textColor)\n .text(minValue.toFixed(2))\n\n // Add max value label\n legend.append('text')\n .attr('x', legendWidth)\n .attr('y', legendHeight + 15)\n .attr('text-anchor', 'end')\n .style('font-size', '11px')\n .style('fill', textColor)\n .text(maxValue.toFixed(2))\n\n // Add field name label\n legend.append('text')\n .attr('x', legendWidth / 2)\n .attr('y', -5)\n .attr('text-anchor', 'middle')\n .style('font-size', '12px')\n .style('font-weight', 'bold')\n .style('fill', textColor)\n .text(getFieldLabel(colorFieldName))\n\n } else {\n // Original categorical legend\n const legendItems = uniqueColors\n\n if (legendItems.length > 0) {\n const legend = g.append('g')\n .attr('class', 'legend')\n .attr('transform', `translate(${width / 2 - (legendItems.length * 80) / 2}, ${chartHeight + 60})`)\n\n const legendItem = legend.selectAll('.legend-item')\n .data(legendItems)\n .enter().append('g')\n .attr('class', 'legend-item')\n .attr('transform', (_d, i) => `translate(${i * 80}, 0)`)\n .style('cursor', 'pointer')\n\n legendItem.append('circle')\n .attr('cx', 5)\n .attr('cy', 5)\n .attr('r', 5)\n .style('fill', d => (colorScale as ScaleOrdinal<string, string>)(d as string))\n .style('opacity', safeDisplayConfig.bubbleOpacity)\n\n legendItem.append('text')\n .attr('x', 15)\n .attr('y', 5)\n .attr('dy', '.35em')\n .style('font-size', '11px')\n .style('fill', textColor)\n .text(d => String(d))\n\n // Legend hover effects\n legendItem\n .on('mouseover', function(_event, legendKey) {\n // Highlight matching bubbles\n bubbles\n .transition()\n .duration(200)\n .style('opacity', d => {\n const matches = colorFieldName && String(d.color) === legendKey\n return matches ? 1 : 0.2\n })\n })\n .on('mouseout', function() {\n // Reset all bubbles\n bubbles\n .transition()\n .duration(200)\n .style('opacity', safeDisplayConfig.bubbleOpacity)\n })\n }\n }\n }\n\n // Cleanup function\n return () => {\n tooltip.remove()\n }\n }, [data, chartConfig, displayConfig, queryObject, dimensions, dimensionsReady, safeDisplayConfig.showLegend, safeDisplayConfig.showGrid, safeDisplayConfig.showTooltip, safeDisplayConfig.minBubbleSize, safeDisplayConfig.maxBubbleSize, safeDisplayConfig.bubbleOpacity, colorPalette, currentTheme])\n\n if (!data || data.length === 0) {\n return (\n <div className=\"flex items-center justify-center w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">No data available</div>\n <div className=\"text-xs text-dc-text-secondary\">No data points to display in bubble chart</div>\n </div>\n </div>\n )\n }\n\n // Validate that we have required fields\n const hasValidConfig = chartConfig?.xAxis && chartConfig?.yAxis && chartConfig?.series\n if (!hasValidConfig) {\n return (\n <div className=\"flex items-center justify-center w-full text-yellow-600\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">Configuration Required</div>\n <div className=\"text-xs\">Bubble chart requires xAxis, yAxis, series, and sizeField dimensions</div>\n <div className=\"text-xs mt-1\">Optional: colorField for bubble coloring</div>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"w-full flex-1 flex flex-col relative\" style={{ height, minHeight: '250px', overflow: 'hidden' }}>\n <div ref={containerRef} className=\"w-full h-full relative\">\n <svg ref={svgRef} className=\"w-full h-full\" />\n {!dimensionsReady && (\n <div className=\"absolute inset-0 flex items-center justify-center\">\n <div className=\"text-dc-text-muted text-sm\">Measuring chart dimensions...</div>\n </div>\n )}\n </div>\n </div>\n )\n}"],"names":["BubbleChart","data","chartConfig","displayConfig","queryObject","height","colorPalette","svgRef","useRef","containerRef","setHoveredBubble","useState","dimensions","setDimensions","dimensionsReady","setDimensionsReady","currentTheme","setCurrentTheme","getFieldLabel","useCubeContext","useEffect","getTheme","watchThemeChanges","theme","safeDisplayConfig","useLayoutEffect","retryCount","maxRetries","rafId","timeoutId","updateDimensions","width","retryWithRaf","resizeObserver","entries","entry","select","xAxisField","yAxisField","seriesField","sizeFieldName","colorFieldName","xGranularity","getFieldGranularity","isTimeDimension","td","bubbleData","item","rawXValue","xNum","xLabel","dateStr","date","isoStr","formatTimeValue","formattedValue","yValue","parseNumericValue","sizeValue","seriesValue","isValidNumericValue","d","margin","CHART_MARGINS","chartHeight","svg","g","xScale","scaleLinear","extent","yScale","sizeScale","scaleSqrt","max","colorScale","isNumericColorField","uniqueColors","colorValues","value","val","minValue","maxValue","scaleQuantize","CHART_COLORS_GRADIENT","scaleOrdinal","CHART_COLORS","getThemeColor","varName","fallback","isDark","textColor","gridColor","xGrid","axisBottom","yGrid","axisLeft","xAxisGenerator","q","xAxis","yAxis","tooltip","bubbles","event","tooltipContent","_event","legend","gradient","gradientColors","color","i","legendItems","legendItem","_d","legendKey","jsx","jsxs"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"chart-bubblechart-5Z0hPYwn.js","sources":["../../../src/client/components/charts/BubbleChart.tsx"],"sourcesContent":["import { useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport { select, scaleLinear, scaleSqrt, scaleOrdinal, scaleQuantize, extent, max, axisBottom, axisLeft, type ScaleOrdinal, type ScaleQuantize } from 'd3'\nimport { CHART_COLORS, CHART_COLORS_GRADIENT, CHART_MARGINS } from '../../utils/chartConstants'\nimport { formatTimeValue, getFieldGranularity, parseNumericValue, isValidNumericValue } from '../../utils/chartUtils'\nimport { useCubeContext } from '../../providers/CubeProvider'\nimport { getTheme, watchThemeChanges, type Theme } from '../../theme'\nimport type { ChartProps } from '../../types'\n\ninterface BubbleData {\n x: number\n xLabel?: string // Formatted label for time dimensions\n y: number\n size: number\n color?: string | number\n label: string\n series?: string\n}\n\nexport default function BubbleChart({\n data,\n chartConfig,\n displayConfig = {},\n queryObject,\n height = \"100%\",\n colorPalette\n}: ChartProps) {\n const svgRef = useRef<SVGSVGElement | null>(null)\n const containerRef = useRef<HTMLDivElement | null>(null)\n const [, setHoveredBubble] = useState<string | null>(null)\n const [dimensions, setDimensions] = useState({ width: 0, height: 0 })\n const [dimensionsReady, setDimensionsReady] = useState(false)\n const [currentTheme, setCurrentTheme] = useState<Theme>('light')\n const { getFieldLabel } = useCubeContext()\n\n // Watch for theme changes\n useEffect(() => {\n setCurrentTheme(getTheme())\n const unwatch = watchThemeChanges((theme) => {\n setCurrentTheme(theme)\n })\n return unwatch\n }, [])\n\n const safeDisplayConfig = {\n showLegend: displayConfig?.showLegend ?? true,\n showGrid: displayConfig?.showGrid ?? true,\n showTooltip: displayConfig?.showTooltip ?? true,\n minBubbleSize: displayConfig?.minBubbleSize ?? 5,\n maxBubbleSize: displayConfig?.maxBubbleSize ?? 50,\n bubbleOpacity: displayConfig?.bubbleOpacity ?? 0.7\n }\n\n // Enhanced dimension measurement with retry mechanism\n useLayoutEffect(() => {\n let retryCount = 0\n const maxRetries = 10\n let rafId: number\n let timeoutId: NodeJS.Timeout\n \n const updateDimensions = () => {\n if (containerRef.current) {\n const { width, height } = containerRef.current.getBoundingClientRect()\n \n if (width > 0 && height > 0) {\n setDimensions({ width, height })\n setDimensionsReady(true)\n return true\n }\n }\n return false\n }\n \n // Immediate measurement\n const success = updateDimensions()\n \n if (!success && retryCount < maxRetries) {\n // Retry with requestAnimationFrame\n const retryWithRaf = () => {\n const rafSuccess = updateDimensions()\n \n if (!rafSuccess && retryCount < maxRetries) {\n retryCount++\n // Use setTimeout for additional retries with increasing delays\n timeoutId = setTimeout(() => {\n rafId = requestAnimationFrame(retryWithRaf)\n }, 50 * retryCount) // Increasing delay: 50ms, 100ms, 150ms, etc.\n }\n }\n \n rafId = requestAnimationFrame(retryWithRaf)\n }\n \n return () => {\n if (rafId) cancelAnimationFrame(rafId)\n if (timeoutId) clearTimeout(timeoutId)\n }\n }, [])\n\n // Enhanced ResizeObserver for dynamic resizing with immediate initialization\n useEffect(() => {\n let resizeObserver: ResizeObserver | null = null\n \n const updateDimensions = () => {\n if (containerRef.current) {\n const { width, height } = containerRef.current.getBoundingClientRect()\n if (width > 0 && height > 0) {\n setDimensions({ width, height })\n if (!dimensionsReady) {\n setDimensionsReady(true)\n }\n }\n }\n }\n \n // Initialize ResizeObserver immediately\n if (containerRef.current) {\n resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const { width, height } = entry.contentRect\n if (width > 0 && height > 0) {\n setDimensions({ width, height })\n if (!dimensionsReady) {\n setDimensionsReady(true)\n }\n }\n }\n })\n \n resizeObserver.observe(containerRef.current)\n \n // Also try immediate measurement as fallback\n updateDimensions()\n }\n\n // Window resize as additional fallback\n window.addEventListener('resize', updateDimensions)\n \n return () => {\n if (resizeObserver) {\n resizeObserver.disconnect()\n }\n window.removeEventListener('resize', updateDimensions)\n }\n }, [dimensionsReady])\n\n useEffect(() => {\n if (!data || data.length === 0 || !svgRef.current || !dimensionsReady || dimensions.width === 0) {\n return\n }\n\n // Clear previous chart\n select(svgRef.current).selectAll('*').remove()\n\n\n // Validate chartConfig - only new format supported\n if (!chartConfig?.xAxis || !chartConfig?.yAxis || !chartConfig?.series) {\n return\n }\n\n const xAxisField = Array.isArray(chartConfig.xAxis) ? chartConfig.xAxis[0] : chartConfig.xAxis\n const yAxisField = Array.isArray(chartConfig.yAxis) ? chartConfig.yAxis[0] : chartConfig.yAxis\n const seriesField = Array.isArray(chartConfig.series) ? chartConfig.series[0] : chartConfig.series\n const sizeFieldName = Array.isArray(chartConfig.sizeField) ? chartConfig.sizeField[0] : chartConfig.sizeField || yAxisField\n const colorFieldName = Array.isArray(chartConfig.colorField) ? chartConfig.colorField[0] : chartConfig.colorField\n\n\n if (!xAxisField || !yAxisField || !seriesField || !sizeFieldName) {\n return\n }\n\n // Transform data for bubble chart\n // Null handling: Filter out bubbles where x, y, or size are null\n const xGranularity = getFieldGranularity(queryObject, xAxisField)\n\n // Check if x-axis field is a time dimension\n const isTimeDimension = queryObject?.timeDimensions?.some(\n (td: { dimension: string }) => td.dimension === xAxisField\n ) || false\n\n const bubbleData: BubbleData[] = data\n .map(item => {\n const rawXValue = item[xAxisField]\n let xNum: number\n let xLabel: string\n\n if (isTimeDimension && rawXValue) {\n // For time dimensions, convert to timestamp for proper numeric positioning\n const dateStr = String(rawXValue)\n // Try to parse as date - handle ISO format and PostgreSQL format\n let date: Date\n if (dateStr.match(/^\\d{4}-\\d{2}-\\d{2}[T ]/)) {\n // Full timestamp format\n let isoStr = dateStr\n if (dateStr.includes(' ')) {\n isoStr = dateStr.replace(' ', 'T').replace('+00', 'Z').replace(/\\+\\d{2}:\\d{2}$/, 'Z')\n }\n if (!isoStr.endsWith('Z') && !isoStr.includes('+')) {\n isoStr = isoStr + 'Z'\n }\n date = new Date(isoStr)\n } else {\n date = new Date(dateStr)\n }\n\n xNum = isNaN(date.getTime()) ? parseFloat(dateStr) : date.getTime()\n xLabel = formatTimeValue(rawXValue, xGranularity)\n } else {\n // Non-time value - use as-is\n const formattedValue = formatTimeValue(rawXValue, xGranularity) || rawXValue\n xNum = typeof formattedValue === 'string' ? parseFloat(formattedValue) : formattedValue\n xLabel = String(formattedValue)\n }\n\n const yValue = parseNumericValue(item[yAxisField])\n const sizeValue = parseNumericValue(item[sizeFieldName])\n const seriesValue = item[seriesField]\n\n return {\n x: xNum,\n xLabel, // Store formatted label for tooltip display\n y: yValue as number, // Type assertion: filter below ensures this is never null\n size: sizeValue !== null ? Math.abs(sizeValue) : 0, // Ensure positive size\n color: colorFieldName ? item[colorFieldName] : seriesValue,\n series: seriesValue,\n label: `${seriesValue || 'Unknown'}`,\n isValid: isValidNumericValue(xNum) && yValue !== null && sizeValue !== null && sizeValue > 0\n }\n })\n .filter(d => d.isValid && d.size > 0) // Filter out bubbles with invalid coordinates or no size\n\n if (bubbleData.length === 0) return\n\n const margin = { \n ...CHART_MARGINS, \n left: CHART_MARGINS.left + 30, // Add extra 30px left margin for Y-axis label\n bottom: (safeDisplayConfig.showLegend && colorFieldName) ? 100 : 40 // Add extra space for legend\n }\n const width = dimensions.width - margin.left - margin.right\n const chartHeight = dimensions.height - margin.top - margin.bottom\n\n const svg = select(svgRef.current)\n .attr('width', dimensions.width)\n .attr('height', dimensions.height)\n\n const g = svg.append('g')\n .attr('transform', `translate(${margin.left},${margin.top})`)\n\n // Set up scales\n const xScale = scaleLinear()\n .domain(extent(bubbleData, d => d.x) as [number, number])\n .range([0, width])\n .nice()\n\n const yScale = scaleLinear()\n .domain(extent(bubbleData, d => d.y) as [number, number])\n .range([chartHeight, 0])\n .nice()\n\n const sizeScale = scaleSqrt()\n .domain([0, max(bubbleData, d => d.size) as number])\n .range([safeDisplayConfig.minBubbleSize, safeDisplayConfig.maxBubbleSize])\n\n // Set up color scale\n let colorScale: ScaleOrdinal<string, string> | ScaleQuantize<string>\n let isNumericColorField = false\n let uniqueColors: string[] = []\n \n if (colorFieldName && bubbleData.length > 0) {\n // Check if color field is numeric for color scaling (same logic as TreeMapChart)\n const colorValues = bubbleData.map(item => {\n const value = item.color\n return typeof value === 'string' ? parseFloat(value) : value\n }).filter((val): val is number => !isNaN(val as number))\n \n isNumericColorField = colorValues.length === bubbleData.length && colorValues.every(val => typeof val === 'number')\n \n if (isNumericColorField) {\n // Use D3 quantize scale for better color distribution with small ranges\n const minValue = Math.min(...colorValues)\n const maxValue = Math.max(...colorValues)\n \n // Create D3 quantize color scale - maps continuous data to discrete color bands\n colorScale = scaleQuantize<string>()\n .domain([minValue, maxValue])\n .range(colorPalette?.gradient || CHART_COLORS_GRADIENT)\n } else {\n // Categorical color field - use series colors\n uniqueColors = [...new Set(bubbleData.map(d => String(d.color)))]\n colorScale = scaleOrdinal<string>()\n .domain(uniqueColors)\n .range(colorPalette?.colors || CHART_COLORS)\n }\n } else {\n // Single color for all bubbles\n colorScale = scaleOrdinal<string>()\n .domain(['default'])\n .range([CHART_COLORS[0]])\n }\n\n // Get theme colors from CSS variables\n const getThemeColor = (varName: string, fallback: string) => {\n const value = getComputedStyle(document.documentElement).getPropertyValue(varName).trim()\n return value || fallback\n }\n\n const isDark = currentTheme !== 'light'\n const textColor = isDark\n ? getThemeColor('--dc-text-muted', '#cbd5e1') // Lighter text for dark mode\n : getThemeColor('--dc-text-secondary', '#374151') // Darker text for light mode\n const gridColor = isDark\n ? getThemeColor('--dc-border', '#475569') // Lighter grid for dark mode\n : '#9ca3af' // Much darker gray for light mode visibility\n\n // Add grid\n if (safeDisplayConfig.showGrid) {\n // X-axis grid\n const xGrid = g.append('g')\n .attr('class', 'grid')\n .attr('transform', `translate(0,${chartHeight})`)\n .call(axisBottom(xScale)\n .tickSize(-chartHeight)\n .tickFormat(() => '')\n )\n\n xGrid.selectAll('line')\n .style('stroke', gridColor)\n .style('stroke-dasharray', '3,3')\n .style('opacity', 0.3)\n\n xGrid.select('.domain')\n .style('stroke', 'none')\n\n // Y-axis grid\n const yGrid = g.append('g')\n .attr('class', 'grid')\n .call(axisLeft(yScale)\n .tickSize(-width)\n .tickFormat(() => '')\n )\n\n yGrid.selectAll('line')\n .style('stroke', gridColor)\n .style('stroke-dasharray', '3,3')\n .style('opacity', 0.3)\n\n yGrid.select('.domain')\n .style('stroke', 'none')\n }\n\n // Add X axis with proper time formatting if needed\n const xAxisGenerator = axisBottom(xScale)\n\n // If it's a time dimension, format the tick labels\n if (isTimeDimension) {\n xAxisGenerator.tickFormat((d) => {\n const date = new Date(d as number)\n if (isNaN(date.getTime())) return String(d)\n\n // Format based on granularity\n switch (xGranularity?.toLowerCase()) {\n case 'year':\n return String(date.getUTCFullYear())\n case 'quarter': {\n const q = Math.floor(date.getUTCMonth() / 3) + 1\n return `${date.getUTCFullYear()}-Q${q}`\n }\n case 'month':\n return `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, '0')}`\n case 'week':\n case 'day':\n return `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, '0')}-${String(date.getUTCDate()).padStart(2, '0')}`\n case 'hour':\n return `${String(date.getUTCMonth() + 1).padStart(2, '0')}-${String(date.getUTCDate()).padStart(2, '0')} ${String(date.getUTCHours()).padStart(2, '0')}:00`\n default:\n return `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, '0')}`\n }\n })\n }\n\n const xAxis = g.append('g')\n .attr('transform', `translate(0,${chartHeight})`)\n .call(xAxisGenerator)\n\n xAxis.selectAll('text')\n .style('fill', textColor)\n\n xAxis.selectAll('line, path')\n .style('stroke', gridColor)\n\n xAxis.append('text')\n .attr('x', width / 2)\n .attr('y', 35)\n .attr('fill', textColor)\n .style('text-anchor', 'middle')\n .style('font-size', '12px')\n .text(getFieldLabel(xAxisField))\n\n // Add Y axis\n const yAxis = g.append('g')\n .call(axisLeft(yScale))\n\n yAxis.selectAll('text')\n .style('fill', textColor)\n\n yAxis.selectAll('line, path')\n .style('stroke', gridColor)\n\n yAxis.append('text')\n .attr('transform', 'rotate(-90)')\n .attr('y', -35)\n .attr('x', -chartHeight / 2)\n .attr('fill', textColor)\n .style('text-anchor', 'middle')\n .style('font-size', '12px')\n .text(getFieldLabel(yAxisField))\n\n // Create tooltip\n const tooltip = select('body').append('div')\n .attr('class', 'bubble-chart-tooltip')\n .style('position', 'absolute')\n .style('padding', '8px')\n .style('background', 'rgba(0, 0, 0, 0.8)')\n .style('color', 'white')\n .style('border-radius', '4px')\n .style('font-size', '12px')\n .style('pointer-events', 'none')\n .style('opacity', 0)\n .style('z-index', 1000)\n\n // Add bubbles\n const bubbles = g.selectAll('.bubble')\n .data(bubbleData)\n .enter().append('circle')\n .attr('class', 'bubble')\n .attr('cx', d => xScale(d.x))\n .attr('cy', d => yScale(d.y))\n .attr('r', d => sizeScale(d.size))\n .style('fill', d => {\n if (colorFieldName && d.color !== undefined) {\n return isNumericColorField\n ? (colorScale as ScaleQuantize<string>)(d.color as number)\n : (colorScale as ScaleOrdinal<string, string>)(String(d.color))\n }\n return CHART_COLORS[0]\n })\n .style('opacity', safeDisplayConfig.bubbleOpacity)\n .style('stroke', '#fff')\n .style('stroke-width', 1)\n .style('cursor', 'pointer')\n\n // Add hover effects\n if (safeDisplayConfig.showTooltip) {\n bubbles\n .on('mouseover', function(event, d) {\n select(this)\n .transition()\n .duration(200)\n .style('opacity', 1)\n .attr('r', sizeScale(d.size) * 1.1)\n\n const tooltipContent = [\n `<strong>${d.series || 'Unknown'}</strong>`,\n `${getFieldLabel(xAxisField)}: ${d.xLabel || d.x}`,\n `${getFieldLabel(yAxisField)}: ${d.y}`,\n `${getFieldLabel(sizeFieldName)}: ${d.size}`,\n colorFieldName && d.color ? `${getFieldLabel(colorFieldName)}: ${d.color}` : ''\n ].filter(Boolean).join('<br>')\n\n tooltip\n .html(tooltipContent)\n .style('left', (event.pageX + 10) + 'px')\n .style('top', (event.pageY - 10) + 'px')\n .transition()\n .duration(200)\n .style('opacity', 1)\n\n setHoveredBubble(d.label)\n })\n .on('mousemove', function(event) {\n tooltip\n .style('left', (event.pageX + 10) + 'px')\n .style('top', (event.pageY - 10) + 'px')\n })\n .on('mouseout', function(_event, d) {\n select(this)\n .transition()\n .duration(200)\n .style('opacity', safeDisplayConfig.bubbleOpacity)\n .attr('r', sizeScale(d.size))\n\n tooltip\n .transition()\n .duration(200)\n .style('opacity', 0)\n\n setHoveredBubble(null)\n })\n }\n\n // Add legend if needed\n if (safeDisplayConfig.showLegend && colorFieldName) {\n if (isNumericColorField) {\n // Create gradient legend for numeric color field\n const legendWidth = 200\n const legendHeight = 20\n const minValue = Math.min(...bubbleData.map(d => d.color as number))\n const maxValue = Math.max(...bubbleData.map(d => d.color as number))\n \n const legend = g.append('g')\n .attr('class', 'color-legend')\n .attr('transform', `translate(${width / 2 - legendWidth / 2}, ${chartHeight + 60})`)\n\n // Create gradient definition\n const defs = svg.append('defs')\n const gradient = defs.append('linearGradient')\n .attr('id', 'color-scale-gradient')\n .attr('x1', '0%')\n .attr('y1', '0%')\n .attr('x2', '100%')\n .attr('y2', '0%')\n\n // Add color stops for the gradient\n const gradientColors = colorPalette?.gradient || CHART_COLORS_GRADIENT\n gradientColors.forEach((color, i) => {\n gradient.append('stop')\n .attr('offset', `${(i / (gradientColors.length - 1)) * 100}%`)\n .attr('stop-color', color)\n })\n\n // Add the gradient rectangle\n legend.append('rect')\n .attr('width', legendWidth)\n .attr('height', legendHeight)\n .style('fill', 'url(#color-scale-gradient)')\n .style('stroke', '#ccc')\n .style('stroke-width', 1)\n\n // Add min value label\n legend.append('text')\n .attr('x', 0)\n .attr('y', legendHeight + 15)\n .attr('text-anchor', 'start')\n .style('font-size', '11px')\n .style('fill', textColor)\n .text(minValue.toFixed(2))\n\n // Add max value label\n legend.append('text')\n .attr('x', legendWidth)\n .attr('y', legendHeight + 15)\n .attr('text-anchor', 'end')\n .style('font-size', '11px')\n .style('fill', textColor)\n .text(maxValue.toFixed(2))\n\n // Add field name label\n legend.append('text')\n .attr('x', legendWidth / 2)\n .attr('y', -5)\n .attr('text-anchor', 'middle')\n .style('font-size', '12px')\n .style('font-weight', 'bold')\n .style('fill', textColor)\n .text(getFieldLabel(colorFieldName))\n\n } else {\n // Original categorical legend\n const legendItems = uniqueColors\n\n if (legendItems.length > 0) {\n const legend = g.append('g')\n .attr('class', 'legend')\n .attr('transform', `translate(${width / 2 - (legendItems.length * 80) / 2}, ${chartHeight + 60})`)\n\n const legendItem = legend.selectAll('.legend-item')\n .data(legendItems)\n .enter().append('g')\n .attr('class', 'legend-item')\n .attr('transform', (_d, i) => `translate(${i * 80}, 0)`)\n .style('cursor', 'pointer')\n\n legendItem.append('circle')\n .attr('cx', 5)\n .attr('cy', 5)\n .attr('r', 5)\n .style('fill', d => (colorScale as ScaleOrdinal<string, string>)(d as string))\n .style('opacity', safeDisplayConfig.bubbleOpacity)\n\n legendItem.append('text')\n .attr('x', 15)\n .attr('y', 5)\n .attr('dy', '.35em')\n .style('font-size', '11px')\n .style('fill', textColor)\n .text(d => String(d))\n\n // Legend hover effects\n legendItem\n .on('mouseover', function(_event, legendKey) {\n // Highlight matching bubbles\n bubbles\n .transition()\n .duration(200)\n .style('opacity', d => {\n const matches = colorFieldName && String(d.color) === legendKey\n return matches ? 1 : 0.2\n })\n })\n .on('mouseout', function() {\n // Reset all bubbles\n bubbles\n .transition()\n .duration(200)\n .style('opacity', safeDisplayConfig.bubbleOpacity)\n })\n }\n }\n }\n\n // Cleanup function\n return () => {\n tooltip.remove()\n }\n }, [data, chartConfig, displayConfig, queryObject, dimensions, dimensionsReady, safeDisplayConfig.showLegend, safeDisplayConfig.showGrid, safeDisplayConfig.showTooltip, safeDisplayConfig.minBubbleSize, safeDisplayConfig.maxBubbleSize, safeDisplayConfig.bubbleOpacity, colorPalette, currentTheme])\n\n if (!data || data.length === 0) {\n return (\n <div className=\"flex items-center justify-center w-full text-dc-text-muted\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">No data available</div>\n <div className=\"text-xs text-dc-text-secondary\">No data points to display in bubble chart</div>\n </div>\n </div>\n )\n }\n\n // Validate that we have required fields\n const hasValidConfig = chartConfig?.xAxis && chartConfig?.yAxis && chartConfig?.series\n if (!hasValidConfig) {\n return (\n <div className=\"flex items-center justify-center w-full text-yellow-600\" style={{ height }}>\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">Configuration Required</div>\n <div className=\"text-xs\">Bubble chart requires xAxis, yAxis, series, and sizeField dimensions</div>\n <div className=\"text-xs mt-1\">Optional: colorField for bubble coloring</div>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"w-full flex-1 flex flex-col relative\" style={{ height, minHeight: '250px', overflow: 'hidden' }}>\n <div ref={containerRef} className=\"w-full h-full relative\">\n <svg ref={svgRef} className=\"w-full h-full\" />\n {!dimensionsReady && (\n <div className=\"absolute inset-0 flex items-center justify-center\">\n <div className=\"text-dc-text-muted text-sm\">Measuring chart dimensions...</div>\n </div>\n )}\n </div>\n </div>\n )\n}"],"names":["BubbleChart","data","chartConfig","displayConfig","queryObject","height","colorPalette","svgRef","useRef","containerRef","setHoveredBubble","useState","dimensions","setDimensions","dimensionsReady","setDimensionsReady","currentTheme","setCurrentTheme","getFieldLabel","useCubeContext","useEffect","getTheme","watchThemeChanges","theme","safeDisplayConfig","useLayoutEffect","retryCount","maxRetries","rafId","timeoutId","updateDimensions","width","retryWithRaf","resizeObserver","entries","entry","select","xAxisField","yAxisField","seriesField","sizeFieldName","colorFieldName","xGranularity","getFieldGranularity","isTimeDimension","td","bubbleData","item","rawXValue","xNum","xLabel","dateStr","date","isoStr","formatTimeValue","formattedValue","yValue","parseNumericValue","sizeValue","seriesValue","isValidNumericValue","d","margin","CHART_MARGINS","chartHeight","svg","g","xScale","scaleLinear","extent","yScale","sizeScale","scaleSqrt","max","colorScale","isNumericColorField","uniqueColors","colorValues","value","val","minValue","maxValue","scaleQuantize","CHART_COLORS_GRADIENT","scaleOrdinal","CHART_COLORS","getThemeColor","varName","fallback","isDark","textColor","gridColor","xGrid","axisBottom","yGrid","axisLeft","xAxisGenerator","q","xAxis","yAxis","tooltip","bubbles","event","tooltipContent","_event","legend","gradient","gradientColors","color","i","legendItems","legendItem","_d","legendKey","jsx","jsxs"],"mappings":"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"}
|
package/dist/client/chunks/{chart-charttooltip-NrFVM1cJ.js → chart-charttooltip-CqtjUW2V.js}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as t } from "react/jsx-runtime";
|
|
2
2
|
import { Tooltip as e } from "recharts";
|
|
3
|
-
import { f as p } from "./chart-activitygridchart-
|
|
3
|
+
import { f as p } from "./chart-activitygridchart-B5OqLgbD.js";
|
|
4
4
|
const i = (r, o) => r == null ? ["No data", o] : [p(r), o];
|
|
5
5
|
function f({ formatter: r, labelFormatter: o }) {
|
|
6
6
|
return /* @__PURE__ */ t(
|
|
@@ -23,4 +23,4 @@ function f({ formatter: r, labelFormatter: o }) {
|
|
|
23
23
|
export {
|
|
24
24
|
f as C
|
|
25
25
|
};
|
|
26
|
-
//# sourceMappingURL=chart-charttooltip-
|
|
26
|
+
//# sourceMappingURL=chart-charttooltip-CqtjUW2V.js.map
|
package/dist/client/chunks/{chart-charttooltip-NrFVM1cJ.js.map → chart-charttooltip-CqtjUW2V.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-charttooltip-
|
|
1
|
+
{"version":3,"file":"chart-charttooltip-CqtjUW2V.js","sources":["../../../src/client/components/charts/ChartTooltip.tsx"],"sourcesContent":["import React from 'react'\nimport { Tooltip } from 'recharts'\nimport { formatNumericValue } from '../../utils/chartUtils'\n\ninterface ChartTooltipProps {\n formatter?: (value: any, name: any, props: any) => [React.ReactText, React.ReactText]\n labelFormatter?: (label: any) => React.ReactText\n}\n\n// Default formatter that rounds numeric values to at most 2 decimal places\nconst defaultFormatter = (value: any, name: any): [React.ReactText, React.ReactText] => {\n if (value === null || value === undefined) {\n return ['No data', name]\n }\n return [formatNumericValue(value), name]\n}\n\nexport default function ChartTooltip({ formatter, labelFormatter }: ChartTooltipProps) {\n return (\n <Tooltip\n formatter={formatter || defaultFormatter}\n labelFormatter={labelFormatter}\n contentStyle={{\n backgroundColor: 'white',\n border: '1px solid #e5e7eb',\n borderRadius: '0.5rem',\n fontSize: '0.875rem',\n color: '#1f2937',\n boxShadow: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',\n padding: '8px 12px'\n }}\n />\n )\n}"],"names":["defaultFormatter","value","name","formatNumericValue","ChartTooltip","formatter","labelFormatter","jsx","Tooltip"],"mappings":";;;AAUA,MAAMA,IAAmB,CAACC,GAAYC,MAChCD,KAAU,OACL,CAAC,WAAWC,CAAI,IAElB,CAACC,EAAmBF,CAAK,GAAGC,CAAI;AAGzC,SAAwBE,EAAa,EAAE,WAAAC,GAAW,gBAAAC,KAAqC;AACrF,SACE,gBAAAC;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,WAAWH,KAAaL;AAAA,MACxB,gBAAAM;AAAA,MACA,cAAc;AAAA,QACZ,iBAAiB;AAAA,QACjB,QAAQ;AAAA,QACR,cAAc;AAAA,QACd,UAAU;AAAA,QACV,OAAO;AAAA,QACP,WAAW;AAAA,QACX,SAAS;AAAA,MAAA;AAAA,IACX;AAAA,EAAA;AAGN;"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as e, jsxs as d } from "react/jsx-runtime";
|
|
2
|
-
import { u as m } from "./chart-activitygridchart-
|
|
2
|
+
import { u as m } from "./chart-activitygridchart-B5OqLgbD.js";
|
|
3
3
|
function b({
|
|
4
4
|
data: t,
|
|
5
5
|
chartConfig: l,
|
|
@@ -54,4 +54,4 @@ function x(t) {
|
|
|
54
54
|
export {
|
|
55
55
|
b as default
|
|
56
56
|
};
|
|
57
|
-
//# sourceMappingURL=chart-datatable-
|
|
57
|
+
//# sourceMappingURL=chart-datatable-uFzkh18f.js.map
|
package/dist/client/chunks/{chart-datatable-BvV7gLPZ.js.map → chart-datatable-uFzkh18f.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-datatable-
|
|
1
|
+
{"version":3,"file":"chart-datatable-uFzkh18f.js","sources":["../../../src/client/components/charts/DataTable.tsx"],"sourcesContent":["/**\n * Simple Data Table component\n * Minimal styling with Tailwind\n */\n\nimport { useCubeContext } from '../../providers/CubeProvider'\nimport type { ChartProps } from '../../types'\n\nexport default function DataTable({ \n data, \n chartConfig,\n height = 300 \n}: ChartProps) {\n const { getFieldLabel } = useCubeContext()\n \n if (!data || data.length === 0) {\n return (\n <div\n className=\"flex items-center justify-center w-full\"\n style={{ height }}\n >\n <div className=\"text-center text-dc-text-muted\">\n <div className=\"text-sm font-semibold mb-1\">No data available</div>\n <div className=\"text-xs text-dc-text-secondary\">No data to display in table</div>\n </div>\n </div>\n )\n }\n\n // Use chartConfig.xAxis to filter columns, or show all if not specified\n const allColumns = Object.keys(data[0] || {})\n const columns = chartConfig?.xAxis && chartConfig.xAxis.length > 0 \n ? chartConfig.xAxis.filter(col => allColumns.includes(col))\n : allColumns\n\n if (columns.length === 0) {\n return (\n <div\n className=\"flex items-center justify-center w-full\"\n style={{ height }}\n >\n <div className=\"text-center text-dc-text-muted\">\n <div className=\"text-sm font-semibold mb-1\">No columns available</div>\n <div className=\"text-xs text-dc-text-secondary\">Data structure is invalid</div>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"w-full overflow-auto\" style={{ height }}>\n <table className=\"min-w-full divide-y border-dc-border\">\n <thead className=\"bg-dc-surface-secondary sticky top-0\">\n <tr>\n {columns.map((column) => (\n <th\n key={column}\n className=\"px-3 py-2 text-left text-xs font-medium text-dc-text-muted uppercase tracking-wider\"\n >\n {getFieldLabel(column)}\n </th>\n ))}\n </tr>\n </thead>\n <tbody className=\"bg-dc-surface 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=\"px-3 py-2 whitespace-nowrap text-sm text-dc-text\"\n >\n {formatCellValue(row[column])}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )\n}\n\nfunction formatCellValue(value: any): string {\n if (value == null) return ''\n if (typeof value === 'number') {\n return value.toLocaleString()\n }\n if (typeof value === 'boolean') {\n return value ? 'Yes' : 'No'\n }\n return String(value)\n}"],"names":["DataTable","data","chartConfig","height","getFieldLabel","useCubeContext","jsx","jsxs","allColumns","columns","col","column","row","index","formatCellValue","value"],"mappings":";;AAQA,SAAwBA,EAAU;AAAA,EAChC,MAAAC;AAAA,EACA,aAAAC;AAAA,EACA,QAAAC,IAAS;AACX,GAAe;AACb,QAAM,EAAE,eAAAC,EAAA,IAAkBC,EAAA;AAE1B,MAAI,CAACJ,KAAQA,EAAK,WAAW;AAC3B,WACE,gBAAAK;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAO,EAAE,QAAAH,EAAA;AAAA,QAET,UAAA,gBAAAI,EAAC,OAAA,EAAI,WAAU,kCACb,UAAA;AAAA,UAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,qBAAiB;AAAA,UAC7D,gBAAAA,EAAC,OAAA,EAAI,WAAU,kCAAiC,UAAA,8BAAA,CAA2B;AAAA,QAAA,EAAA,CAC7E;AAAA,MAAA;AAAA,IAAA;AAMN,QAAME,IAAa,OAAO,KAAKP,EAAK,CAAC,KAAK,EAAE,GACtCQ,IAAUP,GAAa,SAASA,EAAY,MAAM,SAAS,IAC7DA,EAAY,MAAM,OAAO,CAAAQ,MAAOF,EAAW,SAASE,CAAG,CAAC,IACxDF;AAEJ,SAAIC,EAAQ,WAAW,IAEnB,gBAAAH;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,QAAAH,EAAA;AAAA,MAET,UAAA,gBAAAI,EAAC,OAAA,EAAI,WAAU,kCACb,UAAA;AAAA,QAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,wBAAoB;AAAA,QAChE,gBAAAA,EAAC,OAAA,EAAI,WAAU,kCAAiC,UAAA,4BAAA,CAAyB;AAAA,MAAA,EAAA,CAC3E;AAAA,IAAA;AAAA,EAAA,IAMJ,gBAAAA,EAAC,OAAA,EAAI,WAAU,wBAAuB,OAAO,EAAE,QAAAH,EAAA,GAC7C,UAAA,gBAAAI,EAAC,SAAA,EAAM,WAAU,wCACf,UAAA;AAAA,IAAA,gBAAAD,EAAC,SAAA,EAAM,WAAU,wCACf,UAAA,gBAAAA,EAAC,QACE,UAAAG,EAAQ,IAAI,CAACE,MACZ,gBAAAL;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,WAAU;AAAA,QAET,YAAcK,CAAM;AAAA,MAAA;AAAA,MAHhBA;AAAA,IAAA,CAKR,GACH,EAAA,CACF;AAAA,sBACC,SAAA,EAAM,WAAU,2CACd,UAAAV,EAAK,IAAI,CAACW,GAAKC,MACd,gBAAAP,EAAC,QAAe,WAAU,iCACvB,UAAAG,EAAQ,IAAI,CAACE,MACZ,gBAAAL;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,WAAU;AAAA,QAET,UAAAQ,EAAgBF,EAAID,CAAM,CAAC;AAAA,MAAA;AAAA,MAHvBA;AAAA,IAAA,CAKR,EAAA,GARME,CAST,CACD,EAAA,CACH;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;AAEA,SAASC,EAAgBC,GAAoB;AAC3C,SAAIA,KAAS,OAAa,KACtB,OAAOA,KAAU,WACZA,EAAM,eAAA,IAEX,OAAOA,KAAU,YACZA,IAAQ,QAAQ,OAElB,OAAOA,CAAK;AACrB;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as a, jsxs as c } from "react/jsx-runtime";
|
|
2
2
|
import { useState as K, useRef as _, useEffect as te } from "react";
|
|
3
3
|
import { I as ne, f as se } from "./icons-D-n_woAP.js";
|
|
4
|
-
import { u as re } from "./chart-activitygridchart-
|
|
4
|
+
import { u as re } from "./chart-activitygridchart-B5OqLgbD.js";
|
|
5
5
|
function ie(s, r) {
|
|
6
6
|
const e = new Date(s);
|
|
7
7
|
switch (r.toLowerCase()) {
|
|
@@ -431,4 +431,4 @@ export {
|
|
|
431
431
|
pe as K,
|
|
432
432
|
ce as f
|
|
433
433
|
};
|
|
434
|
-
//# sourceMappingURL=chart-kpidelta-
|
|
434
|
+
//# sourceMappingURL=chart-kpidelta-B1zg2dTx.js.map
|