drizzle-cube 0.4.21 → 0.4.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/dist/client/charts.js +12 -12
  2. package/dist/client/chunks/{RetentionCombinedChart-CLq89aOJ.js → RetentionCombinedChart-BK3NPsHP.js} +2 -2
  3. package/dist/client/chunks/{RetentionCombinedChart-CLq89aOJ.js.map → RetentionCombinedChart-BK3NPsHP.js.map} +1 -1
  4. package/dist/client/chunks/{analysis-builder-3z9fHE2F.js → analysis-builder-DVrv9Q4n.js} +9 -9
  5. package/dist/client/chunks/{analysis-builder-3z9fHE2F.js.map → analysis-builder-DVrv9Q4n.js.map} +1 -1
  6. package/dist/client/chunks/{analysis-builder-shared-Da-vlQa_.js → analysis-builder-shared-CrENEvEk.js} +6 -6
  7. package/dist/client/chunks/{analysis-builder-shared-Da-vlQa_.js.map → analysis-builder-shared-CrENEvEk.js.map} +1 -1
  8. package/dist/client/chunks/{chart-activity-grid-CPGcTSuh.js → chart-activity-grid-OG6he4YS.js} +2 -2
  9. package/dist/client/chunks/{chart-activity-grid-CPGcTSuh.js.map → chart-activity-grid-OG6he4YS.js.map} +1 -1
  10. package/dist/client/chunks/{chart-area-ByJQ7NZd.js → chart-area-TawAd2k9.js} +3 -3
  11. package/dist/client/chunks/{chart-area-ByJQ7NZd.js.map → chart-area-TawAd2k9.js.map} +1 -1
  12. package/dist/client/chunks/{chart-bar-dj14frMt.js → chart-bar-D3vtCNQG.js} +2 -2
  13. package/dist/client/chunks/{chart-bar-dj14frMt.js.map → chart-bar-D3vtCNQG.js.map} +1 -1
  14. package/dist/client/chunks/{chart-box-plot-ZatBpatq.js → chart-box-plot-BXwN2rO5.js} +2 -2
  15. package/dist/client/chunks/{chart-box-plot-ZatBpatq.js.map → chart-box-plot-BXwN2rO5.js.map} +1 -1
  16. package/dist/client/chunks/{chart-bubble-CemotLx-.js → chart-bubble-ZfNe8t5k.js} +2 -2
  17. package/dist/client/chunks/{chart-bubble-CemotLx-.js.map → chart-bubble-ZfNe8t5k.js.map} +1 -1
  18. package/dist/client/chunks/{chart-candlestick-BIR4uGGt.js → chart-candlestick-DmF3haFu.js} +2 -2
  19. package/dist/client/chunks/{chart-candlestick-BIR4uGGt.js.map → chart-candlestick-DmF3haFu.js.map} +1 -1
  20. package/dist/client/chunks/{chart-data-table-BsAjHe7o.js → chart-data-table-DJZPkArt.js} +4 -4
  21. package/dist/client/chunks/{chart-data-table-BsAjHe7o.js.map → chart-data-table-DJZPkArt.js.map} +1 -1
  22. package/dist/client/chunks/{chart-funnel-dofnhD24.js → chart-funnel-CE9x0Io9.js} +2 -2
  23. package/dist/client/chunks/{chart-funnel-dofnhD24.js.map → chart-funnel-CE9x0Io9.js.map} +1 -1
  24. package/dist/client/chunks/{chart-gauge-CKJJ8m3b.js → chart-gauge-Djs5FWxB.js} +2 -2
  25. package/dist/client/chunks/{chart-gauge-CKJJ8m3b.js.map → chart-gauge-Djs5FWxB.js.map} +1 -1
  26. package/dist/client/chunks/{chart-heat-map-BVuPUKHT.js → chart-heat-map-CqtMkdxd.js} +2 -2
  27. package/dist/client/chunks/{chart-heat-map-BVuPUKHT.js.map → chart-heat-map-CqtMkdxd.js.map} +1 -1
  28. package/dist/client/chunks/{chart-kpi-delta-DUD3f8vL.js → chart-kpi-delta-DEzA74cL.js} +4 -4
  29. package/dist/client/chunks/{chart-kpi-delta-DUD3f8vL.js.map → chart-kpi-delta-DEzA74cL.js.map} +1 -1
  30. package/dist/client/chunks/{chart-kpi-number-iJh-PzsM.js → chart-kpi-number-Bab-BZtX.js} +3 -3
  31. package/dist/client/chunks/{chart-kpi-number-iJh-PzsM.js.map → chart-kpi-number-Bab-BZtX.js.map} +1 -1
  32. package/dist/client/chunks/{chart-kpi-text-x6pV9v9Q.js → chart-kpi-text-BkTgckDJ.js} +3 -3
  33. package/dist/client/chunks/{chart-kpi-text-x6pV9v9Q.js.map → chart-kpi-text-BkTgckDJ.js.map} +1 -1
  34. package/dist/client/chunks/{chart-line-DzyZkugh.js → chart-line-DhM-Hvu0.js} +3 -3
  35. package/dist/client/chunks/{chart-line-DzyZkugh.js.map → chart-line-DhM-Hvu0.js.map} +1 -1
  36. package/dist/client/chunks/{chart-measure-profile-C2IkBG3V.js → chart-measure-profile-4vQxFm69.js} +3 -3
  37. package/dist/client/chunks/{chart-measure-profile-C2IkBG3V.js.map → chart-measure-profile-4vQxFm69.js.map} +1 -1
  38. package/dist/client/chunks/{chart-pie-akbfRfb9.js → chart-pie-B86KRcHI.js} +2 -2
  39. package/dist/client/chunks/{chart-pie-akbfRfb9.js.map → chart-pie-B86KRcHI.js.map} +1 -1
  40. package/dist/client/chunks/{chart-radar-BaN-Kjww.js → chart-radar-BhDBmJRh.js} +2 -2
  41. package/dist/client/chunks/{chart-radar-BaN-Kjww.js.map → chart-radar-BhDBmJRh.js.map} +1 -1
  42. package/dist/client/chunks/{chart-radial-bar-DpptEL3s.js → chart-radial-bar-Brugya8X.js} +2 -2
  43. package/dist/client/chunks/{chart-radial-bar-DpptEL3s.js.map → chart-radial-bar-Brugya8X.js.map} +1 -1
  44. package/dist/client/chunks/{chart-sankey-CG-3hHmX.js → chart-sankey-D2L8ympI.js} +2 -2
  45. package/dist/client/chunks/{chart-sankey-CG-3hHmX.js.map → chart-sankey-D2L8ympI.js.map} +1 -1
  46. package/dist/client/chunks/{chart-scatter-l_yTVxF3.js → chart-scatter-CAkbBDkK.js} +2 -2
  47. package/dist/client/chunks/{chart-scatter-l_yTVxF3.js.map → chart-scatter-CAkbBDkK.js.map} +1 -1
  48. package/dist/client/chunks/{chart-sunburst-KhDcKhmZ.js → chart-sunburst-DaxJ-cob.js} +2 -2
  49. package/dist/client/chunks/{chart-sunburst-KhDcKhmZ.js.map → chart-sunburst-DaxJ-cob.js.map} +1 -1
  50. package/dist/client/chunks/{chart-tree-map-CBbiaBXV.js → chart-tree-map-CrDJAvZU.js} +2 -2
  51. package/dist/client/chunks/{chart-tree-map-CBbiaBXV.js.map → chart-tree-map-CrDJAvZU.js.map} +1 -1
  52. package/dist/client/chunks/{chart-waterfall-CX3vx_lI.js → chart-waterfall-BBwSfEKT.js} +3 -3
  53. package/dist/client/chunks/{chart-waterfall-CX3vx_lI.js.map → chart-waterfall-BBwSfEKT.js.map} +1 -1
  54. package/dist/client/chunks/{charts-core-CU9u_HtL.js → charts-core-B4Rbfdcn.js} +2 -2
  55. package/dist/client/chunks/{charts-core-CU9u_HtL.js.map → charts-core-B4Rbfdcn.js.map} +1 -1
  56. package/dist/client/chunks/{charts-loader-B3tt5oKG.js → charts-loader-DbrwgvCK.js} +25 -25
  57. package/dist/client/chunks/{charts-loader-B3tt5oKG.js.map → charts-loader-DbrwgvCK.js.map} +1 -1
  58. package/dist/client/chunks/{components-CMGGxqOB.js → components-GzooQM5J.js} +9 -9
  59. package/dist/client/chunks/{components-CMGGxqOB.js.map → components-GzooQM5J.js.map} +1 -1
  60. package/dist/client/chunks/{core-D_8mkGpQ.js → core-Y9e-sNfb.js} +2 -2
  61. package/dist/client/chunks/{core-D_8mkGpQ.js.map → core-Y9e-sNfb.js.map} +1 -1
  62. package/dist/client/chunks/{icons-M7shurcH.js → icons-DFJw-2HU.js} +6 -6
  63. package/dist/client/chunks/{icons-M7shurcH.js.map → icons-DFJw-2HU.js.map} +1 -1
  64. package/dist/client/chunks/{providers-CgxXm6Ll.js → providers-CCw8Kjlc.js} +2 -2
  65. package/dist/client/chunks/{providers-CgxXm6Ll.js.map → providers-CCw8Kjlc.js.map} +1 -1
  66. package/dist/client/chunks/{syntaxHighlighting-BQfjio-i.js → syntaxHighlighting-DAMSW_A6.js} +2 -2
  67. package/dist/client/chunks/{syntaxHighlighting-BQfjio-i.js.map → syntaxHighlighting-DAMSW_A6.js.map} +1 -1
  68. package/dist/client/chunks/{useDirtyStateTracking-Cu1HSjmo.js → useDirtyStateTracking-CjhwBXRw.js} +20 -20
  69. package/dist/client/chunks/{useDirtyStateTracking-Cu1HSjmo.js.map → useDirtyStateTracking-CjhwBXRw.js.map} +1 -1
  70. package/dist/client/chunks/useExplainAI-IiW55BaQ.js +182 -0
  71. package/dist/client/chunks/useExplainAI-IiW55BaQ.js.map +1 -0
  72. package/dist/client/chunks/{vendor-AVsJ2ni0.js → vendor-B2EH3V58.js} +7 -7
  73. package/dist/client/chunks/{vendor-AVsJ2ni0.js.map → vendor-B2EH3V58.js.map} +1 -1
  74. package/dist/client/components.js +1 -1
  75. package/dist/client/hooks/useNotebookLayout.d.ts +8 -0
  76. package/dist/client/hooks.d.ts +2 -0
  77. package/dist/client/hooks.js +51 -190
  78. package/dist/client/hooks.js.map +1 -1
  79. package/dist/client/icons.js +1 -1
  80. package/dist/client/index.js +871 -742
  81. package/dist/client/index.js.map +1 -1
  82. package/dist/client/providers.js +1 -1
  83. package/dist/client/styles.css +1 -1
  84. package/dist/client/utils.js +7 -7
  85. package/dist/client-bundle-stats.html +1 -1
  86. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"charts-core-CU9u_HtL.js","sources":["../../../src/client/components/LoadingIndicator.tsx","../../../src/client/components/AnalysisBuilder/SectionHeading.tsx","../../../src/client/utils/chartUtils.ts","../../../src/client/components/charts/AxisFormatControls.tsx","../../../src/client/hooks/useCubeFieldLabel.ts","../../../src/client/utils/chartConstants.ts","../../../src/client/components/charts/ChartContainer.tsx","../../../src/client/components/charts/ChartTooltip.tsx","../../../src/client/utils/targetUtils.ts"],"sourcesContent":["/**\n * LoadingIndicator Component\n *\n * A centralized, theme-aware loading spinner that uses CSS variables\n * for consistent styling across all drizzle-cube components.\n *\n * Can be overridden at the Dashboard or Portlet level by passing a\n * custom loadingComponent prop.\n */\n\nexport interface LoadingIndicatorProps {\n /** Size variant: 'xs' (12px), 'sm' (24px), 'md' (32px), 'lg' (48px) */\n size?: 'xs' | 'sm' | 'md' | 'lg'\n /** Additional CSS classes */\n className?: string\n}\n\nconst sizeClasses = {\n xs: 'dc:h-3 dc:w-3',\n sm: 'dc:h-6 dc:w-6',\n md: 'dc:h-8 dc:w-8',\n lg: 'dc:h-12 dc:w-12'\n}\n\nexport default function LoadingIndicator({\n size = 'md',\n className = ''\n}: LoadingIndicatorProps) {\n return (\n <div\n className={`dc:animate-spin dc:rounded-full dc:border-b-2 ${sizeClasses[size]} ${className}`}\n style={{ borderBottomColor: 'var(--dc-primary)' }}\n role=\"status\"\n aria-label=\"Loading\"\n />\n )\n}\n","/**\n * SectionHeading Component\n *\n * A reusable section heading for the Analysis Builder panels.\n * Provides consistent styling that can be easily adjusted in one place.\n */\n\nimport type { ReactNode } from 'react'\n\ninterface SectionHeadingProps {\n children: ReactNode\n /** Optional className to add additional styles */\n className?: string\n}\n\n/**\n * Consistent section heading style for Analysis Builder panels.\n * Change the styles here to update all section headings at once.\n */\nexport default function SectionHeading({ children, className = '' }: SectionHeadingProps) {\n return (\n <h3 className={`dc:text-sm dc:font-semibold text-dc-primary dc:uppercase dc:tracking-wide ${className}`}>\n {children}\n </h3>\n )\n}\n","import type { FieldLabelMap, AxisFormatConfig } from '../types'\n\n// Utility function to check if a value is a valid numeric value (not null, undefined, or NaN)\n// This is used to preserve null values instead of converting them to 0\nexport function isValidNumericValue(value: any): boolean {\n return value !== null && value !== undefined && !isNaN(Number(value))\n}\n\n// Utility function to parse numeric value from data, preserving nulls\n// Returns null for null/undefined/NaN values, otherwise returns the numeric value\nexport function parseNumericValue(value: any): number | null {\n if (value === null || value === undefined) return null\n const num = typeof value === 'string' ? parseFloat(value) : Number(value)\n return isNaN(num) ? null : num\n}\n\n// Utility function to format numeric values for display in charts\n// Rounds to at most 2 decimal places, preserves integers\nexport function formatNumericValue(value: any): string {\n if (value === null || value === undefined) return 'No data'\n const num = typeof value === 'number' ? value : parseFloat(value)\n if (isNaN(num)) return String(value)\n if (Number.isInteger(num)) return num.toLocaleString()\n // Round to at most 2 decimal places, remove trailing zeros\n return parseFloat(num.toFixed(2)).toLocaleString()\n}\n\n/**\n * Format a numeric value for axis/tooltip display with configurable formatting\n *\n * @param value - The numeric value to format\n * @param config - Optional formatting configuration\n * @param locale - Optional locale string (defaults to browser locale)\n * @returns Formatted string representation of the value\n *\n * @example\n * formatAxisValue(1250000, { unit: 'currency', abbreviate: true }) // \"$1.25M\"\n * formatAxisValue(0.75, { unit: 'percent', decimals: 1 }) // \"75.0%\"\n * formatAxisValue(1234567, { abbreviate: true, decimals: 2 }) // \"1.23M\"\n */\nexport function formatAxisValue(\n value: number | null | undefined,\n config?: AxisFormatConfig,\n locale?: string\n): string {\n // Handle null/undefined\n if (value === null || value === undefined) {\n return 'No data'\n }\n\n // Handle non-numeric values\n const num = typeof value === 'number' ? value : parseFloat(String(value))\n if (isNaN(num)) {\n return String(value)\n }\n\n // Handle special cases\n if (!isFinite(num)) {\n return num > 0 ? '∞' : '-∞'\n }\n\n // Get locale (default to browser locale)\n const effectiveLocale = locale || (typeof navigator !== 'undefined' ? navigator.language : 'en-US')\n\n // If no config provided, use default formatting\n if (!config) {\n return formatNumericValue(value)\n }\n\n const { unit, abbreviate = true, decimals, customPrefix, customSuffix } = config\n\n // Calculate the display value and suffix for abbreviation\n // Default to true for abbreviation when config is provided\n let displayValue = num\n let abbreviationSuffix = ''\n\n if (abbreviate) {\n const absNum = Math.abs(num)\n if (absNum >= 1_000_000_000) {\n displayValue = num / 1_000_000_000\n abbreviationSuffix = 'B'\n } else if (absNum >= 1_000_000) {\n displayValue = num / 1_000_000\n abbreviationSuffix = 'M'\n } else if (absNum >= 1_000) {\n displayValue = num / 1_000\n abbreviationSuffix = 'K'\n }\n }\n\n // Determine decimal places\n // If decimals is undefined, use auto (2 for non-integers, 0 for integers after abbreviation)\n const effectiveDecimals = decimals !== undefined\n ? decimals\n : (Number.isInteger(displayValue) ? 0 : 2)\n\n // Format based on unit type\n switch (unit) {\n case 'currency': {\n // Use Intl.NumberFormat for currency\n // Currency code is determined by locale (USD for en-US, EUR for de-DE, etc.)\n const currencyCode = getCurrencyCodeForLocale(effectiveLocale)\n\n if (abbreviate && abbreviationSuffix) {\n // For abbreviated currency, format the number part and add suffix\n const formatted = new Intl.NumberFormat(effectiveLocale, {\n style: 'currency',\n currency: currencyCode,\n minimumFractionDigits: effectiveDecimals,\n maximumFractionDigits: effectiveDecimals,\n }).format(displayValue)\n // Insert abbreviation suffix before any trailing currency symbol or at end\n // Handle both \"$1.25\" -> \"$1.25M\" and \"1.25 €\" -> \"1.25M €\"\n const parts = new Intl.NumberFormat(effectiveLocale, {\n style: 'currency',\n currency: currencyCode,\n }).formatToParts(displayValue)\n const hasTrailingCurrency = parts[parts.length - 1]?.type === 'currency'\n if (hasTrailingCurrency) {\n // Currency symbol is at the end (e.g., \"1.25 €\")\n return formatted.replace(/(\\s*[^\\d\\s]+)$/, abbreviationSuffix + '$1')\n }\n return formatted + abbreviationSuffix\n }\n\n return new Intl.NumberFormat(effectiveLocale, {\n style: 'currency',\n currency: currencyCode,\n minimumFractionDigits: effectiveDecimals,\n maximumFractionDigits: effectiveDecimals,\n }).format(displayValue)\n }\n\n case 'percent': {\n // Format as percentage (multiply by 100 if value is 0-1 range, otherwise use as-is)\n // Assume values > 1 are already percentages, values <= 1 need multiplication\n const percentValue = Math.abs(displayValue) <= 1 && !abbreviate ? displayValue * 100 : displayValue\n const formatted = new Intl.NumberFormat(effectiveLocale, {\n minimumFractionDigits: effectiveDecimals,\n maximumFractionDigits: effectiveDecimals,\n }).format(percentValue)\n return formatted + abbreviationSuffix + '%'\n }\n\n case 'custom': {\n // Apply custom prefix/suffix\n const prefix = customPrefix || ''\n const suffix = customSuffix || ''\n const formatted = new Intl.NumberFormat(effectiveLocale, {\n minimumFractionDigits: effectiveDecimals,\n maximumFractionDigits: effectiveDecimals,\n }).format(displayValue)\n return prefix + formatted + abbreviationSuffix + suffix\n }\n\n case 'number':\n default: {\n // Standard number formatting with locale-aware grouping\n const formatted = new Intl.NumberFormat(effectiveLocale, {\n minimumFractionDigits: effectiveDecimals,\n maximumFractionDigits: effectiveDecimals,\n }).format(displayValue)\n return formatted + abbreviationSuffix\n }\n }\n}\n\n/**\n * Get the currency code for a given locale\n * Maps common locales to their default currency\n */\nfunction getCurrencyCodeForLocale(locale: string): string {\n // Extract language and region from locale (e.g., \"en-US\" -> [\"en\", \"US\"])\n const parts = locale.split('-')\n const region = parts[1]?.toUpperCase()\n\n // Map regions to currencies\n const currencyMap: Record<string, string> = {\n 'US': 'USD',\n 'CA': 'CAD',\n 'GB': 'GBP',\n 'UK': 'GBP',\n 'AU': 'AUD',\n 'NZ': 'NZD',\n 'EU': 'EUR',\n 'DE': 'EUR',\n 'FR': 'EUR',\n 'IT': 'EUR',\n 'ES': 'EUR',\n 'NL': 'EUR',\n 'BE': 'EUR',\n 'AT': 'EUR',\n 'IE': 'EUR',\n 'PT': 'EUR',\n 'FI': 'EUR',\n 'JP': 'JPY',\n 'CN': 'CNY',\n 'KR': 'KRW',\n 'IN': 'INR',\n 'BR': 'BRL',\n 'MX': 'MXN',\n 'CH': 'CHF',\n 'SE': 'SEK',\n 'NO': 'NOK',\n 'DK': 'DKK',\n 'PL': 'PLN',\n 'RU': 'RUB',\n 'ZA': 'ZAR',\n 'SG': 'SGD',\n 'HK': 'HKD',\n 'TW': 'TWD',\n 'TH': 'THB',\n 'MY': 'MYR',\n 'PH': 'PHP',\n 'ID': 'IDR',\n 'VN': 'VND',\n 'AE': 'AED',\n 'SA': 'SAR',\n 'IL': 'ILS',\n 'TR': 'TRY',\n }\n\n return currencyMap[region] || 'USD'\n}\n\n/**\n * Create a tick formatter function for Recharts axes\n * Returns a function that can be used as tickFormatter prop\n */\nexport function createAxisTickFormatter(config?: AxisFormatConfig): (value: any) => string {\n return (value: any) => formatAxisValue(value, config)\n}\n\n// Utility function to get field label from field name\nexport function getFieldLabel(fieldName: string, labelMap: FieldLabelMap): string {\n return labelMap[fieldName] || fieldName\n}\n\n// Utility function to transform series keys to use labels\nexport function transformSeriesKeysWithLabels(seriesKeys: string[], labelMap: FieldLabelMap): string[] {\n return seriesKeys.map(key => getFieldLabel(key, labelMap))\n}\n\n// Utility function to format time values for better display using known granularity\nexport function formatTimeValue(value: any, granularity?: string): string {\n if (!value) return String(value || 'Unknown')\n \n const str = String(value)\n \n // Check if it's a timestamp (ISO format or PostgreSQL format)\n // Handles formats like: \"2025-04-01T00:00:00.000\" or \"2023-02-01 00:00:00+00\"\n if (str.match(/^\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}:\\d{2}/)) {\n // Convert PostgreSQL format to ISO format if needed\n let isoStr = str\n if (str.includes(' ')) {\n // Convert \"2023-02-01 00:00:00+00\" to \"2023-02-01T00:00:00Z\"\n isoStr = str.replace(' ', 'T').replace('+00', 'Z').replace(/\\+\\d{2}:\\d{2}$/, 'Z')\n }\n // Ensure the timestamp ends with 'Z' if not present\n if (!isoStr.endsWith('Z') && !isoStr.includes('+')) {\n isoStr = isoStr + 'Z'\n }\n const date = new Date(isoStr)\n \n // Ensure we're working with valid date\n if (isNaN(date.getTime())) {\n return str\n }\n \n // Use UTC methods on the properly UTC-parsed date\n const year = date.getUTCFullYear()\n const month = String(date.getUTCMonth() + 1).padStart(2, '0')\n const day = String(date.getUTCDate()).padStart(2, '0')\n const hours = date.getUTCHours()\n const minutes = date.getUTCMinutes()\n \n // Format based on known granularity if provided\n if (granularity) {\n switch (granularity.toLowerCase()) {\n case 'year':\n return `${year}`\n case 'quarter': {\n const quarter = Math.floor(date.getUTCMonth() / 3) + 1\n return `${year}-Q${quarter}`\n }\n case 'month':\n return `${year}-${month}`\n case 'week':\n // For week, we could calculate week number, but let's use date for simplicity\n return `${year}-${month}-${day}`\n case 'day':\n return `${year}-${month}-${day}`\n case 'hour':\n return `${year}-${month}-${day} ${String(hours).padStart(2, '0')}:00`\n case 'minute':\n return `${year}-${month}-${day} ${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}`\n default:\n // Unknown granularity, fall back to heuristic\n break\n }\n }\n \n // Fallback heuristic if granularity not provided or unknown\n const seconds = date.getUTCSeconds()\n const milliseconds = date.getUTCMilliseconds()\n \n // If it's the first day of the month at exactly midnight UTC, it's likely a month granularity\n if (day === '01' && hours === 0 && minutes === 0 && seconds === 0 && milliseconds === 0) {\n // Check if it's also first month of a quarter (quarter granularity)\n if (month === '01' || month === '04' || month === '07' || month === '10') {\n const quarter = Math.floor(date.getUTCMonth() / 3) + 1\n return `${year}-Q${quarter}`\n }\n // Month granularity\n return `${year}-${month}`\n }\n \n // If it's exactly midnight UTC, it's likely a day granularity\n if (hours === 0 && minutes === 0 && seconds === 0 && milliseconds === 0) {\n return `${year}-${month}-${day}`\n }\n \n // If it has time components, include them (hour/minute granularity)\n if (minutes === 0 && seconds === 0 && milliseconds === 0) {\n // Hour granularity\n return `${year}-${month}-${day} ${String(hours).padStart(2, '0')}:00`\n }\n \n // Full timestamp\n return `${year}-${month}-${day} ${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}`\n }\n \n // Return as-is if not a timestamp\n return str\n}\n\n// Helper function to get granularity for a field from the query timeDimensions\nexport function getFieldGranularity(queryObject: any, fieldName: string): string | undefined {\n try {\n if (queryObject?.timeDimensions) {\n // Find the timeDimension that matches this field\n const timeDim = queryObject.timeDimensions.find((td: any) => {\n // Check if field name matches the dimension or dimension with granularity suffix\n return fieldName === td.dimension || \n fieldName.startsWith(td.dimension.replace('.', '_')) ||\n fieldName === `${td.dimension}_${td.granularity}`\n })\n \n if (timeDim?.granularity) {\n return timeDim.granularity\n }\n }\n \n // Fallback: extract granularity from field name suffix if present\n const granularityMatch = fieldName.match(/_([a-z]+)$/)\n if (granularityMatch) {\n const suffix = granularityMatch[1]\n // Only return if it's a valid granularity\n if (['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second'].includes(suffix)) {\n return suffix\n }\n }\n \n return undefined\n } catch {\n return undefined\n }\n}\n\n// Transform data for charts with proper type handling\n// NOTE: Preserves null values to allow charts to handle gaps/missing data appropriately\nexport function transformChartData(\n data: any[],\n xAxisField: string,\n yAxisFields: string[],\n queryObject: any,\n getFieldLabelFn: (fieldName: string) => string = (fieldName) => fieldName\n) {\n if (!data || data.length === 0) return []\n\n const granularity = getFieldGranularity(queryObject, xAxisField)\n\n return data.map((row: any) => {\n const transformed: any = {\n name: formatTimeValue(row[xAxisField], granularity) || row[xAxisField] || 'Unknown',\n }\n\n yAxisFields.forEach(field => {\n const displayName = getFieldLabelFn(field)\n // Preserve null values instead of converting to 0\n transformed[displayName] = parseNumericValue(row[field])\n })\n\n return transformed\n })\n}\n\nexport interface ChartSeriesResult {\n data: any[]\n seriesKeys: string[]\n hasDimensions: boolean\n}\n\n// Advanced data transformation that handles both measures and dimensions on Y-axis\n// NOTE: Preserves null values to allow charts to handle gaps/missing data appropriately\nexport function transformChartDataWithSeries(\n data: any[],\n xAxisField: string,\n yAxisFields: string[],\n queryObject: any,\n seriesFields?: string[], // New optional parameter for explicit series fields\n getFieldLabelFn: (fieldName: string) => string = (fieldName) => fieldName // Function to get field labels\n): ChartSeriesResult {\n if (!data || data.length === 0) {\n return { data: [], seriesKeys: [], hasDimensions: false }\n }\n\n const originalQuery = queryObject || {}\n const queryDimensions = [\n ...(originalQuery.dimensions || []),\n ...(originalQuery.timeDimensions?.map((td: any) => td.dimension) || [])\n ]\n const queryMeasures = originalQuery.measures || []\n\n // Use explicit series fields if provided, otherwise no dimension-based series\n const yAxisMeasures = yAxisFields.filter(field => queryMeasures.includes(field))\n const yAxisDimensions = (seriesFields || []).filter(field => queryDimensions.includes(field))\n\n // Handle complex case with dimensions on Y-axis\n if (yAxisDimensions.length > 0) {\n // Group data by X-axis field and create separate series for dimension values\n const groupedData: { [key: string]: any } = {}\n\n data.forEach((row: any) => {\n const granularity = getFieldGranularity(queryObject, xAxisField)\n const xValue = formatTimeValue(row[xAxisField], granularity) || row[xAxisField] || 'Unknown'\n if (!groupedData[xValue]) {\n groupedData[xValue] = { name: String(xValue) }\n }\n\n // Add measures - preserve nulls for individual measures\n yAxisMeasures.forEach(measure => {\n const displayName = getFieldLabelFn(measure)\n const measureValue = parseNumericValue(row[measure])\n\n // For aggregation: sum non-null values, preserve null if all are null\n if (measureValue !== null) {\n const currentValue = groupedData[xValue][displayName]\n groupedData[xValue][displayName] = (currentValue === null || currentValue === undefined)\n ? measureValue\n : currentValue + measureValue\n } else if (!(displayName in groupedData[xValue])) {\n // Only set to null if no value exists yet\n groupedData[xValue][displayName] = null\n }\n })\n\n // Add dimensions as separate series (aggregate measure values by dimension)\n yAxisDimensions.forEach(dimension => {\n const dimValue = row[dimension]\n if (dimValue !== undefined && dimValue !== null) {\n const seriesName = String(dimValue)\n // Aggregate the first measure for this dimension value, or use totalCost if available\n const measureToAggregate = yAxisMeasures[0] || queryMeasures.find((m: string) =>\n m.includes('totalCost') || m.includes('count') || m.includes('sum')\n ) || queryMeasures[0]\n\n if (measureToAggregate) {\n const measureValue = parseNumericValue(row[measureToAggregate])\n\n // For dimension series: sum non-null values, preserve null if all are null\n if (measureValue !== null) {\n const currentValue = groupedData[xValue][seriesName]\n groupedData[xValue][seriesName] = (currentValue === null || currentValue === undefined)\n ? measureValue\n : currentValue + measureValue\n } else if (!(seriesName in groupedData[xValue])) {\n // Only set to null if no value exists yet\n groupedData[xValue][seriesName] = null\n }\n }\n }\n })\n })\n \n const chartData = Object.values(groupedData)\n \n // Get all series keys for rendering\n // When dimensions are on Y-axis, only show dimension series, not measures\n // The measures are the values being aggregated for each dimension series\n const dimensionSeries = Array.from(new Set(\n data.flatMap((row: any) => \n yAxisDimensions.map(dimension => {\n const value = row[dimension]\n return value !== undefined && value !== null \n ? String(value)\n : null\n }).filter((value): value is string => value !== null)\n )\n ))\n \n return {\n data: chartData,\n seriesKeys: dimensionSeries,\n hasDimensions: true\n }\n }\n \n // Standard measures-only path\n const chartData = transformChartData(data, xAxisField, yAxisFields, queryObject, getFieldLabelFn)\n const seriesKeys = yAxisFields.map(field => getFieldLabelFn(field))\n \n return {\n data: chartData,\n seriesKeys,\n hasDimensions: false\n }\n}","/**\n * AxisFormatControls Component\n *\n * A reusable component for configuring axis number formatting.\n * Provides controls for unit type, abbreviation, decimal places, and custom labels.\n */\n\nimport { useMemo } from 'react'\nimport SectionHeading from '../AnalysisBuilder/SectionHeading'\nimport type { AxisFormatConfig } from '../../types'\nimport { formatAxisValue } from '../../utils/chartUtils'\n\ninterface AxisFormatControlsProps {\n value: AxisFormatConfig\n onChange: (config: AxisFormatConfig) => void\n axisLabel: string // \"X-Axis\", \"Left Y-Axis\", \"Right Y-Axis\"\n /** Sample value for preview (default: 1250000) */\n previewValue?: number\n}\n\n/**\n * Get the currency symbol for the user's locale\n */\nfunction getLocaleCurrencySymbol(): string {\n const locale = typeof navigator !== 'undefined' ? navigator.language : 'en-US'\n // Format a number as currency and extract just the symbol\n const formatted = new Intl.NumberFormat(locale, {\n style: 'currency',\n currency: getCurrencyCodeForLocale(locale),\n currencyDisplay: 'narrowSymbol'\n }).format(0)\n // Extract the currency symbol (remove digits, spaces, and common separators)\n return formatted.replace(/[\\d.,\\s]/g, '').trim() || '$'\n}\n\n/**\n * Get the currency code for a given locale (duplicated from chartUtils for component isolation)\n */\nfunction getCurrencyCodeForLocale(locale: string): string {\n const parts = locale.split('-')\n const region = parts[1]?.toUpperCase()\n const currencyMap: Record<string, string> = {\n 'US': 'USD', 'CA': 'CAD', 'GB': 'GBP', 'UK': 'GBP', 'AU': 'AUD', 'NZ': 'NZD',\n 'EU': 'EUR', 'DE': 'EUR', 'FR': 'EUR', 'IT': 'EUR', 'ES': 'EUR', 'NL': 'EUR',\n 'BE': 'EUR', 'AT': 'EUR', 'IE': 'EUR', 'PT': 'EUR', 'FI': 'EUR',\n 'JP': 'JPY', 'CN': 'CNY', 'KR': 'KRW', 'IN': 'INR', 'BR': 'BRL', 'MX': 'MXN',\n 'CH': 'CHF', 'SE': 'SEK', 'NO': 'NOK', 'DK': 'DKK', 'PL': 'PLN', 'RU': 'RUB',\n 'ZA': 'ZAR', 'SG': 'SGD', 'HK': 'HKD', 'TW': 'TWD', 'TH': 'THB', 'MY': 'MYR',\n 'PH': 'PHP', 'ID': 'IDR', 'VN': 'VND', 'AE': 'AED', 'SA': 'SAR', 'IL': 'ILS', 'TR': 'TRY',\n }\n return currencyMap[region] || 'USD'\n}\n\n/**\n * Single axis format control section\n */\nexport function AxisFormatControls({\n value,\n onChange,\n axisLabel,\n previewValue = 1250000\n}: AxisFormatControlsProps) {\n const config = useMemo(() => value || {}, [value])\n\n // Get locale-aware currency symbol for the button\n const currencySymbol = useMemo(() => getLocaleCurrencySymbol(), [])\n\n // Generate preview of formatted value\n const preview = useMemo(() => {\n return formatAxisValue(previewValue, config)\n }, [previewValue, config])\n\n const handleChange = (updates: Partial<AxisFormatConfig>) => {\n onChange({ ...config, ...updates })\n }\n\n const unitButtons: Array<{ value: AxisFormatConfig['unit']; label: string }> = [\n { value: 'currency', label: currencySymbol },\n { value: 'percent', label: '%' },\n { value: 'number', label: '#' },\n { value: 'custom', label: 'Custom' }\n ]\n\n return (\n <div className=\"dc:space-y-3 dc:pb-4\">\n {/* Axis Header */}\n <SectionHeading>{axisLabel}</SectionHeading>\n\n {/* Label Input */}\n <div className=\"dc:space-y-1\">\n <label className=\"dc:text-xs text-dc-text-secondary\">Label</label>\n <input\n type=\"text\"\n value={config.label || ''}\n onChange={(e) => handleChange({ label: e.target.value || undefined })}\n placeholder=\"Auto-generated label\"\n className=\"dc:w-full dc:px-2 dc:py-1 dc:text-sm dc:border border-dc-border dc:rounded-sm focus:ring-dc-accent focus:border-dc-accent bg-dc-surface text-dc-text\"\n />\n </div>\n\n {/* Unit Type */}\n <div className=\"dc:space-y-1\">\n <label className=\"dc:text-xs text-dc-text-secondary\">Unit</label>\n <div className=\"dc:flex dc:border border-dc-border dc:rounded-sm dc:overflow-hidden\">\n {unitButtons.map((btn) => (\n <button\n key={btn.value}\n type=\"button\"\n onClick={() => handleChange({ unit: btn.value })}\n className={`dc:flex-1 dc:px-2 dc:py-1.5 dc:text-sm dc:font-medium dc:transition-colors ${\n config.unit === btn.value\n ? 'bg-dc-primary text-white'\n : 'bg-dc-surface text-dc-text hover:bg-dc-border'\n }`}\n >\n {btn.label}\n </button>\n ))}\n </div>\n </div>\n\n {/* Custom Prefix/Suffix (only when Custom is selected) */}\n {config.unit === 'custom' && (\n <div className=\"dc:flex dc:gap-2\">\n <div className=\"dc:flex-1 dc:space-y-1\">\n <label className=\"dc:text-xs text-dc-text-secondary\">Prefix</label>\n <input\n type=\"text\"\n value={config.customPrefix || ''}\n onChange={(e) => handleChange({ customPrefix: e.target.value || undefined })}\n placeholder=\"e.g., $\"\n className=\"dc:w-full dc:px-2 dc:py-1 dc:text-sm dc:border border-dc-border dc:rounded-sm focus:ring-dc-accent focus:border-dc-accent bg-dc-surface text-dc-text\"\n />\n </div>\n <div className=\"dc:flex-1 dc:space-y-1\">\n <label className=\"dc:text-xs text-dc-text-secondary\">Suffix</label>\n <input\n type=\"text\"\n value={config.customSuffix || ''}\n onChange={(e) => handleChange({ customSuffix: e.target.value || undefined })}\n placeholder=\"e.g., units\"\n className=\"dc:w-full dc:px-2 dc:py-1 dc:text-sm dc:border border-dc-border dc:rounded-sm focus:ring-dc-accent focus:border-dc-accent bg-dc-surface text-dc-text\"\n />\n </div>\n </div>\n )}\n\n {/* Abbreviation Toggle */}\n <div className=\"dc:space-y-1\">\n <label className=\"dc:text-xs text-dc-text-secondary\">Abbreviation</label>\n <div className=\"dc:flex dc:border border-dc-border dc:rounded-sm dc:overflow-hidden\">\n <button\n type=\"button\"\n onClick={() => handleChange({ abbreviate: true })}\n className={`dc:flex-1 dc:px-3 dc:py-1.5 dc:text-sm dc:font-medium dc:transition-colors ${\n config.abbreviate !== false\n ? 'bg-dc-primary text-white'\n : 'bg-dc-surface text-dc-text hover:bg-dc-border'\n }`}\n >\n Yes\n </button>\n <button\n type=\"button\"\n onClick={() => handleChange({ abbreviate: false })}\n className={`dc:flex-1 dc:px-3 dc:py-1.5 dc:text-sm dc:font-medium dc:transition-colors ${\n config.abbreviate === false\n ? 'bg-dc-primary text-white'\n : 'bg-dc-surface text-dc-text hover:bg-dc-border'\n }`}\n >\n No\n </button>\n </div>\n </div>\n\n {/* Decimals */}\n <div className=\"dc:space-y-1\">\n <label className=\"dc:text-xs text-dc-text-secondary\">Decimals</label>\n <div className=\"dc:flex dc:gap-2\">\n <button\n type=\"button\"\n onClick={() => {\n const current = config.decimals ?? 2\n if (current > 0) handleChange({ decimals: current - 1 })\n }}\n disabled={(config.decimals ?? 2) <= 0}\n className=\"dc:flex-1 dc:px-3 dc:py-2 dc:text-sm dc:border border-dc-border dc:rounded-sm bg-dc-surface text-dc-text hover:bg-dc-border dc:disabled:opacity-40 dc:disabled:cursor-not-allowed dc:transition-colors\"\n >\n ← .0\n </button>\n <button\n type=\"button\"\n onClick={() => {\n const current = config.decimals ?? 2\n if (current < 4) handleChange({ decimals: current + 1 })\n }}\n disabled={(config.decimals ?? 2) >= 4}\n className=\"dc:flex-1 dc:px-3 dc:py-2 dc:text-sm dc:border border-dc-border dc:rounded-sm bg-dc-surface text-dc-text hover:bg-dc-border dc:disabled:opacity-40 dc:disabled:cursor-not-allowed dc:transition-colors\"\n >\n .00 →\n </button>\n </div>\n </div>\n\n {/* Preview */}\n <div className=\"dc:space-y-1\">\n <label className=\"dc:text-xs text-dc-text-secondary\">Preview</label>\n <div className=\"dc:text-sm dc:font-mono text-dc-text\">\n {preview}\n </div>\n </div>\n </div>\n )\n}\n\ninterface MultiAxisFormatControlsProps {\n displayConfig: {\n xAxisFormat?: AxisFormatConfig\n leftYAxisFormat?: AxisFormatConfig\n rightYAxisFormat?: AxisFormatConfig\n }\n onChange: (updates: {\n xAxisFormat?: AxisFormatConfig\n leftYAxisFormat?: AxisFormatConfig\n rightYAxisFormat?: AxisFormatConfig\n }) => void\n /** Which axes to show controls for */\n showAxes?: {\n xAxis?: boolean\n leftYAxis?: boolean\n rightYAxis?: boolean\n }\n}\n\n/**\n * Container component for multiple axis format controls\n */\nexport function MultiAxisFormatControls({\n displayConfig,\n onChange,\n showAxes = { leftYAxis: true, rightYAxis: true }\n}: MultiAxisFormatControlsProps) {\n return (\n <div className=\"dc:space-y-4\">\n {showAxes.leftYAxis && (\n <AxisFormatControls\n axisLabel=\"Left Y-Axis\"\n value={displayConfig.leftYAxisFormat || {}}\n onChange={(config) =>\n onChange({\n ...displayConfig,\n leftYAxisFormat: Object.keys(config).length > 0 ? config : undefined\n })\n }\n />\n )}\n\n {showAxes.rightYAxis && (\n <AxisFormatControls\n axisLabel=\"Right Y-Axis\"\n value={displayConfig.rightYAxisFormat || {}}\n onChange={(config) =>\n onChange({\n ...displayConfig,\n rightYAxisFormat: Object.keys(config).length > 0 ? config : undefined\n })\n }\n />\n )}\n\n {showAxes.xAxis && (\n <AxisFormatControls\n axisLabel=\"X-Axis\"\n value={displayConfig.xAxisFormat || {}}\n onChange={(config) =>\n onChange({\n ...displayConfig,\n xAxisFormat: Object.keys(config).length > 0 ? config : undefined\n })\n }\n previewValue={2024} // Use a year-like number for X-axis preview\n />\n )}\n </div>\n )\n}\n\nexport default AxisFormatControls\n","/**\n * Optimized hook that only subscribes to field label functionality\n * from CubeMeta context. This prevents re-renders when unrelated\n * contexts (CubeApi, Features) change.\n *\n * Use this instead of useCubeContext() when you only need getFieldLabel.\n */\n\nimport { useContext, useMemo } from 'react'\nimport { CubeMetaContext, type CubeMetaContextValue } from '../providers/CubeMetaContext'\n\n/**\n * Returns a stable reference to the getFieldLabel function.\n * Components using this hook will only re-render when the field label\n * mapping actually changes, not when unrelated API or feature contexts update.\n *\n * @returns Function to get human-readable label for a field name\n * @throws Error if used outside CubeProvider\n */\nexport function useCubeFieldLabel(): (fieldName: string) => string {\n const context = useContext(CubeMetaContext) as CubeMetaContextValue | null\n\n if (!context) {\n throw new Error('useCubeFieldLabel must be used within CubeProvider')\n }\n\n // Return stable reference - only changes when getFieldLabel itself changes\n return useMemo(() => context.getFieldLabel, [context.getFieldLabel])\n}\n","// Default color palette for charts - used as fallback when no dashboard palette is specified\n// These are now part of the 'default' palette in the unified color palette system\nexport const CHART_COLORS = [\n '#3b82f6', // blue\n '#10b981', // green\n '#f59e0b', // yellow\n '#ef4444', // red\n '#8b5cf6', // purple\n '#f97316', // orange\n '#06b6d4', // cyan\n '#84cc16', // lime\n]\n\n// Default gradient colors for continuous numeric scales - used as fallback\n// These are now part of the 'default' palette in the unified color palette system\nexport const CHART_COLORS_GRADIENT = [\n '#440154', // dark purple\n '#414487', // purple-blue\n '#2a788e', // teal\n '#22a884', // green-teal \n '#7ad151', // green\n '#fde725', // yellow\n]\n\n// Colors for positive/negative values\nexport const POSITIVE_COLOR = '#10b981' // green\nexport const NEGATIVE_COLOR = '#ef4444' // red\n\nexport const CHART_MARGINS = {\n top: 5,\n right: 30,\n left: 20,\n bottom: 5\n}\n\nexport const RESPONSIVE_CHART_MARGINS = {\n top: 5,\n right: 30,\n left: 20,\n bottom: 60 // Extra space for rotated labels\n}","import { ReactElement, useState, useRef, useLayoutEffect, startTransition } from 'react'\nimport { ResponsiveContainer } from 'recharts'\nimport LoadingIndicator from '../LoadingIndicator'\n\ninterface ChartContainerProps {\n children: ReactElement\n height?: string | number\n}\n\nexport default function ChartContainer({ children, height = \"100%\" }: ChartContainerProps) {\n // Track if container is ready to render ResponsiveContainer\n // We need to wait for the container to be in the DOM with valid dimensions\n const containerRef = useRef<HTMLDivElement>(null)\n const [isReady, setIsReady] = useState(false)\n const [containerSize, setContainerSize] = useState({ width: 0, height: 0 })\n const sizeRef = useRef({ width: 0, height: 0 })\n const readyRef = useRef(false)\n const pendingSizeRef = useRef<{ width: number; height: number } | null>(null)\n const frameRef = useRef<number | null>(null)\n\n // Use useLayoutEffect to measure before paint\n useLayoutEffect(() => {\n let mounted = true\n let resizeObserver: ResizeObserver | null = null\n\n const flushPendingSize = () => {\n frameRef.current = null\n if (!mounted) return\n const pending = pendingSizeRef.current\n pendingSizeRef.current = null\n if (!pending) return\n\n const nextWidth = Math.round(pending.width)\n const nextHeight = Math.round(pending.height)\n if (nextWidth <= 0 || nextHeight <= 0) return\n\n const sizeChanged =\n sizeRef.current.width !== nextWidth || sizeRef.current.height !== nextHeight\n const shouldBecomeReady = !readyRef.current\n\n if (!sizeChanged && !shouldBecomeReady) return\n\n sizeRef.current = { width: nextWidth, height: nextHeight }\n readyRef.current = true\n\n // Resize-driven chart updates can come in bursts (one per portlet).\n // Transitioning these avoids blocking urgent input and coalesces visual work.\n startTransition(() => {\n if (sizeChanged) {\n setContainerSize({ width: nextWidth, height: nextHeight })\n }\n if (shouldBecomeReady) {\n setIsReady(true)\n }\n })\n }\n\n const scheduleSizeUpdate = (width: number, height: number) => {\n pendingSizeRef.current = { width, height }\n if (frameRef.current === null) {\n frameRef.current = requestAnimationFrame(flushPendingSize)\n }\n }\n\n const measureAndSetReady = () => {\n if (!mounted || !containerRef.current) return\n\n const rect = containerRef.current.getBoundingClientRect()\n // Check both clientWidth/Height AND getBoundingClientRect for robustness\n const width = Math.max(containerRef.current.clientWidth, rect.width)\n const measuredHeight = Math.max(containerRef.current.clientHeight, rect.height)\n\n if (width > 0 && measuredHeight > 0) {\n scheduleSizeUpdate(width, measuredHeight)\n }\n }\n\n // Set up ResizeObserver to detect when container gets valid dimensions\n resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const { width, height: entryHeight } = entry.contentRect\n if (width > 0 && entryHeight > 0) {\n scheduleSizeUpdate(width, entryHeight)\n }\n }\n })\n\n if (containerRef.current) {\n resizeObserver.observe(containerRef.current)\n // Also try immediate measurement\n measureAndSetReady()\n }\n\n return () => {\n mounted = false\n if (frameRef.current !== null) {\n cancelAnimationFrame(frameRef.current)\n frameRef.current = null\n }\n resizeObserver?.disconnect()\n }\n }, [])\n\n try {\n if (height === \"100%\") {\n // For 100% height, make the container fill the available flex space with proper sizing\n // user-select: none prevents browser selection box from appearing when clicking/dragging on charts\n return (\n <div\n ref={containerRef}\n className=\"dc:w-full dc:h-full dc:flex-1 dc:flex dc:flex-col dc:relative\"\n style={{ minHeight: '250px', minWidth: '100px', overflow: 'hidden', userSelect: 'none' }}\n >\n {isReady && containerSize.width > 0 && containerSize.height > 0 ? (\n <ResponsiveContainer\n width={containerSize.width}\n height={containerSize.height - 16}\n debounce={100}\n style={{ marginTop: '16px' }}\n >\n {children}\n </ResponsiveContainer>\n ) : (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full dc:h-full\">\n <LoadingIndicator size=\"sm\" />\n </div>\n )}\n </div>\n )\n }\n\n // For specific heights, use them directly\n // user-select: none prevents browser selection box from appearing when clicking/dragging on charts\n const containerStyle = {\n height: typeof height === 'number' ? `${height}px` : height,\n width: '100%',\n minHeight: '200px',\n minWidth: '100px',\n userSelect: 'none' as const\n }\n\n return (\n <div\n ref={containerRef}\n className=\"dc:w-full dc:flex dc:flex-col dc:relative\"\n style={{ ...containerStyle, overflow: 'hidden' }}\n >\n {isReady && containerSize.width > 0 && containerSize.height > 0 ? (\n <ResponsiveContainer\n width={containerSize.width}\n height={containerSize.height - 16}\n debounce={100}\n style={{ marginTop: '16px' }}\n >\n {children}\n </ResponsiveContainer>\n ) : (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full dc:h-full\">\n <LoadingIndicator size=\"sm\" />\n </div>\n )}\n </div>\n )\n } catch (error) {\n // ChartContainer ResponsiveContainer error\n\n return (\n <div\n className=\"dc:flex dc:flex-col dc:items-center dc:justify-center dc:w-full dc:h-full dc:p-4 dc:text-center dc:border dc:border-dashed dc:rounded-lg\"\n style={{ height, borderColor: 'var(--dc-border)', backgroundColor: 'var(--dc-surface)' }}\n >\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1 text-dc-text-muted\">Unable to display chart</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">\n {error instanceof Error ? error.message : 'Failed to create responsive container'}\n </div>\n </div>\n )\n }\n}\n","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, payload?: readonly 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}","/**\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}"],"names":["sizeClasses","LoadingIndicator","size","className","jsx","SectionHeading","children","isValidNumericValue","value","parseNumericValue","num","formatNumericValue","formatAxisValue","config","locale","effectiveLocale","unit","abbreviate","decimals","customPrefix","customSuffix","displayValue","abbreviationSuffix","absNum","effectiveDecimals","currencyCode","getCurrencyCodeForLocale","formatted","parts","percentValue","prefix","suffix","region","createAxisTickFormatter","getFieldLabel","fieldName","labelMap","transformSeriesKeysWithLabels","seriesKeys","key","formatTimeValue","granularity","str","isoStr","date","year","month","day","hours","minutes","quarter","seconds","milliseconds","getFieldGranularity","queryObject","timeDim","td","granularityMatch","transformChartData","data","xAxisField","yAxisFields","getFieldLabelFn","row","transformed","field","displayName","transformChartDataWithSeries","seriesFields","originalQuery","queryDimensions","queryMeasures","yAxisMeasures","yAxisDimensions","groupedData","xValue","measure","measureValue","currentValue","dimension","dimValue","seriesName","measureToAggregate","m","chartData","dimensionSeries","getLocaleCurrencySymbol","AxisFormatControls","onChange","axisLabel","previewValue","useMemo","currencySymbol","preview","handleChange","updates","unitButtons","jsxs","e","btn","current","useCubeFieldLabel","context","useContext","CubeMetaContext","CHART_COLORS","CHART_COLORS_GRADIENT","POSITIVE_COLOR","NEGATIVE_COLOR","CHART_MARGINS","RESPONSIVE_CHART_MARGINS","ChartContainer","height","containerRef","useRef","isReady","setIsReady","useState","containerSize","setContainerSize","sizeRef","readyRef","pendingSizeRef","frameRef","useLayoutEffect","mounted","resizeObserver","flushPendingSize","pending","nextWidth","nextHeight","sizeChanged","shouldBecomeReady","startTransition","scheduleSizeUpdate","width","measureAndSetReady","rect","measuredHeight","entries","entry","entryHeight","ResponsiveContainer","containerStyle","error","defaultFormatter","name","ChartTooltip","formatter","labelFormatter","Tooltip","parseTargetValues","targetString","trimmed","values","val","spreadTargetValues","targets","dataLength","result","baseGroupSize","remainder","currentIndex","i","groupSize","j","calculateVariance","actual","target","formatVariance","variance"],"mappings":"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"}
1
+ {"version":3,"file":"charts-core-B4Rbfdcn.js","sources":["../../../src/client/components/LoadingIndicator.tsx","../../../src/client/components/AnalysisBuilder/SectionHeading.tsx","../../../src/client/utils/chartUtils.ts","../../../src/client/components/charts/AxisFormatControls.tsx","../../../src/client/hooks/useCubeFieldLabel.ts","../../../src/client/utils/chartConstants.ts","../../../src/client/components/charts/ChartContainer.tsx","../../../src/client/components/charts/ChartTooltip.tsx","../../../src/client/utils/targetUtils.ts"],"sourcesContent":["/**\n * LoadingIndicator Component\n *\n * A centralized, theme-aware loading spinner that uses CSS variables\n * for consistent styling across all drizzle-cube components.\n *\n * Can be overridden at the Dashboard or Portlet level by passing a\n * custom loadingComponent prop.\n */\n\nexport interface LoadingIndicatorProps {\n /** Size variant: 'xs' (12px), 'sm' (24px), 'md' (32px), 'lg' (48px) */\n size?: 'xs' | 'sm' | 'md' | 'lg'\n /** Additional CSS classes */\n className?: string\n}\n\nconst sizeClasses = {\n xs: 'dc:h-3 dc:w-3',\n sm: 'dc:h-6 dc:w-6',\n md: 'dc:h-8 dc:w-8',\n lg: 'dc:h-12 dc:w-12'\n}\n\nexport default function LoadingIndicator({\n size = 'md',\n className = ''\n}: LoadingIndicatorProps) {\n return (\n <div\n className={`dc:animate-spin dc:rounded-full dc:border-b-2 ${sizeClasses[size]} ${className}`}\n style={{ borderBottomColor: 'var(--dc-primary)' }}\n role=\"status\"\n aria-label=\"Loading\"\n />\n )\n}\n","/**\n * SectionHeading Component\n *\n * A reusable section heading for the Analysis Builder panels.\n * Provides consistent styling that can be easily adjusted in one place.\n */\n\nimport type { ReactNode } from 'react'\n\ninterface SectionHeadingProps {\n children: ReactNode\n /** Optional className to add additional styles */\n className?: string\n}\n\n/**\n * Consistent section heading style for Analysis Builder panels.\n * Change the styles here to update all section headings at once.\n */\nexport default function SectionHeading({ children, className = '' }: SectionHeadingProps) {\n return (\n <h3 className={`dc:text-sm dc:font-semibold text-dc-primary dc:uppercase dc:tracking-wide ${className}`}>\n {children}\n </h3>\n )\n}\n","import type { FieldLabelMap, AxisFormatConfig } from '../types'\n\n// Utility function to check if a value is a valid numeric value (not null, undefined, or NaN)\n// This is used to preserve null values instead of converting them to 0\nexport function isValidNumericValue(value: any): boolean {\n return value !== null && value !== undefined && !isNaN(Number(value))\n}\n\n// Utility function to parse numeric value from data, preserving nulls\n// Returns null for null/undefined/NaN values, otherwise returns the numeric value\nexport function parseNumericValue(value: any): number | null {\n if (value === null || value === undefined) return null\n const num = typeof value === 'string' ? parseFloat(value) : Number(value)\n return isNaN(num) ? null : num\n}\n\n// Utility function to format numeric values for display in charts\n// Rounds to at most 2 decimal places, preserves integers\nexport function formatNumericValue(value: any): string {\n if (value === null || value === undefined) return 'No data'\n const num = typeof value === 'number' ? value : parseFloat(value)\n if (isNaN(num)) return String(value)\n if (Number.isInteger(num)) return num.toLocaleString()\n // Round to at most 2 decimal places, remove trailing zeros\n return parseFloat(num.toFixed(2)).toLocaleString()\n}\n\n/**\n * Format a numeric value for axis/tooltip display with configurable formatting\n *\n * @param value - The numeric value to format\n * @param config - Optional formatting configuration\n * @param locale - Optional locale string (defaults to browser locale)\n * @returns Formatted string representation of the value\n *\n * @example\n * formatAxisValue(1250000, { unit: 'currency', abbreviate: true }) // \"$1.25M\"\n * formatAxisValue(0.75, { unit: 'percent', decimals: 1 }) // \"75.0%\"\n * formatAxisValue(1234567, { abbreviate: true, decimals: 2 }) // \"1.23M\"\n */\nexport function formatAxisValue(\n value: number | null | undefined,\n config?: AxisFormatConfig,\n locale?: string\n): string {\n // Handle null/undefined\n if (value === null || value === undefined) {\n return 'No data'\n }\n\n // Handle non-numeric values\n const num = typeof value === 'number' ? value : parseFloat(String(value))\n if (isNaN(num)) {\n return String(value)\n }\n\n // Handle special cases\n if (!isFinite(num)) {\n return num > 0 ? '∞' : '-∞'\n }\n\n // Get locale (default to browser locale)\n const effectiveLocale = locale || (typeof navigator !== 'undefined' ? navigator.language : 'en-US')\n\n // If no config provided, use default formatting\n if (!config) {\n return formatNumericValue(value)\n }\n\n const { unit, abbreviate = true, decimals, customPrefix, customSuffix } = config\n\n // Calculate the display value and suffix for abbreviation\n // Default to true for abbreviation when config is provided\n let displayValue = num\n let abbreviationSuffix = ''\n\n if (abbreviate) {\n const absNum = Math.abs(num)\n if (absNum >= 1_000_000_000) {\n displayValue = num / 1_000_000_000\n abbreviationSuffix = 'B'\n } else if (absNum >= 1_000_000) {\n displayValue = num / 1_000_000\n abbreviationSuffix = 'M'\n } else if (absNum >= 1_000) {\n displayValue = num / 1_000\n abbreviationSuffix = 'K'\n }\n }\n\n // Determine decimal places\n // If decimals is undefined, use auto (2 for non-integers, 0 for integers after abbreviation)\n const effectiveDecimals = decimals !== undefined\n ? decimals\n : (Number.isInteger(displayValue) ? 0 : 2)\n\n // Format based on unit type\n switch (unit) {\n case 'currency': {\n // Use Intl.NumberFormat for currency\n // Currency code is determined by locale (USD for en-US, EUR for de-DE, etc.)\n const currencyCode = getCurrencyCodeForLocale(effectiveLocale)\n\n if (abbreviate && abbreviationSuffix) {\n // For abbreviated currency, format the number part and add suffix\n const formatted = new Intl.NumberFormat(effectiveLocale, {\n style: 'currency',\n currency: currencyCode,\n minimumFractionDigits: effectiveDecimals,\n maximumFractionDigits: effectiveDecimals,\n }).format(displayValue)\n // Insert abbreviation suffix before any trailing currency symbol or at end\n // Handle both \"$1.25\" -> \"$1.25M\" and \"1.25 €\" -> \"1.25M €\"\n const parts = new Intl.NumberFormat(effectiveLocale, {\n style: 'currency',\n currency: currencyCode,\n }).formatToParts(displayValue)\n const hasTrailingCurrency = parts[parts.length - 1]?.type === 'currency'\n if (hasTrailingCurrency) {\n // Currency symbol is at the end (e.g., \"1.25 €\")\n return formatted.replace(/(\\s*[^\\d\\s]+)$/, abbreviationSuffix + '$1')\n }\n return formatted + abbreviationSuffix\n }\n\n return new Intl.NumberFormat(effectiveLocale, {\n style: 'currency',\n currency: currencyCode,\n minimumFractionDigits: effectiveDecimals,\n maximumFractionDigits: effectiveDecimals,\n }).format(displayValue)\n }\n\n case 'percent': {\n // Format as percentage (multiply by 100 if value is 0-1 range, otherwise use as-is)\n // Assume values > 1 are already percentages, values <= 1 need multiplication\n const percentValue = Math.abs(displayValue) <= 1 && !abbreviate ? displayValue * 100 : displayValue\n const formatted = new Intl.NumberFormat(effectiveLocale, {\n minimumFractionDigits: effectiveDecimals,\n maximumFractionDigits: effectiveDecimals,\n }).format(percentValue)\n return formatted + abbreviationSuffix + '%'\n }\n\n case 'custom': {\n // Apply custom prefix/suffix\n const prefix = customPrefix || ''\n const suffix = customSuffix || ''\n const formatted = new Intl.NumberFormat(effectiveLocale, {\n minimumFractionDigits: effectiveDecimals,\n maximumFractionDigits: effectiveDecimals,\n }).format(displayValue)\n return prefix + formatted + abbreviationSuffix + suffix\n }\n\n case 'number':\n default: {\n // Standard number formatting with locale-aware grouping\n const formatted = new Intl.NumberFormat(effectiveLocale, {\n minimumFractionDigits: effectiveDecimals,\n maximumFractionDigits: effectiveDecimals,\n }).format(displayValue)\n return formatted + abbreviationSuffix\n }\n }\n}\n\n/**\n * Get the currency code for a given locale\n * Maps common locales to their default currency\n */\nfunction getCurrencyCodeForLocale(locale: string): string {\n // Extract language and region from locale (e.g., \"en-US\" -> [\"en\", \"US\"])\n const parts = locale.split('-')\n const region = parts[1]?.toUpperCase()\n\n // Map regions to currencies\n const currencyMap: Record<string, string> = {\n 'US': 'USD',\n 'CA': 'CAD',\n 'GB': 'GBP',\n 'UK': 'GBP',\n 'AU': 'AUD',\n 'NZ': 'NZD',\n 'EU': 'EUR',\n 'DE': 'EUR',\n 'FR': 'EUR',\n 'IT': 'EUR',\n 'ES': 'EUR',\n 'NL': 'EUR',\n 'BE': 'EUR',\n 'AT': 'EUR',\n 'IE': 'EUR',\n 'PT': 'EUR',\n 'FI': 'EUR',\n 'JP': 'JPY',\n 'CN': 'CNY',\n 'KR': 'KRW',\n 'IN': 'INR',\n 'BR': 'BRL',\n 'MX': 'MXN',\n 'CH': 'CHF',\n 'SE': 'SEK',\n 'NO': 'NOK',\n 'DK': 'DKK',\n 'PL': 'PLN',\n 'RU': 'RUB',\n 'ZA': 'ZAR',\n 'SG': 'SGD',\n 'HK': 'HKD',\n 'TW': 'TWD',\n 'TH': 'THB',\n 'MY': 'MYR',\n 'PH': 'PHP',\n 'ID': 'IDR',\n 'VN': 'VND',\n 'AE': 'AED',\n 'SA': 'SAR',\n 'IL': 'ILS',\n 'TR': 'TRY',\n }\n\n return currencyMap[region] || 'USD'\n}\n\n/**\n * Create a tick formatter function for Recharts axes\n * Returns a function that can be used as tickFormatter prop\n */\nexport function createAxisTickFormatter(config?: AxisFormatConfig): (value: any) => string {\n return (value: any) => formatAxisValue(value, config)\n}\n\n// Utility function to get field label from field name\nexport function getFieldLabel(fieldName: string, labelMap: FieldLabelMap): string {\n return labelMap[fieldName] || fieldName\n}\n\n// Utility function to transform series keys to use labels\nexport function transformSeriesKeysWithLabels(seriesKeys: string[], labelMap: FieldLabelMap): string[] {\n return seriesKeys.map(key => getFieldLabel(key, labelMap))\n}\n\n// Utility function to format time values for better display using known granularity\nexport function formatTimeValue(value: any, granularity?: string): string {\n if (!value) return String(value || 'Unknown')\n \n const str = String(value)\n \n // Check if it's a timestamp (ISO format or PostgreSQL format)\n // Handles formats like: \"2025-04-01T00:00:00.000\" or \"2023-02-01 00:00:00+00\"\n if (str.match(/^\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}:\\d{2}/)) {\n // Convert PostgreSQL format to ISO format if needed\n let isoStr = str\n if (str.includes(' ')) {\n // Convert \"2023-02-01 00:00:00+00\" to \"2023-02-01T00:00:00Z\"\n isoStr = str.replace(' ', 'T').replace('+00', 'Z').replace(/\\+\\d{2}:\\d{2}$/, 'Z')\n }\n // Ensure the timestamp ends with 'Z' if not present\n if (!isoStr.endsWith('Z') && !isoStr.includes('+')) {\n isoStr = isoStr + 'Z'\n }\n const date = new Date(isoStr)\n \n // Ensure we're working with valid date\n if (isNaN(date.getTime())) {\n return str\n }\n \n // Use UTC methods on the properly UTC-parsed date\n const year = date.getUTCFullYear()\n const month = String(date.getUTCMonth() + 1).padStart(2, '0')\n const day = String(date.getUTCDate()).padStart(2, '0')\n const hours = date.getUTCHours()\n const minutes = date.getUTCMinutes()\n \n // Format based on known granularity if provided\n if (granularity) {\n switch (granularity.toLowerCase()) {\n case 'year':\n return `${year}`\n case 'quarter': {\n const quarter = Math.floor(date.getUTCMonth() / 3) + 1\n return `${year}-Q${quarter}`\n }\n case 'month':\n return `${year}-${month}`\n case 'week':\n // For week, we could calculate week number, but let's use date for simplicity\n return `${year}-${month}-${day}`\n case 'day':\n return `${year}-${month}-${day}`\n case 'hour':\n return `${year}-${month}-${day} ${String(hours).padStart(2, '0')}:00`\n case 'minute':\n return `${year}-${month}-${day} ${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}`\n default:\n // Unknown granularity, fall back to heuristic\n break\n }\n }\n \n // Fallback heuristic if granularity not provided or unknown\n const seconds = date.getUTCSeconds()\n const milliseconds = date.getUTCMilliseconds()\n \n // If it's the first day of the month at exactly midnight UTC, it's likely a month granularity\n if (day === '01' && hours === 0 && minutes === 0 && seconds === 0 && milliseconds === 0) {\n // Check if it's also first month of a quarter (quarter granularity)\n if (month === '01' || month === '04' || month === '07' || month === '10') {\n const quarter = Math.floor(date.getUTCMonth() / 3) + 1\n return `${year}-Q${quarter}`\n }\n // Month granularity\n return `${year}-${month}`\n }\n \n // If it's exactly midnight UTC, it's likely a day granularity\n if (hours === 0 && minutes === 0 && seconds === 0 && milliseconds === 0) {\n return `${year}-${month}-${day}`\n }\n \n // If it has time components, include them (hour/minute granularity)\n if (minutes === 0 && seconds === 0 && milliseconds === 0) {\n // Hour granularity\n return `${year}-${month}-${day} ${String(hours).padStart(2, '0')}:00`\n }\n \n // Full timestamp\n return `${year}-${month}-${day} ${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}`\n }\n \n // Return as-is if not a timestamp\n return str\n}\n\n// Helper function to get granularity for a field from the query timeDimensions\nexport function getFieldGranularity(queryObject: any, fieldName: string): string | undefined {\n try {\n if (queryObject?.timeDimensions) {\n // Find the timeDimension that matches this field\n const timeDim = queryObject.timeDimensions.find((td: any) => {\n // Check if field name matches the dimension or dimension with granularity suffix\n return fieldName === td.dimension || \n fieldName.startsWith(td.dimension.replace('.', '_')) ||\n fieldName === `${td.dimension}_${td.granularity}`\n })\n \n if (timeDim?.granularity) {\n return timeDim.granularity\n }\n }\n \n // Fallback: extract granularity from field name suffix if present\n const granularityMatch = fieldName.match(/_([a-z]+)$/)\n if (granularityMatch) {\n const suffix = granularityMatch[1]\n // Only return if it's a valid granularity\n if (['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second'].includes(suffix)) {\n return suffix\n }\n }\n \n return undefined\n } catch {\n return undefined\n }\n}\n\n// Transform data for charts with proper type handling\n// NOTE: Preserves null values to allow charts to handle gaps/missing data appropriately\nexport function transformChartData(\n data: any[],\n xAxisField: string,\n yAxisFields: string[],\n queryObject: any,\n getFieldLabelFn: (fieldName: string) => string = (fieldName) => fieldName\n) {\n if (!data || data.length === 0) return []\n\n const granularity = getFieldGranularity(queryObject, xAxisField)\n\n return data.map((row: any) => {\n const transformed: any = {\n name: formatTimeValue(row[xAxisField], granularity) || row[xAxisField] || 'Unknown',\n }\n\n yAxisFields.forEach(field => {\n const displayName = getFieldLabelFn(field)\n // Preserve null values instead of converting to 0\n transformed[displayName] = parseNumericValue(row[field])\n })\n\n return transformed\n })\n}\n\nexport interface ChartSeriesResult {\n data: any[]\n seriesKeys: string[]\n hasDimensions: boolean\n}\n\n// Advanced data transformation that handles both measures and dimensions on Y-axis\n// NOTE: Preserves null values to allow charts to handle gaps/missing data appropriately\nexport function transformChartDataWithSeries(\n data: any[],\n xAxisField: string,\n yAxisFields: string[],\n queryObject: any,\n seriesFields?: string[], // New optional parameter for explicit series fields\n getFieldLabelFn: (fieldName: string) => string = (fieldName) => fieldName // Function to get field labels\n): ChartSeriesResult {\n if (!data || data.length === 0) {\n return { data: [], seriesKeys: [], hasDimensions: false }\n }\n\n const originalQuery = queryObject || {}\n const queryDimensions = [\n ...(originalQuery.dimensions || []),\n ...(originalQuery.timeDimensions?.map((td: any) => td.dimension) || [])\n ]\n const queryMeasures = originalQuery.measures || []\n\n // Use explicit series fields if provided, otherwise no dimension-based series\n const yAxisMeasures = yAxisFields.filter(field => queryMeasures.includes(field))\n const yAxisDimensions = (seriesFields || []).filter(field => queryDimensions.includes(field))\n\n // Handle complex case with dimensions on Y-axis\n if (yAxisDimensions.length > 0) {\n // Group data by X-axis field and create separate series for dimension values\n const groupedData: { [key: string]: any } = {}\n\n data.forEach((row: any) => {\n const granularity = getFieldGranularity(queryObject, xAxisField)\n const xValue = formatTimeValue(row[xAxisField], granularity) || row[xAxisField] || 'Unknown'\n if (!groupedData[xValue]) {\n groupedData[xValue] = { name: String(xValue) }\n }\n\n // Add measures - preserve nulls for individual measures\n yAxisMeasures.forEach(measure => {\n const displayName = getFieldLabelFn(measure)\n const measureValue = parseNumericValue(row[measure])\n\n // For aggregation: sum non-null values, preserve null if all are null\n if (measureValue !== null) {\n const currentValue = groupedData[xValue][displayName]\n groupedData[xValue][displayName] = (currentValue === null || currentValue === undefined)\n ? measureValue\n : currentValue + measureValue\n } else if (!(displayName in groupedData[xValue])) {\n // Only set to null if no value exists yet\n groupedData[xValue][displayName] = null\n }\n })\n\n // Add dimensions as separate series (aggregate measure values by dimension)\n yAxisDimensions.forEach(dimension => {\n const dimValue = row[dimension]\n if (dimValue !== undefined && dimValue !== null) {\n const seriesName = String(dimValue)\n // Aggregate the first measure for this dimension value, or use totalCost if available\n const measureToAggregate = yAxisMeasures[0] || queryMeasures.find((m: string) =>\n m.includes('totalCost') || m.includes('count') || m.includes('sum')\n ) || queryMeasures[0]\n\n if (measureToAggregate) {\n const measureValue = parseNumericValue(row[measureToAggregate])\n\n // For dimension series: sum non-null values, preserve null if all are null\n if (measureValue !== null) {\n const currentValue = groupedData[xValue][seriesName]\n groupedData[xValue][seriesName] = (currentValue === null || currentValue === undefined)\n ? measureValue\n : currentValue + measureValue\n } else if (!(seriesName in groupedData[xValue])) {\n // Only set to null if no value exists yet\n groupedData[xValue][seriesName] = null\n }\n }\n }\n })\n })\n \n const chartData = Object.values(groupedData)\n \n // Get all series keys for rendering\n // When dimensions are on Y-axis, only show dimension series, not measures\n // The measures are the values being aggregated for each dimension series\n const dimensionSeries = Array.from(new Set(\n data.flatMap((row: any) => \n yAxisDimensions.map(dimension => {\n const value = row[dimension]\n return value !== undefined && value !== null \n ? String(value)\n : null\n }).filter((value): value is string => value !== null)\n )\n ))\n \n return {\n data: chartData,\n seriesKeys: dimensionSeries,\n hasDimensions: true\n }\n }\n \n // Standard measures-only path\n const chartData = transformChartData(data, xAxisField, yAxisFields, queryObject, getFieldLabelFn)\n const seriesKeys = yAxisFields.map(field => getFieldLabelFn(field))\n \n return {\n data: chartData,\n seriesKeys,\n hasDimensions: false\n }\n}","/**\n * AxisFormatControls Component\n *\n * A reusable component for configuring axis number formatting.\n * Provides controls for unit type, abbreviation, decimal places, and custom labels.\n */\n\nimport { useMemo } from 'react'\nimport SectionHeading from '../AnalysisBuilder/SectionHeading'\nimport type { AxisFormatConfig } from '../../types'\nimport { formatAxisValue } from '../../utils/chartUtils'\n\ninterface AxisFormatControlsProps {\n value: AxisFormatConfig\n onChange: (config: AxisFormatConfig) => void\n axisLabel: string // \"X-Axis\", \"Left Y-Axis\", \"Right Y-Axis\"\n /** Sample value for preview (default: 1250000) */\n previewValue?: number\n}\n\n/**\n * Get the currency symbol for the user's locale\n */\nfunction getLocaleCurrencySymbol(): string {\n const locale = typeof navigator !== 'undefined' ? navigator.language : 'en-US'\n // Format a number as currency and extract just the symbol\n const formatted = new Intl.NumberFormat(locale, {\n style: 'currency',\n currency: getCurrencyCodeForLocale(locale),\n currencyDisplay: 'narrowSymbol'\n }).format(0)\n // Extract the currency symbol (remove digits, spaces, and common separators)\n return formatted.replace(/[\\d.,\\s]/g, '').trim() || '$'\n}\n\n/**\n * Get the currency code for a given locale (duplicated from chartUtils for component isolation)\n */\nfunction getCurrencyCodeForLocale(locale: string): string {\n const parts = locale.split('-')\n const region = parts[1]?.toUpperCase()\n const currencyMap: Record<string, string> = {\n 'US': 'USD', 'CA': 'CAD', 'GB': 'GBP', 'UK': 'GBP', 'AU': 'AUD', 'NZ': 'NZD',\n 'EU': 'EUR', 'DE': 'EUR', 'FR': 'EUR', 'IT': 'EUR', 'ES': 'EUR', 'NL': 'EUR',\n 'BE': 'EUR', 'AT': 'EUR', 'IE': 'EUR', 'PT': 'EUR', 'FI': 'EUR',\n 'JP': 'JPY', 'CN': 'CNY', 'KR': 'KRW', 'IN': 'INR', 'BR': 'BRL', 'MX': 'MXN',\n 'CH': 'CHF', 'SE': 'SEK', 'NO': 'NOK', 'DK': 'DKK', 'PL': 'PLN', 'RU': 'RUB',\n 'ZA': 'ZAR', 'SG': 'SGD', 'HK': 'HKD', 'TW': 'TWD', 'TH': 'THB', 'MY': 'MYR',\n 'PH': 'PHP', 'ID': 'IDR', 'VN': 'VND', 'AE': 'AED', 'SA': 'SAR', 'IL': 'ILS', 'TR': 'TRY',\n }\n return currencyMap[region] || 'USD'\n}\n\n/**\n * Single axis format control section\n */\nexport function AxisFormatControls({\n value,\n onChange,\n axisLabel,\n previewValue = 1250000\n}: AxisFormatControlsProps) {\n const config = useMemo(() => value || {}, [value])\n\n // Get locale-aware currency symbol for the button\n const currencySymbol = useMemo(() => getLocaleCurrencySymbol(), [])\n\n // Generate preview of formatted value\n const preview = useMemo(() => {\n return formatAxisValue(previewValue, config)\n }, [previewValue, config])\n\n const handleChange = (updates: Partial<AxisFormatConfig>) => {\n onChange({ ...config, ...updates })\n }\n\n const unitButtons: Array<{ value: AxisFormatConfig['unit']; label: string }> = [\n { value: 'currency', label: currencySymbol },\n { value: 'percent', label: '%' },\n { value: 'number', label: '#' },\n { value: 'custom', label: 'Custom' }\n ]\n\n return (\n <div className=\"dc:space-y-3 dc:pb-4\">\n {/* Axis Header */}\n <SectionHeading>{axisLabel}</SectionHeading>\n\n {/* Label Input */}\n <div className=\"dc:space-y-1\">\n <label className=\"dc:text-xs text-dc-text-secondary\">Label</label>\n <input\n type=\"text\"\n value={config.label || ''}\n onChange={(e) => handleChange({ label: e.target.value || undefined })}\n placeholder=\"Auto-generated label\"\n className=\"dc:w-full dc:px-2 dc:py-1 dc:text-sm dc:border border-dc-border dc:rounded-sm focus:ring-dc-accent focus:border-dc-accent bg-dc-surface text-dc-text\"\n />\n </div>\n\n {/* Unit Type */}\n <div className=\"dc:space-y-1\">\n <label className=\"dc:text-xs text-dc-text-secondary\">Unit</label>\n <div className=\"dc:flex dc:border border-dc-border dc:rounded-sm dc:overflow-hidden\">\n {unitButtons.map((btn) => (\n <button\n key={btn.value}\n type=\"button\"\n onClick={() => handleChange({ unit: btn.value })}\n className={`dc:flex-1 dc:px-2 dc:py-1.5 dc:text-sm dc:font-medium dc:transition-colors ${\n config.unit === btn.value\n ? 'bg-dc-primary text-white'\n : 'bg-dc-surface text-dc-text hover:bg-dc-border'\n }`}\n >\n {btn.label}\n </button>\n ))}\n </div>\n </div>\n\n {/* Custom Prefix/Suffix (only when Custom is selected) */}\n {config.unit === 'custom' && (\n <div className=\"dc:flex dc:gap-2\">\n <div className=\"dc:flex-1 dc:space-y-1\">\n <label className=\"dc:text-xs text-dc-text-secondary\">Prefix</label>\n <input\n type=\"text\"\n value={config.customPrefix || ''}\n onChange={(e) => handleChange({ customPrefix: e.target.value || undefined })}\n placeholder=\"e.g., $\"\n className=\"dc:w-full dc:px-2 dc:py-1 dc:text-sm dc:border border-dc-border dc:rounded-sm focus:ring-dc-accent focus:border-dc-accent bg-dc-surface text-dc-text\"\n />\n </div>\n <div className=\"dc:flex-1 dc:space-y-1\">\n <label className=\"dc:text-xs text-dc-text-secondary\">Suffix</label>\n <input\n type=\"text\"\n value={config.customSuffix || ''}\n onChange={(e) => handleChange({ customSuffix: e.target.value || undefined })}\n placeholder=\"e.g., units\"\n className=\"dc:w-full dc:px-2 dc:py-1 dc:text-sm dc:border border-dc-border dc:rounded-sm focus:ring-dc-accent focus:border-dc-accent bg-dc-surface text-dc-text\"\n />\n </div>\n </div>\n )}\n\n {/* Abbreviation Toggle */}\n <div className=\"dc:space-y-1\">\n <label className=\"dc:text-xs text-dc-text-secondary\">Abbreviation</label>\n <div className=\"dc:flex dc:border border-dc-border dc:rounded-sm dc:overflow-hidden\">\n <button\n type=\"button\"\n onClick={() => handleChange({ abbreviate: true })}\n className={`dc:flex-1 dc:px-3 dc:py-1.5 dc:text-sm dc:font-medium dc:transition-colors ${\n config.abbreviate !== false\n ? 'bg-dc-primary text-white'\n : 'bg-dc-surface text-dc-text hover:bg-dc-border'\n }`}\n >\n Yes\n </button>\n <button\n type=\"button\"\n onClick={() => handleChange({ abbreviate: false })}\n className={`dc:flex-1 dc:px-3 dc:py-1.5 dc:text-sm dc:font-medium dc:transition-colors ${\n config.abbreviate === false\n ? 'bg-dc-primary text-white'\n : 'bg-dc-surface text-dc-text hover:bg-dc-border'\n }`}\n >\n No\n </button>\n </div>\n </div>\n\n {/* Decimals */}\n <div className=\"dc:space-y-1\">\n <label className=\"dc:text-xs text-dc-text-secondary\">Decimals</label>\n <div className=\"dc:flex dc:gap-2\">\n <button\n type=\"button\"\n onClick={() => {\n const current = config.decimals ?? 2\n if (current > 0) handleChange({ decimals: current - 1 })\n }}\n disabled={(config.decimals ?? 2) <= 0}\n className=\"dc:flex-1 dc:px-3 dc:py-2 dc:text-sm dc:border border-dc-border dc:rounded-sm bg-dc-surface text-dc-text hover:bg-dc-border dc:disabled:opacity-40 dc:disabled:cursor-not-allowed dc:transition-colors\"\n >\n ← .0\n </button>\n <button\n type=\"button\"\n onClick={() => {\n const current = config.decimals ?? 2\n if (current < 4) handleChange({ decimals: current + 1 })\n }}\n disabled={(config.decimals ?? 2) >= 4}\n className=\"dc:flex-1 dc:px-3 dc:py-2 dc:text-sm dc:border border-dc-border dc:rounded-sm bg-dc-surface text-dc-text hover:bg-dc-border dc:disabled:opacity-40 dc:disabled:cursor-not-allowed dc:transition-colors\"\n >\n .00 →\n </button>\n </div>\n </div>\n\n {/* Preview */}\n <div className=\"dc:space-y-1\">\n <label className=\"dc:text-xs text-dc-text-secondary\">Preview</label>\n <div className=\"dc:text-sm dc:font-mono text-dc-text\">\n {preview}\n </div>\n </div>\n </div>\n )\n}\n\ninterface MultiAxisFormatControlsProps {\n displayConfig: {\n xAxisFormat?: AxisFormatConfig\n leftYAxisFormat?: AxisFormatConfig\n rightYAxisFormat?: AxisFormatConfig\n }\n onChange: (updates: {\n xAxisFormat?: AxisFormatConfig\n leftYAxisFormat?: AxisFormatConfig\n rightYAxisFormat?: AxisFormatConfig\n }) => void\n /** Which axes to show controls for */\n showAxes?: {\n xAxis?: boolean\n leftYAxis?: boolean\n rightYAxis?: boolean\n }\n}\n\n/**\n * Container component for multiple axis format controls\n */\nexport function MultiAxisFormatControls({\n displayConfig,\n onChange,\n showAxes = { leftYAxis: true, rightYAxis: true }\n}: MultiAxisFormatControlsProps) {\n return (\n <div className=\"dc:space-y-4\">\n {showAxes.leftYAxis && (\n <AxisFormatControls\n axisLabel=\"Left Y-Axis\"\n value={displayConfig.leftYAxisFormat || {}}\n onChange={(config) =>\n onChange({\n ...displayConfig,\n leftYAxisFormat: Object.keys(config).length > 0 ? config : undefined\n })\n }\n />\n )}\n\n {showAxes.rightYAxis && (\n <AxisFormatControls\n axisLabel=\"Right Y-Axis\"\n value={displayConfig.rightYAxisFormat || {}}\n onChange={(config) =>\n onChange({\n ...displayConfig,\n rightYAxisFormat: Object.keys(config).length > 0 ? config : undefined\n })\n }\n />\n )}\n\n {showAxes.xAxis && (\n <AxisFormatControls\n axisLabel=\"X-Axis\"\n value={displayConfig.xAxisFormat || {}}\n onChange={(config) =>\n onChange({\n ...displayConfig,\n xAxisFormat: Object.keys(config).length > 0 ? config : undefined\n })\n }\n previewValue={2024} // Use a year-like number for X-axis preview\n />\n )}\n </div>\n )\n}\n\nexport default AxisFormatControls\n","/**\n * Optimized hook that only subscribes to field label functionality\n * from CubeMeta context. This prevents re-renders when unrelated\n * contexts (CubeApi, Features) change.\n *\n * Use this instead of useCubeContext() when you only need getFieldLabel.\n */\n\nimport { useContext, useMemo } from 'react'\nimport { CubeMetaContext, type CubeMetaContextValue } from '../providers/CubeMetaContext'\n\n/**\n * Returns a stable reference to the getFieldLabel function.\n * Components using this hook will only re-render when the field label\n * mapping actually changes, not when unrelated API or feature contexts update.\n *\n * @returns Function to get human-readable label for a field name\n * @throws Error if used outside CubeProvider\n */\nexport function useCubeFieldLabel(): (fieldName: string) => string {\n const context = useContext(CubeMetaContext) as CubeMetaContextValue | null\n\n if (!context) {\n throw new Error('useCubeFieldLabel must be used within CubeProvider')\n }\n\n // Return stable reference - only changes when getFieldLabel itself changes\n return useMemo(() => context.getFieldLabel, [context.getFieldLabel])\n}\n","// Default color palette for charts - used as fallback when no dashboard palette is specified\n// These are now part of the 'default' palette in the unified color palette system\nexport const CHART_COLORS = [\n '#3b82f6', // blue\n '#10b981', // green\n '#f59e0b', // yellow\n '#ef4444', // red\n '#8b5cf6', // purple\n '#f97316', // orange\n '#06b6d4', // cyan\n '#84cc16', // lime\n]\n\n// Default gradient colors for continuous numeric scales - used as fallback\n// These are now part of the 'default' palette in the unified color palette system\nexport const CHART_COLORS_GRADIENT = [\n '#440154', // dark purple\n '#414487', // purple-blue\n '#2a788e', // teal\n '#22a884', // green-teal \n '#7ad151', // green\n '#fde725', // yellow\n]\n\n// Colors for positive/negative values\nexport const POSITIVE_COLOR = '#10b981' // green\nexport const NEGATIVE_COLOR = '#ef4444' // red\n\nexport const CHART_MARGINS = {\n top: 5,\n right: 30,\n left: 20,\n bottom: 5\n}\n\nexport const RESPONSIVE_CHART_MARGINS = {\n top: 5,\n right: 30,\n left: 20,\n bottom: 60 // Extra space for rotated labels\n}","import { ReactElement, useState, useRef, useLayoutEffect, startTransition } from 'react'\nimport { ResponsiveContainer } from 'recharts'\nimport LoadingIndicator from '../LoadingIndicator'\n\ninterface ChartContainerProps {\n children: ReactElement\n height?: string | number\n}\n\nexport default function ChartContainer({ children, height = \"100%\" }: ChartContainerProps) {\n // Track if container is ready to render ResponsiveContainer\n // We need to wait for the container to be in the DOM with valid dimensions\n const containerRef = useRef<HTMLDivElement>(null)\n const [isReady, setIsReady] = useState(false)\n const [containerSize, setContainerSize] = useState({ width: 0, height: 0 })\n const sizeRef = useRef({ width: 0, height: 0 })\n const readyRef = useRef(false)\n const pendingSizeRef = useRef<{ width: number; height: number } | null>(null)\n const frameRef = useRef<number | null>(null)\n\n // Use useLayoutEffect to measure before paint\n useLayoutEffect(() => {\n let mounted = true\n let resizeObserver: ResizeObserver | null = null\n\n const flushPendingSize = () => {\n frameRef.current = null\n if (!mounted) return\n const pending = pendingSizeRef.current\n pendingSizeRef.current = null\n if (!pending) return\n\n const nextWidth = Math.round(pending.width)\n const nextHeight = Math.round(pending.height)\n if (nextWidth <= 0 || nextHeight <= 0) return\n\n const sizeChanged =\n sizeRef.current.width !== nextWidth || sizeRef.current.height !== nextHeight\n const shouldBecomeReady = !readyRef.current\n\n if (!sizeChanged && !shouldBecomeReady) return\n\n sizeRef.current = { width: nextWidth, height: nextHeight }\n readyRef.current = true\n\n // Resize-driven chart updates can come in bursts (one per portlet).\n // Transitioning these avoids blocking urgent input and coalesces visual work.\n startTransition(() => {\n if (sizeChanged) {\n setContainerSize({ width: nextWidth, height: nextHeight })\n }\n if (shouldBecomeReady) {\n setIsReady(true)\n }\n })\n }\n\n const scheduleSizeUpdate = (width: number, height: number) => {\n pendingSizeRef.current = { width, height }\n if (frameRef.current === null) {\n frameRef.current = requestAnimationFrame(flushPendingSize)\n }\n }\n\n const measureAndSetReady = () => {\n if (!mounted || !containerRef.current) return\n\n const rect = containerRef.current.getBoundingClientRect()\n // Check both clientWidth/Height AND getBoundingClientRect for robustness\n const width = Math.max(containerRef.current.clientWidth, rect.width)\n const measuredHeight = Math.max(containerRef.current.clientHeight, rect.height)\n\n if (width > 0 && measuredHeight > 0) {\n scheduleSizeUpdate(width, measuredHeight)\n }\n }\n\n // Set up ResizeObserver to detect when container gets valid dimensions\n resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const { width, height: entryHeight } = entry.contentRect\n if (width > 0 && entryHeight > 0) {\n scheduleSizeUpdate(width, entryHeight)\n }\n }\n })\n\n if (containerRef.current) {\n resizeObserver.observe(containerRef.current)\n // Also try immediate measurement\n measureAndSetReady()\n }\n\n return () => {\n mounted = false\n if (frameRef.current !== null) {\n cancelAnimationFrame(frameRef.current)\n frameRef.current = null\n }\n resizeObserver?.disconnect()\n }\n }, [])\n\n try {\n if (height === \"100%\") {\n // For 100% height, make the container fill the available flex space with proper sizing\n // user-select: none prevents browser selection box from appearing when clicking/dragging on charts\n return (\n <div\n ref={containerRef}\n className=\"dc:w-full dc:h-full dc:flex-1 dc:flex dc:flex-col dc:relative\"\n style={{ minHeight: '250px', minWidth: '100px', overflow: 'hidden', userSelect: 'none' }}\n >\n {isReady && containerSize.width > 0 && containerSize.height > 0 ? (\n <ResponsiveContainer\n width={containerSize.width}\n height={containerSize.height - 16}\n debounce={100}\n style={{ marginTop: '16px' }}\n >\n {children}\n </ResponsiveContainer>\n ) : (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full dc:h-full\">\n <LoadingIndicator size=\"sm\" />\n </div>\n )}\n </div>\n )\n }\n\n // For specific heights, use them directly\n // user-select: none prevents browser selection box from appearing when clicking/dragging on charts\n const containerStyle = {\n height: typeof height === 'number' ? `${height}px` : height,\n width: '100%',\n minHeight: '200px',\n minWidth: '100px',\n userSelect: 'none' as const\n }\n\n return (\n <div\n ref={containerRef}\n className=\"dc:w-full dc:flex dc:flex-col dc:relative\"\n style={{ ...containerStyle, overflow: 'hidden' }}\n >\n {isReady && containerSize.width > 0 && containerSize.height > 0 ? (\n <ResponsiveContainer\n width={containerSize.width}\n height={containerSize.height - 16}\n debounce={100}\n style={{ marginTop: '16px' }}\n >\n {children}\n </ResponsiveContainer>\n ) : (\n <div className=\"dc:flex dc:items-center dc:justify-center dc:w-full dc:h-full\">\n <LoadingIndicator size=\"sm\" />\n </div>\n )}\n </div>\n )\n } catch (error) {\n // ChartContainer ResponsiveContainer error\n\n return (\n <div\n className=\"dc:flex dc:flex-col dc:items-center dc:justify-center dc:w-full dc:h-full dc:p-4 dc:text-center dc:border dc:border-dashed dc:rounded-lg\"\n style={{ height, borderColor: 'var(--dc-border)', backgroundColor: 'var(--dc-surface)' }}\n >\n <div className=\"dc:text-sm dc:font-semibold dc:mb-1 text-dc-text-muted\">Unable to display chart</div>\n <div className=\"dc:text-xs text-dc-text-secondary\">\n {error instanceof Error ? error.message : 'Failed to create responsive container'}\n </div>\n </div>\n )\n }\n}\n","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, payload?: readonly 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}","/**\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}"],"names":["sizeClasses","LoadingIndicator","size","className","jsx","SectionHeading","children","isValidNumericValue","value","parseNumericValue","num","formatNumericValue","formatAxisValue","config","locale","effectiveLocale","unit","abbreviate","decimals","customPrefix","customSuffix","displayValue","abbreviationSuffix","absNum","effectiveDecimals","currencyCode","getCurrencyCodeForLocale","formatted","parts","percentValue","prefix","suffix","region","createAxisTickFormatter","getFieldLabel","fieldName","labelMap","transformSeriesKeysWithLabels","seriesKeys","key","formatTimeValue","granularity","str","isoStr","date","year","month","day","hours","minutes","quarter","seconds","milliseconds","getFieldGranularity","queryObject","timeDim","td","granularityMatch","transformChartData","data","xAxisField","yAxisFields","getFieldLabelFn","row","transformed","field","displayName","transformChartDataWithSeries","seriesFields","originalQuery","queryDimensions","queryMeasures","yAxisMeasures","yAxisDimensions","groupedData","xValue","measure","measureValue","currentValue","dimension","dimValue","seriesName","measureToAggregate","m","chartData","dimensionSeries","getLocaleCurrencySymbol","AxisFormatControls","onChange","axisLabel","previewValue","useMemo","currencySymbol","preview","handleChange","updates","unitButtons","jsxs","e","btn","current","useCubeFieldLabel","context","useContext","CubeMetaContext","CHART_COLORS","CHART_COLORS_GRADIENT","POSITIVE_COLOR","NEGATIVE_COLOR","CHART_MARGINS","RESPONSIVE_CHART_MARGINS","ChartContainer","height","containerRef","useRef","isReady","setIsReady","useState","containerSize","setContainerSize","sizeRef","readyRef","pendingSizeRef","frameRef","useLayoutEffect","mounted","resizeObserver","flushPendingSize","pending","nextWidth","nextHeight","sizeChanged","shouldBecomeReady","startTransition","scheduleSizeUpdate","width","measureAndSetReady","rect","measuredHeight","entries","entry","entryHeight","ResponsiveContainer","containerStyle","error","defaultFormatter","name","ChartTooltip","formatter","labelFormatter","Tooltip","parseTargetValues","targetString","trimmed","values","val","spreadTargetValues","targets","dataLength","result","baseGroupSize","remainder","currentIndex","i","groupSize","j","calculateVariance","actual","target","formatVariance","variance"],"mappings":"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"}
@@ -147,32 +147,32 @@ const l = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Set(), f = {
147
147
  }
148
148
  // Charts with no external deps: table, activityGrid, kpiNumber, kpiDelta, kpiText, markdown, retentionHeatmap, boxPlot, candlestick
149
149
  }, o = {
150
- bar: () => import("./chart-bar-dj14frMt.js").then((a) => a.a),
151
- line: () => import("./chart-line-DzyZkugh.js").then((a) => a.h),
152
- area: () => import("./chart-area-ByJQ7NZd.js"),
153
- pie: () => import("./chart-pie-akbfRfb9.js"),
154
- scatter: () => import("./chart-scatter-l_yTVxF3.js"),
155
- radar: () => import("./chart-radar-BaN-Kjww.js"),
156
- radialBar: () => import("./chart-radial-bar-DpptEL3s.js"),
157
- treemap: () => import("./chart-tree-map-CBbiaBXV.js"),
158
- bubble: () => import("./chart-bubble-CemotLx-.js").then((a) => a.B),
159
- table: () => import("./chart-data-table-BsAjHe7o.js").then((a) => a.b),
160
- activityGrid: () => import("./chart-activity-grid-CPGcTSuh.js"),
161
- kpiNumber: () => import("./chart-kpi-number-iJh-PzsM.js").then((a) => a.K),
162
- kpiDelta: () => import("./chart-kpi-delta-DUD3f8vL.js"),
163
- kpiText: () => import("./chart-kpi-text-x6pV9v9Q.js"),
150
+ bar: () => import("./chart-bar-D3vtCNQG.js").then((a) => a.a),
151
+ line: () => import("./chart-line-DhM-Hvu0.js").then((a) => a.h),
152
+ area: () => import("./chart-area-TawAd2k9.js"),
153
+ pie: () => import("./chart-pie-B86KRcHI.js"),
154
+ scatter: () => import("./chart-scatter-CAkbBDkK.js"),
155
+ radar: () => import("./chart-radar-BhDBmJRh.js"),
156
+ radialBar: () => import("./chart-radial-bar-Brugya8X.js"),
157
+ treemap: () => import("./chart-tree-map-CrDJAvZU.js"),
158
+ bubble: () => import("./chart-bubble-ZfNe8t5k.js").then((a) => a.B),
159
+ table: () => import("./chart-data-table-DJZPkArt.js").then((a) => a.b),
160
+ activityGrid: () => import("./chart-activity-grid-OG6he4YS.js"),
161
+ kpiNumber: () => import("./chart-kpi-number-Bab-BZtX.js").then((a) => a.K),
162
+ kpiDelta: () => import("./chart-kpi-delta-DEzA74cL.js"),
163
+ kpiText: () => import("./chart-kpi-text-BkTgckDJ.js"),
164
164
  markdown: () => import("./chart-markdown-Du4Z2iqK.js").then((a) => a.a),
165
- funnel: () => import("./chart-funnel-dofnhD24.js"),
166
- sankey: () => import("./chart-sankey-CG-3hHmX.js"),
167
- sunburst: () => import("./chart-sunburst-KhDcKhmZ.js"),
168
- heatmap: () => import("./chart-heat-map-BVuPUKHT.js"),
165
+ funnel: () => import("./chart-funnel-CE9x0Io9.js"),
166
+ sankey: () => import("./chart-sankey-D2L8ympI.js"),
167
+ sunburst: () => import("./chart-sunburst-DaxJ-cob.js"),
168
+ heatmap: () => import("./chart-heat-map-CqtMkdxd.js"),
169
169
  retentionHeatmap: () => import("./RetentionHeatmap-BHYU8MXY.js"),
170
- retentionCombined: () => import("./RetentionCombinedChart-CLq89aOJ.js"),
171
- boxPlot: () => import("./chart-box-plot-ZatBpatq.js"),
172
- waterfall: () => import("./chart-waterfall-CX3vx_lI.js"),
173
- candlestick: () => import("./chart-candlestick-BIR4uGGt.js"),
174
- measureProfile: () => import("./chart-measure-profile-C2IkBG3V.js"),
175
- gauge: () => import("./chart-gauge-CKJJ8m3b.js")
170
+ retentionCombined: () => import("./RetentionCombinedChart-BK3NPsHP.js"),
171
+ boxPlot: () => import("./chart-box-plot-BXwN2rO5.js"),
172
+ waterfall: () => import("./chart-waterfall-BBwSfEKT.js"),
173
+ candlestick: () => import("./chart-candlestick-DmF3haFu.js"),
174
+ measureProfile: () => import("./chart-measure-profile-4vQxFm69.js"),
175
+ gauge: () => import("./chart-gauge-Djs5FWxB.js")
176
176
  };
177
177
  function u(a) {
178
178
  const e = f[a], r = ({ height: n }) => /* @__PURE__ */ t(
@@ -255,4 +255,4 @@ export {
255
255
  v as i,
256
256
  k as p
257
257
  };
258
- //# sourceMappingURL=charts-loader-B3tt5oKG.js.map
258
+ //# sourceMappingURL=charts-loader-DbrwgvCK.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"charts-loader-B3tt5oKG.js","sources":["../../../src/client/components/charts/MissingDependencyFallback.tsx","../../../src/client/charts/ChartLoader.tsx"],"sourcesContent":["interface MissingDependencyFallbackProps {\n chartType: string\n packageName: string\n installCommand: string\n height?: string | number\n}\n\n/**\n * Fallback component shown when a chart's optional dependency is not installed.\n * Provides clear instructions on how to install the missing package.\n */\nexport function MissingDependencyFallback({\n chartType,\n packageName,\n installCommand,\n height = 200\n}: MissingDependencyFallbackProps) {\n return (\n <div\n className=\"dc-missing-dependency-fallback\"\n style={{\n height: typeof height === 'number' ? `${height}px` : height,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n width: '100%',\n padding: '1.5rem',\n textAlign: 'center',\n border: '1px dashed var(--dc-border, #e5e7eb)',\n borderRadius: '0.5rem',\n backgroundColor: 'var(--dc-surface, #f9fafb)'\n }}\n >\n <div style={{ fontSize: '2.5rem', marginBottom: '1rem' }}>📦</div>\n <h3 style={{\n fontSize: '1.125rem',\n fontWeight: 600,\n marginBottom: '0.5rem',\n color: 'var(--dc-text, #111827)'\n }}>\n Missing Dependency\n </h3>\n <p style={{\n fontSize: '0.875rem',\n color: 'var(--dc-text-secondary, #6b7280)',\n marginBottom: '1rem',\n maxWidth: '28rem'\n }}>\n The <code style={{\n padding: '0.125rem 0.375rem',\n backgroundColor: 'var(--dc-surface-secondary, #f3f4f6)',\n borderRadius: '0.25rem',\n fontFamily: 'monospace',\n fontSize: '0.75rem'\n }}>{chartType}</code> chart requires the <code style={{\n padding: '0.125rem 0.375rem',\n backgroundColor: 'var(--dc-surface-secondary, #f3f4f6)',\n borderRadius: '0.25rem',\n fontFamily: 'monospace',\n fontSize: '0.75rem'\n }}>{packageName}</code> package.\n </p>\n <div style={{\n backgroundColor: 'var(--dc-surface-secondary, #f3f4f6)',\n borderRadius: '0.5rem',\n padding: '0.75rem 1rem',\n fontFamily: 'monospace',\n fontSize: '0.875rem',\n color: 'var(--dc-text, #111827)'\n }}>\n <span style={{\n color: 'var(--dc-text-muted, #9ca3af)',\n userSelect: 'none'\n }}>$ </span>\n {installCommand}\n </div>\n <p style={{\n fontSize: '0.75rem',\n color: 'var(--dc-text-muted, #9ca3af)',\n marginTop: '0.75rem'\n }}>\n After installing, restart your development server.\n </p>\n </div>\n )\n}\n","/**\n * Lazy Chart Loader\n *\n * Provides React.lazy-based dynamic loading for chart components.\n * This enables code splitting - each chart type loads only when needed.\n *\n * Handles missing optional dependencies gracefully by showing a fallback\n * component instead of crashing the application.\n */\n\nimport { lazy, Suspense, ComponentType, ReactNode, LazyExoticComponent } from 'react'\nimport type { ChartType, ChartProps } from '../types'\nimport { MissingDependencyFallback } from '../components/charts/MissingDependencyFallback'\n\n// Type for lazy-loaded chart components\ntype LazyChartComponent = ComponentType<ChartProps>\n\n// Chart loader cache to prevent re-creating lazy components\nconst chartLoaderCache = new Map<ChartType, LazyExoticComponent<LazyChartComponent>>()\n\n// Track which chart types have failed to load due to missing dependencies\nconst failedChartTypes = new Set<ChartType>()\n\n/**\n * Maps chart types to their optional peer dependencies.\n * Charts not listed here have no external dependencies (table, KPIs, markdown).\n */\nconst chartDependencyMap: Partial<Record<ChartType, { packageName: string; installCommand: string }>> = {\n // Recharts-based charts\n bar: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n line: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n area: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n pie: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n scatter: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n radar: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n radialBar: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n treemap: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n bubble: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n funnel: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n sankey: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n sunburst: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n // Nivo-based charts\n heatmap: {\n packageName: '@nivo/heatmap',\n installCommand: 'npm install @nivo/heatmap'\n },\n waterfall: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n measureProfile: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n gauge: {\n packageName: 'd3-shape',\n installCommand: 'npm install d3-shape'\n },\n // Charts with no external deps: table, activityGrid, kpiNumber, kpiDelta, kpiText, markdown, retentionHeatmap, boxPlot, candlestick\n}\n\n// Dynamic import functions for each chart type\nconst chartImportMap: Record<ChartType, () => Promise<{ default: LazyChartComponent }>> = {\n bar: () => import('../components/charts/BarChart'),\n line: () => import('../components/charts/LineChart'),\n area: () => import('../components/charts/AreaChart'),\n pie: () => import('../components/charts/PieChart'),\n scatter: () => import('../components/charts/ScatterChart'),\n radar: () => import('../components/charts/RadarChart'),\n radialBar: () => import('../components/charts/RadialBarChart'),\n treemap: () => import('../components/charts/TreeMapChart'),\n bubble: () => import('../components/charts/BubbleChart'),\n table: () => import('../components/charts/DataTable'),\n activityGrid: () => import('../components/charts/ActivityGridChart'),\n kpiNumber: () => import('../components/charts/KpiNumber'),\n kpiDelta: () => import('../components/charts/KpiDelta'),\n kpiText: () => import('../components/charts/KpiText'),\n markdown: () => import('../components/charts/MarkdownChart'),\n funnel: () => import('../components/charts/FunnelChart'),\n sankey: () => import('../components/charts/SankeyChart'),\n sunburst: () => import('../components/charts/SunburstChart'),\n heatmap: () => import('../components/charts/HeatMapChart'),\n retentionHeatmap: () => import('../components/charts/RetentionHeatmap'),\n retentionCombined: () => import('../components/charts/RetentionCombinedChart'),\n boxPlot: () => import('../components/charts/BoxPlotChart'),\n waterfall: () => import('../components/charts/WaterfallChart'),\n candlestick: () => import('../components/charts/CandlestickChart'),\n measureProfile: () => import('../components/charts/MeasureProfileChart'),\n gauge: () => import('../components/charts/GaugeChart'),\n}\n\n/**\n * Creates a fallback component for a chart type with missing dependencies.\n */\nfunction createFallbackComponent(chartType: ChartType): LazyChartComponent {\n const depInfo = chartDependencyMap[chartType]\n\n const FallbackComponent: LazyChartComponent = ({ height }) => (\n <MissingDependencyFallback\n chartType={chartType}\n packageName={depInfo?.packageName || 'unknown'}\n installCommand={depInfo?.installCommand || `npm install [package-name]`}\n height={height}\n />\n )\n\n FallbackComponent.displayName = `${chartType}Fallback`\n return FallbackComponent\n}\n\n/**\n * Wraps a chart import function with error handling.\n * If the import fails (e.g., missing dependency), returns a fallback component.\n */\nfunction createSafeImport(\n chartType: ChartType,\n importFn: () => Promise<{ default: LazyChartComponent }>\n): () => Promise<{ default: LazyChartComponent }> {\n return async () => {\n try {\n return await importFn()\n } catch (error) {\n // Log the error for debugging\n console.warn(\n `[drizzle-cube] Failed to load ${chartType} chart:`,\n error instanceof Error ? error.message : error\n )\n\n // Track that this chart type failed\n failedChartTypes.add(chartType)\n\n // Return the fallback component wrapped in the expected format\n return { default: createFallbackComponent(chartType) }\n }\n }\n}\n\n/**\n * Get or create a lazy component for a chart type.\n * Handles import failures gracefully by returning a fallback component.\n */\nfunction getLazyChart(chartType: ChartType): LazyExoticComponent<LazyChartComponent> {\n if (!chartLoaderCache.has(chartType)) {\n const importFn = chartImportMap[chartType]\n if (!importFn) {\n throw new Error(`Unknown chart type: ${chartType}`)\n }\n // Wrap the import with error handling for graceful degradation\n const safeImport = createSafeImport(chartType, importFn)\n chartLoaderCache.set(chartType, lazy(safeImport))\n }\n return chartLoaderCache.get(chartType)!\n}\n\n/**\n * Check if a chart type is supported\n */\nexport function isValidChartType(chartType: string): chartType is ChartType {\n return chartType in chartImportMap\n}\n\n// Props for the LazyChart wrapper\nexport interface LazyChartProps extends ChartProps {\n chartType: ChartType\n fallback?: ReactNode\n}\n\n/**\n * Default loading placeholder for charts\n */\nfunction DefaultChartFallback({ height }: { height?: string | number }) {\n return (\n <div\n className=\"dc:flex dc:items-center dc:justify-center dc:w-full\"\n style={{ height: typeof height === 'number' ? `${height}px` : height || '200px' }}\n >\n <div className=\"dc:animate-pulse bg-dc-surface-secondary dc:rounded dc:w-full dc:h-full dc:min-h-[100px]\" />\n </div>\n )\n}\n\n/**\n * Lazy Chart Component\n *\n * Renders a chart component with React.lazy dynamic loading.\n * The chart type determines which chart component is loaded.\n *\n * @example\n * ```tsx\n * <LazyChart\n * chartType=\"bar\"\n * data={chartData}\n * chartConfig={{ yAxis: ['value'] }}\n * height={300}\n * />\n * ```\n */\nexport function LazyChart({\n chartType,\n fallback,\n height,\n ...chartProps\n}: LazyChartProps) {\n const ChartComponent = getLazyChart(chartType)\n\n return (\n <Suspense fallback={fallback ?? <DefaultChartFallback height={height} />}>\n <ChartComponent height={height} {...chartProps} />\n </Suspense>\n )\n}\n\n/**\n * Preload a chart type\n *\n * Triggers the dynamic import without rendering.\n * Useful for prefetching charts that will likely be needed.\n *\n * @example\n * ```tsx\n * // Preload bar chart on hover\n * onMouseEnter={() => preloadChart('bar')}\n * ```\n */\nexport function preloadChart(chartType: ChartType): void {\n const importFn = chartImportMap[chartType]\n if (importFn) {\n importFn()\n }\n}\n\n/**\n * Preload multiple chart types\n *\n * @example\n * ```tsx\n * // Preload common charts on app init\n * useEffect(() => {\n * preloadCharts(['bar', 'line', 'pie'])\n * }, [])\n * ```\n */\nexport function preloadCharts(chartTypes: ChartType[]): void {\n chartTypes.forEach(preloadChart)\n}\n\n/**\n * Get all available chart types\n */\nexport function getAvailableChartTypes(): ChartType[] {\n return Object.keys(chartImportMap) as ChartType[]\n}\n\n/**\n * Check if a chart type has loaded successfully.\n * Returns false if the chart failed to load due to missing dependencies.\n *\n * Note: This only returns accurate results after the chart has been attempted to load.\n * Use this for conditional UI logic (e.g., hiding unavailable chart types).\n */\nexport function isChartTypeAvailable(chartType: ChartType): boolean {\n return !failedChartTypes.has(chartType)\n}\n\n/**\n * Get list of chart types that failed to load due to missing dependencies.\n */\nexport function getUnavailableChartTypes(): ChartType[] {\n return Array.from(failedChartTypes)\n}\n"],"names":["MissingDependencyFallback","chartType","packageName","installCommand","height","jsxs","jsx","chartLoaderCache","failedChartTypes","chartDependencyMap","chartImportMap","n","createFallbackComponent","depInfo","FallbackComponent","createSafeImport","importFn","error","getLazyChart","safeImport","lazy","isValidChartType","DefaultChartFallback","LazyChart","fallback","chartProps","ChartComponent","Suspense","preloadChart","preloadCharts","chartTypes","getAvailableChartTypes","isChartTypeAvailable","getUnavailableChartTypes"],"mappings":"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"}
1
+ {"version":3,"file":"charts-loader-DbrwgvCK.js","sources":["../../../src/client/components/charts/MissingDependencyFallback.tsx","../../../src/client/charts/ChartLoader.tsx"],"sourcesContent":["interface MissingDependencyFallbackProps {\n chartType: string\n packageName: string\n installCommand: string\n height?: string | number\n}\n\n/**\n * Fallback component shown when a chart's optional dependency is not installed.\n * Provides clear instructions on how to install the missing package.\n */\nexport function MissingDependencyFallback({\n chartType,\n packageName,\n installCommand,\n height = 200\n}: MissingDependencyFallbackProps) {\n return (\n <div\n className=\"dc-missing-dependency-fallback\"\n style={{\n height: typeof height === 'number' ? `${height}px` : height,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n width: '100%',\n padding: '1.5rem',\n textAlign: 'center',\n border: '1px dashed var(--dc-border, #e5e7eb)',\n borderRadius: '0.5rem',\n backgroundColor: 'var(--dc-surface, #f9fafb)'\n }}\n >\n <div style={{ fontSize: '2.5rem', marginBottom: '1rem' }}>📦</div>\n <h3 style={{\n fontSize: '1.125rem',\n fontWeight: 600,\n marginBottom: '0.5rem',\n color: 'var(--dc-text, #111827)'\n }}>\n Missing Dependency\n </h3>\n <p style={{\n fontSize: '0.875rem',\n color: 'var(--dc-text-secondary, #6b7280)',\n marginBottom: '1rem',\n maxWidth: '28rem'\n }}>\n The <code style={{\n padding: '0.125rem 0.375rem',\n backgroundColor: 'var(--dc-surface-secondary, #f3f4f6)',\n borderRadius: '0.25rem',\n fontFamily: 'monospace',\n fontSize: '0.75rem'\n }}>{chartType}</code> chart requires the <code style={{\n padding: '0.125rem 0.375rem',\n backgroundColor: 'var(--dc-surface-secondary, #f3f4f6)',\n borderRadius: '0.25rem',\n fontFamily: 'monospace',\n fontSize: '0.75rem'\n }}>{packageName}</code> package.\n </p>\n <div style={{\n backgroundColor: 'var(--dc-surface-secondary, #f3f4f6)',\n borderRadius: '0.5rem',\n padding: '0.75rem 1rem',\n fontFamily: 'monospace',\n fontSize: '0.875rem',\n color: 'var(--dc-text, #111827)'\n }}>\n <span style={{\n color: 'var(--dc-text-muted, #9ca3af)',\n userSelect: 'none'\n }}>$ </span>\n {installCommand}\n </div>\n <p style={{\n fontSize: '0.75rem',\n color: 'var(--dc-text-muted, #9ca3af)',\n marginTop: '0.75rem'\n }}>\n After installing, restart your development server.\n </p>\n </div>\n )\n}\n","/**\n * Lazy Chart Loader\n *\n * Provides React.lazy-based dynamic loading for chart components.\n * This enables code splitting - each chart type loads only when needed.\n *\n * Handles missing optional dependencies gracefully by showing a fallback\n * component instead of crashing the application.\n */\n\nimport { lazy, Suspense, ComponentType, ReactNode, LazyExoticComponent } from 'react'\nimport type { ChartType, ChartProps } from '../types'\nimport { MissingDependencyFallback } from '../components/charts/MissingDependencyFallback'\n\n// Type for lazy-loaded chart components\ntype LazyChartComponent = ComponentType<ChartProps>\n\n// Chart loader cache to prevent re-creating lazy components\nconst chartLoaderCache = new Map<ChartType, LazyExoticComponent<LazyChartComponent>>()\n\n// Track which chart types have failed to load due to missing dependencies\nconst failedChartTypes = new Set<ChartType>()\n\n/**\n * Maps chart types to their optional peer dependencies.\n * Charts not listed here have no external dependencies (table, KPIs, markdown).\n */\nconst chartDependencyMap: Partial<Record<ChartType, { packageName: string; installCommand: string }>> = {\n // Recharts-based charts\n bar: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n line: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n area: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n pie: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n scatter: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n radar: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n radialBar: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n treemap: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n bubble: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n funnel: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n sankey: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n sunburst: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n // Nivo-based charts\n heatmap: {\n packageName: '@nivo/heatmap',\n installCommand: 'npm install @nivo/heatmap'\n },\n waterfall: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n measureProfile: {\n packageName: 'recharts',\n installCommand: 'npm install recharts'\n },\n gauge: {\n packageName: 'd3-shape',\n installCommand: 'npm install d3-shape'\n },\n // Charts with no external deps: table, activityGrid, kpiNumber, kpiDelta, kpiText, markdown, retentionHeatmap, boxPlot, candlestick\n}\n\n// Dynamic import functions for each chart type\nconst chartImportMap: Record<ChartType, () => Promise<{ default: LazyChartComponent }>> = {\n bar: () => import('../components/charts/BarChart'),\n line: () => import('../components/charts/LineChart'),\n area: () => import('../components/charts/AreaChart'),\n pie: () => import('../components/charts/PieChart'),\n scatter: () => import('../components/charts/ScatterChart'),\n radar: () => import('../components/charts/RadarChart'),\n radialBar: () => import('../components/charts/RadialBarChart'),\n treemap: () => import('../components/charts/TreeMapChart'),\n bubble: () => import('../components/charts/BubbleChart'),\n table: () => import('../components/charts/DataTable'),\n activityGrid: () => import('../components/charts/ActivityGridChart'),\n kpiNumber: () => import('../components/charts/KpiNumber'),\n kpiDelta: () => import('../components/charts/KpiDelta'),\n kpiText: () => import('../components/charts/KpiText'),\n markdown: () => import('../components/charts/MarkdownChart'),\n funnel: () => import('../components/charts/FunnelChart'),\n sankey: () => import('../components/charts/SankeyChart'),\n sunburst: () => import('../components/charts/SunburstChart'),\n heatmap: () => import('../components/charts/HeatMapChart'),\n retentionHeatmap: () => import('../components/charts/RetentionHeatmap'),\n retentionCombined: () => import('../components/charts/RetentionCombinedChart'),\n boxPlot: () => import('../components/charts/BoxPlotChart'),\n waterfall: () => import('../components/charts/WaterfallChart'),\n candlestick: () => import('../components/charts/CandlestickChart'),\n measureProfile: () => import('../components/charts/MeasureProfileChart'),\n gauge: () => import('../components/charts/GaugeChart'),\n}\n\n/**\n * Creates a fallback component for a chart type with missing dependencies.\n */\nfunction createFallbackComponent(chartType: ChartType): LazyChartComponent {\n const depInfo = chartDependencyMap[chartType]\n\n const FallbackComponent: LazyChartComponent = ({ height }) => (\n <MissingDependencyFallback\n chartType={chartType}\n packageName={depInfo?.packageName || 'unknown'}\n installCommand={depInfo?.installCommand || `npm install [package-name]`}\n height={height}\n />\n )\n\n FallbackComponent.displayName = `${chartType}Fallback`\n return FallbackComponent\n}\n\n/**\n * Wraps a chart import function with error handling.\n * If the import fails (e.g., missing dependency), returns a fallback component.\n */\nfunction createSafeImport(\n chartType: ChartType,\n importFn: () => Promise<{ default: LazyChartComponent }>\n): () => Promise<{ default: LazyChartComponent }> {\n return async () => {\n try {\n return await importFn()\n } catch (error) {\n // Log the error for debugging\n console.warn(\n `[drizzle-cube] Failed to load ${chartType} chart:`,\n error instanceof Error ? error.message : error\n )\n\n // Track that this chart type failed\n failedChartTypes.add(chartType)\n\n // Return the fallback component wrapped in the expected format\n return { default: createFallbackComponent(chartType) }\n }\n }\n}\n\n/**\n * Get or create a lazy component for a chart type.\n * Handles import failures gracefully by returning a fallback component.\n */\nfunction getLazyChart(chartType: ChartType): LazyExoticComponent<LazyChartComponent> {\n if (!chartLoaderCache.has(chartType)) {\n const importFn = chartImportMap[chartType]\n if (!importFn) {\n throw new Error(`Unknown chart type: ${chartType}`)\n }\n // Wrap the import with error handling for graceful degradation\n const safeImport = createSafeImport(chartType, importFn)\n chartLoaderCache.set(chartType, lazy(safeImport))\n }\n return chartLoaderCache.get(chartType)!\n}\n\n/**\n * Check if a chart type is supported\n */\nexport function isValidChartType(chartType: string): chartType is ChartType {\n return chartType in chartImportMap\n}\n\n// Props for the LazyChart wrapper\nexport interface LazyChartProps extends ChartProps {\n chartType: ChartType\n fallback?: ReactNode\n}\n\n/**\n * Default loading placeholder for charts\n */\nfunction DefaultChartFallback({ height }: { height?: string | number }) {\n return (\n <div\n className=\"dc:flex dc:items-center dc:justify-center dc:w-full\"\n style={{ height: typeof height === 'number' ? `${height}px` : height || '200px' }}\n >\n <div className=\"dc:animate-pulse bg-dc-surface-secondary dc:rounded dc:w-full dc:h-full dc:min-h-[100px]\" />\n </div>\n )\n}\n\n/**\n * Lazy Chart Component\n *\n * Renders a chart component with React.lazy dynamic loading.\n * The chart type determines which chart component is loaded.\n *\n * @example\n * ```tsx\n * <LazyChart\n * chartType=\"bar\"\n * data={chartData}\n * chartConfig={{ yAxis: ['value'] }}\n * height={300}\n * />\n * ```\n */\nexport function LazyChart({\n chartType,\n fallback,\n height,\n ...chartProps\n}: LazyChartProps) {\n const ChartComponent = getLazyChart(chartType)\n\n return (\n <Suspense fallback={fallback ?? <DefaultChartFallback height={height} />}>\n <ChartComponent height={height} {...chartProps} />\n </Suspense>\n )\n}\n\n/**\n * Preload a chart type\n *\n * Triggers the dynamic import without rendering.\n * Useful for prefetching charts that will likely be needed.\n *\n * @example\n * ```tsx\n * // Preload bar chart on hover\n * onMouseEnter={() => preloadChart('bar')}\n * ```\n */\nexport function preloadChart(chartType: ChartType): void {\n const importFn = chartImportMap[chartType]\n if (importFn) {\n importFn()\n }\n}\n\n/**\n * Preload multiple chart types\n *\n * @example\n * ```tsx\n * // Preload common charts on app init\n * useEffect(() => {\n * preloadCharts(['bar', 'line', 'pie'])\n * }, [])\n * ```\n */\nexport function preloadCharts(chartTypes: ChartType[]): void {\n chartTypes.forEach(preloadChart)\n}\n\n/**\n * Get all available chart types\n */\nexport function getAvailableChartTypes(): ChartType[] {\n return Object.keys(chartImportMap) as ChartType[]\n}\n\n/**\n * Check if a chart type has loaded successfully.\n * Returns false if the chart failed to load due to missing dependencies.\n *\n * Note: This only returns accurate results after the chart has been attempted to load.\n * Use this for conditional UI logic (e.g., hiding unavailable chart types).\n */\nexport function isChartTypeAvailable(chartType: ChartType): boolean {\n return !failedChartTypes.has(chartType)\n}\n\n/**\n * Get list of chart types that failed to load due to missing dependencies.\n */\nexport function getUnavailableChartTypes(): ChartType[] {\n return Array.from(failedChartTypes)\n}\n"],"names":["MissingDependencyFallback","chartType","packageName","installCommand","height","jsxs","jsx","chartLoaderCache","failedChartTypes","chartDependencyMap","chartImportMap","n","createFallbackComponent","depInfo","FallbackComponent","createSafeImport","importFn","error","getLazyChart","safeImport","lazy","isValidChartType","DefaultChartFallback","LazyChart","fallback","chartProps","ChartComponent","Suspense","preloadChart","preloadCharts","chartTypes","getAvailableChartTypes","isChartTypeAvailable","getUnavailableChartTypes"],"mappings":"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"}
@@ -1,17 +1,17 @@
1
1
  import { jsxs as u, jsx as r, Fragment as be } from "react/jsx-runtime";
2
2
  import ct, { Component as sn, useRef as Z, useState as j, useEffect as ce, useMemo as J, useCallback as w, forwardRef as Nr, useImperativeHandle as on, createContext as an, useContext as qt, Suspense as ln, lazy as un, memo as Dr, startTransition as St } from "react";
3
- import { j as mn, u as fn, c as kr, d as hn, e as pn, s as gn, f as Ut } from "./vendor-AVsJ2ni0.js";
4
- import { c as yn, u as Tr, g as vt, k as bn, l as xn, S as Sr, e as vn } from "./providers-CgxXm6Ll.js";
5
- import { a as G, g as Mr, i as gt } from "./icons-M7shurcH.js";
6
- import { L as Fr, S as wn, A as Cn } from "./charts-core-CU9u_HtL.js";
3
+ import { j as mn, u as fn, e as kr, f as hn, h as pn, s as gn, i as Ut } from "./vendor-B2EH3V58.js";
4
+ import { c as yn, u as Tr, g as vt, k as bn, l as xn, S as Sr, e as vn } from "./providers-CCw8Kjlc.js";
5
+ import { a as G, g as Mr, i as gt } from "./icons-DFJw-2HU.js";
6
+ import { L as Fr, S as wn, A as Cn } from "./charts-core-B4Rbfdcn.js";
7
7
  import { createPortal as Pr } from "react-dom";
8
- import { i as Nn, L as Dn } from "./charts-loader-B3tt5oKG.js";
8
+ import { i as Nn, L as Dn } from "./charts-loader-DbrwgvCK.js";
9
9
  import { useChartConfig as Ir } from "../charts.js";
10
10
  import { a as kn } from "./flow-utils-CjQZG5qq.js";
11
11
  import { h as Er, g as Lr, d as Tn, D as $r } from "./retention-CzCo8262.js";
12
- import { u as Sn, a as Mn, b as Fn, d as Pn, o as In, t as Gt, z as Yt, A as Jt, p as Ar, q as Xt, r as Rr, D as Mt, s as at, n as dt, F as Or, B as En, y as Ln, x as $n } from "./useDirtyStateTracking-Cu1HSjmo.js";
12
+ import { u as Sn, a as Mn, b as Fn, e as Pn, p as In, c as Gt, z as Yt, A as Jt, q as Ar, r as Xt, t as Rr, D as Mt, w as at, o as dt, F as Or, B as En, y as Ln, x as $n } from "./useDirtyStateTracking-CjhwBXRw.js";
13
13
  import An, { verticalCompactor as Rn } from "react-grid-layout";
14
- import { l as On, g as qn } from "./syntaxHighlighting-BQfjio-i.js";
14
+ import { l as On, g as qn } from "./syntaxHighlighting-DAMSW_A6.js";
15
15
  import { M as Bn } from "./chart-markdown-Du4Z2iqK.js";
16
16
  import "./index-CApFCBF9.js";
17
17
  const jn = G("refresh");
@@ -3950,7 +3950,7 @@ const Bt = ({
3950
3950
  )
3951
3951
  }
3952
3952
  ) : null;
3953
- }, zc = un(() => import("./analysis-builder-3z9fHE2F.js")), Gr = Nr((e, t) => /* @__PURE__ */ r(
3953
+ }, zc = un(() => import("./analysis-builder-DVrv9Q4n.js")), Gr = Nr((e, t) => /* @__PURE__ */ r(
3954
3954
  ln,
3955
3955
  {
3956
3956
  fallback: /* @__PURE__ */ r("div", { className: "dc:flex dc:items-center dc:justify-center dc:w-full dc:py-6", children: /* @__PURE__ */ r(Fr, {}) }),
@@ -10063,4 +10063,4 @@ export {
10063
10063
  ro as y,
10064
10064
  no as z
10065
10065
  };
10066
- //# sourceMappingURL=components-CMGGxqOB.js.map
10066
+ //# sourceMappingURL=components-GzooQM5J.js.map