web-mojo 2.1.1110 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin.cjs.js +1 -1
- package/dist/admin.cjs.js.map +1 -1
- package/dist/admin.es.js +4 -4
- package/dist/admin.es.js.map +1 -1
- package/dist/auth.cjs.js +1 -1
- package/dist/auth.es.js +1 -1
- package/dist/charts.cjs.js +1 -1
- package/dist/charts.css +61 -20
- package/dist/charts.es.js +2 -2
- package/dist/chunks/{MetricsMiniChartWidget-BJJY9R-s.js → MetricsMiniChartWidget-CTPAXwFC.js} +2 -2
- package/dist/chunks/MetricsMiniChartWidget-CTPAXwFC.js.map +1 -0
- package/dist/chunks/{MetricsMiniChartWidget-bmnV82d1.js → MetricsMiniChartWidget-DaP5lSll.js} +194 -205
- package/dist/chunks/{MetricsMiniChartWidget-bmnV82d1.js.map → MetricsMiniChartWidget-DaP5lSll.js.map} +1 -1
- package/dist/chunks/version-YvYg2w4d.js +2 -0
- package/dist/chunks/version-YvYg2w4d.js.map +1 -0
- package/dist/chunks/{version-FRgkiWti.js → version-uoDXr8WG.js} +5 -5
- package/dist/chunks/version-uoDXr8WG.js.map +1 -0
- package/dist/css/web-mojo.css +1 -1
- package/dist/docit.cjs.js +1 -1
- package/dist/docit.es.js +1 -1
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +1 -1
- package/dist/lightbox.cjs.js +1 -1
- package/dist/lightbox.es.js +1 -1
- package/package.json +1 -1
- package/dist/chunks/MetricsMiniChartWidget-BJJY9R-s.js.map +0 -1
- package/dist/chunks/version-C5lFa1F0.js +0 -2
- package/dist/chunks/version-C5lFa1F0.js.map +0 -1
- package/dist/chunks/version-FRgkiWti.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MetricsMiniChartWidget-bmnV82d1.js","sources":["../../src/extensions/charts/BaseChart.js","../../src/extensions/charts/SeriesChart.js","../../src/extensions/charts/PieChart.js","../../src/extensions/charts/MetricsChart.js","../../src/extensions/charts/MiniChart.js","../../src/extensions/charts/MetricsMiniChart.js","../../src/extensions/charts/MetricsMiniChartWidget.js"],"sourcesContent":["/**\n * BaseChart - Foundation class for all chart components in MOJO framework\n * Uses Chart.js 4.x with API integration, refresh capabilities, and event system\n */\n\nimport View from '@core/View.js';\nimport WebSocketClient from '@core/services/WebSocketClient.js';\nimport dataFormatter from '@core/utils/DataFormatter.js';\n\nexport default class BaseChart extends View {\n constructor(options = {}) {\n super({\n ...options,\n className: `chart-component ${options.className || ''}`,\n tagName: 'div'\n });\n\n // Chart.js instance\n this.chart = null;\n this.chartType = options.chartType || 'line';\n\n // Data source options\n this.endpoint = options.endpoint || null;\n this.data = options.data || null;\n this.dataTransform = options.dataTransform || null; // Function to transform API data\n\n // Refresh options\n this.refreshInterval = options.refreshInterval || null; // ms\n this.autoRefresh = options.autoRefresh !== false;\n this.refreshTimer = null;\n\n // WebSocket for real-time updates\n this.websocketUrl = options.websocketUrl || null;\n this.websocket = null;\n this.websocketReconnect = options.websocketReconnect !== false;\n\n // Dimensions\n this.width = options.width || null;\n this.height = options.height || null;\n // Precompute inline content style for initial render (Mustache section)\n this.contentStyle = [\n this.width ? `width: ${this.width}px;` : '',\n this.height ? `height: ${this.height}px;` : ''\n ].filter(Boolean).join(' ');\n if (options.maintainAspectRatio === undefined) {\n options.maintainAspectRatio = true;\n }\n\n // Chart configuration\n this.title = options.title || '';\n this.chartTitle = options.chartTitle || '';\n this.chartOptions = {\n responsive: true,\n maintainAspectRatio: options.maintainAspectRatio,\n interaction: {\n intersect: false,\n mode: 'index'\n },\n plugins: {\n legend: {\n display: options.showLegend !== false,\n position: options.legendPosition || 'top'\n },\n title: {\n display: !!this.chartTitle,\n text: this.chartTitle\n },\n tooltip: {\n enabled: options.showTooltips !== false,\n backgroundColor: 'rgba(0,0,0,0.8)',\n titleColor: '#fff',\n bodyColor: '#fff',\n borderColor: 'rgba(255,255,255,0.1)',\n borderWidth: 1\n }\n },\n ...options.chartOptions\n };\n\n // Axis configuration with DataFormatter support\n this.xAxis = options.xAxis || null;\n this.yAxis = options.yAxis || null;\n this.tooltipFormatters = options.tooltip || {};\n\n // Theme and appearance\n this.theme = options.theme || 'light';\n this.colorScheme = options.colorScheme || 'default';\n this.animations = options.animations !== false;\n\n // Export options\n this.exportEnabled = options.exportEnabled === true;\n this.exportFormats = options.exportFormats || ['png', 'jpg', 'csv'];\n\n // State\n this.isLoading = false;\n this.hasError = false;\n this.lastFetch = null;\n this.dataPoints = 0;\n\n // Canvas element\n this.canvas = null;\n\n // Chart.js CDN URL - can be customized\n this.chartJsCdn = options.chartJsCdn || 'https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.js';\n\n // DataFormatter instance (use singleton)\n this.dataFormatter = dataFormatter;\n\n // Template data properties (available to Mustache)\n\n // Store essential listeners for cleanup\n this._essentialListeners = [];\n }\n\n get refreshEnabled() {\n return !!(this.endpoint || this.websocketUrl);\n }\n\n buildDefaultHeaderConfig() {\n return {\n titleHtml: this.title || '',\n chartTitle: this.chartTitle || '',\n showExport: this.exportEnabled === true,\n showRefresh: this.refreshEnabled,\n showTheme: true,\n controls: []\n };\n }\n\n async getTemplate() {\n return `\n <div class=\"chart-container\" data-theme=\"{{theme}}\">\n <div class=\"chart-header mb-3\">\n <div data-container=\"header\"></div>\n <div class=\"chart-header-aux mt-2\">\n <div data-container=\"header-aux\"></div>\n </div>\n </div>\n\n <div class=\"chart-content position-relative\" {{#contentStyle}}style=\"{{contentStyle}}\"{{/contentStyle}}>\n <canvas class=\"chart-canvas\" data-container=\"canvas\"></canvas>\n\n <!-- Loading overlay -->\n <div class=\"chart-overlay d-none\" data-loading>\n <div class=\"d-flex flex-column align-items-center\">\n <div class=\"spinner-border text-primary mb-2\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n <small class=\"text-muted\">Loading chart data...</small>\n </div>\n </div>\n\n <!-- Error overlay -->\n <div class=\"chart-overlay d-none\" data-error>\n <div class=\"alert alert-danger mb-0\" role=\"alert\">\n <div class=\"d-flex align-items-center\">\n <i class=\"bi bi-exclamation-triangle me-2\"></i>\n <div class=\"flex-grow-1\">\n <strong>Error:</strong> <span class=\"error-message\">Failed to load chart data</span>\n </div>\n <button class=\"btn btn-sm btn-outline-danger ms-2\" data-action=\"retry-load\">\n <i class=\"bi bi-arrow-clockwise\"></i> Retry\n </button>\n </div>\n </div>\n </div>\n\n <!-- No data overlay -->\n <div class=\"chart-overlay d-none\" data-no-data>\n <div class=\"text-center text-muted\">\n <i class=\"bi bi-bar-chart display-4 mb-3 opacity-50\"></i>\n <p class=\"mb-0\">No data available</p>\n {{#refreshEnabled}}\n <button class=\"btn btn-sm btn-outline-secondary mt-2\" data-action=\"refresh-chart\">\n <i class=\"bi bi-arrow-clockwise\"></i> Refresh\n </button>\n {{/refreshEnabled}}\n </div>\n </div>\n\n <!-- WebSocket status indicator -->\n <div class=\"position-absolute top-0 end-0 mt-2 me-2\">\n <span class=\"badge bg-success websocket-status\" style=\"display: none;\" data-websocket-status>\n <i class=\"bi bi-wifi\"></i> Live\n </span>\n </div>\n </div>\n\n <div class=\"chart-footer mt-2\" style=\"display: none;\">\n <div class=\"row\">\n <div class=\"col\">\n <small class=\"text-muted\">\n <i class=\"bi bi-graph-up me-1\"></i>\n <span class=\"data-points\">0 data points</span>\n </small>\n </div>\n <div class=\"col text-end\">\n <small class=\"text-muted refresh-info\">\n Auto-refresh: <span class=\"refresh-status\">Off</span>\n </small>\n </div>\n </div>\n </div>\n </div>\n `;\n }\n\n async onInit() {\n // Initialize Chart.js\n await this.initializeChartJS();\n\n // Build and create header view in onInit\n try {\n const headerConfig = this.headerConfig || (this.buildDefaultHeaderConfig ? this.buildDefaultHeaderConfig() : null);\n if (headerConfig) {\n this.headerView = new ChartHeaderView({ ...headerConfig, containerId: 'header' });\n this.addChild(this.headerView);\n }\n } catch (e) {\n // Header is optional; ignore if missing\n console.debug('ChartHeaderView not available:', e?.message);\n }\n }\n\n async onAfterRender() {\n // Cache DOM elements\n this.canvas = this.element.querySelector('.chart-canvas');\n this.titleElement = this.element.querySelector('.chart-title');\n this.contentElement = this.element.querySelector('.chart-content');\n this.footerElement = this.element.querySelector('.chart-footer');\n\n // Overlay elements\n this.loadingOverlay = this.element.querySelector('[data-loading]');\n this.errorOverlay = this.element.querySelector('[data-error]');\n this.noDataOverlay = this.element.querySelector('[data-no-data]');\n this.websocketStatus = this.element.querySelector('[data-websocket-status]');\n\n // Control elements\n this.refreshBtn = this.element.querySelector('.refresh-btn');\n this.themeToggle = this.element.querySelector('.theme-toggle');\n\n // Apply initial theme\n this.applyTheme();\n\n // Header is created in onInit\n\n // First-time data fetch occurs here, before creating the chart\n if (this.endpoint) {\n await this.fetchData(); // fetchData will call updateChart() which creates the chart\n await this.updateChart(this.data, true);\n if (this.height || this.width) {\n this._updateChartDimensions();\n }\n } else if (this.data) {\n await this.updateChart(this.data, true);\n if (this.height || this.width) {\n this._updateChartDimensions();\n }\n } else {\n this.showNoData();\n }\n\n // Set up auto-refresh\n if (this.autoRefresh && this.refreshInterval && this.endpoint) {\n this.startAutoRefresh();\n }\n\n // Set up WebSocket\n if (this.websocketUrl) {\n await this.connectWebSocket();\n }\n\n // Set up resize observer\n this.setupResizeObserver();\n\n // Show footer with stats\n this.showFooter();\n }\n\n async initializeChartJS() {\n try {\n // Load Chart.js if not already loaded\n if (typeof window.Chart === 'undefined') {\n await this.loadChartJS();\n }\n\n return true;\n } catch (error) {\n console.error('Failed to initialize Chart.js:', error);\n this.showError('Failed to initialize charting library');\n return false;\n }\n }\n\n async loadChartJS() {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src = this.chartJsCdn;\n script.onload = () => {\n console.log('Chart.js loaded successfully');\n resolve();\n };\n script.onerror = () => {\n reject(new Error('Failed to load Chart.js'));\n };\n document.head.appendChild(script);\n });\n }\n\n // Action Handlers (EventDelegate)\n async handleActionRefreshChart() {\n await this.fetchData();\n }\n\n async handleActionRetryLoad() {\n this.hideError();\n await this.fetchData();\n }\n\n async handleActionExportChart(event, element) {\n const format = element.getAttribute('data-format') || 'png';\n this.exportChart(format);\n }\n\n async handleActionToggleTheme() {\n this.toggleTheme();\n }\n\n async handleActionSetChartType(event, element) {\n const type = element.getAttribute('data-type');\n if (type && this.setChartType) {\n await this.setChartType(type);\n }\n }\n\n // Data Management\n async fetchData() {\n if (!this.endpoint) return;\n\n this.showLoading();\n this.setRefreshButtonState(true);\n\n try {\n const response = await fetch(this.endpoint, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json'\n }\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n let data = await response.json();\n\n // Transform data if transformer provided\n if (this.dataTransform && typeof this.dataTransform === 'function') {\n data = this.dataTransform(data);\n }\n\n this.lastFetch = new Date();\n this.data = data;\n this.updateLastUpdatedTime();\n\n // Emit success event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('chart:data-loaded', {\n chart: this,\n data,\n source: 'http',\n endpoint: this.endpoint\n });\n }\n\n } catch (error) {\n console.error('Failed to fetch chart data:', error);\n this.showError(`Failed to load data: ${error.message}`);\n\n // Emit error event\n this.emit('chart:error', {\n chart: this,\n error,\n source: 'http',\n endpoint: this.endpoint\n });\n } finally {\n this.hideLoading();\n this.setRefreshButtonState(false);\n }\n }\n\n async connectWebSocket() {\n if (!this.websocketUrl) return;\n\n try {\n this.websocket = new WebSocketClient({\n url: this.websocketUrl,\n autoReconnect: this.websocketReconnect,\n dataTransform: this.dataTransform,\n eventBus: this.getApp()?.events,\n debug: false\n });\n\n // Set up WebSocket event handlers\n this.websocket.on('connected', () => {\n this.showWebSocketStatus(true);\n console.log('WebSocket connected for chart data');\n });\n\n this.websocket.on('disconnected', () => {\n this.showWebSocketStatus(false);\n console.log('WebSocket disconnected');\n });\n\n this.websocket.on('data', async (data) => {\n await this.updateChart(data);\n this.updateLastUpdatedTime();\n\n // Emit real-time update event\n this.emit('chart:data-updated', {\n chart: this,\n data,\n source: 'websocket'\n });\n });\n\n this.websocket.on('error', (error) => {\n console.error('WebSocket error:', error);\n this.showWebSocketStatus(false, 'error');\n });\n\n // Connect\n await this.websocket.connect();\n\n } catch (error) {\n console.error('Failed to connect WebSocket:', error);\n this.showWebSocketStatus(false, 'error');\n }\n }\n\n async updateChart(data, recreate=false) {\n if (!data) {\n this.showNoData();\n return;\n }\n\n this.data = data;\n\n // If canvas is not ready yet (called before render), defer chart creation\n if (!this.canvas || typeof window.Chart === 'undefined') {\n return;\n }\n\n this.hideAllOverlays();\n\n // Process data with axis formatters\n const processedData = this.processChartData(data);\n\n if (recreate && this.chart) {\n this.chart.destroy();\n this.chart = null;\n }\n\n if (this.chart) {\n // Update existing chart\n this.chart.data = processedData;\n this.chart.update('none'); // No animation for real-time updates\n } else {\n // Create new chart\n await this.createChart(processedData);\n }\n\n // Update stats\n this.updateDataStats(processedData);\n\n if (this.height || this.width) {\n this._updateChartDimensions();\n }\n\n }\n\n processChartData(data) {\n // This method should be overridden by subclasses\n // Base implementation just applies formatters to labels if configured\n\n let processedData = { ...data };\n\n // Apply formatters to labels if xAxis formatter is configured (normalized)\n const xAxisCfg = this.normalizeAxis(this.xAxis);\n if (xAxisCfg && xAxisCfg.formatter && processedData.labels) {\n processedData.labels = processedData.labels.map(label =>\n this.dataFormatter.pipe(label, xAxisCfg.formatter)\n );\n }\n\n return processedData;\n }\n\n async createChart(data) {\n if (!this.canvas || typeof window.Chart === 'undefined') {\n throw new Error('Chart.js not loaded or canvas not found');\n }\n\n // Chart.js handles canvas dimensions internally\n // Container dimensions are set via CSS in template\n\n // Build chart configuration\n const config = {\n type: this.chartType,\n data: data,\n options: this.buildChartOptions()\n };\n\n try {\n this.chart = new window.Chart(this.canvas, config);\n\n // Set up chart event handlers\n this.setupChartEventHandlers();\n\n } catch (error) {\n console.error('Failed to create chart:', error);\n throw error;\n }\n }\n\n buildChartOptions() {\n const options = { ...this.chartOptions };\n\n // Handle custom dimensions\n if (this.width || this.height) {\n options.responsive = true;\n options.maintainAspectRatio = false;\n }\n\n // Build scales from normalized axis configs\n const xAxisCfg = this.normalizeAxis(this.xAxis);\n const yAxisCfg = this.normalizeAxis(this.yAxis);\n\n options.scales = options.scales || {};\n\n // X-axis\n options.scales.x = {\n type: this._detectAxisType(this.data, xAxisCfg, 'x'),\n display: true,\n title: {\n display: !!xAxisCfg.label,\n text: xAxisCfg.label || ''\n },\n grid: { display: true },\n ticks: {}\n };\n if (xAxisCfg.formatter) {\n options.scales.x.ticks.callback = this._createFormatterCallback(xAxisCfg.formatter);\n }\n\n // Y-axis\n options.scales.y = {\n type: this._detectAxisType(this.data, yAxisCfg, 'y'),\n display: true,\n beginAtZero: yAxisCfg.beginAtZero !== false,\n title: {\n display: !!yAxisCfg.label,\n text: yAxisCfg.label || ''\n },\n grid: { display: true },\n ticks: {}\n };\n if (yAxisCfg.formatter) {\n options.scales.y.ticks.callback = this._createFormatterCallback(yAxisCfg.formatter);\n }\n\n // Apply theme colors\n this.applyThemeToOptions(options);\n\n // Configure tooltips with formatters\n if (this.tooltipFormatters.x || this.tooltipFormatters.y) {\n options.plugins = options.plugins || {};\n options.plugins.tooltip = options.plugins.tooltip || {};\n options.plugins.tooltip.callbacks = options.plugins.tooltip.callbacks || {};\n\n if (this.tooltipFormatters.x) {\n options.plugins.tooltip.callbacks.title = (context) => {\n const value = context[0]?.label;\n return value ? this.dataFormatter.pipe(value, this.tooltipFormatters.x) : value;\n };\n }\n\n if (this.tooltipFormatters.y) {\n options.plugins.tooltip.callbacks.label = (context) => {\n const value = context.raw;\n const formattedValue = this.dataFormatter.pipe(value, this.tooltipFormatters.y);\n return `${context.dataset.label}: ${formattedValue}`;\n };\n }\n }\n\n // Allow subclasses to tweak chart options (e.g., indexAxis, stacking)\n if (typeof this.applySubclassChartOptions === 'function') {\n this.applySubclassChartOptions(options);\n }\n\n return options;\n }\n\n // Helper method to create Chart.js callback from MOJO formatter\n _createFormatterCallback(formatter) {\n if (!formatter) return null;\n\n return (value) => {\n try {\n return this.dataFormatter.pipe(value, formatter);\n } catch (error) {\n console.warn(`Chart formatter error:`, error);\n return value;\n }\n };\n }\n\n // Normalize axis configuration into a consistent object\n normalizeAxis(axisConfig) {\n if (!axisConfig) return {};\n if (typeof axisConfig === 'string') {\n // Simple formatter shorthand\n return { formatter: axisConfig };\n }\n if (typeof axisConfig === 'object') {\n const { formatter, label, type, beginAtZero, ...rest } = axisConfig;\n return { formatter, label, type, beginAtZero, ...rest };\n }\n return {};\n }\n\n // Smart axis type detection from data\n _detectAxisType(data, axisConfig, axisName = 'x') {\n // If user explicitly set the type, use it\n if (axisConfig && axisConfig.type) {\n return axisConfig.type;\n }\n\n // If formatter suggests a type\n if (axisConfig && axisConfig.formatter) {\n const formatter = axisConfig.formatter.toLowerCase();\n if (formatter.includes('date') || formatter.includes('time')) {\n return 'time';\n }\n }\n\n // Auto-detect from data based on axis\n if (data) {\n if (axisName === 'x' && data.labels && data.labels.length > 0) {\n // X-axis: check labels\n const firstLabel = data.labels[0];\n\n // Check if labels are strings (category axis)\n if (typeof firstLabel === 'string') {\n // If it's a string that's not purely numeric, treat as category\n // This handles cases like \"01:00\", \"Jan\", \"Q1 2023\", etc.\n if (!/^\\d+\\.?\\d*$/.test(firstLabel.trim())) {\n return 'category';\n }\n }\n\n // Check if labels are dates\n if (firstLabel instanceof Date ||\n (typeof firstLabel === 'string' && !isNaN(Date.parse(firstLabel)))) {\n return 'time';\n }\n\n // Numeric labels default to linear\n return 'linear';\n } else if (axisName === 'y' && data.datasets && data.datasets.length > 0) {\n // Y-axis: check data values\n const firstDataset = data.datasets[0];\n if (firstDataset.data && firstDataset.data.length > 0) {\n const firstValue = firstDataset.data[0];\n\n // If it's numeric data, use linear\n if (typeof firstValue === 'number' || !isNaN(parseFloat(firstValue))) {\n return 'linear';\n }\n\n // If it's string data, use category\n return 'category';\n }\n }\n }\n\n // Default based on axis\n return axisName === 'x' ? 'category' : 'linear';\n }\n\n setupChartEventHandlers() {\n if (!this.chart) return;\n\n // Click events\n this.chart.options.onClick = (event, elements) => {\n if (elements.length > 0) {\n const element = elements[0];\n const datasetIndex = element.datasetIndex;\n const index = element.index;\n const value = this.chart.data.datasets[datasetIndex].data[index];\n const label = this.chart.data.labels[index];\n\n // Emit click event\n this.emit('chart:point-clicked', {\n chart: this,\n datasetIndex,\n index,\n value,\n label,\n dataset: this.chart.data.datasets[datasetIndex]\n });\n }\n };\n\n // Hover events\n this.chart.options.onHover = (event, elements) => {\n this.canvas.style.cursor = elements.length > 0 ? 'pointer' : 'default';\n };\n }\n\n // Theme Management\n applyTheme() {\n this.element.setAttribute('data-theme', this.theme);\n\n if (this.chart) {\n this.chart.options = this.buildChartOptions();\n this.chart.update('none');\n }\n }\n\n applyThemeToOptions(options) {\n const isDark = this.theme === 'dark';\n\n // Grid and axis colors\n if (options.scales) {\n Object.keys(options.scales).forEach(scaleId => {\n const scale = options.scales[scaleId];\n scale.grid = scale.grid || {};\n scale.ticks = scale.ticks || {};\n\n scale.grid.color = isDark ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.1)';\n scale.ticks.color = isDark ? '#e9ecef' : '#495057';\n });\n }\n\n // Legend colors\n if (options.plugins?.legend) {\n options.plugins.legend.labels = options.plugins.legend.labels || {};\n options.plugins.legend.labels.color = isDark ? '#e9ecef' : '#495057';\n }\n\n // Title colors\n if (options.plugins?.title) {\n options.plugins.title.color = isDark ? '#ffffff' : '#212529';\n }\n }\n\n toggleTheme() {\n this.theme = this.theme === 'light' ? 'dark' : 'light';\n this.applyTheme();\n\n // Emit theme change event\n this.emit('chart:theme-changed', {\n chart: this,\n theme: this.theme\n });\n }\n\n // Auto-refresh Management\n startAutoRefresh() {\n if (!this.endpoint || !this.refreshInterval) return;\n\n this.stopAutoRefresh();\n\n this.refreshTimer = setInterval(() => {\n this.fetchData();\n }, this.refreshInterval);\n\n this.updateRefreshStatus(true);\n }\n\n stopAutoRefresh() {\n if (this.refreshTimer) {\n clearInterval(this.refreshTimer);\n this.refreshTimer = null;\n }\n this.updateRefreshStatus(false);\n }\n\n // Export Functionality\n exportChart(format = 'png') {\n if (!this.chart) return;\n\n try {\n if (format === 'csv') {\n this.exportCSV();\n } else {\n const url = this.chart.toBase64Image('image/' + format, 1);\n const link = document.createElement('a');\n link.download = `chart-${Date.now()}.${format}`;\n link.href = url;\n link.click();\n\n // Emit export event\n this.emit('chart:exported', {\n chart: this,\n format,\n filename: link.download\n });\n }\n\n } catch (error) {\n console.error('Failed to export chart:', error);\n this.showError('Failed to export chart');\n }\n }\n\n // CSV Export Functionality\n exportCSV() {\n if (!this.chart || !this.chart.data) return;\n\n try {\n const csvData = this.generateCSV();\n const blob = new Blob([csvData], { type: 'text/csv;charset=utf-8;' });\n const url = URL.createObjectURL(blob);\n\n const link = document.createElement('a');\n link.download = `chart-data-${Date.now()}.csv`;\n link.href = url;\n link.click();\n\n // Clean up\n URL.revokeObjectURL(url);\n\n // Emit export event\n this.emit('chart:exported', {\n chart: this,\n format: 'csv',\n filename: link.download\n });\n\n } catch (error) {\n console.error('Failed to export CSV:', error);\n this.showError('Failed to export CSV');\n }\n }\n\n // Generate CSV data from chart\n generateCSV() {\n const data = this.chart.data;\n const labels = data.labels || [];\n const datasets = data.datasets || [];\n\n // Create CSV header\n let csv = 'Label';\n datasets.forEach(dataset => {\n csv += ',' + (dataset.label || 'Data');\n });\n csv += '\\n';\n\n // Add data rows\n labels.forEach((label, index) => {\n csv += `\"${label}\"`;\n datasets.forEach(dataset => {\n const value = dataset.data[index] || '';\n csv += ',' + value;\n });\n csv += '\\n';\n });\n\n return csv;\n }\n\n // UI State Management\n showLoading() {\n this.isLoading = true;\n this.hideAllOverlays();\n this.loadingOverlay?.classList.remove('d-none');\n }\n\n hideLoading() {\n this.isLoading = false;\n this.loadingOverlay?.classList.add('d-none');\n }\n\n showError(message) {\n this.hasError = true;\n this.hideAllOverlays();\n const errorMessageEl = this.errorOverlay?.querySelector('.error-message');\n if (errorMessageEl) {\n errorMessageEl.textContent = message;\n }\n this.errorOverlay?.classList.remove('d-none');\n }\n\n hideError() {\n this.hasError = false;\n this.errorOverlay?.classList.add('d-none');\n }\n\n showNoData() {\n this.hideAllOverlays();\n this.noDataOverlay?.classList.remove('d-none');\n }\n\n hideAllOverlays() {\n this.loadingOverlay?.classList.add('d-none');\n this.errorOverlay?.classList.add('d-none');\n this.noDataOverlay?.classList.add('d-none');\n }\n\n showWebSocketStatus(connected, status = 'connected') {\n if (!this.websocketStatus) return;\n\n if (connected) {\n this.websocketStatus.className = 'badge bg-success';\n this.websocketStatus.innerHTML = '<i class=\"bi bi-wifi\"></i> Live';\n } else {\n this.websocketStatus.className = status === 'error' ? 'badge bg-danger' : 'badge bg-secondary';\n this.websocketStatus.innerHTML = status === 'error' ?\n '<i class=\"bi bi-wifi-off\"></i> Error' :\n '<i class=\"bi bi-wifi-off\"></i> Offline';\n }\n\n this.websocketStatus.style.display = 'inline-block';\n }\n\n setRefreshButtonState(loading) {\n if (!this.refreshBtn) return;\n\n const icon = this.refreshBtn.querySelector('i');\n if (loading) {\n this.refreshBtn.disabled = true;\n icon?.classList.add('spin');\n } else {\n this.refreshBtn.disabled = false;\n icon?.classList.remove('spin');\n }\n }\n\n updateLastUpdatedTime() {\n const lastUpdatedEl = this.element.querySelector('.last-updated');\n const timestampEl = this.element.querySelector('.timestamp');\n\n if (lastUpdatedEl && timestampEl) {\n timestampEl.textContent = new Date().toLocaleTimeString();\n lastUpdatedEl.style.display = 'block';\n }\n }\n\n updateRefreshStatus(active) {\n const statusEl = this.element.querySelector('.refresh-status');\n if (statusEl) {\n statusEl.textContent = active ?\n `Every ${this.refreshInterval / 1000}s` : 'Off';\n }\n }\n\n updateDataStats(data) {\n // Count data points\n let points = 0;\n if (data.datasets) {\n points = data.datasets.reduce((sum, dataset) => {\n return sum + (dataset.data ? dataset.data.length : 0);\n }, 0);\n }\n\n this.dataPoints = points;\n\n const dataPointsEl = this.element.querySelector('.data-points');\n if (dataPointsEl) {\n dataPointsEl.textContent = `${points} data point${points !== 1 ? 's' : ''}`;\n }\n }\n\n showFooter() {\n if (this.footerElement) {\n this.footerElement.style.display = 'block';\n }\n }\n\n setupResizeObserver() {\n if (!window.ResizeObserver || !this.contentElement) return;\n\n const resizeObserver = new ResizeObserver(() => {\n if (this.chart) {\n this.chart.resize();\n }\n });\n\n resizeObserver.observe(this.contentElement);\n this._resizeObserver = resizeObserver;\n }\n\n // Cleanup\n async onBeforeDestroy() {\n // Stop auto-refresh\n this.stopAutoRefresh();\n\n // Disconnect WebSocket\n if (this.websocket) {\n this.websocket.disconnect();\n this.websocket = null;\n }\n\n // Destroy Chart.js instance\n if (this.chart) {\n this.chart.destroy();\n this.chart = null;\n }\n\n // Clean up resize observer\n if (this._resizeObserver) {\n this._resizeObserver.disconnect();\n this._resizeObserver = null;\n }\n\n // Clean up essential listeners\n if (this._essentialListeners) {\n this._essentialListeners.forEach(({ el, type, fn }) => {\n if (el) el.removeEventListener(type, fn);\n });\n this._essentialListeners = [];\n }\n\n // Emit destroy event\n this.emit('chart:destroyed', { chart: this });\n }\n\n // Public API\n setData(data) {\n this.data = data;\n return this.updateChart(data);\n }\n\n setEndpoint(endpoint) {\n this.endpoint = endpoint;\n if (endpoint) {\n return this.fetchData();\n }\n }\n\n setWebSocketUrl(url) {\n if (this.websocket) {\n this.websocket.disconnect();\n }\n this.websocketUrl = url;\n if (url) {\n return this.connectWebSocket();\n }\n }\n\n // Dimension Control Methods\n setWidth(width) {\n this.width = width;\n this.contentStyle = [\n this.width ? `width: ${this.width}px;` : '',\n this.height ? `height: ${this.height}px;` : ''\n ].filter(Boolean).join(' ');\n if (this.contentElement) {\n this._updateChartDimensions();\n }\n }\n\n setHeight(height) {\n this.height = height;\n this.contentStyle = [\n this.width ? `width: ${this.width}px;` : '',\n this.height ? `height: ${this.height}px;` : ''\n ].filter(Boolean).join(' ');\n if (this.contentElement) {\n this._updateChartDimensions();\n }\n }\n\n setDimensions(width, height) {\n this.width = width;\n this.height = height;\n this.contentStyle = [\n this.width ? `width: ${this.width}px;` : '',\n this.height ? `height: ${this.height}px;` : ''\n ].filter(Boolean).join(' ');\n if (this.contentElement) {\n this._updateChartDimensions();\n }\n }\n\n _updateChartDimensions() {\n if (this.chart) {\n // Update chart options for custom dimensions\n if (this.width || this.height) {\n this.chart.options.responsive = true;\n this.chart.options.maintainAspectRatio = false;\n if (this.width && this.contentElement) {\n this.contentElement.style.width = this.width ? this.width + 'px' : '';\n }\n if (this.height && this.contentElement) {\n this.contentElement.style.height = this.height ? this.height + 'px' : '';\n }\n } else {\n this.chart.options.responsive = true;\n this.chart.options.maintainAspectRatio = this.chartOptions.maintainAspectRatio;\n }\n this.chart.resize();\n }\n }\n\n resize() {\n if (this.chart) {\n this.chart.resize();\n }\n }\n\n refresh() {\n return this.fetchData();\n }\n\n export(format = 'png') {\n return this.exportChart(format);\n }\n\n setTheme(theme) {\n this.theme = theme;\n this.applyTheme();\n }\n\n getStats() {\n return {\n isLoading: this.isLoading,\n hasError: this.hasError,\n dataPoints: this.dataPoints,\n lastFetch: this.lastFetch,\n theme: this.theme,\n chartType: this.chartType,\n autoRefresh: !!this.refreshTimer,\n websocketConnected: this.websocket?.isConnected || false\n };\n }\n}\n\nclass ChartHeaderView extends View {\n constructor(options = {}) {\n super({\n ...options,\n className: `mojo-chart-header ${options.className || ''}`,\n tagName: 'div'\n });\n\n // Header configuration\n this.titleHtml = options.titleHtml || '';\n this.chartTitle = options.chartTitle || '';\n this.showExport = options.showExport === true;\n this.showRefresh = !!options.showRefresh;\n this.showTheme = false;\n this.showTheme = options.showTheme === true;\n this.controls = Array.isArray(options.controls) ? options.controls : [];\n\n // Pre-rendered controls HTML\n this.controlsHtml = this._buildControlsHtml(this.controls);\n }\n\n async getTemplate() {\n return `\n <div class=\"d-flex justify-content-between align-items-center\">\n <div class=\"chart-title-section\">\n <h5 class=\"mb-2 chart-title\">{{{titleHtml}}}</h5>\n <small class=\"text-muted last-updated\" style=\"display: none;\">\n Last updated: <span class=\"timestamp\"></span>\n </small>\n </div>\n\n <div class=\"chart-controls\">\n <div class=\"btn-toolbar\" role=\"toolbar\">\n {{{controlsHtml}}}\n\n <div class=\"btn-group btn-group-sm\" role=\"group\">\n\n {{#showTheme}}\n <button type=\"button\" class=\"btn btn-outline-secondary theme-toggle\" data-action=\"toggle-theme\" title=\"Toggle Theme\">\n <i class=\"bi bi-palette\"></i>\n </button>\n {{/showTheme}}\n\n {{#showExport}}\n <div class=\"btn-group btn-group-sm\" role=\"group\">\n <button type=\"button\" class=\"btn btn-outline-secondary dropdown-toggle\" data-bs-toggle=\"dropdown\" title=\"Export Chart\">\n <i class=\"bi bi-download\"></i>\n </button>\n <ul class=\"dropdown-menu\">\n <li><a class=\"dropdown-item\" href=\"#\" data-action=\"export-chart\" data-format=\"png\">\n <i class=\"bi bi-image\"></i> PNG\n </a></li>\n <li><a class=\"dropdown-item\" href=\"#\" data-action=\"export-chart\" data-format=\"jpg\">\n <i class=\"bi bi-image\"></i> JPEG\n </a></li>\n <li><a class=\"dropdown-item\" href=\"#\" data-action=\"export-chart\" data-format=\"csv\">\n <i class=\"bi bi-file-earmark-spreadsheet\"></i> CSV\n </a></li>\n </ul>\n </div>\n {{/showExport}}\n\n {{#showRefresh}}\n <button type=\"button\" class=\"btn btn-outline-secondary refresh-btn\" data-action=\"refresh-chart\" title=\"Refresh Data\">\n <i class=\"bi bi-arrow-clockwise\"></i>\n </button>\n {{/showRefresh}}\n </div>\n </div>\n </div>\n </div>\n `;\n }\n\n // Build custom controls HTML for the toolbar from config\n _buildControlsHtml(controls) {\n if (!Array.isArray(controls) || controls.length === 0) return '';\n\n const parts = [];\n\n controls.forEach((item) => {\n if (!item || !item.type) return;\n\n switch (item.type) {\n case 'select': {\n const sizeCls = item.size === 'md' ? '' : ' form-select-sm';\n const cls = `form-select${sizeCls} ${item.className || ''}`.trim();\n const optionsHtml = (item.options || [])\n .map(opt => `<option value=\"${this._escapeAttr(opt.value)}\"${opt.selected ? ' selected' : ''}>${this._escapeHtml(opt.label)}</option>`)\n .join('');\n parts.push(`\n <div class=\"btn-group btn-group-sm me-2\" role=\"group\">\n <select class=\"${cls}\" data-change-action=\"${this._escapeAttr(item.action || item.name || 'select-changed')}\" style=\"width: auto;\">\n ${optionsHtml}\n </select>\n </div>\n `);\n break;\n }\n\n case 'button': {\n const { variant = 'outline-secondary', size = 'sm' } = item;\n const sizeCls = size === 'md' ? '' : ' btn-sm';\n const btnCls = `btn btn-${variant}${sizeCls} ${item.className || ''}`.trim();\n const titleAttr = item.title ? ` title=\"${this._escapeAttr(item.title)}\"` : '';\n const dataAttrs = this._buildDataAttrs(item.data);\n parts.push(`\n <div class=\"btn-group btn-group-sm me-2\" role=\"group\">\n <button type=\"button\" class=\"${btnCls}\" data-action=\"${this._escapeAttr(item.action || 'button-action')}\"${titleAttr}${dataAttrs}>\n ${item.labelHtml || ''}\n </button>\n </div>\n `);\n break;\n }\n\n case 'buttongroup': {\n const size = item.size || 'sm';\n const groupCls = `btn-group btn-group-${size} me-2 ${item.className || ''}`.trim();\n const buttons = (item.buttons || []).map(btn => {\n const variant = btn.variant || 'outline-secondary';\n const sizeCls = size === 'md' ? '' : ' btn-sm';\n const btnCls = `btn btn-${variant}${sizeCls} ${btn.className || ''}`.trim();\n const titleAttr = btn.title ? ` title=\"${this._escapeAttr(btn.title)}\"` : '';\n const dataAttrs = this._buildDataAttrs(btn.data);\n return `<button type=\"button\" class=\"${btnCls}\" data-action=\"${this._escapeAttr(btn.action || 'button-action')}\"${titleAttr}${dataAttrs}>${btn.labelHtml || ''}</button>`;\n }).join('');\n parts.push(`\n <div class=\"${groupCls}\" role=\"group\">\n ${buttons}\n </div>\n `);\n break;\n }\n\n case 'divider': {\n parts.push(`<div class=\"vr mx-2\"></div>`);\n break;\n }\n\n case 'html': {\n const html = item.html || '';\n parts.push(`<div class=\"me-2 d-inline-block\">${html}</div>`);\n break;\n }\n\n default:\n // Unknown type; ignore silently\n break;\n }\n });\n\n return parts.join('\\n');\n }\n\n _buildDataAttrs(data) {\n if (!data || typeof data !== 'object') return '';\n return Object.entries(data)\n .map(([key, val]) => ` data-${this._kebabCase(String(key))}=\"${this._escapeAttr(String(val))}\"`)\n .join('');\n }\n\n _kebabCase(str) {\n return str\n .replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, '$1-$2')\n .toLowerCase()\n .replace(/[^a-z0-9\\-]/g, '-')\n .replace(/--+/g, '-')\n .replace(/^-|-$/g, '');\n }\n\n _escapeAttr(value) {\n return String(value)\n .replace(/\"/g, '"')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n }\n\n _escapeHtml(value) {\n return String(value)\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n }\n}\n","/**\n * SeriesChart - Combined Line and Bar chart component for MOJO framework\n * Supports switching between line and bar chart types with the same data\n */\n\nimport BaseChart from './BaseChart.js';\nimport Dialog from '@core/views/feedback/Dialog.js';\n\n\nexport default class SeriesChart extends BaseChart {\n constructor(options = {}) {\n super({\n ...options,\n chartType: options.chartType || 'line'\n });\n\n // Series-specific options\n this.showTypeSwitch = true;\n if (options.showTypeSwitch !== undefined) this.showTypeSwitch = options.showTypeSwitch;\n this.orientation = options.orientation || 'vertical'; // 'vertical' or 'horizontal'\n this.stacked = options.stacked || false;\n this.stepped = options.stepped || false; // For line charts\n this.tension = options.tension || 0.4; // Line curve tension\n this.fill = options.fill || false; // Fill area under line\n this.showRefreshButton = options.showRefreshButton !== false;\n\n if (!this.headerConfig) {\n this.headerConfig = {\n titleHtml: this.title || '',\n chartTitle: this.chartTitle || '',\n showExport: this.exportEnabled,\n showRefresh: this.refreshEnabled,\n showTheme: true,\n controls: []\n }\n }\n\n\n // Data series configuration\n this.series = options.series || [];\n this.xField = options.xField || 'x';\n this.yField = options.yField || 'y';\n\n\n\n // Color scheme for multiple datasets\n this.colors = options.colors || [\n 'rgba(54, 162, 235, 0.8)', // Blue\n 'rgba(255, 99, 132, 0.8)', // Red\n 'rgba(75, 192, 192, 0.8)', // Green\n 'rgba(255, 206, 86, 0.8)', // Yellow\n 'rgba(153, 102, 255, 0.8)', // Purple\n 'rgba(255, 159, 64, 0.8)', // Orange\n 'rgba(199, 199, 199, 0.8)', // Grey\n 'rgba(83, 102, 255, 0.8)' // Indigo\n ];\n\n\n\n // Process tooltip formatters\n this.tooltipFormatters = options.tooltip || {};\n }\n\n async getTemplate() {\n return await super.getTemplate();\n }\n\n async onInit() {\n // Provide header controls (type switcher) via BaseChart headerConfig\n if (this.showTypeSwitch) {\n this.headerConfig.controls.push({\n type: 'buttongroup',\n size: 'sm',\n buttons: [\n { action: 'set-chart-type', labelHtml: '<i class=\"bi bi-graph-up\"></i>', title: 'Line', variant: (this.chartType === 'line' ? 'primary' : 'outline-primary'), data: { type: 'line' } },\n { action: 'set-chart-type', labelHtml: '<i class=\"bi bi-bar-chart\"></i>', title: 'Bar', variant: (this.chartType === 'bar' ? 'primary' : 'outline-primary'), data: { type: 'bar' } }\n ]\n });\n }\n\n await super.onInit();\n\n }\n\n // Action Handlers\n async onActionSetChartType(event, element) {\n event.stopPropagation();\n const newType = element.getAttribute('data-type');\n if (newType && newType !== this.chartType) {\n await this.setChartType(newType);\n }\n }\n\n async rebuildChart() {\n if (this.chart && this.data) {\n this.chart.destroy();\n this.chart = null;\n\n const processedData = this.processChartData(this.data);\n await this.createChart(processedData);\n }\n }\n\n async setChartType(newType) {\n if (!['line', 'bar'].includes(newType)) {\n throw new Error(`Unsupported chart type: ${newType}`);\n }\n\n const oldType = this.chartType;\n this.chartType = newType;\n\n // Recreate chart with new type\n if (this.chart && this.data) {\n this.chart.destroy();\n this.chart = null;\n\n const processedData = this.processChartData(this.data);\n await this.createChart(processedData);\n }\n\n // Update type switcher button styles dynamically\n this._updateTypeSwitcherButtons();\n\n // Emit type change event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('chart:type-changed', {\n chart: this,\n oldType,\n newType: this.chartType\n });\n }\n }\n\n processChartData(data) {\n if (!data) return data;\n\n let processedData;\n\n // Handle different data input formats\n if (Array.isArray(data)) {\n // Array of objects: [{x: '2024-01', y: 100}, {x: '2024-02', y: 150}]\n processedData = this.processArrayData(data);\n } else if (data.labels && data.datasets) {\n // Chart.js format: {labels: [...], datasets: [...]}\n processedData = this.processChartJSData(data);\n } else if (data.series) {\n // Custom series format: {series: [{name: 'Sales', data: [...]}]}\n processedData = this.processSeriesData(data);\n } else {\n processedData = data;\n }\n\n // Apply formatters to the processed data\n return this.applyFormattersToData(processedData);\n }\n\n processArrayData(data) {\n const labels = [];\n const values = [];\n\n data.forEach(item => {\n const xValue = item[this.xField];\n const yValue = item[this.yField];\n\n labels.push(xValue);\n values.push(yValue);\n });\n\n return {\n labels,\n datasets: [{\n label: this.title || 'Data',\n data: values,\n backgroundColor: this.colors[0].replace('0.8', '0.6'),\n borderColor: this.colors[0],\n borderWidth: 2,\n tension: this.chartType === 'line' ? this.tension : 0,\n fill: this.chartType === 'line' ? this.fill : false,\n stepped: this.chartType === 'line' ? this.stepped : false\n }]\n };\n }\n\n processChartJSData(data) {\n // Already in Chart.js format, just apply our styling\n const processedData = { ...data };\n\n processedData.datasets = processedData.datasets.map((dataset, index) => ({\n ...dataset,\n backgroundColor: dataset.backgroundColor || this.colors[index % this.colors.length].replace('0.8', '0.6'),\n borderColor: dataset.borderColor || this.colors[index % this.colors.length],\n borderWidth: dataset.borderWidth || 2,\n tension: this.chartType === 'line' ? (dataset.tension ?? this.tension) : 0,\n fill: this.chartType === 'line' ? (dataset.fill ?? this.fill) : false,\n stepped: this.chartType === 'line' ? (dataset.stepped ?? this.stepped) : false\n }));\n\n return processedData;\n }\n\n processSeriesData(data) {\n const labels = data.labels || [];\n const datasets = [];\n\n data.series.forEach((series, index) => {\n datasets.push({\n label: series.name || series.label || `Series ${index + 1}`,\n data: series.data || [],\n backgroundColor: series.backgroundColor || this.colors[index % this.colors.length].replace('0.8', '0.6'),\n borderColor: series.borderColor || this.colors[index % this.colors.length],\n borderWidth: series.borderWidth || 2,\n tension: this.chartType === 'line' ? (series.tension ?? this.tension) : 0,\n fill: this.chartType === 'line' ? (series.fill ?? this.fill) : false,\n stepped: this.chartType === 'line' ? (series.stepped ?? this.stepped) : false\n });\n });\n\n return { labels, datasets };\n }\n\n applyFormattersToData(data) {\n if (!data) return data;\n\n const processedData = { ...data };\n\n // Apply x-axis formatter to labels if configured\n const xAxisCfg = this.normalizeAxis ? this.normalizeAxis(this.xAxis) : {};\n if (xAxisCfg.formatter && processedData.labels) {\n processedData.labels = processedData.labels.map(label =>\n this.dataFormatter.pipe(label, xAxisCfg.formatter)\n );\n }\n\n return processedData;\n }\n\n applySubclassChartOptions(options) {\n // Stacking for bar charts\n if (this.stacked && this.chartType === 'bar' && options.scales) {\n if (options.scales.x) options.scales.x.stacked = true;\n if (options.scales.y) options.scales.y.stacked = true;\n }\n\n // Horizontal bars\n if (this.chartType === 'bar' && this.orientation === 'horizontal') {\n options.indexAxis = 'y';\n }\n\n // Interaction mode tuned to chart type\n options.interaction = options.interaction || {};\n options.interaction.intersect = false;\n options.interaction.mode = this.chartType === 'line' ? 'index' : 'nearest';\n\n // Elements styling\n options.elements = options.elements || {};\n options.elements.line = {\n ...(options.elements.line || {}),\n tension: this.tension,\n borderWidth: 2\n };\n options.elements.point = {\n ...(options.elements.point || {}),\n radius: this.chartType === 'line' ? 4 : 0,\n hoverRadius: 6,\n hitRadius: 8\n };\n options.elements.bar = {\n ...(options.elements.bar || {}),\n borderWidth: 1,\n borderSkipped: false\n };\n }\n\n\n\n // Process simple axis configuration into detailed config\n processAxisConfig(axisConfig) {\n if (!axisConfig) return {};\n\n if (typeof axisConfig === 'string') {\n // Simple string format: just a formatter name\n return { formatter: axisConfig };\n }\n\n if (typeof axisConfig === 'object') {\n // Object format: full configuration\n return {\n formatter: axisConfig.formatter,\n label: axisConfig.label,\n type: axisConfig.type,\n beginAtZero: axisConfig.beginAtZero,\n ...axisConfig\n };\n }\n\n return {};\n }\n\n\n\n\n\n _updateTypeSwitcherButtons() {\n const buttons = this.element?.querySelectorAll('[data-action=\"set-chart-type\"]');\n if (!buttons || buttons.length === 0) return;\n\n buttons.forEach(button => {\n const buttonType = button.getAttribute('data-type');\n const isActive = buttonType === this.chartType;\n\n // Normalize classes for Bootstrap primary/outline-primary variants\n button.classList.toggle('btn-primary', isActive);\n button.classList.toggle('btn-outline-primary', !isActive);\n\n // Optional 'active' state for accessibility/visual feedback\n button.classList.toggle('active', isActive);\n });\n }\n\n // Public API extensions\n setOrientation(orientation) {\n if (!['vertical', 'horizontal'].includes(orientation)) {\n throw new Error(`Invalid orientation: ${orientation}`);\n }\n\n this.orientation = orientation;\n\n if (this.chart) {\n this.chart.destroy();\n this.chart = null;\n\n if (this.data) {\n const processedData = this.processChartData(this.data);\n this.createChart(processedData);\n }\n }\n }\n\n setStacked(stacked) {\n this.stacked = stacked;\n\n if (this.chart) {\n this.chart.options.scales.x.stacked = stacked;\n this.chart.options.scales.y.stacked = stacked;\n this.chart.update();\n }\n }\n\n addSeries(series) {\n if (!this.data || !this.data.datasets) return;\n\n const newDataset = {\n label: series.label || series.name || `Series ${this.data.datasets.length + 1}`,\n data: series.data || [],\n backgroundColor: series.backgroundColor || this.colors[this.data.datasets.length % this.colors.length].replace('0.8', '0.6'),\n borderColor: series.borderColor || this.colors[this.data.datasets.length % this.colors.length],\n borderWidth: series.borderWidth || 2,\n tension: this.chartType === 'line' ? (series.tension ?? this.tension) : 0,\n fill: this.chartType === 'line' ? (series.fill ?? this.fill) : false\n };\n\n this.data.datasets.push(newDataset);\n\n if (this.chart) {\n this.chart.data.datasets.push(newDataset);\n this.chart.update();\n }\n\n // Emit series added event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('chart:series-added', {\n chart: this,\n series: newDataset\n });\n }\n }\n\n removeSeries(index) {\n if (!this.data || !this.data.datasets || index < 0 || index >= this.data.datasets.length) {\n return;\n }\n\n const removedSeries = this.data.datasets.splice(index, 1)[0];\n\n if (this.chart) {\n this.chart.data.datasets.splice(index, 1);\n this.chart.update();\n }\n\n // Emit series removed event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('chart:series-removed', {\n chart: this,\n series: removedSeries,\n index\n });\n }\n }\n\n // Static dialog method\n static async showDialog(options = {}) {\n const {\n title = 'Chart Viewer',\n size = 'xl',\n ...chartOptions\n } = options;\n\n const chart = new SeriesChart({\n ...chartOptions,\n title\n });\n\n\n\n const dialog = new Dialog({\n title,\n body: chart,\n size,\n centered: true,\n backdrop: 'static',\n keyboard: true,\n buttons: [\n {\n text: 'Export PNG',\n action: 'export',\n class: 'btn btn-outline-primary'\n },\n {\n text: 'Close',\n action: 'close',\n class: 'btn btn-secondary',\n dismiss: true\n }\n ]\n });\n\n // Render and mount\n await dialog.render();\n document.body.appendChild(dialog.element);\n await dialog.mount();\n\n // Show the dialog\n dialog.show();\n\n return new Promise((resolve) => {\n dialog.on('hidden', () => {\n dialog.destroy();\n resolve(chart);\n });\n\n dialog.on('action:export', () => {\n chart.exportChart('png');\n });\n\n dialog.on('action:close', () => {\n dialog.hide();\n });\n });\n }\n}\n","/**\n * PieChart - Pie chart component with segment interactions for MOJO framework\n * Supports click interactions, custom colors, and DataFormatter integration\n */\n\nimport BaseChart from './BaseChart.js';\nimport Dialog from '@core/views/feedback/Dialog.js';\n\nexport default class PieChart extends BaseChart {\n constructor(options = {}) {\n super({\n ...options,\n chartType: 'pie'\n });\n\n // Pie-specific options\n this.cutout = options.cutout || 0; // 0 for pie, >0 for doughnut\n this.rotation = options.rotation || 0; // Starting angle\n this.circumference = options.circumference || 360; // Full circle\n \n // Segment configuration\n this.borderWidth = options.borderWidth || 2;\n this.borderColor = options.borderColor || '#ffffff';\n this.hoverBorderWidth = options.hoverBorderWidth || 3;\n \n // Label configuration\n this.showLabels = options.showLabels !== false;\n this.labelPosition = options.labelPosition || 'outside'; // 'inside', 'outside'\n this.labelFormatter = options.labelFormatter || null;\n this.valueFormatter = options.valueFormatter || null;\n \n // Data field configuration\n this.labelField = options.labelField || 'label';\n this.valueField = options.valueField || 'value';\n \n // Color scheme for segments\n this.colors = options.colors || [\n '#FF6384', // Red\n '#36A2EB', // Blue \n '#FFCE56', // Yellow\n '#4BC0C0', // Teal\n '#9966FF', // Purple\n '#FF9F40', // Orange\n '#C9CBCF', // Grey\n '#4BC0C0', // Green\n '#FF6384', // Pink\n '#36A2EB' // Light Blue\n ];\n\n // Animation options\n this.animateRotate = options.animateRotate !== false;\n this.animateScale = options.animateScale || false;\n \n // Interaction options\n this.clickable = options.clickable !== false;\n this.hoverable = options.hoverable !== false;\n \n // Selected segment tracking\n this.selectedSegment = null;\n this.highlightedSegments = new Set();\n\n // Value formatting\n this.valueFormatter = options.valueFormatter || null;\n\n\n }\n\n\n\n processChartData(data) {\n if (!data) return data;\n\n let processedData;\n\n // Handle different data input formats\n if (Array.isArray(data)) {\n // Array of objects: [{label: 'A', value: 100}, {label: 'B', value: 200}]\n processedData = this.processArrayData(data);\n } else if (data.labels && data.datasets) {\n // Chart.js format: {labels: [...], datasets: [...]}\n processedData = this.processChartJSData(data);\n } else if (typeof data === 'object' && !data.labels) {\n // Simple object: {A: 100, B: 200}\n processedData = this.processObjectData(data);\n } else {\n processedData = data;\n }\n\n // Apply formatters to the processed data\n return this.applyFormattersToData(processedData);\n }\n\n processArrayData(data) {\n const labels = [];\n const values = [];\n\n data.forEach(item => {\n const label = item[this.labelField];\n const value = item[this.valueField];\n \n if (label !== undefined && value !== undefined) {\n labels.push(label);\n values.push(value);\n }\n });\n\n return {\n labels,\n datasets: [{\n data: values,\n backgroundColor: this.generateColors(labels.length),\n borderColor: this.borderColor,\n borderWidth: this.borderWidth,\n hoverBorderWidth: this.hoverBorderWidth\n }]\n };\n }\n\n processChartJSData(data) {\n const processedData = { ...data };\n \n // Apply our styling to existing datasets\n processedData.datasets = processedData.datasets.map(dataset => ({\n ...dataset,\n backgroundColor: dataset.backgroundColor || this.generateColors(processedData.labels.length),\n borderColor: dataset.borderColor || this.borderColor,\n borderWidth: dataset.borderWidth || this.borderWidth,\n hoverBorderWidth: dataset.hoverBorderWidth || this.hoverBorderWidth\n }));\n\n return processedData;\n }\n\n processObjectData(data) {\n const labels = Object.keys(data);\n const values = Object.values(data);\n\n return {\n labels,\n datasets: [{\n data: values,\n backgroundColor: this.generateColors(labels.length),\n borderColor: this.borderColor,\n borderWidth: this.borderWidth,\n hoverBorderWidth: this.hoverBorderWidth\n }]\n };\n }\n\n applyFormattersToData(data) {\n if (!data) return data;\n\n const processedData = { ...data };\n\n // Apply label formatter to labels\n if (this.labelFormatter && processedData.labels) {\n processedData.labels = processedData.labels.map(label =>\n this.dataFormatter.pipe(label, this.labelFormatter)\n );\n }\n\n return processedData;\n }\n\n generateColors(count) {\n const colors = [];\n for (let i = 0; i < count; i++) {\n colors.push(this.colors[i % this.colors.length]);\n }\n return colors;\n }\n\n buildChartOptions() {\n const options = super.buildChartOptions();\n\n // Pie chart specific configuration\n options.cutout = this.cutout;\n options.rotation = this.rotation;\n options.circumference = this.circumference;\n\n // Animation configuration\n options.animation = {\n animateRotate: this.animateRotate,\n animateScale: this.animateScale,\n duration: this.animations ? 1000 : 0\n };\n\n // Plugin configuration\n options.plugins = {\n ...options.plugins,\n legend: {\n ...options.plugins.legend,\n position: options.plugins.legend.position || 'right',\n labels: {\n ...options.plugins.legend.labels,\n usePointStyle: true,\n padding: 20,\n generateLabels: (chart) => {\n const data = chart.data;\n if (data.labels.length && data.datasets.length) {\n return data.labels.map((label, i) => {\n const dataset = data.datasets[0];\n const value = dataset.data[i];\n const backgroundColor = dataset.backgroundColor[i];\n \n // Calculate percentage\n const total = dataset.data.reduce((sum, val) => sum + val, 0);\n const percentage = ((value / total) * 100).toFixed(1);\n \n return {\n text: `${label} (${percentage}%)`,\n fillStyle: backgroundColor,\n strokeStyle: backgroundColor,\n lineWidth: 0,\n hidden: false,\n index: i\n };\n });\n }\n return [];\n }\n }\n },\n tooltip: {\n ...options.plugins.tooltip,\n callbacks: {\n ...options.plugins.tooltip.callbacks,\n label: (context) => {\n const label = context.label || '';\n const value = context.raw;\n const dataset = context.dataset;\n \n // Calculate percentage\n const total = dataset.data.reduce((sum, val) => sum + val, 0);\n const percentage = ((value / total) * 100).toFixed(1);\n \n // Apply value formatter if configured\n let formattedValue = value;\n if (this.valueFormatter) {\n formattedValue = this.dataFormatter.pipe(value, this.valueFormatter);\n } else if (this.tooltipFormatters && this.tooltipFormatters.y) {\n formattedValue = this.dataFormatter.pipe(value, this.tooltipFormatters.y);\n }\n \n return `${label}: ${formattedValue} (${percentage}%)`;\n }\n }\n }\n };\n\n // Remove scales (not used in pie charts)\n delete options.scales;\n\n return options;\n }\n\n setupChartEventHandlers() {\n super.setupChartEventHandlers();\n\n if (!this.chart || !this.clickable) return;\n\n // Override click handler for pie chart specific behavior\n this.chart.options.onClick = (event, elements) => {\n if (elements.length > 0) {\n const element = elements[0];\n const index = element.index;\n const dataset = this.chart.data.datasets[0];\n const label = this.chart.data.labels[index];\n const value = dataset.data[index];\n\n // Calculate percentage\n const total = dataset.data.reduce((sum, val) => sum + val, 0);\n const percentage = ((value / total) * 100).toFixed(1);\n\n // Toggle segment selection\n this.toggleSegmentSelection(index);\n\n // Emit click event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('chart:segment-clicked', {\n chart: this,\n index,\n label,\n value,\n percentage: parseFloat(percentage),\n isSelected: this.selectedSegment === index\n });\n }\n }\n };\n\n // Hover handler for visual feedback\n if (this.hoverable) {\n this.chart.options.onHover = (event, elements) => {\n this.canvas.style.cursor = elements.length > 0 ? 'pointer' : 'default';\n \n if (elements.length > 0) {\n const element = elements[0];\n const index = element.index;\n \n // Emit hover event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('chart:segment-hover', {\n chart: this,\n index,\n label: this.chart.data.labels[index],\n value: this.chart.data.datasets[0].data[index]\n });\n }\n }\n };\n }\n }\n\n toggleSegmentSelection(index) {\n if (this.selectedSegment === index) {\n // Deselect current segment\n this.selectedSegment = null;\n this.resetSegmentStyle(index);\n } else {\n // Reset previous selection\n if (this.selectedSegment !== null) {\n this.resetSegmentStyle(this.selectedSegment);\n }\n \n // Select new segment\n this.selectedSegment = index;\n this.highlightSegment(index);\n }\n }\n\n highlightSegment(index) {\n if (!this.chart) return;\n\n const meta = this.chart.getDatasetMeta(0);\n const segment = meta.data[index];\n \n if (segment) {\n // Expand segment slightly\n segment.outerRadius += 10;\n this.chart.update('none');\n }\n }\n\n resetSegmentStyle(index) {\n if (!this.chart) return;\n\n const meta = this.chart.getDatasetMeta(0);\n const segment = meta.data[index];\n \n if (segment) {\n // Reset segment to normal size\n segment.outerRadius -= 10;\n this.chart.update('none');\n }\n }\n\n highlightSegments(indices) {\n if (!Array.isArray(indices)) {\n indices = [indices];\n }\n\n this.highlightedSegments.clear();\n indices.forEach(index => {\n this.highlightedSegments.add(index);\n this.highlightSegment(index);\n });\n }\n\n clearHighlights() {\n this.highlightedSegments.forEach(index => {\n this.resetSegmentStyle(index);\n });\n this.highlightedSegments.clear();\n \n if (this.selectedSegment !== null) {\n this.resetSegmentStyle(this.selectedSegment);\n this.selectedSegment = null;\n }\n }\n\n // Public API extensions\n selectSegment(index) {\n if (index >= 0 && index < this.chart?.data?.labels?.length) {\n this.toggleSegmentSelection(index);\n }\n }\n\n getSegmentData(index) {\n if (!this.chart || !this.chart.data) return null;\n\n const dataset = this.chart.data.datasets[0];\n const label = this.chart.data.labels[index];\n const value = dataset.data[index];\n const total = dataset.data.reduce((sum, val) => sum + val, 0);\n const percentage = ((value / total) * 100).toFixed(1);\n\n return {\n index,\n label,\n value,\n percentage: parseFloat(percentage),\n color: dataset.backgroundColor[index],\n isSelected: this.selectedSegment === index\n };\n }\n\n getAllSegments() {\n if (!this.chart || !this.chart.data) return [];\n\n return this.chart.data.labels.map((_, index) => this.getSegmentData(index));\n }\n\n updateSegmentColor(index, color) {\n if (!this.chart || !this.chart.data.datasets[0]) return;\n\n this.chart.data.datasets[0].backgroundColor[index] = color;\n this.chart.update('none');\n\n // Emit color change event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('chart:segment-color-changed', {\n chart: this,\n index,\n color,\n segment: this.getSegmentData(index)\n });\n }\n }\n\n addSegment(label, value, color = null) {\n if (!this.chart || !this.chart.data) return;\n\n const dataset = this.chart.data.datasets[0];\n const segmentColor = color || this.colors[this.chart.data.labels.length % this.colors.length];\n\n this.chart.data.labels.push(label);\n dataset.data.push(value);\n dataset.backgroundColor.push(segmentColor);\n\n this.chart.update();\n\n // Emit segment added event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('chart:segment-added', {\n chart: this,\n label,\n value,\n color: segmentColor,\n index: this.chart.data.labels.length - 1\n });\n }\n }\n\n removeSegment(index) {\n if (!this.chart || !this.chart.data || index < 0 || index >= this.chart.data.labels.length) {\n return;\n }\n\n const dataset = this.chart.data.datasets[0];\n const label = this.chart.data.labels[index];\n const value = dataset.data[index];\n\n this.chart.data.labels.splice(index, 1);\n dataset.data.splice(index, 1);\n dataset.backgroundColor.splice(index, 1);\n\n // Reset selection if removed segment was selected\n if (this.selectedSegment === index) {\n this.selectedSegment = null;\n } else if (this.selectedSegment > index) {\n this.selectedSegment--;\n }\n\n this.chart.update();\n\n // Emit segment removed event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('chart:segment-removed', {\n chart: this,\n label,\n value,\n index,\n removedSegment: { label, value, index }\n });\n }\n }\n\n // Override applyThemeToOptions for pie chart specific theming\n applyThemeToOptions(options) {\n super.applyThemeToOptions(options);\n\n const isDark = this.theme === 'dark';\n \n // Adjust border colors for theme\n if (isDark) {\n this.borderColor = '#404449';\n } else {\n this.borderColor = '#ffffff';\n }\n }\n\n // Static dialog method\n static async showDialog(options = {}) {\n const {\n title = 'Pie Chart',\n size = 'lg',\n ...chartOptions\n } = options;\n\n const chart = new PieChart({\n ...chartOptions,\n title\n });\n\n // Using static import at top: import Dialog from '@core/views/feedback/Dialog.js';\n\n const dialog = new Dialog({\n title,\n body: chart,\n size,\n centered: true,\n backdrop: 'static',\n keyboard: true,\n buttons: [\n { \n text: 'Export PNG', \n action: 'export', \n class: 'btn btn-outline-primary' \n },\n { \n text: 'Close', \n action: 'close', \n class: 'btn btn-secondary',\n dismiss: true\n }\n ]\n });\n\n // Render and mount\n await dialog.render();\n document.body.appendChild(dialog.element);\n await dialog.mount();\n\n // Show the dialog\n dialog.show();\n\n return new Promise((resolve) => {\n dialog.on('hidden', () => {\n dialog.destroy();\n resolve(chart);\n });\n\n dialog.on('action:export', () => {\n chart.exportChart('png');\n });\n\n dialog.on('action:close', () => {\n dialog.hide();\n });\n });\n }\n}","/**\n * MetricsChart - Specialized metrics chart extending SeriesChart\n * Provides header controls and a REST-based fetch to transform API data into Chart.js format\n */\n\nimport SeriesChart from './SeriesChart.js';\nimport Dialog from '@core/views/feedback/Dialog.js';\n\nexport default class MetricsChart extends SeriesChart {\n constructor(options = {}) {\n super({\n ...options,\n chartType: options.chartType || 'line',\n title: options.title || 'Metrics',\n colors: options.colors || [\n 'rgba(54, 162, 235, 0.8)', // Blue\n 'rgba(255, 99, 132, 0.8)', // Red\n 'rgba(75, 192, 192, 0.8)', // Green\n 'rgba(255, 206, 86, 0.8)', // Yellow\n 'rgba(153, 102, 255, 0.8)', // Purple\n 'rgba(255, 159, 64, 0.8)', // Orange\n 'rgba(199, 199, 199, 0.8)', // Grey\n 'rgba(83, 102, 255, 0.8)' // Indigo\n ],\n yAxis: options.yAxis || { label: 'Count', beginAtZero: true },\n tooltip: options.tooltip || { y: 'number' },\n width: options.width,\n height: options.height\n });\n\n // API configuration\n this.endpoint = options.endpoint || '/api/metrics/fetch';\n this.account = options.account || 'global';\n\n // Initial parameters\n this.granularity = options.granularity || 'hours';\n this.slugs = options.slugs || null;\n this.category = options.category || null;\n this.dateStart = options.dateStart || null;\n this.dateEnd = options.dateEnd || null;\n this.defaultDateRange = options.defaultDateRange || '24h';\n\n // Control visibility options\n this.showGranularity = options.showGranularity !== false;\n this.showDateRange = options.showDateRange !== false;\n\n // Options for controls\n this.granularityOptions = options.granularityOptions || [\n { value: 'minutes', label: 'Minutes' },\n { value: 'hours', label: 'Hours' },\n { value: 'days', label: 'Days' },\n { value: 'weeks', label: 'Weeks' },\n { value: 'months', label: 'Months' }\n ];\n\n this.quickRanges = options.quickRanges || [\n { value: '1h', label: '1H' },\n { value: '24h', label: '24H' },\n { value: '7d', label: '7D' },\n { value: '30d', label: '30D' }\n ];\n\n this.availableMetrics = options.availableMetrics || [\n { value: 'api_calls', label: 'API Calls' },\n { value: 'api_errors', label: 'API Errors' },\n { value: 'incident_evt', label: 'System Events' },\n { value: 'incidents', label: 'Incidents' }\n ];\n\n // State\n this.isLoading = false;\n this.lastFetch = null;\n\n // Initialize date range if missing\n if (!this.dateStart || !this.dateEnd) {\n this.setQuickRange(this.defaultDateRange);\n }\n }\n\n async onInit() {\n // Build header controls for granularity and date range\n const controls = [];\n\n if (this.showGranularity) {\n controls.push({\n type: 'select',\n name: 'granularity',\n action: 'granularity-changed',\n size: 'sm',\n options: this.granularityOptions.map(opt => ({\n value: opt.value,\n label: opt.label,\n selected: opt.value === this.granularity\n }))\n });\n }\n\n if (this.showDateRange) {\n controls.push({\n type: 'button',\n action: 'show-date-range-dialog',\n labelHtml: `<i class=\"bi bi-calendar-range me-1\"></i>${this.formatDateRangeDisplay()}`,\n title: 'Select Date Range',\n variant: 'outline-secondary',\n size: 'sm'\n });\n }\n\n this.headerConfig = {\n titleHtml: this.title || 'Metrics',\n chartTitle: this.chartTitle || '',\n showExport: this.exportEnabled === true,\n showRefresh: this.refreshEnabled,\n showTheme: false,\n controls\n };\n\n await super.onInit();\n }\n\n // Action Handlers\n async onActionGranularityChanged(event, element) {\n const newGranularity = element.value;\n if (newGranularity && newGranularity !== this.granularity) {\n this.granularity = newGranularity;\n await this.fetchData();\n }\n }\n\n async onActionShowDateRangeDialog() {\n try {\n const result = await Dialog.showForm({\n title: 'Select Date Range',\n size: 'md',\n fields: [\n {\n name: 'dateRange',\n type: 'daterange',\n label: 'Date Range',\n startName: 'dt_start',\n endName: 'dt_end',\n startDate: this.formatDateTimeLocal(this.dateStart),\n endDate: this.formatDateTimeLocal(this.dateEnd),\n required: true\n }\n ],\n formConfig: {\n options: {\n submitButton: false,\n resetButton: false\n }\n }\n });\n\n if (result && result.startDate && result.endDate) {\n this.dateStart = new Date(result.startDate);\n this.dateEnd = new Date(result.endDate);\n\n // Update the header button label\n const btn = this.element?.querySelector('[data-action=\"show-date-range-dialog\"]');\n if (btn) {\n btn.innerHTML = `<i class=\"bi bi-calendar-range me-1\"></i>${this.formatDateRangeDisplay()}`;\n }\n\n await this.fetchData();\n }\n } catch (error) {\n console.error('Date range dialog error:', error);\n }\n }\n\n // Data Management\n buildApiParams() {\n const params = {\n granularity: this.granularity,\n account: this.account,\n with_labels: true\n };\n\n // Add slugs\n if (this.slugs) {\n this.slugs.forEach(slug => {\n if (!params['slugs[]']) params['slugs[]'] = [];\n params['slugs[]'].push(slug);\n });\n }\n\n if (this.category) {\n params.category = this.category;\n }\n // Date range\n if (this.dateStart) {\n params.dr_start = Math.floor(this.dateStart.getTime() / 1000);\n }\n if (this.dateEnd) {\n params.dr_end = Math.floor(this.dateEnd.getTime() / 1000);\n }\n\n // Cache buster\n params._ = Date.now();\n\n return params;\n }\n\n async fetchData() {\n if (!this.endpoint) return;\n\n this.isLoading = true;\n this.showLoading();\n\n try {\n const rest = this.getApp()?.rest;\n if (!rest) {\n throw new Error('No REST client available');\n }\n\n const params = this.buildApiParams();\n const response = await rest.GET(this.endpoint, params);\n\n // Handle Rest standardized response\n if (!response.success) {\n throw new Error(response.message || 'Network error');\n }\n if (!response.data?.status) {\n throw new Error(response.data?.error || 'Server error');\n }\n\n const metricsData = response.data.data;\n const chartData = this.processMetricsData(metricsData);\n await this.setData(chartData);\n this.lastFetch = new Date();\n\n // Emit success event\n this.emit('metrics:data-loaded', {\n chart: this,\n data: metricsData,\n params\n });\n\n } catch (error) {\n console.error('Failed to fetch metrics data:', error);\n this.showError(`Failed to load metrics: ${error.message}`);\n\n // Emit error event\n this.emit('metrics:error', { chart: this, error });\n\n } finally {\n this.isLoading = false;\n this.hideLoading();\n }\n }\n\n processMetricsData(data) {\n // Expecting: { labels: [...], data: { metric_slug: [values...] } }\n const { data: metricsData, labels } = data;\n const datasets = [];\n\n Object.keys(metricsData).forEach((metric, index) => {\n const values = metricsData[metric];\n\n const sanitizedValues = values.map(val => {\n if (val === null || val === undefined || val === '') return 0;\n return typeof val === 'number' ? val : (parseFloat(val) || 0);\n });\n\n datasets.push({\n label: this.formatMetricLabel(metric),\n data: sanitizedValues,\n backgroundColor: this.colors[index % this.colors.length].replace('0.8', '0.6'),\n borderColor: this.colors[index % this.colors.length],\n borderWidth: 2,\n tension: this.chartType === 'line' ? 0.4 : 0,\n fill: false,\n pointRadius: this.chartType === 'line' ? 3 : 0,\n pointHoverRadius: 5\n });\n });\n\n return { labels, datasets };\n }\n\n formatMetricLabel(metric) {\n return metric\n .split('_')\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n }\n\n // Date utilities\n setQuickRange(range) {\n const now = new Date();\n let startDate;\n\n switch (range) {\n case '1h':\n startDate = new Date(now.getTime() - (60 * 60 * 1000));\n break;\n case '24h':\n startDate = new Date(now.getTime() - (24 * 60 * 60 * 1000));\n break;\n case '7d':\n startDate = new Date(now.getTime() - (7 * 24 * 60 * 60 * 1000));\n break;\n case '30d':\n startDate = new Date(now.getTime() - (30 * 24 * 60 * 60 * 1000));\n break;\n default:\n startDate = new Date(now.getTime() - (24 * 60 * 60 * 1000));\n }\n\n this.dateStart = startDate;\n this.dateEnd = now;\n }\n\n formatDateTimeLocal(date) {\n if (!date) return '';\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n const hours = String(date.getHours()).padStart(2, '0');\n const minutes = String(date.getMinutes()).padStart(2, '0');\n return `${year}-${month}-${day}T${hours}:${minutes}`;\n }\n\n // Public API\n setGranularity(granularity) {\n this.granularity = granularity;\n return this.fetchData();\n }\n\n setDateRange(startDate, endDate) {\n this.dateStart = new Date(startDate);\n this.dateEnd = new Date(endDate);\n return this.fetchData();\n }\n\n setMetrics(slugs) {\n this.slugs = [...slugs];\n return this.fetchData();\n }\n\n getStats() {\n const base = super.getStats();\n return {\n ...base,\n lastFetch: this.lastFetch,\n granularity: this.granularity,\n slugs: [...this.slugs],\n dateRange: {\n start: this.dateStart,\n end: this.dateEnd\n }\n };\n }\n}\n","/**\n * MiniChart - Lightweight sparkline chart component\n * Renders simple line or bar charts with minimal configuration\n * Uses SVG for crisp rendering at any size\n */\n\nimport View from '@core/View.js';\nimport dataFormatter from '@core/utils/DataFormatter.js';\n\nexport default class MiniChart extends View {\n constructor(options = {}) {\n super({\n className: 'mini-chart',\n ...options\n });\n\n // Chart type: 'line' or 'bar'\n this.chartType = options.chartType || 'line';\n\n // Data\n this.data = options.data || [];\n\n // Dimensions\n this.width = options.width || '100%'; // Support both number and '100%'\n this.height = options.height || 30;\n this.maintainAspectRatio = options.maintainAspectRatio || false;\n\n // Styling\n this.color = options.color || 'rgba(54, 162, 235, 1)'; // Primary blue\n this.fillColor = options.fillColor || 'rgba(54, 162, 235, 0.1)'; // Light fill\n this.strokeWidth = options.strokeWidth || 2;\n this.barGap = options.barGap || 2;\n\n // Fill area under line\n this.fill = options.fill !== false; // Default true\n\n // Curve smoothing (0 = straight lines, 1 = very smooth)\n this.smoothing = options.smoothing || 0.3;\n\n // Padding\n this.padding = options.padding || 2;\n\n // Min/Max values (auto-calculated if not provided)\n this.minValue = options.minValue;\n this.maxValue = options.maxValue;\n\n // Show dots on line chart\n this.showDots = options.showDots || false;\n this.dotRadius = options.dotRadius || 2;\n\n // Animation\n this.animate = options.animate !== false;\n this.animationDuration = options.animationDuration || 300;\n\n // Tooltip\n this.showTooltip = options.showTooltip !== false;\n this.tooltipFormatter = options.tooltipFormatter || null;\n this.tooltipTemplate = options.tooltipTemplate || null; // Function returning HTML\n this.valueFormat = options.valueFormat || null; // DataFormatter string\n this.labelFormat = options.labelFormat || null; // DataFormatter string for labels\n\n // Crosshair\n this.showCrosshair = options.showCrosshair !== false;\n this.crosshairColor = options.crosshairColor || 'rgba(0, 0, 0, 0.2)';\n this.crosshairWidth = options.crosshairWidth || 1;\n\n // X-axis\n this.showXAxis = options.showXAxis || false;\n this.xAxisColor = options.xAxisColor || this.color;\n this.xAxisWidth = options.xAxisWidth || 1;\n this.xAxisDashed = options.xAxisDashed !== false;\n\n // Tooltip state\n this.tooltip = null;\n this.crosshair = null;\n this.hoveredIndex = -1;\n\n // DataFormatter instance\n this.dataFormatter = dataFormatter;\n\n // Labels array (can be set externally or from API)\n this.labels = options.labels || null;\n }\n\n getTemplate() {\n const widthStyle = typeof this.width === 'number' ? `${this.width}px` : this.width;\n const heightStyle = typeof this.height === 'number' ? `${this.height}px` : this.height;\n const preserveAspectRatio = this.maintainAspectRatio ? 'xMidYMid meet' : 'none';\n\n return `\n <div class=\"mini-chart-wrapper\" style=\"position: relative; display: block; width: ${widthStyle}; height: ${heightStyle};\">\n <svg\n class=\"mini-chart-svg\"\n width=\"100%\"\n height=\"100%\"\n viewBox=\"0 0 100 ${this.height}\"\n preserveAspectRatio=\"${preserveAspectRatio}\"\n style=\"display: block;\">\n </svg>\n ${this.showTooltip ? '<div class=\"mini-chart-tooltip\" style=\"display: none;\"></div>' : ''}\n </div>\n `;\n }\n\n async onAfterRender() {\n this.svg = this.element.querySelector('.mini-chart-svg');\n this.tooltip = this.element.querySelector('.mini-chart-tooltip');\n\n // Get actual rendered dimensions\n this.updateDimensions();\n\n if (this.data && this.data.length > 0) {\n this.renderChart();\n }\n\n // Setup hover interactions if tooltip enabled\n if (this.showTooltip && this.svg) {\n this.setupTooltip();\n }\n\n // Setup resize observer for responsive behavior\n this.setupResizeObserver();\n }\n\n updateDimensions() {\n if (!this.svg) return;\n\n const rect = this.svg.getBoundingClientRect();\n this.actualWidth = rect.width || 100;\n this.actualHeight = rect.height || this.height;\n\n // Update viewBox to match aspect ratio\n this.svg.setAttribute('viewBox', `0 0 ${this.actualWidth} ${this.actualHeight}`);\n }\n\n setupResizeObserver() {\n if (typeof ResizeObserver === 'undefined') return;\n\n this.resizeObserver = new ResizeObserver(() => {\n this.updateDimensions();\n if (this.data && this.data.length > 0) {\n this.renderChart();\n }\n });\n\n if (this.svg) {\n this.resizeObserver.observe(this.svg);\n }\n }\n\n renderChart() {\n if (!this.svg || !this.data || this.data.length === 0) return;\n\n // Clear previous content\n this.svg.innerHTML = '';\n\n // Calculate bounds\n const { min, max } = this.calculateBounds();\n\n // Add x-axis line if enabled (render first so it's behind chart)\n if (this.showXAxis) {\n this.renderXAxis(min, max);\n }\n\n if (this.chartType === 'line') {\n this.renderLine(min, max);\n } else if (this.chartType === 'bar') {\n this.renderBar(min, max);\n }\n\n // Add crosshair line (initially hidden)\n if (this.showCrosshair) {\n const height = this.getActualHeight();\n this.crosshair = this.createSVGElement('line', {\n x1: 0,\n y1: 0,\n x2: 0,\n y2: height,\n stroke: this.crosshairColor,\n 'stroke-width': this.crosshairWidth,\n 'stroke-dasharray': '3,3',\n style: 'display: none; pointer-events: none;'\n });\n this.svg.appendChild(this.crosshair);\n }\n\n // Setup tooltip hit areas after rendering chart\n if (this.showTooltip && this.tooltip) {\n this.setupTooltip();\n }\n\n // Apply animation if enabled\n if (this.animate) {\n this.applyAnimation();\n }\n }\n\n renderXAxis(min, max) {\n const width = this.getActualWidth();\n const height = this.getActualHeight();\n\n // Calculate y position for x-axis (at zero if data crosses zero, otherwise at bottom)\n let yPos;\n if (min <= 0 && max >= 0) {\n // Data crosses zero, place axis at zero\n const range = max - min;\n const yScale = (height - this.padding * 2) / range;\n yPos = height - this.padding - ((0 - min) * yScale);\n } else {\n // Place at bottom\n yPos = height - this.padding;\n }\n\n const xAxis = this.createSVGElement('line', {\n x1: this.padding,\n y1: yPos,\n x2: width - this.padding,\n y2: yPos,\n stroke: this.xAxisColor,\n 'stroke-width': this.xAxisWidth,\n 'stroke-dasharray': this.xAxisDashed ? '2,2' : 'none',\n 'stroke-opacity': '0.5'\n });\n\n this.svg.appendChild(xAxis);\n }\n\n calculateBounds() {\n const values = this.data.map(d => typeof d === 'object' ? d.value : d);\n\n let min = this.minValue !== undefined ? this.minValue : Math.min(...values);\n let max = this.maxValue !== undefined ? this.maxValue : Math.max(...values);\n\n // Handle zero-range cases\n const range = max - min;\n if (range === 0) {\n if (this.chartType === 'bar') {\n // For bar charts with all zeros, keep baseline at 0\n if (min === 0) {\n min = 0;\n max = 1;\n } else {\n // For constant non-zero values, add a small symmetric range\n min = min - 1;\n max = max + 1;\n }\n } else {\n // For line charts, add a small symmetric range\n min = min - 1;\n max = max + 1;\n }\n }\n\n return { min, max };\n }\n\n getActualWidth() {\n return this.actualWidth || this.width || 100;\n }\n\n getActualHeight() {\n return this.actualHeight || this.height || 30;\n }\n\n renderLine(min, max) {\n const values = this.data.map(d => typeof d === 'object' ? d.value : d);\n const points = this.calculatePoints(values, min, max);\n\n // Create filled area under line\n if (this.fill) {\n const areaPath = this.createAreaPath(points);\n const area = this.createSVGElement('path', {\n d: areaPath,\n fill: this.fillColor,\n stroke: 'none'\n });\n this.svg.appendChild(area);\n }\n\n // Create line path\n const linePath = this.smoothing > 0\n ? this.createSmoothPath(points)\n : this.createLinePath(points);\n\n const line = this.createSVGElement('path', {\n d: linePath,\n fill: 'none',\n stroke: this.color,\n 'stroke-width': this.strokeWidth,\n 'stroke-linecap': 'round',\n 'stroke-linejoin': 'round'\n });\n this.svg.appendChild(line);\n\n // Add dots if enabled\n if (this.showDots) {\n points.forEach(point => {\n const dot = this.createSVGElement('circle', {\n cx: point.x,\n cy: point.y,\n r: this.dotRadius,\n fill: this.color\n });\n this.svg.appendChild(dot);\n });\n }\n }\n\n renderBar(min, max) {\n const values = this.data.map(d => typeof d === 'object' ? d.value : d);\n const points = this.calculatePoints(values, min, max);\n\n const width = this.getActualWidth();\n const height = this.getActualHeight();\n const barWidth = (width - this.padding * 2 - (this.barGap * (values.length - 1))) / values.length;\n\n points.forEach((point, index) => {\n const barHeight = height - this.padding * 2 - point.y + this.padding;\n const x = point.x - barWidth / 2;\n const y = point.y;\n\n const bar = this.createSVGElement('rect', {\n x: x,\n y: y,\n width: barWidth,\n height: barHeight,\n fill: this.color,\n rx: 1, // Slight rounding\n 'data-bar-index': index,\n class: 'mini-chart-bar'\n });\n this.svg.appendChild(bar);\n });\n }\n\n calculatePoints(values, min, max) {\n const range = max - min;\n const width = this.getActualWidth();\n const height = this.getActualHeight();\n const xStep = (width - this.padding * 2) / (values.length - 1 || 1);\n const yScale = (height - this.padding * 2) / range;\n\n return values.map((value, index) => ({\n x: this.padding + (index * xStep),\n y: height - this.padding - ((value - min) * yScale)\n }));\n }\n\n createLinePath(points) {\n if (points.length === 0) return '';\n\n let path = `M ${points[0].x},${points[0].y}`;\n for (let i = 1; i < points.length; i++) {\n path += ` L ${points[i].x},${points[i].y}`;\n }\n return path;\n }\n\n createSmoothPath(points) {\n if (points.length < 2) return this.createLinePath(points);\n\n let path = `M ${points[0].x},${points[0].y}`;\n\n for (let i = 0; i < points.length - 1; i++) {\n const current = points[i];\n const next = points[i + 1];\n\n // Calculate control points for cubic bezier curve\n const cp1x = current.x + (next.x - current.x) * this.smoothing;\n const cp1y = current.y;\n const cp2x = next.x - (next.x - current.x) * this.smoothing;\n const cp2y = next.y;\n\n path += ` C ${cp1x},${cp1y} ${cp2x},${cp2y} ${next.x},${next.y}`;\n }\n\n return path;\n }\n\n createAreaPath(points) {\n if (points.length === 0) return '';\n\n const linePath = this.smoothing > 0\n ? this.createSmoothPath(points)\n : this.createLinePath(points);\n\n // Close the path along the bottom\n const lastPoint = points[points.length - 1];\n const firstPoint = points[0];\n const height = this.getActualHeight();\n\n return `${linePath} L ${lastPoint.x},${height - this.padding} L ${firstPoint.x},${height - this.padding} Z`;\n }\n\n createSVGElement(tag, attributes = {}) {\n const element = document.createElementNS('http://www.w3.org/2000/svg', tag);\n Object.entries(attributes).forEach(([key, value]) => {\n element.setAttribute(key, value);\n });\n return element;\n }\n\n applyAnimation() {\n const paths = this.svg.querySelectorAll('path');\n paths.forEach(path => {\n const length = path.getTotalLength();\n path.style.strokeDasharray = length;\n path.style.strokeDashoffset = length;\n path.style.animation = `mini-chart-draw ${this.animationDuration}ms ease-out forwards`;\n });\n\n const bars = this.svg.querySelectorAll('rect');\n bars.forEach((bar, index) => {\n bar.style.transformOrigin = 'bottom';\n bar.style.animation = `mini-chart-bar-grow ${this.animationDuration}ms ease-out ${index * 20}ms forwards`;\n bar.style.transform = 'scaleY(0)';\n });\n }\n\n setupTooltip() {\n if (!this.svg || !this.tooltip) return;\n\n // Create invisible overlay rects for hover detection\n const values = this.data.map(d => typeof d === 'object' ? d.value : d);\n const points = this.calculatePoints(values, ...Object.values(this.calculateBounds()));\n\n const width = this.getActualWidth();\n const height = this.getActualHeight();\n const barWidth = width / values.length;\n\n points.forEach((point, index) => {\n const hitArea = this.createSVGElement('rect', {\n x: index * barWidth,\n y: 0,\n width: barWidth,\n height: height,\n fill: 'transparent',\n style: 'cursor: pointer;'\n });\n\n hitArea.addEventListener('mouseenter', (e) => {\n this.showTooltipAtIndex(index, e);\n });\n\n hitArea.addEventListener('mousemove', (e) => {\n this.updateTooltipPosition(e);\n });\n\n hitArea.addEventListener('mouseleave', () => {\n this.hideTooltip();\n });\n\n this.svg.appendChild(hitArea);\n });\n }\n\n showTooltipAtIndex(index, event) {\n if (!this.tooltip) return;\n\n this.hoveredIndex = index;\n const value = typeof this.data[index] === 'object' ? this.data[index].value : this.data[index];\n const dataLabel = typeof this.data[index] === 'object' ? this.data[index].label : null;\n const label = this.labels ? this.labels[index] : dataLabel;\n\n // Build tooltip content using priority system\n let content;\n\n if (this.tooltipTemplate && typeof this.tooltipTemplate === 'function') {\n // 1. Custom template function (highest priority)\n content = this.tooltipTemplate({ value, label, index, data: this.data[index] });\n } else {\n // 2. Format value with DataFormatter or custom formatter\n let displayValue = value;\n\n if (this.valueFormat && this.dataFormatter) {\n // Use DataFormatter with format string\n displayValue = this.dataFormatter.pipe(value, this.valueFormat);\n } else if (this.tooltipFormatter && typeof this.tooltipFormatter === 'function') {\n // Use custom formatter function\n displayValue = this.tooltipFormatter(value, index);\n } else {\n // Default formatting\n displayValue = typeof value === 'number' ? value.toLocaleString() : value;\n }\n\n // Format label if formatter provided\n let displayLabel = label;\n if (label && this.labelFormat && this.dataFormatter) {\n displayLabel = this.dataFormatter.pipe(label, this.labelFormat);\n }\n\n // Build default tooltip HTML\n content = `<strong>${displayValue}</strong>`;\n if (displayLabel) {\n content = `<div class=\"mini-chart-tooltip-label\">${displayLabel}</div>${content}`;\n }\n }\n\n this.tooltip.innerHTML = content;\n this.tooltip.style.display = 'block';\n this.updateTooltipPosition(event);\n\n // Highlight bar if in bar chart mode\n if (this.chartType === 'bar') {\n this.highlightBar(index);\n }\n\n // Show crosshair at the hovered position\n if (this.crosshair && this.showCrosshair) {\n const width = this.getActualWidth();\n const barWidth = width / this.data.length;\n const x = (index * barWidth) + (barWidth / 2);\n this.crosshair.setAttribute('x1', x);\n this.crosshair.setAttribute('x2', x);\n this.crosshair.style.display = 'block';\n }\n }\n\n updateTooltipPosition(event) {\n if (!this.tooltip || this.tooltip.style.display === 'none') return;\n\n const rect = this.svg.getBoundingClientRect();\n const x = event.clientX - rect.left;\n const y = event.clientY - rect.top;\n\n // Position tooltip above cursor\n this.tooltip.style.left = `${x}px`;\n this.tooltip.style.top = `${y - 10}px`;\n this.tooltip.style.transform = 'translate(-50%, -100%)';\n }\n\n hideTooltip() {\n if (this.tooltip) {\n this.tooltip.style.display = 'none';\n this.hoveredIndex = -1;\n }\n\n // Remove bar highlight\n if (this.chartType === 'bar') {\n this.unhighlightBars();\n }\n\n // Hide crosshair\n if (this.crosshair) {\n this.crosshair.style.display = 'none';\n }\n }\n\n highlightBar(index) {\n if (!this.svg) return;\n\n // Remove previous highlights\n this.unhighlightBars();\n\n // Highlight the hovered bar\n const bar = this.svg.querySelector(`rect.mini-chart-bar[data-bar-index=\"${index}\"]`);\n if (bar) {\n bar.style.opacity = '0.7';\n }\n }\n\n unhighlightBars() {\n if (!this.svg) return;\n\n const bars = this.svg.querySelectorAll('rect.mini-chart-bar');\n bars.forEach(bar => {\n bar.style.opacity = '1';\n });\n }\n\n // Public API\n setData(data) {\n this.data = data;\n if (this.svg) {\n this.renderChart();\n }\n }\n\n setColor(color) {\n this.color = color;\n if (this.svg) {\n this.renderChart();\n }\n }\n\n setType(type) {\n if (['line', 'bar'].includes(type)) {\n this.chartType = type;\n if (this.svg) {\n this.renderChart();\n }\n }\n }\n\n resize(width, height) {\n this.width = width;\n this.height = height;\n this.updateDimensions();\n if (this.svg) {\n this.renderChart();\n }\n }\n\n async onBeforeDestroy() {\n // Clean up resize observer\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n this.resizeObserver = null;\n }\n await super.onBeforeDestroy();\n }\n}\n","/**\n * MetricsMiniChart - MiniChart with API integration\n * Extends MiniChart to add /api/metrics/fetch support (same API as MetricsChart)\n */\n\nimport MiniChart from './MiniChart.js';\n\nexport default class MetricsMiniChart extends MiniChart {\n constructor(options = {}) {\n super(options);\n\n // API configuration (matching MetricsChart)\n this.endpoint = options.endpoint || '/api/metrics/fetch';\n this.account = options.account || 'global';\n this.granularity = options.granularity || 'hours';\n this.slugs = options.slugs || null; // Single slug or array of slugs\n this.category = options.category || null;\n this.dateStart = options.dateStart || null;\n this.dateEnd = options.dateEnd || null;\n this.defaultDateRange = options.defaultDateRange || '24h';\n\n // State\n this.isLoading = false;\n this.lastFetch = null;\n this.refreshInterval = options.refreshInterval;\n\n // Initialize date range if missing\n if (!this.dateStart || !this.dateEnd) {\n this.setQuickRange(this.defaultDateRange);\n }\n\n // Normalize slugs to array\n if (this.slugs && !Array.isArray(this.slugs)) {\n this.slugs = [this.slugs];\n }\n }\n\n async onAfterRender() {\n await super.onAfterRender();\n\n // Fetch initial data if endpoint provided and no data\n if (this.endpoint && (!this.data || this.data.length === 0)) {\n this.fetchData();\n }\n\n // Setup auto-refresh if configured\n if (this.refreshInterval && this.endpoint) {\n this.startAutoRefresh();\n }\n }\n\n buildApiParams() {\n const params = {\n granularity: this.granularity,\n account: this.account,\n with_labels: true\n };\n\n // Add slugs\n if (this.slugs && this.slugs.length > 0) {\n this.slugs.forEach(slug => {\n if (!params['slugs[]']) params['slugs[]'] = [];\n params['slugs[]'].push(slug);\n });\n }\n\n if (this.category) {\n params.category = this.category;\n }\n\n // Date range\n if (this.dateStart) {\n params.dr_start = Math.floor(this.dateStart.getTime() / 1000);\n }\n if (this.dateEnd) {\n params.dr_end = Math.floor(this.dateEnd.getTime() / 1000);\n }\n\n // Cache buster\n params._ = Date.now();\n\n return params;\n }\n\n async fetchData() {\n if (!this.endpoint) return;\n\n this.isLoading = true;\n\n try {\n const rest = this.getApp()?.rest;\n if (!rest) {\n throw new Error('No REST client available');\n }\n\n const params = this.buildApiParams();\n const response = await rest.GET(this.endpoint, params);\n\n // Handle Rest standardized response\n if (!response.success) {\n throw new Error(response.message || 'Network error');\n }\n if (!response.data?.status) {\n throw new Error(response.data?.error || 'Server error');\n }\n\n const metricsData = response.data.data;\n this.processMetricsData(metricsData);\n this.lastFetch = new Date();\n\n // Re-render to show updated values\n await this.render();\n\n this.emit('metrics:loaded', { chart: this, data: metricsData, params });\n\n } catch (error) {\n console.error('Failed to fetch metrics:', error);\n this.emit('metrics:error', { chart: this, error });\n } finally {\n this.isLoading = false;\n }\n }\n\n processMetricsData(metricsData) {\n // Expecting: { labels: [...], data: { metric_slug: [values...] } }\n const { data: metrics, labels } = metricsData;\n\n if (!metrics) return;\n\n // Get the first (or only) metric's data\n const metricKeys = Object.keys(metrics);\n if (metricKeys.length === 0) return;\n\n const metricSlug = metricKeys[0];\n const values = metrics[metricSlug];\n\n // Sanitize values\n const sanitizedValues = values.map(val => {\n if (val === null || val === undefined || val === '') return 0;\n return typeof val === 'number' ? val : (parseFloat(val) || 0);\n });\n\n // Update labels (for tooltips)\n this.labels = labels || null;\n\n // Update chart data\n this.setData(sanitizedValues);\n }\n\n setQuickRange(range) {\n const now = new Date();\n let startDate;\n\n switch (range) {\n case '1h':\n startDate = new Date(now.getTime() - (60 * 60 * 1000));\n break;\n case '24h':\n startDate = new Date(now.getTime() - (24 * 60 * 60 * 1000));\n break;\n case '7d':\n startDate = new Date(now.getTime() - (7 * 24 * 60 * 60 * 1000));\n break;\n case '30d':\n startDate = new Date(now.getTime() - (30 * 24 * 60 * 60 * 1000));\n break;\n default:\n startDate = new Date(now.getTime() - (24 * 60 * 60 * 1000));\n }\n\n this.dateStart = startDate;\n this.dateEnd = now;\n }\n\n startAutoRefresh() {\n if (this.refreshTimer) {\n clearInterval(this.refreshTimer);\n }\n\n this.refreshTimer = setInterval(() => {\n this.fetchData();\n }, this.refreshInterval);\n }\n\n stopAutoRefresh() {\n if (this.refreshTimer) {\n clearInterval(this.refreshTimer);\n this.refreshTimer = null;\n }\n }\n\n // Public API\n setGranularity(granularity) {\n this.granularity = granularity;\n return this.fetchData();\n }\n\n setDateRange(startDate, endDate) {\n this.dateStart = new Date(startDate);\n this.dateEnd = new Date(endDate);\n return this.fetchData();\n }\n\n setMetrics(slugs) {\n this.slugs = Array.isArray(slugs) ? slugs : [slugs];\n return this.fetchData();\n }\n\n refresh() {\n return this.fetchData();\n }\n\n async onBeforeDestroy() {\n this.stopAutoRefresh();\n await super.onBeforeDestroy();\n }\n}\n","/**\n * MetricsMiniChartWidget - Bootstrap card wrapper around MetricsMiniChart\n *\n * Renders a compact card with:\n * - icon (Bootstrap Icons class)\n * - title\n * - subtitle (inserted raw into the template so Mustache can render tokens like '{{total}}')\n * - optional trending indicator (up/down percent) under the subtitle\n * - embedded MetricsMiniChart\n * - optional settings dropdown (granularity, chartType, date range)\n *\n * Usage:\n * new MetricsMiniChartWidget({\n * icon: \"bi bi-credit-card-fill\",\n * title: 'Declined Transactions',\n * subtitle: '{{total}} Transactions', // will be rendered by Mustache at runtime\n * background: \"#F3465D\",\n * textColor: \"#FFFFFF\",\n * granularity: 'hours',\n * slugs: ['pos_tx_declined'],\n * account: 'global',\n * chartType: 'bar',\n * showTooltip: true,\n * showXAxis: true,\n * height: 80,\n * chartWidth: '100%',\n * color: 'rgba(245, 245, 255, 0.8)',\n * fill: true,\n * fillColor: 'rgba(245, 245, 255, 0.6)',\n * smoothing: 0.3,\n * showTrending: true, // optional\n * showSettings: true, // optional - show settings dropdown\n * settingsKey: 'myChart', // optional - localStorage key for persisting settings\n * showDateRange: true, // optional - include date range in settings\n * containerId: 'decline-24h-chart'\n * });\n */\n\nimport View from '@core/View.js';\nimport MetricsMiniChart from './MetricsMiniChart.js';\n\nexport default class MetricsMiniChartWidget extends View {\n constructor(options = {}) {\n super({\n ...options,\n tagName: 'div',\n className: `metrics-mini-chart-widget ${options.className || ''}`.trim()\n });\n\n // Display config\n this.icon = options.icon || null;\n this.title = options.title || '';\n // Subtitle is injected RAW into the template string so Mustache parses its tokens\n this.subtitle = options.subtitle || '';\n this.background = options.background || null;\n this.textColor = options.textColor || null;\n\n // Settings config\n this.showSettings = options.showSettings || false;\n this.settingsKey = options.settingsKey || null;\n this.showDateRange = options.showDateRange || false;\n this._pendingSettings = null; // Store pending settings until Apply is clicked\n\n // Trending options/state\n this.showTrending = !!options.showTrending;\n this.trendRange = options.trendRange ?? null; // e.g. 4 => compare last 2 vs prev 2\n this.trendOffset = options.trendOffset ?? 0; // e.g. 1 => skip most recent incomplete bucket\n this.prevTrendOffset = options.prevTrendOffset ?? 0; // e.g. 7 => align previous window to same day last week\n this.total = 0;\n this.lastValue = 0;\n this.prevValue = 0;\n this.trendingPercent = 0;\n this.trendingUp = null; // null means unknown\n this.hasTrending = false;\n this.trendingClass = 'metrics-mini-chart-trending-text';\n this.trendingIcon = '';\n this.trendingLabel = '';\n\n // Chart config (we'll forward these to the child MetricsMiniChart)\n this.chartOptions = {\n endpoint: options.endpoint, // defaults inside MetricsMiniChart\n account: options.account,\n granularity: options.granularity,\n slugs: options.slugs,\n category: options.category,\n dateStart: options.dateStart,\n dateEnd: options.dateEnd,\n defaultDateRange: options.defaultDateRange,\n refreshInterval: options.refreshInterval,\n\n // Visuals and interactions\n chartType: options.chartType || 'line',\n showTooltip: options.showTooltip !== undefined ? options.showTooltip : true,\n showXAxis: options.showXAxis || false,\n height: options.height || 80,\n width: options.chartWidth || options.width || '100%',\n color: options.color,\n fill: options.fill !== undefined ? options.fill : true,\n fillColor: options.fillColor,\n smoothing: options.smoothing ?? 0.3,\n strokeWidth: options.strokeWidth,\n barGap: options.barGap,\n\n // Optional formatters and templates\n valueFormat: options.valueFormat,\n labelFormat: options.labelFormat,\n tooltipFormatter: options.tooltipFormatter,\n tooltipTemplate: options.tooltipTemplate,\n\n // Crosshair and axis styling overrides (optional passthroughs)\n showCrosshair: options.showCrosshair,\n crosshairColor: options.crosshairColor,\n crosshairWidth: options.crosshairWidth,\n xAxisColor: options.xAxisColor,\n xAxisWidth: options.xAxisWidth,\n xAxisDashed: options.xAxisDashed,\n\n // Other rendering params\n padding: options.padding,\n minValue: options.minValue,\n maxValue: options.maxValue,\n showDots: options.showDots,\n dotRadius: options.dotRadius,\n animate: options.animate,\n animationDuration: options.animationDuration\n };\n }\n\n async onInit() {\n // Load saved settings if available\n if (this.showSettings && this.settingsKey) {\n this._loadSettings();\n }\n\n // Create and register the child chart\n this.chart = new MetricsMiniChart({\n ...this.chartOptions,\n containerId: 'chart' // mount inside our template container\n });\n\n this.addChild(this.chart);\n\n this.header = new View({\n containerId: 'chart-header',\n title: this.title,\n icon: this.icon,\n template: `\n <div class=\"d-flex justify-content-between align-items-start mb-2\">\n <div class=\"me-3 flex-grow-1\">\n <h6 class=\"card-title mb-1\" style=\"${this.textColor ? `color: ${this.textColor}` : ''}\">${this.title}</h6>\n <div class=\"metrics-mini-chart-subtitle\" style=\"${this.textColor ? `color: ${this.textColor}` : ''}\">${this.subtitle}</div>\n {{#hasTrending}}\n <div class=\"{{trendingClass}}\" style=\"${this.textColor ? `color: ${this.textColor}` : ''}\">\n <i class=\"{{trendingIcon}} me-1\"></i>{{trendingLabel}}\n </div>\n {{/hasTrending}}\n </div>\n <div class=\"d-flex align-items-center gap-2\">\n ${this.showSettings ? `\n <button class=\"btn btn-link p-0 text-muted metrics-settings-btn\" type=\"button\" data-settings-trigger style=\"${this.textColor ? `color: ${this.textColor} !important` : ''}\">\n <i class=\"bi bi-gear-fill\" style=\"font-size: 1.1rem;\"></i>\n </button>\n ` : ''}\n ${this.icon ? `<i class=\"${this.icon} fs-4 flex-shrink-0\" aria-hidden=\"true\" style=\"${this.textColor ? `color: ${this.textColor}` : ''}\"></i>` : ''}\n </div>\n </div>`\n });\n\n this.addChild(this.header);\n\n // Listen for data load events to compute totals/trending and refresh the widget UI\n if (this.chart?.on) {\n this.chart.on('metrics:loaded', this.onChildMetricsLoaded, this);\n }\n\n // If the chart already has data (e.g., provided via options), compute immediately\n this.updateFromChartData({ render: false });\n }\n\n async onAfterRender() {\n await super.onAfterRender();\n\n // Initialize popover if settings are enabled\n if (this.showSettings) {\n this._initSettingsPopover();\n }\n }\n\n onChildMetricsLoaded() {\n this.updateFromChartData({ render: true });\n \n // Reinitialize popover after chart updates (in case DOM was re-rendered)\n if (this.showSettings && this.isMounted()) {\n // Small delay to ensure DOM is ready\n setTimeout(() => {\n this._initSettingsPopover();\n }, 100);\n }\n }\n\n updateFromChartData({ render = true } = {}) {\n const values = Array.isArray(this.chart?.data) ? this.chart.data : null;\n if (!values || values.length === 0) {\n this.total = 0;\n this.hasTrending = false;\n // Refresh the view to ensure subtitle using {{total}} updates to 0\n this.header.title = this.title;\n if (render) this.render();\n return;\n }\n\n // Normalize values to numbers\n const nums = values.map((v) => {\n if (typeof v === 'number') return v;\n if (v && typeof v.value === 'number') return v.value;\n const n = parseFloat(v);\n return Number.isNaN(n) ? 0 : n;\n });\n\n // Compute total\n this.header.title = this.title;\n this.header.total = nums.reduce((a, b) => a + b, 0);\n const offset = Math.max(0, parseInt(this.trendOffset || 0, 10) || 0);\n const endIndex = Math.max(0, nums.length - 1 - offset);\n this.header.now_value = nums[endIndex];\n \n // Set dynamic labels based on granularity\n this._updateGranularityLabels();\n\n // Compute trending using windowed sums with optional offset\n let hasTrend = false;\n let lastSum = 0;\n let prevSum = 0;\n\n const k = (this.trendRange && this.trendRange >= 2) ? Math.max(1, Math.floor(this.trendRange / 2)) : 1;\n\n if (endIndex >= 0) {\n const lastEnd = endIndex;\n const lastStart = lastEnd - (k - 1);\n let prevStart, prevEnd;\n if (this.prevTrendOffset && this.prevTrendOffset > 0) {\n prevStart = lastStart - this.prevTrendOffset;\n prevEnd = lastEnd - this.prevTrendOffset;\n } else {\n prevEnd = lastStart - 1;\n prevStart = prevEnd - (k - 1);\n }\n\n if (lastStart >= 0 && prevStart >= 0) {\n // Sum helper\n const sumRange = (arr, s, e) => {\n let sum = 0;\n for (let i = s; i <= e; i++) sum += arr[i] || 0;\n return sum;\n };\n\n lastSum = sumRange(nums, lastStart, lastEnd);\n prevSum = sumRange(nums, prevStart, prevEnd);\n hasTrend = true;\n }\n }\n\n // Fallback to single-point comparison if not enough data for windows\n if (!hasTrend) {\n const prevIndex = endIndex - (this.prevTrendOffset && this.prevTrendOffset > 0 ? this.prevTrendOffset : 1);\n if (prevIndex >= 0) {\n lastSum = nums[endIndex];\n prevSum = nums[prevIndex];\n hasTrend = true;\n }\n }\n\n if (hasTrend) {\n this.header.lastValue = lastSum;\n this.header.prevValue = prevSum;\n\n let percent = 0;\n if (prevSum === 0) {\n percent = lastSum > 0 ? 100 : 0;\n } else {\n percent = ((lastSum - prevSum) / Math.abs(prevSum)) * 100;\n }\n\n this.header.trendingPercent = percent;\n this.header.trendingUp = percent >= 0;\n if (!this.textColor) {\n this.header.trendingClass = this.header.trendingUp ? 'text-success' : 'text-danger';\n } else {\n this.header.trendingClass = '';\n }\n\n this.header.trendingIcon = this.header.trendingUp ? 'bi bi-arrow-up' : 'bi bi-arrow-down';\n\n const sign = percent > 0 ? '+' : '';\n this.header.trendingLabel = `${sign}${percent.toFixed(1)}%`;\n this.header.hasTrending = this.showTrending;\n } else {\n this.header.hasTrending = false;\n }\n\n if (render) {\n // Re-render to update the UI (subtitle with {{total}} and trending block)\n this.header.render();\n }\n }\n\n /**\n * Update labels based on current granularity\n * @private\n */\n _updateGranularityLabels() {\n const granularity = this.chartOptions.granularity || 'days';\n \n // Mapping for \"now\" label (current/most recent bucket)\n const nowLabels = {\n 'hours': 'This Hour',\n 'days': 'Today',\n 'weeks': 'This Week',\n 'months': 'This Month',\n 'years': 'This Year'\n };\n \n // Mapping for \"total\" label (sum of all buckets in range)\n const totalLabels = {\n 'hours': 'Total (24h)',\n 'days': 'Total (Period)',\n 'weeks': 'Total (Period)',\n 'months': 'Total (Period)',\n 'years': 'Total (Period)'\n };\n \n this.header.now_label = nowLabels[granularity] || 'Current';\n this.header.total_label = totalLabels[granularity] || 'Total';\n }\n\n get cardStyle() {\n const styles = [];\n if (this.background) styles.push(`background: ${this.background}`);\n if (this.textColor) styles.push(`color: ${this.textColor}`);\n // Ensure inner elements inherit text color\n styles.push('border: 0');\n return styles.join('; ');\n }\n\n async getTemplate() {\n return `\n <div class=\"card h-100 shadow-sm\" style=\"${this.cardStyle}\">\n <div class=\"card-body p-3\">\n <div data-container=\"chart-header\"></div>\n <div data-container=\"chart\"></div>\n </div>\n </div>\n `;\n }\n\n async onBeforeDestroy() {\n // Dispose of popover if it exists\n if (this._settingsPopover) {\n this._settingsPopover.dispose();\n this._settingsPopover = null;\n }\n\n if (this.chart?.off) {\n this.chart.off('metrics:loaded', this.onChildMetricsLoaded, this);\n }\n await super.onBeforeDestroy();\n }\n\n /**\n * Initialize settings popover\n * @private\n */\n _initSettingsPopover() {\n const button = this.element.querySelector('[data-settings-trigger]');\n if (!button) {\n console.warn('MetricsMiniChartWidget: Settings button not found');\n return;\n }\n\n // Dispose of existing popover if any\n if (this._settingsPopover) {\n try {\n this._settingsPopover.dispose();\n } catch (e) {\n // Popover might already be disposed\n console.warn('Error disposing popover:', e);\n }\n this._settingsPopover = null;\n }\n\n // Create popover content\n const content = this._getSettingsContent();\n\n // Initialize Bootstrap popover with callback\n this._settingsPopover = new bootstrap.Popover(button, {\n content: content,\n html: true,\n placement: 'bottom',\n trigger: 'click',\n sanitize: false,\n customClass: 'metrics-chart-settings-popover'\n });\n\n // Use Bootstrap's native event on the element\n button.addEventListener('shown.bs.popover', () => {\n // Use setTimeout to ensure DOM is ready\n setTimeout(() => {\n this._attachSettingsHandlers();\n }, 10);\n });\n\n // Also try inserting event listener directly\n button.addEventListener('inserted.bs.popover', () => {\n this._attachSettingsHandlers();\n });\n }\n\n /**\n * Generate settings popover HTML content\n * @private\n */\n _getSettingsContent() {\n return `\n <div class=\"metrics-chart-settings-content\" style=\"min-width: 220px;\">\n <div class=\"d-flex justify-content-between align-items-center mb-2 pb-2 border-bottom\">\n <h6 class=\"mb-0\">Chart Settings</h6>\n <button type=\"button\" class=\"btn-close btn-close-sm\" data-setting-action=\"close\" aria-label=\"Close\"></button>\n </div>\n\n <label class=\"form-label small mb-1\">Granularity</label>\n <select class=\"form-select form-select-sm mb-2\" data-setting=\"granularity\">\n <option value=\"hours\" ${this.chartOptions.granularity === 'hours' ? 'selected' : ''}>Hours</option>\n <option value=\"days\" ${this.chartOptions.granularity === 'days' ? 'selected' : ''}>Days</option>\n <option value=\"weeks\" ${this.chartOptions.granularity === 'weeks' ? 'selected' : ''}>Weeks</option>\n <option value=\"months\" ${this.chartOptions.granularity === 'months' ? 'selected' : ''}>Months</option>\n <option value=\"years\" ${this.chartOptions.granularity === 'years' ? 'selected' : ''}>Years</option>\n </select>\n\n <label class=\"form-label small mb-1\">Chart Type</label>\n <select class=\"form-select form-select-sm mb-2\" data-setting=\"chartType\">\n <option value=\"line\" ${this.chartOptions.chartType === 'line' ? 'selected' : ''}>Line</option>\n <option value=\"bar\" ${this.chartOptions.chartType === 'bar' ? 'selected' : ''}>Bar</option>\n </select>\n\n ${this.showDateRange ? `\n <label class=\"form-label small mb-1\">Date Range</label>\n <input type=\"date\" class=\"form-control form-control-sm mb-1\" data-setting=\"dateStart\" value=\"${this.chartOptions.dateStart || ''}\" />\n <input type=\"date\" class=\"form-control form-control-sm mb-2\" data-setting=\"dateEnd\" value=\"${this.chartOptions.dateEnd || ''}\" />\n ` : ''}\n \n <div class=\"d-grid gap-2\">\n <button type=\"button\" class=\"btn btn-sm btn-primary\" data-setting-action=\"apply\">Apply</button>\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary\" data-setting-action=\"cancel\">Cancel</button>\n </div>\n </div>\n `;\n }\n\n /**\n * Attach event handlers to settings controls in popover\n * @private\n */\n _attachSettingsHandlers() {\n // Try multiple selectors to find the popover\n let popoverElement = document.querySelector('.metrics-chart-settings-popover');\n\n if (!popoverElement) {\n // Try finding by the popover content class\n popoverElement = document.querySelector('.popover.metrics-chart-settings-popover');\n }\n\n if (!popoverElement) {\n // Try finding any popover that's currently visible\n const popovers = document.querySelectorAll('.popover.show');\n if (popovers.length > 0) {\n popoverElement = popovers[popovers.length - 1]; // Get the last one (most recent)\n }\n }\n\n if (!popoverElement) {\n console.warn('MetricsMiniChartWidget: Could not find popover element');\n return;\n }\n\n // Initialize pending settings\n this._pendingSettings = {\n granularity: this.chartOptions.granularity,\n chartType: this.chartOptions.chartType,\n dateStart: this.chartOptions.dateStart,\n dateEnd: this.chartOptions.dateEnd\n };\n\n // Granularity change - just store pending\n const granularitySelect = popoverElement.querySelector('[data-setting=\"granularity\"]');\n if (granularitySelect) {\n granularitySelect.addEventListener('change', (e) => {\n this._pendingSettings.granularity = e.target.value;\n });\n }\n\n // Chart type change - just store pending\n const chartTypeSelect = popoverElement.querySelector('[data-setting=\"chartType\"]');\n if (chartTypeSelect) {\n chartTypeSelect.addEventListener('change', (e) => {\n this._pendingSettings.chartType = e.target.value;\n });\n }\n\n // Date range changes - just store pending\n if (this.showDateRange) {\n const dateStartInput = popoverElement.querySelector('[data-setting=\"dateStart\"]');\n if (dateStartInput) {\n dateStartInput.addEventListener('change', (e) => {\n this._pendingSettings.dateStart = e.target.value;\n });\n }\n\n const dateEndInput = popoverElement.querySelector('[data-setting=\"dateEnd\"]');\n if (dateEndInput) {\n dateEndInput.addEventListener('change', (e) => {\n this._pendingSettings.dateEnd = e.target.value;\n });\n }\n }\n\n // Apply button - apply all pending changes\n const applyButton = popoverElement.querySelector('[data-setting-action=\"apply\"]');\n if (applyButton) {\n applyButton.addEventListener('click', async () => {\n await this._applyPendingSettings();\n if (this._settingsPopover) {\n this._settingsPopover.hide();\n }\n });\n }\n\n // Cancel button - close without applying\n const cancelButton = popoverElement.querySelector('[data-setting-action=\"cancel\"]');\n if (cancelButton) {\n cancelButton.addEventListener('click', () => {\n this._pendingSettings = null;\n if (this._settingsPopover) {\n this._settingsPopover.hide();\n }\n });\n }\n\n // Close X button - close without applying\n const closeButton = popoverElement.querySelector('[data-setting-action=\"close\"]');\n if (closeButton) {\n closeButton.addEventListener('click', () => {\n this._pendingSettings = null;\n if (this._settingsPopover) {\n this._settingsPopover.hide();\n }\n });\n }\n }\n\n /**\n * Apply all pending settings changes\n * @private\n */\n async _applyPendingSettings() {\n if (!this._pendingSettings) return;\n\n let hasChanges = false;\n\n // Apply granularity\n if (this._pendingSettings.granularity !== this.chartOptions.granularity) {\n this.chartOptions.granularity = this._pendingSettings.granularity;\n this.chart.granularity = this._pendingSettings.granularity;\n hasChanges = true;\n }\n\n // Apply chart type\n if (this._pendingSettings.chartType !== this.chartOptions.chartType) {\n this.chartOptions.chartType = this._pendingSettings.chartType;\n this.chart.chartType = this._pendingSettings.chartType;\n hasChanges = true;\n }\n\n // Apply date start\n if (this._pendingSettings.dateStart !== this.chartOptions.dateStart) {\n this.chartOptions.dateStart = this._pendingSettings.dateStart;\n this.chart.dateStart = this._pendingSettings.dateStart;\n hasChanges = true;\n }\n\n // Apply date end\n if (this._pendingSettings.dateEnd !== this.chartOptions.dateEnd) {\n this.chartOptions.dateEnd = this._pendingSettings.dateEnd;\n this.chart.dateEnd = this._pendingSettings.dateEnd;\n hasChanges = true;\n }\n\n // Save and refresh if changes were made\n if (hasChanges) {\n this._saveSettings();\n await this.chart.refresh();\n \n // Reinitialize popover after refresh (in case header was re-rendered)\n setTimeout(() => {\n if (this.showSettings && this.isMounted()) {\n this._initSettingsPopover();\n }\n }, 150);\n }\n\n this._pendingSettings = null;\n }\n\n refresh() {\n if (this.chart) {\n if (this.account) this.chart.account = this.account;\n this.chart.refresh();\n }\n }\n\n /**\n * Handle granularity change\n */\n async onActionChangeGranularity(event, element) {\n const newGranularity = element.value;\n this.chartOptions.granularity = newGranularity;\n this.chart.granularity = newGranularity;\n this._saveSettings();\n await this.chart.refresh();\n }\n\n /**\n * Handle chart type change\n */\n async onActionChangeChartType(event, element) {\n const newChartType = element.value;\n this.chartOptions.chartType = newChartType;\n this.chart.chartType = newChartType;\n this._saveSettings();\n await this.chart.refresh();\n }\n\n /**\n * Handle date start change\n */\n async onActionChangeDateStart(event, element) {\n const newDateStart = element.value;\n this.chartOptions.dateStart = newDateStart;\n this.chart.dateStart = newDateStart;\n this._saveSettings();\n await this.chart.refresh();\n }\n\n /**\n * Handle date end change\n */\n async onActionChangeDateEnd(event, element) {\n const newDateEnd = element.value;\n this.chartOptions.dateEnd = newDateEnd;\n this.chart.dateEnd = newDateEnd;\n this._saveSettings();\n await this.chart.refresh();\n }\n\n /**\n * Load settings from localStorage\n * @private\n */\n _loadSettings() {\n if (!this.settingsKey) return;\n\n try {\n const stored = localStorage.getItem(`metrics-chart-${this.settingsKey}`);\n if (stored) {\n const settings = JSON.parse(stored);\n\n if (settings.granularity) {\n this.chartOptions.granularity = settings.granularity;\n }\n if (settings.chartType) {\n this.chartOptions.chartType = settings.chartType;\n }\n if (settings.dateStart !== undefined) {\n this.chartOptions.dateStart = settings.dateStart;\n }\n if (settings.dateEnd !== undefined) {\n this.chartOptions.dateEnd = settings.dateEnd;\n }\n }\n } catch (error) {\n console.error('Failed to load chart settings:', error);\n }\n }\n\n /**\n * Save settings to localStorage\n * @private\n */\n _saveSettings() {\n if (!this.settingsKey) return;\n\n try {\n const settings = {\n granularity: this.chartOptions.granularity,\n chartType: this.chartOptions.chartType,\n dateStart: this.chartOptions.dateStart,\n dateEnd: this.chartOptions.dateEnd\n };\n\n localStorage.setItem(`metrics-chart-${this.settingsKey}`, JSON.stringify(settings));\n } catch (error) {\n console.error('Failed to save chart settings:', error);\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MetricsMiniChartWidget-DaP5lSll.js","sources":["../../src/extensions/charts/BaseChart.js","../../src/extensions/charts/SeriesChart.js","../../src/extensions/charts/PieChart.js","../../src/extensions/charts/MetricsChart.js","../../src/extensions/charts/MiniChart.js","../../src/extensions/charts/MetricsMiniChart.js","../../src/extensions/charts/MetricsMiniChartWidget.js"],"sourcesContent":["/**\n * BaseChart - Foundation class for all chart components in MOJO framework\n * Uses Chart.js 4.x with API integration, refresh capabilities, and event system\n */\n\nimport View from '@core/View.js';\nimport WebSocketClient from '@core/services/WebSocketClient.js';\nimport dataFormatter from '@core/utils/DataFormatter.js';\n\nexport default class BaseChart extends View {\n constructor(options = {}) {\n super({\n ...options,\n className: `chart-component ${options.className || ''}`,\n tagName: 'div'\n });\n\n // Chart.js instance\n this.chart = null;\n this.chartType = options.chartType || 'line';\n\n // Data source options\n this.endpoint = options.endpoint || null;\n this.data = options.data || null;\n this.dataTransform = options.dataTransform || null; // Function to transform API data\n\n // Refresh options\n this.refreshInterval = options.refreshInterval || null; // ms\n this.autoRefresh = options.autoRefresh !== false;\n this.refreshTimer = null;\n\n // WebSocket for real-time updates\n this.websocketUrl = options.websocketUrl || null;\n this.websocket = null;\n this.websocketReconnect = options.websocketReconnect !== false;\n\n // Dimensions\n this.width = options.width || null;\n this.height = options.height || null;\n // Precompute inline content style for initial render (Mustache section)\n this.contentStyle = [\n this.width ? `width: ${this.width}px;` : '',\n this.height ? `height: ${this.height}px;` : ''\n ].filter(Boolean).join(' ');\n if (options.maintainAspectRatio === undefined) {\n options.maintainAspectRatio = true;\n }\n\n // Chart configuration\n this.title = options.title || '';\n this.chartTitle = options.chartTitle || '';\n this.chartOptions = {\n responsive: true,\n maintainAspectRatio: options.maintainAspectRatio,\n interaction: {\n intersect: false,\n mode: 'index'\n },\n plugins: {\n legend: {\n display: options.showLegend !== false,\n position: options.legendPosition || 'top'\n },\n title: {\n display: !!this.chartTitle,\n text: this.chartTitle\n },\n tooltip: {\n enabled: options.showTooltips !== false,\n backgroundColor: 'rgba(0,0,0,0.8)',\n titleColor: '#fff',\n bodyColor: '#fff',\n borderColor: 'rgba(255,255,255,0.1)',\n borderWidth: 1\n }\n },\n ...options.chartOptions\n };\n\n // Axis configuration with DataFormatter support\n this.xAxis = options.xAxis || null;\n this.yAxis = options.yAxis || null;\n this.tooltipFormatters = options.tooltip || {};\n\n // Theme and appearance\n this.theme = options.theme || 'light';\n this.colorScheme = options.colorScheme || 'default';\n this.animations = options.animations !== false;\n\n // Export options\n this.exportEnabled = options.exportEnabled === true;\n this.exportFormats = options.exportFormats || ['png', 'jpg', 'csv'];\n\n // State\n this.isLoading = false;\n this.hasError = false;\n this.lastFetch = null;\n this.dataPoints = 0;\n\n // Canvas element\n this.canvas = null;\n\n // Chart.js CDN URL - can be customized\n this.chartJsCdn = options.chartJsCdn || 'https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.js';\n\n // DataFormatter instance (use singleton)\n this.dataFormatter = dataFormatter;\n\n // Template data properties (available to Mustache)\n\n // Store essential listeners for cleanup\n this._essentialListeners = [];\n }\n\n get refreshEnabled() {\n return !!(this.endpoint || this.websocketUrl);\n }\n\n buildDefaultHeaderConfig() {\n return {\n titleHtml: this.title || '',\n chartTitle: this.chartTitle || '',\n showExport: this.exportEnabled === true,\n showRefresh: this.refreshEnabled,\n showTheme: true,\n controls: []\n };\n }\n\n async getTemplate() {\n return `\n <div class=\"chart-container\" data-theme=\"{{theme}}\">\n <div class=\"chart-header mb-3\">\n <div data-container=\"header\"></div>\n <div class=\"chart-header-aux mt-2\">\n <div data-container=\"header-aux\"></div>\n </div>\n </div>\n\n <div class=\"chart-content position-relative\" {{#contentStyle}}style=\"{{contentStyle}}\"{{/contentStyle}}>\n <canvas class=\"chart-canvas\" data-container=\"canvas\"></canvas>\n\n <!-- Loading overlay -->\n <div class=\"chart-overlay d-none\" data-loading>\n <div class=\"d-flex flex-column align-items-center\">\n <div class=\"spinner-border text-primary mb-2\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n <small class=\"text-muted\">Loading chart data...</small>\n </div>\n </div>\n\n <!-- Error overlay -->\n <div class=\"chart-overlay d-none\" data-error>\n <div class=\"alert alert-danger mb-0\" role=\"alert\">\n <div class=\"d-flex align-items-center\">\n <i class=\"bi bi-exclamation-triangle me-2\"></i>\n <div class=\"flex-grow-1\">\n <strong>Error:</strong> <span class=\"error-message\">Failed to load chart data</span>\n </div>\n <button class=\"btn btn-sm btn-outline-danger ms-2\" data-action=\"retry-load\">\n <i class=\"bi bi-arrow-clockwise\"></i> Retry\n </button>\n </div>\n </div>\n </div>\n\n <!-- No data overlay -->\n <div class=\"chart-overlay d-none\" data-no-data>\n <div class=\"text-center text-muted\">\n <i class=\"bi bi-bar-chart display-4 mb-3 opacity-50\"></i>\n <p class=\"mb-0\">No data available</p>\n {{#refreshEnabled}}\n <button class=\"btn btn-sm btn-outline-secondary mt-2\" data-action=\"refresh-chart\">\n <i class=\"bi bi-arrow-clockwise\"></i> Refresh\n </button>\n {{/refreshEnabled}}\n </div>\n </div>\n\n <!-- WebSocket status indicator -->\n <div class=\"position-absolute top-0 end-0 mt-2 me-2\">\n <span class=\"badge bg-success websocket-status\" style=\"display: none;\" data-websocket-status>\n <i class=\"bi bi-wifi\"></i> Live\n </span>\n </div>\n </div>\n\n <div class=\"chart-footer mt-2\" style=\"display: none;\">\n <div class=\"row\">\n <div class=\"col\">\n <small class=\"text-muted\">\n <i class=\"bi bi-graph-up me-1\"></i>\n <span class=\"data-points\">0 data points</span>\n </small>\n </div>\n <div class=\"col text-end\">\n <small class=\"text-muted refresh-info\">\n Auto-refresh: <span class=\"refresh-status\">Off</span>\n </small>\n </div>\n </div>\n </div>\n </div>\n `;\n }\n\n async onInit() {\n // Initialize Chart.js\n await this.initializeChartJS();\n\n // Build and create header view in onInit\n try {\n const headerConfig = this.headerConfig || (this.buildDefaultHeaderConfig ? this.buildDefaultHeaderConfig() : null);\n if (headerConfig) {\n this.headerView = new ChartHeaderView({ ...headerConfig, containerId: 'header' });\n this.addChild(this.headerView);\n }\n } catch (e) {\n // Header is optional; ignore if missing\n console.debug('ChartHeaderView not available:', e?.message);\n }\n }\n\n async onAfterRender() {\n // Cache DOM elements\n this.canvas = this.element.querySelector('.chart-canvas');\n this.titleElement = this.element.querySelector('.chart-title');\n this.contentElement = this.element.querySelector('.chart-content');\n this.footerElement = this.element.querySelector('.chart-footer');\n\n // Overlay elements\n this.loadingOverlay = this.element.querySelector('[data-loading]');\n this.errorOverlay = this.element.querySelector('[data-error]');\n this.noDataOverlay = this.element.querySelector('[data-no-data]');\n this.websocketStatus = this.element.querySelector('[data-websocket-status]');\n\n // Control elements\n this.refreshBtn = this.element.querySelector('.refresh-btn');\n this.themeToggle = this.element.querySelector('.theme-toggle');\n\n // Apply initial theme\n this.applyTheme();\n\n // Header is created in onInit\n\n // First-time data fetch occurs here, before creating the chart\n if (this.endpoint) {\n await this.fetchData(); // fetchData will call updateChart() which creates the chart\n await this.updateChart(this.data, true);\n if (this.height || this.width) {\n this._updateChartDimensions();\n }\n } else if (this.data) {\n await this.updateChart(this.data, true);\n if (this.height || this.width) {\n this._updateChartDimensions();\n }\n } else {\n this.showNoData();\n }\n\n // Set up auto-refresh\n if (this.autoRefresh && this.refreshInterval && this.endpoint) {\n this.startAutoRefresh();\n }\n\n // Set up WebSocket\n if (this.websocketUrl) {\n await this.connectWebSocket();\n }\n\n // Set up resize observer\n this.setupResizeObserver();\n\n // Show footer with stats\n this.showFooter();\n }\n\n async initializeChartJS() {\n try {\n // Load Chart.js if not already loaded\n if (typeof window.Chart === 'undefined') {\n await this.loadChartJS();\n }\n\n return true;\n } catch (error) {\n console.error('Failed to initialize Chart.js:', error);\n this.showError('Failed to initialize charting library');\n return false;\n }\n }\n\n async loadChartJS() {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src = this.chartJsCdn;\n script.onload = () => {\n console.log('Chart.js loaded successfully');\n resolve();\n };\n script.onerror = () => {\n reject(new Error('Failed to load Chart.js'));\n };\n document.head.appendChild(script);\n });\n }\n\n // Action Handlers (EventDelegate)\n async handleActionRefreshChart() {\n await this.fetchData();\n }\n\n async handleActionRetryLoad() {\n this.hideError();\n await this.fetchData();\n }\n\n async handleActionExportChart(event, element) {\n const format = element.getAttribute('data-format') || 'png';\n this.exportChart(format);\n }\n\n async handleActionToggleTheme() {\n this.toggleTheme();\n }\n\n async handleActionSetChartType(event, element) {\n const type = element.getAttribute('data-type');\n if (type && this.setChartType) {\n await this.setChartType(type);\n }\n }\n\n // Data Management\n async fetchData() {\n if (!this.endpoint) return;\n\n this.showLoading();\n this.setRefreshButtonState(true);\n\n try {\n const response = await fetch(this.endpoint, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json'\n }\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n let data = await response.json();\n\n // Transform data if transformer provided\n if (this.dataTransform && typeof this.dataTransform === 'function') {\n data = this.dataTransform(data);\n }\n\n this.lastFetch = new Date();\n this.data = data;\n this.updateLastUpdatedTime();\n\n // Emit success event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('chart:data-loaded', {\n chart: this,\n data,\n source: 'http',\n endpoint: this.endpoint\n });\n }\n\n } catch (error) {\n console.error('Failed to fetch chart data:', error);\n this.showError(`Failed to load data: ${error.message}`);\n\n // Emit error event\n this.emit('chart:error', {\n chart: this,\n error,\n source: 'http',\n endpoint: this.endpoint\n });\n } finally {\n this.hideLoading();\n this.setRefreshButtonState(false);\n }\n }\n\n async connectWebSocket() {\n if (!this.websocketUrl) return;\n\n try {\n this.websocket = new WebSocketClient({\n url: this.websocketUrl,\n autoReconnect: this.websocketReconnect,\n dataTransform: this.dataTransform,\n eventBus: this.getApp()?.events,\n debug: false\n });\n\n // Set up WebSocket event handlers\n this.websocket.on('connected', () => {\n this.showWebSocketStatus(true);\n console.log('WebSocket connected for chart data');\n });\n\n this.websocket.on('disconnected', () => {\n this.showWebSocketStatus(false);\n console.log('WebSocket disconnected');\n });\n\n this.websocket.on('data', async (data) => {\n await this.updateChart(data);\n this.updateLastUpdatedTime();\n\n // Emit real-time update event\n this.emit('chart:data-updated', {\n chart: this,\n data,\n source: 'websocket'\n });\n });\n\n this.websocket.on('error', (error) => {\n console.error('WebSocket error:', error);\n this.showWebSocketStatus(false, 'error');\n });\n\n // Connect\n await this.websocket.connect();\n\n } catch (error) {\n console.error('Failed to connect WebSocket:', error);\n this.showWebSocketStatus(false, 'error');\n }\n }\n\n async updateChart(data, recreate=false) {\n if (!data) {\n this.showNoData();\n return;\n }\n\n this.data = data;\n\n // If canvas is not ready yet (called before render), defer chart creation\n if (!this.canvas || typeof window.Chart === 'undefined') {\n return;\n }\n\n this.hideAllOverlays();\n\n // Process data with axis formatters\n const processedData = this.processChartData(data);\n\n if (recreate && this.chart) {\n this.chart.destroy();\n this.chart = null;\n }\n\n if (this.chart) {\n // Update existing chart\n this.chart.data = processedData;\n this.chart.update('none'); // No animation for real-time updates\n } else {\n // Create new chart\n await this.createChart(processedData);\n }\n\n // Update stats\n this.updateDataStats(processedData);\n\n if (this.height || this.width) {\n this._updateChartDimensions();\n }\n\n }\n\n processChartData(data) {\n // This method should be overridden by subclasses\n // Base implementation just applies formatters to labels if configured\n\n let processedData = { ...data };\n\n // Apply formatters to labels if xAxis formatter is configured (normalized)\n const xAxisCfg = this.normalizeAxis(this.xAxis);\n if (xAxisCfg && xAxisCfg.formatter && processedData.labels) {\n processedData.labels = processedData.labels.map(label =>\n this.dataFormatter.pipe(label, xAxisCfg.formatter)\n );\n }\n\n return processedData;\n }\n\n async createChart(data) {\n if (!this.canvas || typeof window.Chart === 'undefined') {\n throw new Error('Chart.js not loaded or canvas not found');\n }\n\n // Chart.js handles canvas dimensions internally\n // Container dimensions are set via CSS in template\n\n // Build chart configuration\n const config = {\n type: this.chartType,\n data: data,\n options: this.buildChartOptions()\n };\n\n try {\n this.chart = new window.Chart(this.canvas, config);\n\n // Set up chart event handlers\n this.setupChartEventHandlers();\n\n } catch (error) {\n console.error('Failed to create chart:', error);\n throw error;\n }\n }\n\n buildChartOptions() {\n const options = { ...this.chartOptions };\n\n // Handle custom dimensions\n if (this.width || this.height) {\n options.responsive = true;\n options.maintainAspectRatio = false;\n }\n\n // Build scales from normalized axis configs\n const xAxisCfg = this.normalizeAxis(this.xAxis);\n const yAxisCfg = this.normalizeAxis(this.yAxis);\n\n options.scales = options.scales || {};\n\n // X-axis\n options.scales.x = {\n type: this._detectAxisType(this.data, xAxisCfg, 'x'),\n display: true,\n title: {\n display: !!xAxisCfg.label,\n text: xAxisCfg.label || ''\n },\n grid: { display: true },\n ticks: {}\n };\n if (xAxisCfg.formatter) {\n options.scales.x.ticks.callback = this._createFormatterCallback(xAxisCfg.formatter);\n }\n\n // Y-axis\n options.scales.y = {\n type: this._detectAxisType(this.data, yAxisCfg, 'y'),\n display: true,\n beginAtZero: yAxisCfg.beginAtZero !== false,\n title: {\n display: !!yAxisCfg.label,\n text: yAxisCfg.label || ''\n },\n grid: { display: true },\n ticks: {}\n };\n if (yAxisCfg.formatter) {\n options.scales.y.ticks.callback = this._createFormatterCallback(yAxisCfg.formatter);\n }\n\n // Apply theme colors\n this.applyThemeToOptions(options);\n\n // Configure tooltips with formatters\n if (this.tooltipFormatters.x || this.tooltipFormatters.y) {\n options.plugins = options.plugins || {};\n options.plugins.tooltip = options.plugins.tooltip || {};\n options.plugins.tooltip.callbacks = options.plugins.tooltip.callbacks || {};\n\n if (this.tooltipFormatters.x) {\n options.plugins.tooltip.callbacks.title = (context) => {\n const value = context[0]?.label;\n return value ? this.dataFormatter.pipe(value, this.tooltipFormatters.x) : value;\n };\n }\n\n if (this.tooltipFormatters.y) {\n options.plugins.tooltip.callbacks.label = (context) => {\n const value = context.raw;\n const formattedValue = this.dataFormatter.pipe(value, this.tooltipFormatters.y);\n return `${context.dataset.label}: ${formattedValue}`;\n };\n }\n }\n\n // Allow subclasses to tweak chart options (e.g., indexAxis, stacking)\n if (typeof this.applySubclassChartOptions === 'function') {\n this.applySubclassChartOptions(options);\n }\n\n return options;\n }\n\n // Helper method to create Chart.js callback from MOJO formatter\n _createFormatterCallback(formatter) {\n if (!formatter) return null;\n\n return (value) => {\n try {\n return this.dataFormatter.pipe(value, formatter);\n } catch (error) {\n console.warn(`Chart formatter error:`, error);\n return value;\n }\n };\n }\n\n // Normalize axis configuration into a consistent object\n normalizeAxis(axisConfig) {\n if (!axisConfig) return {};\n if (typeof axisConfig === 'string') {\n // Simple formatter shorthand\n return { formatter: axisConfig };\n }\n if (typeof axisConfig === 'object') {\n const { formatter, label, type, beginAtZero, ...rest } = axisConfig;\n return { formatter, label, type, beginAtZero, ...rest };\n }\n return {};\n }\n\n // Smart axis type detection from data\n _detectAxisType(data, axisConfig, axisName = 'x') {\n // If user explicitly set the type, use it\n if (axisConfig && axisConfig.type) {\n return axisConfig.type;\n }\n\n // If formatter suggests a type\n if (axisConfig && axisConfig.formatter) {\n const formatter = axisConfig.formatter.toLowerCase();\n if (formatter.includes('date') || formatter.includes('time')) {\n return 'time';\n }\n }\n\n // Auto-detect from data based on axis\n if (data) {\n if (axisName === 'x' && data.labels && data.labels.length > 0) {\n // X-axis: check labels\n const firstLabel = data.labels[0];\n\n // Check if labels are strings (category axis)\n if (typeof firstLabel === 'string') {\n // If it's a string that's not purely numeric, treat as category\n // This handles cases like \"01:00\", \"Jan\", \"Q1 2023\", etc.\n if (!/^\\d+\\.?\\d*$/.test(firstLabel.trim())) {\n return 'category';\n }\n }\n\n // Check if labels are dates\n if (firstLabel instanceof Date ||\n (typeof firstLabel === 'string' && !isNaN(Date.parse(firstLabel)))) {\n return 'time';\n }\n\n // Numeric labels default to linear\n return 'linear';\n } else if (axisName === 'y' && data.datasets && data.datasets.length > 0) {\n // Y-axis: check data values\n const firstDataset = data.datasets[0];\n if (firstDataset.data && firstDataset.data.length > 0) {\n const firstValue = firstDataset.data[0];\n\n // If it's numeric data, use linear\n if (typeof firstValue === 'number' || !isNaN(parseFloat(firstValue))) {\n return 'linear';\n }\n\n // If it's string data, use category\n return 'category';\n }\n }\n }\n\n // Default based on axis\n return axisName === 'x' ? 'category' : 'linear';\n }\n\n setupChartEventHandlers() {\n if (!this.chart) return;\n\n // Click events\n this.chart.options.onClick = (event, elements) => {\n if (elements.length > 0) {\n const element = elements[0];\n const datasetIndex = element.datasetIndex;\n const index = element.index;\n const value = this.chart.data.datasets[datasetIndex].data[index];\n const label = this.chart.data.labels[index];\n\n // Emit click event\n this.emit('chart:point-clicked', {\n chart: this,\n datasetIndex,\n index,\n value,\n label,\n dataset: this.chart.data.datasets[datasetIndex]\n });\n }\n };\n\n // Hover events\n this.chart.options.onHover = (event, elements) => {\n this.canvas.style.cursor = elements.length > 0 ? 'pointer' : 'default';\n };\n }\n\n // Theme Management\n applyTheme() {\n this.element.setAttribute('data-theme', this.theme);\n\n if (this.chart) {\n this.chart.options = this.buildChartOptions();\n this.chart.update('none');\n }\n }\n\n applyThemeToOptions(options) {\n const isDark = this.theme === 'dark';\n\n // Grid and axis colors\n if (options.scales) {\n Object.keys(options.scales).forEach(scaleId => {\n const scale = options.scales[scaleId];\n scale.grid = scale.grid || {};\n scale.ticks = scale.ticks || {};\n\n scale.grid.color = isDark ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.1)';\n scale.ticks.color = isDark ? '#e9ecef' : '#495057';\n });\n }\n\n // Legend colors\n if (options.plugins?.legend) {\n options.plugins.legend.labels = options.plugins.legend.labels || {};\n options.plugins.legend.labels.color = isDark ? '#e9ecef' : '#495057';\n }\n\n // Title colors\n if (options.plugins?.title) {\n options.plugins.title.color = isDark ? '#ffffff' : '#212529';\n }\n }\n\n toggleTheme() {\n this.theme = this.theme === 'light' ? 'dark' : 'light';\n this.applyTheme();\n\n // Emit theme change event\n this.emit('chart:theme-changed', {\n chart: this,\n theme: this.theme\n });\n }\n\n // Auto-refresh Management\n startAutoRefresh() {\n if (!this.endpoint || !this.refreshInterval) return;\n\n this.stopAutoRefresh();\n\n this.refreshTimer = setInterval(() => {\n this.fetchData();\n }, this.refreshInterval);\n\n this.updateRefreshStatus(true);\n }\n\n stopAutoRefresh() {\n if (this.refreshTimer) {\n clearInterval(this.refreshTimer);\n this.refreshTimer = null;\n }\n this.updateRefreshStatus(false);\n }\n\n // Export Functionality\n exportChart(format = 'png') {\n if (!this.chart) return;\n\n try {\n if (format === 'csv') {\n this.exportCSV();\n } else {\n const url = this.chart.toBase64Image('image/' + format, 1);\n const link = document.createElement('a');\n link.download = `chart-${Date.now()}.${format}`;\n link.href = url;\n link.click();\n\n // Emit export event\n this.emit('chart:exported', {\n chart: this,\n format,\n filename: link.download\n });\n }\n\n } catch (error) {\n console.error('Failed to export chart:', error);\n this.showError('Failed to export chart');\n }\n }\n\n // CSV Export Functionality\n exportCSV() {\n if (!this.chart || !this.chart.data) return;\n\n try {\n const csvData = this.generateCSV();\n const blob = new Blob([csvData], { type: 'text/csv;charset=utf-8;' });\n const url = URL.createObjectURL(blob);\n\n const link = document.createElement('a');\n link.download = `chart-data-${Date.now()}.csv`;\n link.href = url;\n link.click();\n\n // Clean up\n URL.revokeObjectURL(url);\n\n // Emit export event\n this.emit('chart:exported', {\n chart: this,\n format: 'csv',\n filename: link.download\n });\n\n } catch (error) {\n console.error('Failed to export CSV:', error);\n this.showError('Failed to export CSV');\n }\n }\n\n // Generate CSV data from chart\n generateCSV() {\n const data = this.chart.data;\n const labels = data.labels || [];\n const datasets = data.datasets || [];\n\n // Create CSV header\n let csv = 'Label';\n datasets.forEach(dataset => {\n csv += ',' + (dataset.label || 'Data');\n });\n csv += '\\n';\n\n // Add data rows\n labels.forEach((label, index) => {\n csv += `\"${label}\"`;\n datasets.forEach(dataset => {\n const value = dataset.data[index] || '';\n csv += ',' + value;\n });\n csv += '\\n';\n });\n\n return csv;\n }\n\n // UI State Management\n showLoading() {\n this.isLoading = true;\n this.hideAllOverlays();\n this.loadingOverlay?.classList.remove('d-none');\n }\n\n hideLoading() {\n this.isLoading = false;\n this.loadingOverlay?.classList.add('d-none');\n }\n\n showError(message) {\n this.hasError = true;\n this.hideAllOverlays();\n const errorMessageEl = this.errorOverlay?.querySelector('.error-message');\n if (errorMessageEl) {\n errorMessageEl.textContent = message;\n }\n this.errorOverlay?.classList.remove('d-none');\n }\n\n hideError() {\n this.hasError = false;\n this.errorOverlay?.classList.add('d-none');\n }\n\n showNoData() {\n this.hideAllOverlays();\n this.noDataOverlay?.classList.remove('d-none');\n }\n\n hideAllOverlays() {\n this.loadingOverlay?.classList.add('d-none');\n this.errorOverlay?.classList.add('d-none');\n this.noDataOverlay?.classList.add('d-none');\n }\n\n showWebSocketStatus(connected, status = 'connected') {\n if (!this.websocketStatus) return;\n\n if (connected) {\n this.websocketStatus.className = 'badge bg-success';\n this.websocketStatus.innerHTML = '<i class=\"bi bi-wifi\"></i> Live';\n } else {\n this.websocketStatus.className = status === 'error' ? 'badge bg-danger' : 'badge bg-secondary';\n this.websocketStatus.innerHTML = status === 'error' ?\n '<i class=\"bi bi-wifi-off\"></i> Error' :\n '<i class=\"bi bi-wifi-off\"></i> Offline';\n }\n\n this.websocketStatus.style.display = 'inline-block';\n }\n\n setRefreshButtonState(loading) {\n if (!this.refreshBtn) return;\n\n const icon = this.refreshBtn.querySelector('i');\n if (loading) {\n this.refreshBtn.disabled = true;\n icon?.classList.add('spin');\n } else {\n this.refreshBtn.disabled = false;\n icon?.classList.remove('spin');\n }\n }\n\n updateLastUpdatedTime() {\n const lastUpdatedEl = this.element.querySelector('.last-updated');\n const timestampEl = this.element.querySelector('.timestamp');\n\n if (lastUpdatedEl && timestampEl) {\n timestampEl.textContent = new Date().toLocaleTimeString();\n lastUpdatedEl.style.display = 'block';\n }\n }\n\n updateRefreshStatus(active) {\n const statusEl = this.element.querySelector('.refresh-status');\n if (statusEl) {\n statusEl.textContent = active ?\n `Every ${this.refreshInterval / 1000}s` : 'Off';\n }\n }\n\n updateDataStats(data) {\n // Count data points\n let points = 0;\n if (data.datasets) {\n points = data.datasets.reduce((sum, dataset) => {\n return sum + (dataset.data ? dataset.data.length : 0);\n }, 0);\n }\n\n this.dataPoints = points;\n\n const dataPointsEl = this.element.querySelector('.data-points');\n if (dataPointsEl) {\n dataPointsEl.textContent = `${points} data point${points !== 1 ? 's' : ''}`;\n }\n }\n\n showFooter() {\n if (this.footerElement) {\n this.footerElement.style.display = 'block';\n }\n }\n\n setupResizeObserver() {\n if (!window.ResizeObserver || !this.contentElement) return;\n\n const resizeObserver = new ResizeObserver(() => {\n if (this.chart) {\n this.chart.resize();\n }\n });\n\n resizeObserver.observe(this.contentElement);\n this._resizeObserver = resizeObserver;\n }\n\n // Cleanup\n async onBeforeDestroy() {\n // Stop auto-refresh\n this.stopAutoRefresh();\n\n // Disconnect WebSocket\n if (this.websocket) {\n this.websocket.disconnect();\n this.websocket = null;\n }\n\n // Destroy Chart.js instance\n if (this.chart) {\n this.chart.destroy();\n this.chart = null;\n }\n\n // Clean up resize observer\n if (this._resizeObserver) {\n this._resizeObserver.disconnect();\n this._resizeObserver = null;\n }\n\n // Clean up essential listeners\n if (this._essentialListeners) {\n this._essentialListeners.forEach(({ el, type, fn }) => {\n if (el) el.removeEventListener(type, fn);\n });\n this._essentialListeners = [];\n }\n\n // Emit destroy event\n this.emit('chart:destroyed', { chart: this });\n }\n\n // Public API\n setData(data) {\n this.data = data;\n return this.updateChart(data);\n }\n\n setEndpoint(endpoint) {\n this.endpoint = endpoint;\n if (endpoint) {\n return this.fetchData();\n }\n }\n\n setWebSocketUrl(url) {\n if (this.websocket) {\n this.websocket.disconnect();\n }\n this.websocketUrl = url;\n if (url) {\n return this.connectWebSocket();\n }\n }\n\n // Dimension Control Methods\n setWidth(width) {\n this.width = width;\n this.contentStyle = [\n this.width ? `width: ${this.width}px;` : '',\n this.height ? `height: ${this.height}px;` : ''\n ].filter(Boolean).join(' ');\n if (this.contentElement) {\n this._updateChartDimensions();\n }\n }\n\n setHeight(height) {\n this.height = height;\n this.contentStyle = [\n this.width ? `width: ${this.width}px;` : '',\n this.height ? `height: ${this.height}px;` : ''\n ].filter(Boolean).join(' ');\n if (this.contentElement) {\n this._updateChartDimensions();\n }\n }\n\n setDimensions(width, height) {\n this.width = width;\n this.height = height;\n this.contentStyle = [\n this.width ? `width: ${this.width}px;` : '',\n this.height ? `height: ${this.height}px;` : ''\n ].filter(Boolean).join(' ');\n if (this.contentElement) {\n this._updateChartDimensions();\n }\n }\n\n _updateChartDimensions() {\n if (this.chart) {\n // Update chart options for custom dimensions\n if (this.width || this.height) {\n this.chart.options.responsive = true;\n this.chart.options.maintainAspectRatio = false;\n if (this.width && this.contentElement) {\n this.contentElement.style.width = this.width ? this.width + 'px' : '';\n }\n if (this.height && this.contentElement) {\n this.contentElement.style.height = this.height ? this.height + 'px' : '';\n }\n } else {\n this.chart.options.responsive = true;\n this.chart.options.maintainAspectRatio = this.chartOptions.maintainAspectRatio;\n }\n this.chart.resize();\n }\n }\n\n resize() {\n if (this.chart) {\n this.chart.resize();\n }\n }\n\n refresh() {\n return this.fetchData();\n }\n\n export(format = 'png') {\n return this.exportChart(format);\n }\n\n setTheme(theme) {\n this.theme = theme;\n this.applyTheme();\n }\n\n getStats() {\n return {\n isLoading: this.isLoading,\n hasError: this.hasError,\n dataPoints: this.dataPoints,\n lastFetch: this.lastFetch,\n theme: this.theme,\n chartType: this.chartType,\n autoRefresh: !!this.refreshTimer,\n websocketConnected: this.websocket?.isConnected || false\n };\n }\n}\n\nclass ChartHeaderView extends View {\n constructor(options = {}) {\n super({\n ...options,\n className: `mojo-chart-header ${options.className || ''}`,\n tagName: 'div'\n });\n\n // Header configuration\n this.titleHtml = options.titleHtml || '';\n this.chartTitle = options.chartTitle || '';\n this.showExport = options.showExport === true;\n this.showRefresh = !!options.showRefresh;\n this.showTheme = false;\n this.showTheme = options.showTheme === true;\n this.controls = Array.isArray(options.controls) ? options.controls : [];\n\n // Pre-rendered controls HTML\n this.controlsHtml = this._buildControlsHtml(this.controls);\n }\n\n async getTemplate() {\n return `\n <div class=\"d-flex justify-content-between align-items-center\">\n <div class=\"chart-title-section\">\n <h5 class=\"mb-2 chart-title\">{{{titleHtml}}}</h5>\n <small class=\"text-muted last-updated\" style=\"display: none;\">\n Last updated: <span class=\"timestamp\"></span>\n </small>\n </div>\n\n <div class=\"chart-controls\">\n <div class=\"btn-toolbar\" role=\"toolbar\">\n {{{controlsHtml}}}\n\n <div class=\"btn-group btn-group-sm\" role=\"group\">\n\n {{#showTheme}}\n <button type=\"button\" class=\"btn btn-outline-secondary theme-toggle\" data-action=\"toggle-theme\" title=\"Toggle Theme\">\n <i class=\"bi bi-palette\"></i>\n </button>\n {{/showTheme}}\n\n {{#showExport}}\n <div class=\"btn-group btn-group-sm\" role=\"group\">\n <button type=\"button\" class=\"btn btn-outline-secondary dropdown-toggle\" data-bs-toggle=\"dropdown\" title=\"Export Chart\">\n <i class=\"bi bi-download\"></i>\n </button>\n <ul class=\"dropdown-menu\">\n <li><a class=\"dropdown-item\" href=\"#\" data-action=\"export-chart\" data-format=\"png\">\n <i class=\"bi bi-image\"></i> PNG\n </a></li>\n <li><a class=\"dropdown-item\" href=\"#\" data-action=\"export-chart\" data-format=\"jpg\">\n <i class=\"bi bi-image\"></i> JPEG\n </a></li>\n <li><a class=\"dropdown-item\" href=\"#\" data-action=\"export-chart\" data-format=\"csv\">\n <i class=\"bi bi-file-earmark-spreadsheet\"></i> CSV\n </a></li>\n </ul>\n </div>\n {{/showExport}}\n\n {{#showRefresh}}\n <button type=\"button\" class=\"btn btn-outline-secondary refresh-btn\" data-action=\"refresh-chart\" title=\"Refresh Data\">\n <i class=\"bi bi-arrow-clockwise\"></i>\n </button>\n {{/showRefresh}}\n </div>\n </div>\n </div>\n </div>\n `;\n }\n\n // Build custom controls HTML for the toolbar from config\n _buildControlsHtml(controls) {\n if (!Array.isArray(controls) || controls.length === 0) return '';\n\n const parts = [];\n\n controls.forEach((item) => {\n if (!item || !item.type) return;\n\n switch (item.type) {\n case 'select': {\n const sizeCls = item.size === 'md' ? '' : ' form-select-sm';\n const cls = `form-select${sizeCls} ${item.className || ''}`.trim();\n const optionsHtml = (item.options || [])\n .map(opt => `<option value=\"${this._escapeAttr(opt.value)}\"${opt.selected ? ' selected' : ''}>${this._escapeHtml(opt.label)}</option>`)\n .join('');\n parts.push(`\n <div class=\"btn-group btn-group-sm me-2\" role=\"group\">\n <select class=\"${cls}\" data-change-action=\"${this._escapeAttr(item.action || item.name || 'select-changed')}\" style=\"width: auto;\">\n ${optionsHtml}\n </select>\n </div>\n `);\n break;\n }\n\n case 'button': {\n const { variant = 'outline-secondary', size = 'sm' } = item;\n const sizeCls = size === 'md' ? '' : ' btn-sm';\n const btnCls = `btn btn-${variant}${sizeCls} ${item.className || ''}`.trim();\n const titleAttr = item.title ? ` title=\"${this._escapeAttr(item.title)}\"` : '';\n const dataAttrs = this._buildDataAttrs(item.data);\n parts.push(`\n <div class=\"btn-group btn-group-sm me-2\" role=\"group\">\n <button type=\"button\" class=\"${btnCls}\" data-action=\"${this._escapeAttr(item.action || 'button-action')}\"${titleAttr}${dataAttrs}>\n ${item.labelHtml || ''}\n </button>\n </div>\n `);\n break;\n }\n\n case 'buttongroup': {\n const size = item.size || 'sm';\n const groupCls = `btn-group btn-group-${size} me-2 ${item.className || ''}`.trim();\n const buttons = (item.buttons || []).map(btn => {\n const variant = btn.variant || 'outline-secondary';\n const sizeCls = size === 'md' ? '' : ' btn-sm';\n const btnCls = `btn btn-${variant}${sizeCls} ${btn.className || ''}`.trim();\n const titleAttr = btn.title ? ` title=\"${this._escapeAttr(btn.title)}\"` : '';\n const dataAttrs = this._buildDataAttrs(btn.data);\n return `<button type=\"button\" class=\"${btnCls}\" data-action=\"${this._escapeAttr(btn.action || 'button-action')}\"${titleAttr}${dataAttrs}>${btn.labelHtml || ''}</button>`;\n }).join('');\n parts.push(`\n <div class=\"${groupCls}\" role=\"group\">\n ${buttons}\n </div>\n `);\n break;\n }\n\n case 'divider': {\n parts.push(`<div class=\"vr mx-2\"></div>`);\n break;\n }\n\n case 'html': {\n const html = item.html || '';\n parts.push(`<div class=\"me-2 d-inline-block\">${html}</div>`);\n break;\n }\n\n default:\n // Unknown type; ignore silently\n break;\n }\n });\n\n return parts.join('\\n');\n }\n\n _buildDataAttrs(data) {\n if (!data || typeof data !== 'object') return '';\n return Object.entries(data)\n .map(([key, val]) => ` data-${this._kebabCase(String(key))}=\"${this._escapeAttr(String(val))}\"`)\n .join('');\n }\n\n _kebabCase(str) {\n return str\n .replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, '$1-$2')\n .toLowerCase()\n .replace(/[^a-z0-9\\-]/g, '-')\n .replace(/--+/g, '-')\n .replace(/^-|-$/g, '');\n }\n\n _escapeAttr(value) {\n return String(value)\n .replace(/\"/g, '"')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n }\n\n _escapeHtml(value) {\n return String(value)\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n }\n}\n","/**\n * SeriesChart - Combined Line and Bar chart component for MOJO framework\n * Supports switching between line and bar chart types with the same data\n */\n\nimport BaseChart from './BaseChart.js';\nimport Dialog from '@core/views/feedback/Dialog.js';\n\n\nexport default class SeriesChart extends BaseChart {\n constructor(options = {}) {\n super({\n ...options,\n chartType: options.chartType || 'line'\n });\n\n // Series-specific options\n this.showTypeSwitch = true;\n if (options.showTypeSwitch !== undefined) this.showTypeSwitch = options.showTypeSwitch;\n this.orientation = options.orientation || 'vertical'; // 'vertical' or 'horizontal'\n this.stacked = options.stacked || false;\n this.stepped = options.stepped || false; // For line charts\n this.tension = options.tension || 0.4; // Line curve tension\n this.fill = options.fill || false; // Fill area under line\n this.showRefreshButton = options.showRefreshButton !== false;\n\n if (!this.headerConfig) {\n this.headerConfig = {\n titleHtml: this.title || '',\n chartTitle: this.chartTitle || '',\n showExport: this.exportEnabled,\n showRefresh: this.refreshEnabled,\n showTheme: true,\n controls: []\n }\n }\n\n\n // Data series configuration\n this.series = options.series || [];\n this.xField = options.xField || 'x';\n this.yField = options.yField || 'y';\n\n\n\n // Color scheme for multiple datasets\n this.colors = options.colors || [\n 'rgba(54, 162, 235, 0.8)', // Blue\n 'rgba(255, 99, 132, 0.8)', // Red\n 'rgba(75, 192, 192, 0.8)', // Green\n 'rgba(255, 206, 86, 0.8)', // Yellow\n 'rgba(153, 102, 255, 0.8)', // Purple\n 'rgba(255, 159, 64, 0.8)', // Orange\n 'rgba(199, 199, 199, 0.8)', // Grey\n 'rgba(83, 102, 255, 0.8)' // Indigo\n ];\n\n\n\n // Process tooltip formatters\n this.tooltipFormatters = options.tooltip || {};\n }\n\n async getTemplate() {\n return await super.getTemplate();\n }\n\n async onInit() {\n // Provide header controls (type switcher) via BaseChart headerConfig\n if (this.showTypeSwitch) {\n this.headerConfig.controls.push({\n type: 'buttongroup',\n size: 'sm',\n buttons: [\n { action: 'set-chart-type', labelHtml: '<i class=\"bi bi-graph-up\"></i>', title: 'Line', variant: (this.chartType === 'line' ? 'primary' : 'outline-primary'), data: { type: 'line' } },\n { action: 'set-chart-type', labelHtml: '<i class=\"bi bi-bar-chart\"></i>', title: 'Bar', variant: (this.chartType === 'bar' ? 'primary' : 'outline-primary'), data: { type: 'bar' } }\n ]\n });\n }\n\n await super.onInit();\n\n }\n\n // Action Handlers\n async onActionSetChartType(event, element) {\n event.stopPropagation();\n const newType = element.getAttribute('data-type');\n if (newType && newType !== this.chartType) {\n await this.setChartType(newType);\n }\n }\n\n async rebuildChart() {\n if (this.chart && this.data) {\n this.chart.destroy();\n this.chart = null;\n\n const processedData = this.processChartData(this.data);\n await this.createChart(processedData);\n }\n }\n\n async setChartType(newType) {\n if (!['line', 'bar'].includes(newType)) {\n throw new Error(`Unsupported chart type: ${newType}`);\n }\n\n const oldType = this.chartType;\n this.chartType = newType;\n\n // Recreate chart with new type\n if (this.chart && this.data) {\n this.chart.destroy();\n this.chart = null;\n\n const processedData = this.processChartData(this.data);\n await this.createChart(processedData);\n }\n\n // Update type switcher button styles dynamically\n this._updateTypeSwitcherButtons();\n\n // Emit type change event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('chart:type-changed', {\n chart: this,\n oldType,\n newType: this.chartType\n });\n }\n }\n\n processChartData(data) {\n if (!data) return data;\n\n let processedData;\n\n // Handle different data input formats\n if (Array.isArray(data)) {\n // Array of objects: [{x: '2024-01', y: 100}, {x: '2024-02', y: 150}]\n processedData = this.processArrayData(data);\n } else if (data.labels && data.datasets) {\n // Chart.js format: {labels: [...], datasets: [...]}\n processedData = this.processChartJSData(data);\n } else if (data.series) {\n // Custom series format: {series: [{name: 'Sales', data: [...]}]}\n processedData = this.processSeriesData(data);\n } else {\n processedData = data;\n }\n\n // Apply formatters to the processed data\n return this.applyFormattersToData(processedData);\n }\n\n processArrayData(data) {\n const labels = [];\n const values = [];\n\n data.forEach(item => {\n const xValue = item[this.xField];\n const yValue = item[this.yField];\n\n labels.push(xValue);\n values.push(yValue);\n });\n\n return {\n labels,\n datasets: [{\n label: this.title || 'Data',\n data: values,\n backgroundColor: this.colors[0].replace('0.8', '0.6'),\n borderColor: this.colors[0],\n borderWidth: 2,\n tension: this.chartType === 'line' ? this.tension : 0,\n fill: this.chartType === 'line' ? this.fill : false,\n stepped: this.chartType === 'line' ? this.stepped : false\n }]\n };\n }\n\n processChartJSData(data) {\n // Already in Chart.js format, just apply our styling\n const processedData = { ...data };\n\n processedData.datasets = processedData.datasets.map((dataset, index) => ({\n ...dataset,\n backgroundColor: dataset.backgroundColor || this.colors[index % this.colors.length].replace('0.8', '0.6'),\n borderColor: dataset.borderColor || this.colors[index % this.colors.length],\n borderWidth: dataset.borderWidth || 2,\n tension: this.chartType === 'line' ? (dataset.tension ?? this.tension) : 0,\n fill: this.chartType === 'line' ? (dataset.fill ?? this.fill) : false,\n stepped: this.chartType === 'line' ? (dataset.stepped ?? this.stepped) : false\n }));\n\n return processedData;\n }\n\n processSeriesData(data) {\n const labels = data.labels || [];\n const datasets = [];\n\n data.series.forEach((series, index) => {\n datasets.push({\n label: series.name || series.label || `Series ${index + 1}`,\n data: series.data || [],\n backgroundColor: series.backgroundColor || this.colors[index % this.colors.length].replace('0.8', '0.6'),\n borderColor: series.borderColor || this.colors[index % this.colors.length],\n borderWidth: series.borderWidth || 2,\n tension: this.chartType === 'line' ? (series.tension ?? this.tension) : 0,\n fill: this.chartType === 'line' ? (series.fill ?? this.fill) : false,\n stepped: this.chartType === 'line' ? (series.stepped ?? this.stepped) : false\n });\n });\n\n return { labels, datasets };\n }\n\n applyFormattersToData(data) {\n if (!data) return data;\n\n const processedData = { ...data };\n\n // Apply x-axis formatter to labels if configured\n const xAxisCfg = this.normalizeAxis ? this.normalizeAxis(this.xAxis) : {};\n if (xAxisCfg.formatter && processedData.labels) {\n processedData.labels = processedData.labels.map(label =>\n this.dataFormatter.pipe(label, xAxisCfg.formatter)\n );\n }\n\n return processedData;\n }\n\n applySubclassChartOptions(options) {\n // Stacking for bar charts\n if (this.stacked && this.chartType === 'bar' && options.scales) {\n if (options.scales.x) options.scales.x.stacked = true;\n if (options.scales.y) options.scales.y.stacked = true;\n }\n\n // Horizontal bars\n if (this.chartType === 'bar' && this.orientation === 'horizontal') {\n options.indexAxis = 'y';\n }\n\n // Interaction mode tuned to chart type\n options.interaction = options.interaction || {};\n options.interaction.intersect = false;\n options.interaction.mode = this.chartType === 'line' ? 'index' : 'nearest';\n\n // Elements styling\n options.elements = options.elements || {};\n options.elements.line = {\n ...(options.elements.line || {}),\n tension: this.tension,\n borderWidth: 2\n };\n options.elements.point = {\n ...(options.elements.point || {}),\n radius: this.chartType === 'line' ? 4 : 0,\n hoverRadius: 6,\n hitRadius: 8\n };\n options.elements.bar = {\n ...(options.elements.bar || {}),\n borderWidth: 1,\n borderSkipped: false\n };\n }\n\n\n\n // Process simple axis configuration into detailed config\n processAxisConfig(axisConfig) {\n if (!axisConfig) return {};\n\n if (typeof axisConfig === 'string') {\n // Simple string format: just a formatter name\n return { formatter: axisConfig };\n }\n\n if (typeof axisConfig === 'object') {\n // Object format: full configuration\n return {\n formatter: axisConfig.formatter,\n label: axisConfig.label,\n type: axisConfig.type,\n beginAtZero: axisConfig.beginAtZero,\n ...axisConfig\n };\n }\n\n return {};\n }\n\n\n\n\n\n _updateTypeSwitcherButtons() {\n const buttons = this.element?.querySelectorAll('[data-action=\"set-chart-type\"]');\n if (!buttons || buttons.length === 0) return;\n\n buttons.forEach(button => {\n const buttonType = button.getAttribute('data-type');\n const isActive = buttonType === this.chartType;\n\n // Normalize classes for Bootstrap primary/outline-primary variants\n button.classList.toggle('btn-primary', isActive);\n button.classList.toggle('btn-outline-primary', !isActive);\n\n // Optional 'active' state for accessibility/visual feedback\n button.classList.toggle('active', isActive);\n });\n }\n\n // Public API extensions\n setOrientation(orientation) {\n if (!['vertical', 'horizontal'].includes(orientation)) {\n throw new Error(`Invalid orientation: ${orientation}`);\n }\n\n this.orientation = orientation;\n\n if (this.chart) {\n this.chart.destroy();\n this.chart = null;\n\n if (this.data) {\n const processedData = this.processChartData(this.data);\n this.createChart(processedData);\n }\n }\n }\n\n setStacked(stacked) {\n this.stacked = stacked;\n\n if (this.chart) {\n this.chart.options.scales.x.stacked = stacked;\n this.chart.options.scales.y.stacked = stacked;\n this.chart.update();\n }\n }\n\n addSeries(series) {\n if (!this.data || !this.data.datasets) return;\n\n const newDataset = {\n label: series.label || series.name || `Series ${this.data.datasets.length + 1}`,\n data: series.data || [],\n backgroundColor: series.backgroundColor || this.colors[this.data.datasets.length % this.colors.length].replace('0.8', '0.6'),\n borderColor: series.borderColor || this.colors[this.data.datasets.length % this.colors.length],\n borderWidth: series.borderWidth || 2,\n tension: this.chartType === 'line' ? (series.tension ?? this.tension) : 0,\n fill: this.chartType === 'line' ? (series.fill ?? this.fill) : false\n };\n\n this.data.datasets.push(newDataset);\n\n if (this.chart) {\n this.chart.data.datasets.push(newDataset);\n this.chart.update();\n }\n\n // Emit series added event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('chart:series-added', {\n chart: this,\n series: newDataset\n });\n }\n }\n\n removeSeries(index) {\n if (!this.data || !this.data.datasets || index < 0 || index >= this.data.datasets.length) {\n return;\n }\n\n const removedSeries = this.data.datasets.splice(index, 1)[0];\n\n if (this.chart) {\n this.chart.data.datasets.splice(index, 1);\n this.chart.update();\n }\n\n // Emit series removed event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('chart:series-removed', {\n chart: this,\n series: removedSeries,\n index\n });\n }\n }\n\n // Static dialog method\n static async showDialog(options = {}) {\n const {\n title = 'Chart Viewer',\n size = 'xl',\n ...chartOptions\n } = options;\n\n const chart = new SeriesChart({\n ...chartOptions,\n title\n });\n\n\n\n const dialog = new Dialog({\n title,\n body: chart,\n size,\n centered: true,\n backdrop: 'static',\n keyboard: true,\n buttons: [\n {\n text: 'Export PNG',\n action: 'export',\n class: 'btn btn-outline-primary'\n },\n {\n text: 'Close',\n action: 'close',\n class: 'btn btn-secondary',\n dismiss: true\n }\n ]\n });\n\n // Render and mount\n await dialog.render();\n document.body.appendChild(dialog.element);\n await dialog.mount();\n\n // Show the dialog\n dialog.show();\n\n return new Promise((resolve) => {\n dialog.on('hidden', () => {\n dialog.destroy();\n resolve(chart);\n });\n\n dialog.on('action:export', () => {\n chart.exportChart('png');\n });\n\n dialog.on('action:close', () => {\n dialog.hide();\n });\n });\n }\n}\n","/**\n * PieChart - Pie chart component with segment interactions for MOJO framework\n * Supports click interactions, custom colors, and DataFormatter integration\n */\n\nimport BaseChart from './BaseChart.js';\nimport Dialog from '@core/views/feedback/Dialog.js';\n\nexport default class PieChart extends BaseChart {\n constructor(options = {}) {\n super({\n ...options,\n chartType: 'pie'\n });\n\n // Pie-specific options\n this.cutout = options.cutout || 0; // 0 for pie, >0 for doughnut\n this.rotation = options.rotation || 0; // Starting angle\n this.circumference = options.circumference || 360; // Full circle\n \n // Segment configuration\n this.borderWidth = options.borderWidth || 2;\n this.borderColor = options.borderColor || '#ffffff';\n this.hoverBorderWidth = options.hoverBorderWidth || 3;\n \n // Label configuration\n this.showLabels = options.showLabels !== false;\n this.labelPosition = options.labelPosition || 'outside'; // 'inside', 'outside'\n this.labelFormatter = options.labelFormatter || null;\n this.valueFormatter = options.valueFormatter || null;\n \n // Data field configuration\n this.labelField = options.labelField || 'label';\n this.valueField = options.valueField || 'value';\n \n // Color scheme for segments\n this.colors = options.colors || [\n '#FF6384', // Red\n '#36A2EB', // Blue \n '#FFCE56', // Yellow\n '#4BC0C0', // Teal\n '#9966FF', // Purple\n '#FF9F40', // Orange\n '#C9CBCF', // Grey\n '#4BC0C0', // Green\n '#FF6384', // Pink\n '#36A2EB' // Light Blue\n ];\n\n // Animation options\n this.animateRotate = options.animateRotate !== false;\n this.animateScale = options.animateScale || false;\n \n // Interaction options\n this.clickable = options.clickable !== false;\n this.hoverable = options.hoverable !== false;\n \n // Selected segment tracking\n this.selectedSegment = null;\n this.highlightedSegments = new Set();\n\n // Value formatting\n this.valueFormatter = options.valueFormatter || null;\n\n\n }\n\n\n\n processChartData(data) {\n if (!data) return data;\n\n let processedData;\n\n // Handle different data input formats\n if (Array.isArray(data)) {\n // Array of objects: [{label: 'A', value: 100}, {label: 'B', value: 200}]\n processedData = this.processArrayData(data);\n } else if (data.labels && data.datasets) {\n // Chart.js format: {labels: [...], datasets: [...]}\n processedData = this.processChartJSData(data);\n } else if (typeof data === 'object' && !data.labels) {\n // Simple object: {A: 100, B: 200}\n processedData = this.processObjectData(data);\n } else {\n processedData = data;\n }\n\n // Apply formatters to the processed data\n return this.applyFormattersToData(processedData);\n }\n\n processArrayData(data) {\n const labels = [];\n const values = [];\n\n data.forEach(item => {\n const label = item[this.labelField];\n const value = item[this.valueField];\n \n if (label !== undefined && value !== undefined) {\n labels.push(label);\n values.push(value);\n }\n });\n\n return {\n labels,\n datasets: [{\n data: values,\n backgroundColor: this.generateColors(labels.length),\n borderColor: this.borderColor,\n borderWidth: this.borderWidth,\n hoverBorderWidth: this.hoverBorderWidth\n }]\n };\n }\n\n processChartJSData(data) {\n const processedData = { ...data };\n \n // Apply our styling to existing datasets\n processedData.datasets = processedData.datasets.map(dataset => ({\n ...dataset,\n backgroundColor: dataset.backgroundColor || this.generateColors(processedData.labels.length),\n borderColor: dataset.borderColor || this.borderColor,\n borderWidth: dataset.borderWidth || this.borderWidth,\n hoverBorderWidth: dataset.hoverBorderWidth || this.hoverBorderWidth\n }));\n\n return processedData;\n }\n\n processObjectData(data) {\n const labels = Object.keys(data);\n const values = Object.values(data);\n\n return {\n labels,\n datasets: [{\n data: values,\n backgroundColor: this.generateColors(labels.length),\n borderColor: this.borderColor,\n borderWidth: this.borderWidth,\n hoverBorderWidth: this.hoverBorderWidth\n }]\n };\n }\n\n applyFormattersToData(data) {\n if (!data) return data;\n\n const processedData = { ...data };\n\n // Apply label formatter to labels\n if (this.labelFormatter && processedData.labels) {\n processedData.labels = processedData.labels.map(label =>\n this.dataFormatter.pipe(label, this.labelFormatter)\n );\n }\n\n return processedData;\n }\n\n generateColors(count) {\n const colors = [];\n for (let i = 0; i < count; i++) {\n colors.push(this.colors[i % this.colors.length]);\n }\n return colors;\n }\n\n buildChartOptions() {\n const options = super.buildChartOptions();\n\n // Pie chart specific configuration\n options.cutout = this.cutout;\n options.rotation = this.rotation;\n options.circumference = this.circumference;\n\n // Animation configuration\n options.animation = {\n animateRotate: this.animateRotate,\n animateScale: this.animateScale,\n duration: this.animations ? 1000 : 0\n };\n\n // Plugin configuration\n options.plugins = {\n ...options.plugins,\n legend: {\n ...options.plugins.legend,\n position: options.plugins.legend.position || 'right',\n labels: {\n ...options.plugins.legend.labels,\n usePointStyle: true,\n padding: 20,\n generateLabels: (chart) => {\n const data = chart.data;\n if (data.labels.length && data.datasets.length) {\n return data.labels.map((label, i) => {\n const dataset = data.datasets[0];\n const value = dataset.data[i];\n const backgroundColor = dataset.backgroundColor[i];\n \n // Calculate percentage\n const total = dataset.data.reduce((sum, val) => sum + val, 0);\n const percentage = ((value / total) * 100).toFixed(1);\n \n return {\n text: `${label} (${percentage}%)`,\n fillStyle: backgroundColor,\n strokeStyle: backgroundColor,\n lineWidth: 0,\n hidden: false,\n index: i\n };\n });\n }\n return [];\n }\n }\n },\n tooltip: {\n ...options.plugins.tooltip,\n callbacks: {\n ...options.plugins.tooltip.callbacks,\n label: (context) => {\n const label = context.label || '';\n const value = context.raw;\n const dataset = context.dataset;\n \n // Calculate percentage\n const total = dataset.data.reduce((sum, val) => sum + val, 0);\n const percentage = ((value / total) * 100).toFixed(1);\n \n // Apply value formatter if configured\n let formattedValue = value;\n if (this.valueFormatter) {\n formattedValue = this.dataFormatter.pipe(value, this.valueFormatter);\n } else if (this.tooltipFormatters && this.tooltipFormatters.y) {\n formattedValue = this.dataFormatter.pipe(value, this.tooltipFormatters.y);\n }\n \n return `${label}: ${formattedValue} (${percentage}%)`;\n }\n }\n }\n };\n\n // Remove scales (not used in pie charts)\n delete options.scales;\n\n return options;\n }\n\n setupChartEventHandlers() {\n super.setupChartEventHandlers();\n\n if (!this.chart || !this.clickable) return;\n\n // Override click handler for pie chart specific behavior\n this.chart.options.onClick = (event, elements) => {\n if (elements.length > 0) {\n const element = elements[0];\n const index = element.index;\n const dataset = this.chart.data.datasets[0];\n const label = this.chart.data.labels[index];\n const value = dataset.data[index];\n\n // Calculate percentage\n const total = dataset.data.reduce((sum, val) => sum + val, 0);\n const percentage = ((value / total) * 100).toFixed(1);\n\n // Toggle segment selection\n this.toggleSegmentSelection(index);\n\n // Emit click event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('chart:segment-clicked', {\n chart: this,\n index,\n label,\n value,\n percentage: parseFloat(percentage),\n isSelected: this.selectedSegment === index\n });\n }\n }\n };\n\n // Hover handler for visual feedback\n if (this.hoverable) {\n this.chart.options.onHover = (event, elements) => {\n this.canvas.style.cursor = elements.length > 0 ? 'pointer' : 'default';\n \n if (elements.length > 0) {\n const element = elements[0];\n const index = element.index;\n \n // Emit hover event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('chart:segment-hover', {\n chart: this,\n index,\n label: this.chart.data.labels[index],\n value: this.chart.data.datasets[0].data[index]\n });\n }\n }\n };\n }\n }\n\n toggleSegmentSelection(index) {\n if (this.selectedSegment === index) {\n // Deselect current segment\n this.selectedSegment = null;\n this.resetSegmentStyle(index);\n } else {\n // Reset previous selection\n if (this.selectedSegment !== null) {\n this.resetSegmentStyle(this.selectedSegment);\n }\n \n // Select new segment\n this.selectedSegment = index;\n this.highlightSegment(index);\n }\n }\n\n highlightSegment(index) {\n if (!this.chart) return;\n\n const meta = this.chart.getDatasetMeta(0);\n const segment = meta.data[index];\n \n if (segment) {\n // Expand segment slightly\n segment.outerRadius += 10;\n this.chart.update('none');\n }\n }\n\n resetSegmentStyle(index) {\n if (!this.chart) return;\n\n const meta = this.chart.getDatasetMeta(0);\n const segment = meta.data[index];\n \n if (segment) {\n // Reset segment to normal size\n segment.outerRadius -= 10;\n this.chart.update('none');\n }\n }\n\n highlightSegments(indices) {\n if (!Array.isArray(indices)) {\n indices = [indices];\n }\n\n this.highlightedSegments.clear();\n indices.forEach(index => {\n this.highlightedSegments.add(index);\n this.highlightSegment(index);\n });\n }\n\n clearHighlights() {\n this.highlightedSegments.forEach(index => {\n this.resetSegmentStyle(index);\n });\n this.highlightedSegments.clear();\n \n if (this.selectedSegment !== null) {\n this.resetSegmentStyle(this.selectedSegment);\n this.selectedSegment = null;\n }\n }\n\n // Public API extensions\n selectSegment(index) {\n if (index >= 0 && index < this.chart?.data?.labels?.length) {\n this.toggleSegmentSelection(index);\n }\n }\n\n getSegmentData(index) {\n if (!this.chart || !this.chart.data) return null;\n\n const dataset = this.chart.data.datasets[0];\n const label = this.chart.data.labels[index];\n const value = dataset.data[index];\n const total = dataset.data.reduce((sum, val) => sum + val, 0);\n const percentage = ((value / total) * 100).toFixed(1);\n\n return {\n index,\n label,\n value,\n percentage: parseFloat(percentage),\n color: dataset.backgroundColor[index],\n isSelected: this.selectedSegment === index\n };\n }\n\n getAllSegments() {\n if (!this.chart || !this.chart.data) return [];\n\n return this.chart.data.labels.map((_, index) => this.getSegmentData(index));\n }\n\n updateSegmentColor(index, color) {\n if (!this.chart || !this.chart.data.datasets[0]) return;\n\n this.chart.data.datasets[0].backgroundColor[index] = color;\n this.chart.update('none');\n\n // Emit color change event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('chart:segment-color-changed', {\n chart: this,\n index,\n color,\n segment: this.getSegmentData(index)\n });\n }\n }\n\n addSegment(label, value, color = null) {\n if (!this.chart || !this.chart.data) return;\n\n const dataset = this.chart.data.datasets[0];\n const segmentColor = color || this.colors[this.chart.data.labels.length % this.colors.length];\n\n this.chart.data.labels.push(label);\n dataset.data.push(value);\n dataset.backgroundColor.push(segmentColor);\n\n this.chart.update();\n\n // Emit segment added event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('chart:segment-added', {\n chart: this,\n label,\n value,\n color: segmentColor,\n index: this.chart.data.labels.length - 1\n });\n }\n }\n\n removeSegment(index) {\n if (!this.chart || !this.chart.data || index < 0 || index >= this.chart.data.labels.length) {\n return;\n }\n\n const dataset = this.chart.data.datasets[0];\n const label = this.chart.data.labels[index];\n const value = dataset.data[index];\n\n this.chart.data.labels.splice(index, 1);\n dataset.data.splice(index, 1);\n dataset.backgroundColor.splice(index, 1);\n\n // Reset selection if removed segment was selected\n if (this.selectedSegment === index) {\n this.selectedSegment = null;\n } else if (this.selectedSegment > index) {\n this.selectedSegment--;\n }\n\n this.chart.update();\n\n // Emit segment removed event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('chart:segment-removed', {\n chart: this,\n label,\n value,\n index,\n removedSegment: { label, value, index }\n });\n }\n }\n\n // Override applyThemeToOptions for pie chart specific theming\n applyThemeToOptions(options) {\n super.applyThemeToOptions(options);\n\n const isDark = this.theme === 'dark';\n \n // Adjust border colors for theme\n if (isDark) {\n this.borderColor = '#404449';\n } else {\n this.borderColor = '#ffffff';\n }\n }\n\n // Static dialog method\n static async showDialog(options = {}) {\n const {\n title = 'Pie Chart',\n size = 'lg',\n ...chartOptions\n } = options;\n\n const chart = new PieChart({\n ...chartOptions,\n title\n });\n\n // Using static import at top: import Dialog from '@core/views/feedback/Dialog.js';\n\n const dialog = new Dialog({\n title,\n body: chart,\n size,\n centered: true,\n backdrop: 'static',\n keyboard: true,\n buttons: [\n { \n text: 'Export PNG', \n action: 'export', \n class: 'btn btn-outline-primary' \n },\n { \n text: 'Close', \n action: 'close', \n class: 'btn btn-secondary',\n dismiss: true\n }\n ]\n });\n\n // Render and mount\n await dialog.render();\n document.body.appendChild(dialog.element);\n await dialog.mount();\n\n // Show the dialog\n dialog.show();\n\n return new Promise((resolve) => {\n dialog.on('hidden', () => {\n dialog.destroy();\n resolve(chart);\n });\n\n dialog.on('action:export', () => {\n chart.exportChart('png');\n });\n\n dialog.on('action:close', () => {\n dialog.hide();\n });\n });\n }\n}","/**\n * MetricsChart - Specialized metrics chart extending SeriesChart\n * Provides header controls and a REST-based fetch to transform API data into Chart.js format\n */\n\nimport SeriesChart from './SeriesChart.js';\nimport Dialog from '@core/views/feedback/Dialog.js';\n\nexport default class MetricsChart extends SeriesChart {\n constructor(options = {}) {\n super({\n ...options,\n chartType: options.chartType || 'line',\n title: options.title || 'Metrics',\n colors: options.colors || [\n 'rgba(54, 162, 235, 0.8)', // Blue\n 'rgba(255, 99, 132, 0.8)', // Red\n 'rgba(75, 192, 192, 0.8)', // Green\n 'rgba(255, 206, 86, 0.8)', // Yellow\n 'rgba(153, 102, 255, 0.8)', // Purple\n 'rgba(255, 159, 64, 0.8)', // Orange\n 'rgba(199, 199, 199, 0.8)', // Grey\n 'rgba(83, 102, 255, 0.8)' // Indigo\n ],\n yAxis: options.yAxis || { label: 'Count', beginAtZero: true },\n tooltip: options.tooltip || { y: 'number' },\n width: options.width,\n height: options.height\n });\n\n // API configuration\n this.endpoint = options.endpoint || '/api/metrics/fetch';\n this.account = options.account || 'global';\n\n // Initial parameters\n this.granularity = options.granularity || 'hours';\n this.slugs = options.slugs || null;\n this.category = options.category || null;\n this.dateStart = options.dateStart || null;\n this.dateEnd = options.dateEnd || null;\n this.defaultDateRange = options.defaultDateRange || '24h';\n\n // Control visibility options\n this.showGranularity = options.showGranularity !== false;\n this.showDateRange = options.showDateRange !== false;\n\n // Options for controls\n this.granularityOptions = options.granularityOptions || [\n { value: 'minutes', label: 'Minutes' },\n { value: 'hours', label: 'Hours' },\n { value: 'days', label: 'Days' },\n { value: 'weeks', label: 'Weeks' },\n { value: 'months', label: 'Months' }\n ];\n\n this.quickRanges = options.quickRanges || [\n { value: '1h', label: '1H' },\n { value: '24h', label: '24H' },\n { value: '7d', label: '7D' },\n { value: '30d', label: '30D' }\n ];\n\n this.availableMetrics = options.availableMetrics || [\n { value: 'api_calls', label: 'API Calls' },\n { value: 'api_errors', label: 'API Errors' },\n { value: 'incident_evt', label: 'System Events' },\n { value: 'incidents', label: 'Incidents' }\n ];\n\n // State\n this.isLoading = false;\n this.lastFetch = null;\n\n // Initialize date range if missing\n if (!this.dateStart || !this.dateEnd) {\n this.setQuickRange(this.defaultDateRange);\n }\n }\n\n async onInit() {\n // Build header controls for granularity and date range\n const controls = [];\n\n if (this.showGranularity) {\n controls.push({\n type: 'select',\n name: 'granularity',\n action: 'granularity-changed',\n size: 'sm',\n options: this.granularityOptions.map(opt => ({\n value: opt.value,\n label: opt.label,\n selected: opt.value === this.granularity\n }))\n });\n }\n\n if (this.showDateRange) {\n controls.push({\n type: 'button',\n action: 'show-date-range-dialog',\n labelHtml: `<i class=\"bi bi-calendar-range me-1\"></i>${this.formatDateRangeDisplay()}`,\n title: 'Select Date Range',\n variant: 'outline-secondary',\n size: 'sm'\n });\n }\n\n this.headerConfig = {\n titleHtml: this.title || 'Metrics',\n chartTitle: this.chartTitle || '',\n showExport: this.exportEnabled === true,\n showRefresh: this.refreshEnabled,\n showTheme: false,\n controls\n };\n\n await super.onInit();\n }\n\n // Action Handlers\n async onActionGranularityChanged(event, element) {\n const newGranularity = element.value;\n if (newGranularity && newGranularity !== this.granularity) {\n this.granularity = newGranularity;\n await this.fetchData();\n }\n }\n\n async onActionShowDateRangeDialog() {\n try {\n const result = await Dialog.showForm({\n title: 'Select Date Range',\n size: 'md',\n fields: [\n {\n name: 'dateRange',\n type: 'daterange',\n label: 'Date Range',\n startName: 'dt_start',\n endName: 'dt_end',\n startDate: this.formatDateTimeLocal(this.dateStart),\n endDate: this.formatDateTimeLocal(this.dateEnd),\n required: true\n }\n ],\n formConfig: {\n options: {\n submitButton: false,\n resetButton: false\n }\n }\n });\n\n if (result && result.startDate && result.endDate) {\n this.dateStart = new Date(result.startDate);\n this.dateEnd = new Date(result.endDate);\n\n // Update the header button label\n const btn = this.element?.querySelector('[data-action=\"show-date-range-dialog\"]');\n if (btn) {\n btn.innerHTML = `<i class=\"bi bi-calendar-range me-1\"></i>${this.formatDateRangeDisplay()}`;\n }\n\n await this.fetchData();\n }\n } catch (error) {\n console.error('Date range dialog error:', error);\n }\n }\n\n // Data Management\n buildApiParams() {\n const params = {\n granularity: this.granularity,\n account: this.account,\n with_labels: true\n };\n\n // Add slugs\n if (this.slugs) {\n this.slugs.forEach(slug => {\n if (!params['slugs[]']) params['slugs[]'] = [];\n params['slugs[]'].push(slug);\n });\n }\n\n if (this.category) {\n params.category = this.category;\n }\n // Date range\n if (this.dateStart) {\n params.dr_start = Math.floor(this.dateStart.getTime() / 1000);\n }\n if (this.dateEnd) {\n params.dr_end = Math.floor(this.dateEnd.getTime() / 1000);\n }\n\n // Cache buster\n params._ = Date.now();\n\n return params;\n }\n\n async fetchData() {\n if (!this.endpoint) return;\n\n this.isLoading = true;\n this.showLoading();\n\n try {\n const rest = this.getApp()?.rest;\n if (!rest) {\n throw new Error('No REST client available');\n }\n\n const params = this.buildApiParams();\n const response = await rest.GET(this.endpoint, params);\n\n // Handle Rest standardized response\n if (!response.success) {\n throw new Error(response.message || 'Network error');\n }\n if (!response.data?.status) {\n throw new Error(response.data?.error || 'Server error');\n }\n\n const metricsData = response.data.data;\n const chartData = this.processMetricsData(metricsData);\n await this.setData(chartData);\n this.lastFetch = new Date();\n\n // Emit success event\n this.emit('metrics:data-loaded', {\n chart: this,\n data: metricsData,\n params\n });\n\n } catch (error) {\n console.error('Failed to fetch metrics data:', error);\n this.showError(`Failed to load metrics: ${error.message}`);\n\n // Emit error event\n this.emit('metrics:error', { chart: this, error });\n\n } finally {\n this.isLoading = false;\n this.hideLoading();\n }\n }\n\n processMetricsData(data) {\n // Expecting: { labels: [...], data: { metric_slug: [values...] } }\n const { data: metricsData, labels } = data;\n const datasets = [];\n\n Object.keys(metricsData).forEach((metric, index) => {\n const values = metricsData[metric];\n\n const sanitizedValues = values.map(val => {\n if (val === null || val === undefined || val === '') return 0;\n return typeof val === 'number' ? val : (parseFloat(val) || 0);\n });\n\n datasets.push({\n label: this.formatMetricLabel(metric),\n data: sanitizedValues,\n backgroundColor: this.colors[index % this.colors.length].replace('0.8', '0.6'),\n borderColor: this.colors[index % this.colors.length],\n borderWidth: 2,\n tension: this.chartType === 'line' ? 0.4 : 0,\n fill: false,\n pointRadius: this.chartType === 'line' ? 3 : 0,\n pointHoverRadius: 5\n });\n });\n\n return { labels, datasets };\n }\n\n formatMetricLabel(metric) {\n return metric\n .split('_')\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n }\n\n // Date utilities\n setQuickRange(range) {\n const now = new Date();\n let startDate;\n\n switch (range) {\n case '1h':\n startDate = new Date(now.getTime() - (60 * 60 * 1000));\n break;\n case '24h':\n startDate = new Date(now.getTime() - (24 * 60 * 60 * 1000));\n break;\n case '7d':\n startDate = new Date(now.getTime() - (7 * 24 * 60 * 60 * 1000));\n break;\n case '30d':\n startDate = new Date(now.getTime() - (30 * 24 * 60 * 60 * 1000));\n break;\n default:\n startDate = new Date(now.getTime() - (24 * 60 * 60 * 1000));\n }\n\n this.dateStart = startDate;\n this.dateEnd = now;\n }\n\n formatDateTimeLocal(date) {\n if (!date) return '';\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n const hours = String(date.getHours()).padStart(2, '0');\n const minutes = String(date.getMinutes()).padStart(2, '0');\n return `${year}-${month}-${day}T${hours}:${minutes}`;\n }\n\n // Public API\n setGranularity(granularity) {\n this.granularity = granularity;\n return this.fetchData();\n }\n\n setDateRange(startDate, endDate) {\n this.dateStart = new Date(startDate);\n this.dateEnd = new Date(endDate);\n return this.fetchData();\n }\n\n setMetrics(slugs) {\n this.slugs = [...slugs];\n return this.fetchData();\n }\n\n getStats() {\n const base = super.getStats();\n return {\n ...base,\n lastFetch: this.lastFetch,\n granularity: this.granularity,\n slugs: [...this.slugs],\n dateRange: {\n start: this.dateStart,\n end: this.dateEnd\n }\n };\n }\n}\n","/**\n * MiniChart - Lightweight sparkline chart component\n * Renders simple line or bar charts with minimal configuration\n * Uses SVG for crisp rendering at any size\n */\n\nimport View from '@core/View.js';\nimport dataFormatter from '@core/utils/DataFormatter.js';\n\nexport default class MiniChart extends View {\n constructor(options = {}) {\n super({\n className: 'mini-chart',\n ...options\n });\n\n // Chart type: 'line' or 'bar'\n this.chartType = options.chartType || 'line';\n\n // Data\n this.data = options.data || [];\n\n // Dimensions\n this.width = options.width || '100%'; // Support both number and '100%'\n this.height = options.height || 30;\n this.maintainAspectRatio = options.maintainAspectRatio || false;\n\n // Styling\n this.color = options.color || 'rgba(54, 162, 235, 1)'; // Primary blue\n this.fillColor = options.fillColor || 'rgba(54, 162, 235, 0.1)'; // Light fill\n this.strokeWidth = options.strokeWidth || 2;\n this.barGap = options.barGap || 2;\n\n // Fill area under line\n this.fill = options.fill !== false; // Default true\n\n // Curve smoothing (0 = straight lines, 1 = very smooth)\n this.smoothing = options.smoothing || 0.3;\n\n // Padding\n this.padding = options.padding || 2;\n\n // Min/Max values (auto-calculated if not provided)\n this.minValue = options.minValue;\n this.maxValue = options.maxValue;\n\n // Show dots on line chart\n this.showDots = options.showDots || false;\n this.dotRadius = options.dotRadius || 2;\n\n // Animation\n this.animate = options.animate !== false;\n this.animationDuration = options.animationDuration || 300;\n\n // Tooltip\n this.showTooltip = options.showTooltip !== false;\n this.tooltipFormatter = options.tooltipFormatter || null;\n this.tooltipTemplate = options.tooltipTemplate || null; // Function returning HTML\n this.valueFormat = options.valueFormat || null; // DataFormatter string\n this.labelFormat = options.labelFormat || null; // DataFormatter string for labels\n\n // Crosshair\n this.showCrosshair = options.showCrosshair !== false;\n this.crosshairColor = options.crosshairColor || 'rgba(0, 0, 0, 0.2)';\n this.crosshairWidth = options.crosshairWidth || 1;\n\n // X-axis\n this.showXAxis = options.showXAxis || false;\n this.xAxisColor = options.xAxisColor || this.color;\n this.xAxisWidth = options.xAxisWidth || 1;\n this.xAxisDashed = options.xAxisDashed !== false;\n\n // Tooltip state\n this.tooltip = null;\n this.crosshair = null;\n this.hoveredIndex = -1;\n\n // DataFormatter instance\n this.dataFormatter = dataFormatter;\n\n // Labels array (can be set externally or from API)\n this.labels = options.labels || null;\n }\n\n getTemplate() {\n const widthStyle = typeof this.width === 'number' ? `${this.width}px` : this.width;\n const heightStyle = typeof this.height === 'number' ? `${this.height}px` : this.height;\n const preserveAspectRatio = this.maintainAspectRatio ? 'xMidYMid meet' : 'none';\n\n return `\n <div class=\"mini-chart-wrapper\" style=\"position: relative; display: block; width: ${widthStyle}; height: ${heightStyle};\">\n <svg\n class=\"mini-chart-svg\"\n width=\"100%\"\n height=\"100%\"\n viewBox=\"0 0 100 ${this.height}\"\n preserveAspectRatio=\"${preserveAspectRatio}\"\n style=\"display: block;\">\n </svg>\n ${this.showTooltip ? '<div class=\"mini-chart-tooltip\" style=\"display: none;\"></div>' : ''}\n </div>\n `;\n }\n\n async onAfterRender() {\n this.svg = this.element.querySelector('.mini-chart-svg');\n this.tooltip = this.element.querySelector('.mini-chart-tooltip');\n\n // Get actual rendered dimensions\n this.updateDimensions();\n\n if (this.data && this.data.length > 0) {\n this.renderChart();\n }\n\n // Setup hover interactions if tooltip enabled\n if (this.showTooltip && this.svg) {\n this.setupTooltip();\n }\n\n // Setup resize observer for responsive behavior\n this.setupResizeObserver();\n }\n\n updateDimensions() {\n if (!this.svg) return;\n\n const rect = this.svg.getBoundingClientRect();\n this.actualWidth = rect.width || 100;\n this.actualHeight = rect.height || this.height;\n\n // Update viewBox to match aspect ratio\n this.svg.setAttribute('viewBox', `0 0 ${this.actualWidth} ${this.actualHeight}`);\n }\n\n setupResizeObserver() {\n if (typeof ResizeObserver === 'undefined') return;\n\n this.resizeObserver = new ResizeObserver(() => {\n this.updateDimensions();\n if (this.data && this.data.length > 0) {\n this.renderChart();\n }\n });\n\n if (this.svg) {\n this.resizeObserver.observe(this.svg);\n }\n }\n\n renderChart() {\n if (!this.svg || !this.data || this.data.length === 0) return;\n\n // Clear previous content\n this.svg.innerHTML = '';\n\n // Calculate bounds\n const { min, max } = this.calculateBounds();\n\n // Add x-axis line if enabled (render first so it's behind chart)\n if (this.showXAxis) {\n this.renderXAxis(min, max);\n }\n\n if (this.chartType === 'line') {\n this.renderLine(min, max);\n } else if (this.chartType === 'bar') {\n this.renderBar(min, max);\n }\n\n // Add crosshair line (initially hidden)\n if (this.showCrosshair) {\n const height = this.getActualHeight();\n this.crosshair = this.createSVGElement('line', {\n x1: 0,\n y1: 0,\n x2: 0,\n y2: height,\n stroke: this.crosshairColor,\n 'stroke-width': this.crosshairWidth,\n 'stroke-dasharray': '3,3',\n style: 'display: none; pointer-events: none;'\n });\n this.svg.appendChild(this.crosshair);\n }\n\n // Setup tooltip hit areas after rendering chart\n if (this.showTooltip && this.tooltip) {\n this.setupTooltip();\n }\n\n // Apply animation if enabled\n if (this.animate) {\n this.applyAnimation();\n }\n }\n\n renderXAxis(min, max) {\n const width = this.getActualWidth();\n const height = this.getActualHeight();\n\n // Calculate y position for x-axis (at zero if data crosses zero, otherwise at bottom)\n let yPos;\n if (min <= 0 && max >= 0) {\n // Data crosses zero, place axis at zero\n const range = max - min;\n const yScale = (height - this.padding * 2) / range;\n yPos = height - this.padding - ((0 - min) * yScale);\n } else {\n // Place at bottom\n yPos = height - this.padding;\n }\n\n const xAxis = this.createSVGElement('line', {\n x1: this.padding,\n y1: yPos,\n x2: width - this.padding,\n y2: yPos,\n stroke: this.xAxisColor,\n 'stroke-width': this.xAxisWidth,\n 'stroke-dasharray': this.xAxisDashed ? '2,2' : 'none',\n 'stroke-opacity': '0.5'\n });\n\n this.svg.appendChild(xAxis);\n }\n\n calculateBounds() {\n const values = this.data.map(d => typeof d === 'object' ? d.value : d);\n\n let min = this.minValue !== undefined ? this.minValue : Math.min(...values);\n let max = this.maxValue !== undefined ? this.maxValue : Math.max(...values);\n\n // Handle zero-range cases\n const range = max - min;\n if (range === 0) {\n if (this.chartType === 'bar') {\n // For bar charts with all zeros, keep baseline at 0\n if (min === 0) {\n min = 0;\n max = 1;\n } else {\n // For constant non-zero values, add a small symmetric range\n min = min - 1;\n max = max + 1;\n }\n } else {\n // For line charts, add a small symmetric range\n min = min - 1;\n max = max + 1;\n }\n }\n\n return { min, max };\n }\n\n getActualWidth() {\n return this.actualWidth || this.width || 100;\n }\n\n getActualHeight() {\n return this.actualHeight || this.height || 30;\n }\n\n renderLine(min, max) {\n const values = this.data.map(d => typeof d === 'object' ? d.value : d);\n const points = this.calculatePoints(values, min, max);\n\n // Create filled area under line\n if (this.fill) {\n const areaPath = this.createAreaPath(points);\n const area = this.createSVGElement('path', {\n d: areaPath,\n fill: this.fillColor,\n stroke: 'none'\n });\n this.svg.appendChild(area);\n }\n\n // Create line path\n const linePath = this.smoothing > 0\n ? this.createSmoothPath(points)\n : this.createLinePath(points);\n\n const line = this.createSVGElement('path', {\n d: linePath,\n fill: 'none',\n stroke: this.color,\n 'stroke-width': this.strokeWidth,\n 'stroke-linecap': 'round',\n 'stroke-linejoin': 'round'\n });\n this.svg.appendChild(line);\n\n // Add dots if enabled\n if (this.showDots) {\n points.forEach(point => {\n const dot = this.createSVGElement('circle', {\n cx: point.x,\n cy: point.y,\n r: this.dotRadius,\n fill: this.color\n });\n this.svg.appendChild(dot);\n });\n }\n }\n\n renderBar(min, max) {\n const values = this.data.map(d => typeof d === 'object' ? d.value : d);\n const points = this.calculatePoints(values, min, max);\n\n const width = this.getActualWidth();\n const height = this.getActualHeight();\n const barWidth = (width - this.padding * 2 - (this.barGap * (values.length - 1))) / values.length;\n\n points.forEach((point, index) => {\n const barHeight = height - this.padding * 2 - point.y + this.padding;\n const x = point.x - barWidth / 2;\n const y = point.y;\n\n const bar = this.createSVGElement('rect', {\n x: x,\n y: y,\n width: barWidth,\n height: barHeight,\n fill: this.color,\n rx: 1, // Slight rounding\n 'data-bar-index': index,\n class: 'mini-chart-bar'\n });\n this.svg.appendChild(bar);\n });\n }\n\n calculatePoints(values, min, max) {\n const range = max - min;\n const width = this.getActualWidth();\n const height = this.getActualHeight();\n const xStep = (width - this.padding * 2) / (values.length - 1 || 1);\n const yScale = (height - this.padding * 2) / range;\n\n return values.map((value, index) => ({\n x: this.padding + (index * xStep),\n y: height - this.padding - ((value - min) * yScale)\n }));\n }\n\n createLinePath(points) {\n if (points.length === 0) return '';\n\n let path = `M ${points[0].x},${points[0].y}`;\n for (let i = 1; i < points.length; i++) {\n path += ` L ${points[i].x},${points[i].y}`;\n }\n return path;\n }\n\n createSmoothPath(points) {\n if (points.length < 2) return this.createLinePath(points);\n\n let path = `M ${points[0].x},${points[0].y}`;\n\n for (let i = 0; i < points.length - 1; i++) {\n const current = points[i];\n const next = points[i + 1];\n\n // Calculate control points for cubic bezier curve\n const cp1x = current.x + (next.x - current.x) * this.smoothing;\n const cp1y = current.y;\n const cp2x = next.x - (next.x - current.x) * this.smoothing;\n const cp2y = next.y;\n\n path += ` C ${cp1x},${cp1y} ${cp2x},${cp2y} ${next.x},${next.y}`;\n }\n\n return path;\n }\n\n createAreaPath(points) {\n if (points.length === 0) return '';\n\n const linePath = this.smoothing > 0\n ? this.createSmoothPath(points)\n : this.createLinePath(points);\n\n // Close the path along the bottom\n const lastPoint = points[points.length - 1];\n const firstPoint = points[0];\n const height = this.getActualHeight();\n\n return `${linePath} L ${lastPoint.x},${height - this.padding} L ${firstPoint.x},${height - this.padding} Z`;\n }\n\n createSVGElement(tag, attributes = {}) {\n const element = document.createElementNS('http://www.w3.org/2000/svg', tag);\n Object.entries(attributes).forEach(([key, value]) => {\n element.setAttribute(key, value);\n });\n return element;\n }\n\n applyAnimation() {\n const paths = this.svg.querySelectorAll('path');\n paths.forEach(path => {\n const length = path.getTotalLength();\n path.style.strokeDasharray = length;\n path.style.strokeDashoffset = length;\n path.style.animation = `mini-chart-draw ${this.animationDuration}ms ease-out forwards`;\n });\n\n const bars = this.svg.querySelectorAll('rect');\n bars.forEach((bar, index) => {\n bar.style.transformOrigin = 'bottom';\n bar.style.animation = `mini-chart-bar-grow ${this.animationDuration}ms ease-out ${index * 20}ms forwards`;\n bar.style.transform = 'scaleY(0)';\n });\n }\n\n setupTooltip() {\n if (!this.svg || !this.tooltip) return;\n\n // Create invisible overlay rects for hover detection\n const values = this.data.map(d => typeof d === 'object' ? d.value : d);\n const points = this.calculatePoints(values, ...Object.values(this.calculateBounds()));\n\n const width = this.getActualWidth();\n const height = this.getActualHeight();\n const barWidth = width / values.length;\n\n points.forEach((point, index) => {\n const hitArea = this.createSVGElement('rect', {\n x: index * barWidth,\n y: 0,\n width: barWidth,\n height: height,\n fill: 'transparent',\n style: 'cursor: pointer;'\n });\n\n hitArea.addEventListener('mouseenter', (e) => {\n this.showTooltipAtIndex(index, e);\n });\n\n hitArea.addEventListener('mousemove', (e) => {\n this.updateTooltipPosition(e);\n });\n\n hitArea.addEventListener('mouseleave', () => {\n this.hideTooltip();\n });\n\n this.svg.appendChild(hitArea);\n });\n }\n\n showTooltipAtIndex(index, event) {\n if (!this.tooltip) return;\n\n this.hoveredIndex = index;\n const value = typeof this.data[index] === 'object' ? this.data[index].value : this.data[index];\n const dataLabel = typeof this.data[index] === 'object' ? this.data[index].label : null;\n const label = this.labels ? this.labels[index] : dataLabel;\n\n // Build tooltip content using priority system\n let content;\n\n if (this.tooltipTemplate && typeof this.tooltipTemplate === 'function') {\n // 1. Custom template function (highest priority)\n content = this.tooltipTemplate({ value, label, index, data: this.data[index] });\n } else {\n // 2. Format value with DataFormatter or custom formatter\n let displayValue = value;\n\n if (this.valueFormat && this.dataFormatter) {\n // Use DataFormatter with format string\n displayValue = this.dataFormatter.pipe(value, this.valueFormat);\n } else if (this.tooltipFormatter && typeof this.tooltipFormatter === 'function') {\n // Use custom formatter function\n displayValue = this.tooltipFormatter(value, index);\n } else {\n // Default formatting\n displayValue = typeof value === 'number' ? value.toLocaleString() : value;\n }\n\n // Format label if formatter provided\n let displayLabel = label;\n if (label && this.labelFormat && this.dataFormatter) {\n displayLabel = this.dataFormatter.pipe(label, this.labelFormat);\n }\n\n // Build default tooltip HTML\n content = `<strong>${displayValue}</strong>`;\n if (displayLabel) {\n content = `<div class=\"mini-chart-tooltip-label\">${displayLabel}</div>${content}`;\n }\n }\n\n this.tooltip.innerHTML = content;\n this.tooltip.style.display = 'block';\n this.updateTooltipPosition(event);\n\n // Highlight bar if in bar chart mode\n if (this.chartType === 'bar') {\n this.highlightBar(index);\n }\n\n // Show crosshair at the hovered position\n if (this.crosshair && this.showCrosshair) {\n const width = this.getActualWidth();\n const barWidth = width / this.data.length;\n const x = (index * barWidth) + (barWidth / 2);\n this.crosshair.setAttribute('x1', x);\n this.crosshair.setAttribute('x2', x);\n this.crosshair.style.display = 'block';\n }\n }\n\n updateTooltipPosition(event) {\n if (!this.tooltip || this.tooltip.style.display === 'none') return;\n\n const rect = this.svg.getBoundingClientRect();\n const x = event.clientX - rect.left;\n const y = event.clientY - rect.top;\n\n // Position tooltip above cursor\n this.tooltip.style.left = `${x}px`;\n this.tooltip.style.top = `${y - 10}px`;\n this.tooltip.style.transform = 'translate(-50%, -100%)';\n }\n\n hideTooltip() {\n if (this.tooltip) {\n this.tooltip.style.display = 'none';\n this.hoveredIndex = -1;\n }\n\n // Remove bar highlight\n if (this.chartType === 'bar') {\n this.unhighlightBars();\n }\n\n // Hide crosshair\n if (this.crosshair) {\n this.crosshair.style.display = 'none';\n }\n }\n\n highlightBar(index) {\n if (!this.svg) return;\n\n // Remove previous highlights\n this.unhighlightBars();\n\n // Highlight the hovered bar\n const bar = this.svg.querySelector(`rect.mini-chart-bar[data-bar-index=\"${index}\"]`);\n if (bar) {\n bar.style.opacity = '0.7';\n }\n }\n\n unhighlightBars() {\n if (!this.svg) return;\n\n const bars = this.svg.querySelectorAll('rect.mini-chart-bar');\n bars.forEach(bar => {\n bar.style.opacity = '1';\n });\n }\n\n // Public API\n setData(data) {\n this.data = data;\n if (this.svg) {\n this.renderChart();\n }\n }\n\n setColor(color) {\n this.color = color;\n if (this.svg) {\n this.renderChart();\n }\n }\n\n setType(type) {\n if (['line', 'bar'].includes(type)) {\n this.chartType = type;\n if (this.svg) {\n this.renderChart();\n }\n }\n }\n\n resize(width, height) {\n this.width = width;\n this.height = height;\n this.updateDimensions();\n if (this.svg) {\n this.renderChart();\n }\n }\n\n async onBeforeDestroy() {\n // Clean up resize observer\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n this.resizeObserver = null;\n }\n await super.onBeforeDestroy();\n }\n}\n","/**\n * MetricsMiniChart - MiniChart with API integration\n * Extends MiniChart to add /api/metrics/fetch support (same API as MetricsChart)\n */\n\nimport MiniChart from './MiniChart.js';\n\nexport default class MetricsMiniChart extends MiniChart {\n constructor(options = {}) {\n super(options);\n\n // API configuration (matching MetricsChart)\n this.endpoint = options.endpoint || '/api/metrics/fetch';\n this.account = options.account || 'global';\n this.granularity = options.granularity || 'hours';\n this.slugs = options.slugs || null; // Single slug or array of slugs\n this.category = options.category || null;\n this.dateStart = options.dateStart || null;\n this.dateEnd = options.dateEnd || null;\n this.defaultDateRange = options.defaultDateRange || '24h';\n\n // State\n this.isLoading = false;\n this.lastFetch = null;\n this.refreshInterval = options.refreshInterval;\n\n // Initialize date range if missing\n if (!this.dateStart || !this.dateEnd) {\n this.setQuickRange(this.defaultDateRange);\n }\n\n // Normalize slugs to array\n if (this.slugs && !Array.isArray(this.slugs)) {\n this.slugs = [this.slugs];\n }\n }\n\n async onAfterRender() {\n await super.onAfterRender();\n\n // Fetch initial data if endpoint provided and no data\n if (this.endpoint && (!this.data || this.data.length === 0)) {\n this.fetchData();\n }\n\n // Setup auto-refresh if configured\n if (this.refreshInterval && this.endpoint) {\n this.startAutoRefresh();\n }\n }\n\n buildApiParams() {\n const params = {\n granularity: this.granularity,\n account: this.account,\n with_labels: true\n };\n\n // Add slugs\n if (this.slugs && this.slugs.length > 0) {\n this.slugs.forEach(slug => {\n if (!params['slugs[]']) params['slugs[]'] = [];\n params['slugs[]'].push(slug);\n });\n }\n\n if (this.category) {\n params.category = this.category;\n }\n\n // Date range\n if (this.dateStart) {\n params.dr_start = Math.floor(this.dateStart.getTime() / 1000);\n }\n if (this.dateEnd) {\n params.dr_end = Math.floor(this.dateEnd.getTime() / 1000);\n }\n\n // Cache buster\n params._ = Date.now();\n\n return params;\n }\n\n async fetchData() {\n if (!this.endpoint) return;\n\n this.isLoading = true;\n\n try {\n const rest = this.getApp()?.rest;\n if (!rest) {\n throw new Error('No REST client available');\n }\n\n const params = this.buildApiParams();\n const response = await rest.GET(this.endpoint, params);\n\n // Handle Rest standardized response\n if (!response.success) {\n throw new Error(response.message || 'Network error');\n }\n if (!response.data?.status) {\n throw new Error(response.data?.error || 'Server error');\n }\n\n const metricsData = response.data.data;\n this.processMetricsData(metricsData);\n this.lastFetch = new Date();\n\n // Re-render to show updated values\n await this.render();\n\n this.emit('metrics:loaded', { chart: this, data: metricsData, params });\n\n } catch (error) {\n console.error('Failed to fetch metrics:', error);\n this.emit('metrics:error', { chart: this, error });\n } finally {\n this.isLoading = false;\n }\n }\n\n processMetricsData(metricsData) {\n // Expecting: { labels: [...], data: { metric_slug: [values...] } }\n const { data: metrics, labels } = metricsData;\n\n if (!metrics) return;\n\n // Get the first (or only) metric's data\n const metricKeys = Object.keys(metrics);\n if (metricKeys.length === 0) return;\n\n const metricSlug = metricKeys[0];\n const values = metrics[metricSlug];\n\n // Sanitize values\n const sanitizedValues = values.map(val => {\n if (val === null || val === undefined || val === '') return 0;\n return typeof val === 'number' ? val : (parseFloat(val) || 0);\n });\n\n // Update labels (for tooltips)\n this.labels = labels || null;\n\n // Update chart data\n this.setData(sanitizedValues);\n }\n\n setQuickRange(range) {\n const now = new Date();\n let startDate;\n\n switch (range) {\n case '1h':\n startDate = new Date(now.getTime() - (60 * 60 * 1000));\n break;\n case '24h':\n startDate = new Date(now.getTime() - (24 * 60 * 60 * 1000));\n break;\n case '7d':\n startDate = new Date(now.getTime() - (7 * 24 * 60 * 60 * 1000));\n break;\n case '30d':\n startDate = new Date(now.getTime() - (30 * 24 * 60 * 60 * 1000));\n break;\n default:\n startDate = new Date(now.getTime() - (24 * 60 * 60 * 1000));\n }\n\n this.dateStart = startDate;\n this.dateEnd = now;\n }\n\n startAutoRefresh() {\n if (this.refreshTimer) {\n clearInterval(this.refreshTimer);\n }\n\n this.refreshTimer = setInterval(() => {\n this.fetchData();\n }, this.refreshInterval);\n }\n\n stopAutoRefresh() {\n if (this.refreshTimer) {\n clearInterval(this.refreshTimer);\n this.refreshTimer = null;\n }\n }\n\n // Public API\n setGranularity(granularity) {\n this.granularity = granularity;\n return this.fetchData();\n }\n\n setDateRange(startDate, endDate) {\n this.dateStart = new Date(startDate);\n this.dateEnd = new Date(endDate);\n return this.fetchData();\n }\n\n setMetrics(slugs) {\n this.slugs = Array.isArray(slugs) ? slugs : [slugs];\n return this.fetchData();\n }\n\n refresh() {\n return this.fetchData();\n }\n\n async onBeforeDestroy() {\n this.stopAutoRefresh();\n await super.onBeforeDestroy();\n }\n}\n","/**\n * MetricsMiniChartWidget - Bootstrap card wrapper around MetricsMiniChart\n *\n * Renders a compact card with:\n * - icon (Bootstrap Icons class)\n * - title\n * - subtitle (inserted raw into the template so Mustache can render tokens like '{{total}}')\n * - optional trending indicator (up/down percent) under the subtitle\n * - embedded MetricsMiniChart\n * - optional settings dropdown (granularity, chartType, date range)\n *\n * Usage:\n * new MetricsMiniChartWidget({\n * icon: \"bi bi-credit-card-fill\",\n * title: 'Declined Transactions',\n * subtitle: '{{total}} Transactions', // will be rendered by Mustache at runtime\n * background: \"#F3465D\",\n * textColor: \"#FFFFFF\",\n * granularity: 'hours',\n * slugs: ['pos_tx_declined'],\n * account: 'global',\n * chartType: 'bar',\n * showTooltip: true,\n * showXAxis: true,\n * height: 80,\n * chartWidth: '100%',\n * color: 'rgba(245, 245, 255, 0.8)',\n * fill: true,\n * fillColor: 'rgba(245, 245, 255, 0.6)',\n * smoothing: 0.3,\n * showTrending: true, // optional\n * showSettings: true, // optional - show settings dropdown\n * settingsKey: 'myChart', // optional - localStorage key for persisting settings\n * showDateRange: true, // optional - include date range in settings\n * containerId: 'decline-24h-chart'\n * });\n */\n\nimport View from '@core/View.js';\nimport MetricsMiniChart from './MetricsMiniChart.js';\n\n/**\n * Settings content view for the popover\n * @private\n */\nclass SettingsView extends View {\n constructor(options = {}) {\n super({\n tagName: 'div',\n className: 'metrics-chart-settings-content',\n ...options\n });\n \n this.granularity = options.granularity;\n this.chartType = options.chartType;\n this.dateStart = options.dateStart;\n this.dateEnd = options.dateEnd;\n this.showDateRange = options.showDateRange;\n }\n \n getTemplate() {\n return `\n <div style=\"min-width: 220px;\">\n <div class=\"d-flex justify-content-between align-items-center mb-2 pb-2 border-bottom\">\n <h6 class=\"mb-0\">Chart Settings</h6>\n <button type=\"button\" class=\"btn-close btn-close-sm\" data-action=\"close\" aria-label=\"Close\"></button>\n </div>\n\n <label class=\"form-label small mb-1\">Granularity</label>\n <select class=\"form-select form-select-sm mb-2\" data-setting=\"granularity\">\n <option value=\"hours\" ${this.granularity === 'hours' ? 'selected' : ''}>Hours</option>\n <option value=\"days\" ${this.granularity === 'days' ? 'selected' : ''}>Days</option>\n <option value=\"weeks\" ${this.granularity === 'weeks' ? 'selected' : ''}>Weeks</option>\n <option value=\"months\" ${this.granularity === 'months' ? 'selected' : ''}>Months</option>\n <option value=\"years\" ${this.granularity === 'years' ? 'selected' : ''}>Years</option>\n </select>\n \n <label class=\"form-label small mb-1\">Chart Type</label>\n <select class=\"form-select form-select-sm mb-2\" data-setting=\"chartType\">\n <option value=\"line\" ${this.chartType === 'line' ? 'selected' : ''}>Line</option>\n <option value=\"bar\" ${this.chartType === 'bar' ? 'selected' : ''}>Bar</option>\n </select>\n \n ${this.showDateRange ? `\n <label class=\"form-label small mb-1\">Date Range</label>\n <input type=\"date\" class=\"form-control form-control-sm mb-1\" data-setting=\"dateStart\" value=\"${this.dateStart || ''}\" />\n <input type=\"date\" class=\"form-control form-control-sm mb-2\" data-setting=\"dateEnd\" value=\"${this.dateEnd || ''}\" />\n ` : ''}\n \n <div class=\"d-grid gap-2\">\n <button type=\"button\" class=\"btn btn-sm btn-primary\" data-action=\"apply\">Apply</button>\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary\" data-action=\"cancel\">Cancel</button>\n </div>\n </div>\n `;\n }\n \n async onActionApply() {\n const granularity = this.element.querySelector('[data-setting=\"granularity\"]')?.value;\n const chartType = this.element.querySelector('[data-setting=\"chartType\"]')?.value;\n const dateStart = this.element.querySelector('[data-setting=\"dateStart\"]')?.value;\n const dateEnd = this.element.querySelector('[data-setting=\"dateEnd\"]')?.value;\n \n this.emit('settings:apply', { granularity, chartType, dateStart, dateEnd });\n }\n \n async onActionCancel() {\n this.emit('settings:cancel');\n }\n \n async onActionClose() {\n this.emit('settings:cancel');\n }\n}\n\nexport default class MetricsMiniChartWidget extends View {\n constructor(options = {}) {\n super({\n ...options,\n tagName: 'div',\n className: `metrics-mini-chart-widget ${options.className || ''}`.trim()\n });\n\n // Display config\n this.icon = options.icon || null;\n this.title = options.title || '';\n // Subtitle is injected RAW into the template string so Mustache parses its tokens\n this.subtitle = options.subtitle || '';\n this.background = options.background || null;\n this.textColor = options.textColor || null;\n\n // Settings config\n this.showSettings = options.showSettings || false;\n this.settingsKey = options.settingsKey || null;\n this.showDateRange = options.showDateRange || false;\n this.showRefresh = options.showRefresh !== false; // Enabled by default\n this._pendingSettings = null; // Store pending settings until Apply is clicked\n\n // Trending options/state\n this.showTrending = !!options.showTrending;\n this.trendRange = options.trendRange ?? null; // e.g. 4 => compare last 2 vs prev 2\n this.trendOffset = options.trendOffset ?? 0; // e.g. 1 => skip most recent incomplete bucket\n this.prevTrendOffset = options.prevTrendOffset ?? 0; // e.g. 7 => align previous window to same day last week\n this.total = 0;\n this.lastValue = 0;\n this.prevValue = 0;\n this.trendingPercent = 0;\n this.trendingUp = null; // null means unknown\n this.hasTrending = false;\n this.trendingClass = 'metrics-mini-chart-trending-text';\n this.trendingIcon = '';\n this.trendingLabel = '';\n\n // Chart config (we'll forward these to the child MetricsMiniChart)\n this.chartOptions = {\n endpoint: options.endpoint, // defaults inside MetricsMiniChart\n account: options.account,\n granularity: options.granularity,\n slugs: options.slugs,\n category: options.category,\n dateStart: options.dateStart,\n dateEnd: options.dateEnd,\n defaultDateRange: options.defaultDateRange,\n refreshInterval: options.refreshInterval,\n\n // Visuals and interactions\n chartType: options.chartType || 'line',\n showTooltip: options.showTooltip !== undefined ? options.showTooltip : true,\n showXAxis: options.showXAxis || false,\n height: options.height || 80,\n width: options.chartWidth || options.width || '100%',\n color: options.color,\n fill: options.fill !== undefined ? options.fill : true,\n fillColor: options.fillColor,\n smoothing: options.smoothing ?? 0.3,\n strokeWidth: options.strokeWidth,\n barGap: options.barGap,\n\n // Optional formatters and templates\n valueFormat: options.valueFormat,\n labelFormat: options.labelFormat,\n tooltipFormatter: options.tooltipFormatter,\n tooltipTemplate: options.tooltipTemplate,\n\n // Crosshair and axis styling overrides (optional passthroughs)\n showCrosshair: options.showCrosshair,\n crosshairColor: options.crosshairColor,\n crosshairWidth: options.crosshairWidth,\n xAxisColor: options.xAxisColor,\n xAxisWidth: options.xAxisWidth,\n xAxisDashed: options.xAxisDashed,\n\n // Other rendering params\n padding: options.padding,\n minValue: options.minValue,\n maxValue: options.maxValue,\n showDots: options.showDots,\n dotRadius: options.dotRadius,\n animate: options.animate,\n animationDuration: options.animationDuration\n };\n }\n\n async onInit() {\n // Load saved settings if available\n if (this.showSettings && this.settingsKey) {\n this._loadSettings();\n }\n\n // Create and register the child chart\n this.chart = new MetricsMiniChart({\n ...this.chartOptions,\n containerId: 'chart' // mount inside our template container\n });\n\n this.addChild(this.chart);\n\n this.header = new View({\n containerId: 'chart-header',\n title: this.title,\n icon: this.icon,\n template: `\n <div class=\"d-flex justify-content-between align-items-start mb-2\">\n <div class=\"flex-grow-1\">\n <h6 class=\"card-title mb-1\" style=\"${this.textColor ? `color: ${this.textColor}` : ''}\">${this.title}</h6>\n <div class=\"metrics-mini-chart-subtitle\" style=\"${this.textColor ? `color: ${this.textColor}` : ''}\">${this.subtitle}</div>\n {{#hasTrending}}\n <div class=\"{{trendingClass}}\" style=\"${this.textColor ? `color: ${this.textColor}` : ''}\">\n <i class=\"{{trendingIcon}} me-1\"></i>{{trendingLabel}}\n </div>\n {{/hasTrending}}\n </div>\n ${this.icon ? `<i class=\"${this.icon} fs-4 flex-shrink-0\" aria-hidden=\"true\" style=\"${this.textColor ? `color: ${this.textColor}` : ''}\"></i>` : ''}\n </div>`\n });\n\n this.addChild(this.header);\n\n // Listen for data load events to compute totals/trending and refresh the widget UI\n if (this.chart?.on) {\n this.chart.on('metrics:loaded', this.onChildMetricsLoaded, this);\n }\n\n // If the chart already has data (e.g., provided via options), compute immediately\n this.updateFromChartData({ render: false });\n }\n\n async onAfterRender() {\n await super.onAfterRender();\n\n // Initialize popover if settings are enabled\n if (this.showSettings) {\n this._initSettingsPopover();\n }\n }\n\n onChildMetricsLoaded() {\n this.updateFromChartData({ render: true });\n \n // Reinitialize popover after chart updates (in case DOM was re-rendered)\n // Skip if we just applied settings (to avoid double initialization)\n if (this.showSettings && this.isMounted() && !this._skipNextPopoverInit) {\n // Small delay to ensure DOM is ready\n setTimeout(() => {\n this._initSettingsPopover();\n }, 100);\n }\n \n // Reset flag\n this._skipNextPopoverInit = false;\n }\n\n updateFromChartData({ render = true } = {}) {\n const values = Array.isArray(this.chart?.data) ? this.chart.data : null;\n if (!values || values.length === 0) {\n this.total = 0;\n this.hasTrending = false;\n // Refresh the view to ensure subtitle using {{total}} updates to 0\n this.header.title = this.title;\n if (render) this.render();\n return;\n }\n\n // Normalize values to numbers\n const nums = values.map((v) => {\n if (typeof v === 'number') return v;\n if (v && typeof v.value === 'number') return v.value;\n const n = parseFloat(v);\n return Number.isNaN(n) ? 0 : n;\n });\n\n // Compute total\n this.header.title = this.title;\n this.header.total = nums.reduce((a, b) => a + b, 0);\n const offset = Math.max(0, parseInt(this.trendOffset || 0, 10) || 0);\n const endIndex = Math.max(0, nums.length - 1 - offset);\n this.header.now_value = nums[endIndex];\n \n // Set dynamic labels based on granularity\n this._updateGranularityLabels();\n\n // Compute trending using windowed sums with optional offset\n let hasTrend = false;\n let lastSum = 0;\n let prevSum = 0;\n\n const k = (this.trendRange && this.trendRange >= 2) ? Math.max(1, Math.floor(this.trendRange / 2)) : 1;\n\n if (endIndex >= 0) {\n const lastEnd = endIndex;\n const lastStart = lastEnd - (k - 1);\n let prevStart, prevEnd;\n if (this.prevTrendOffset && this.prevTrendOffset > 0) {\n prevStart = lastStart - this.prevTrendOffset;\n prevEnd = lastEnd - this.prevTrendOffset;\n } else {\n prevEnd = lastStart - 1;\n prevStart = prevEnd - (k - 1);\n }\n\n if (lastStart >= 0 && prevStart >= 0) {\n // Sum helper\n const sumRange = (arr, s, e) => {\n let sum = 0;\n for (let i = s; i <= e; i++) sum += arr[i] || 0;\n return sum;\n };\n\n lastSum = sumRange(nums, lastStart, lastEnd);\n prevSum = sumRange(nums, prevStart, prevEnd);\n hasTrend = true;\n }\n }\n\n // Fallback to single-point comparison if not enough data for windows\n if (!hasTrend) {\n const prevIndex = endIndex - (this.prevTrendOffset && this.prevTrendOffset > 0 ? this.prevTrendOffset : 1);\n if (prevIndex >= 0) {\n lastSum = nums[endIndex];\n prevSum = nums[prevIndex];\n hasTrend = true;\n }\n }\n\n if (hasTrend) {\n this.header.lastValue = lastSum;\n this.header.prevValue = prevSum;\n\n let percent = 0;\n if (prevSum === 0) {\n percent = lastSum > 0 ? 100 : 0;\n } else {\n percent = ((lastSum - prevSum) / Math.abs(prevSum)) * 100;\n }\n\n this.header.trendingPercent = percent;\n this.header.trendingUp = percent >= 0;\n if (!this.textColor) {\n this.header.trendingClass = this.header.trendingUp ? 'text-success' : 'text-danger';\n } else {\n this.header.trendingClass = '';\n }\n\n this.header.trendingIcon = this.header.trendingUp ? 'bi bi-arrow-up' : 'bi bi-arrow-down';\n\n const sign = percent > 0 ? '+' : '';\n this.header.trendingLabel = `${sign}${percent.toFixed(1)}%`;\n this.header.hasTrending = this.showTrending;\n } else {\n this.header.hasTrending = false;\n }\n\n if (render) {\n // Re-render to update the UI (subtitle with {{total}} and trending block)\n this.header.render();\n }\n }\n\n /**\n * Update labels based on current granularity\n * @private\n */\n _updateGranularityLabels() {\n const granularity = this.chartOptions.granularity || 'days';\n \n // Mapping for \"now\" label (current/most recent bucket)\n const nowLabels = {\n 'hours': 'This Hour',\n 'days': 'Today',\n 'weeks': 'This Week',\n 'months': 'This Month',\n 'years': 'This Year'\n };\n \n // Mapping for \"total\" label (sum of all buckets in range)\n const totalLabels = {\n 'hours': 'Total (24h)',\n 'days': 'Total (Period)',\n 'weeks': 'Total (Period)',\n 'months': 'Total (Period)',\n 'years': 'Total (Period)'\n };\n \n this.header.now_label = nowLabels[granularity] || 'Current';\n this.header.total_label = totalLabels[granularity] || 'Total';\n }\n\n get cardStyle() {\n const styles = [];\n if (this.background) styles.push(`background: ${this.background}`);\n if (this.textColor) styles.push(`color: ${this.textColor}`);\n // Ensure inner elements inherit text color\n styles.push('border: 0');\n return styles.join('; ');\n }\n\n async getTemplate() {\n return `\n <div class=\"card h-100 shadow-sm\" style=\"${this.cardStyle}; position: relative;\">\n ${this.showRefresh || this.showSettings ? `\n <div class=\"metrics-chart-actions\">\n ${this.showRefresh ? `\n <button class=\"btn btn-link p-0 text-muted metrics-refresh-btn\" type=\"button\" data-action=\"refresh-chart\" style=\"${this.textColor ? `color: ${this.textColor} !important` : ''}\">\n <i class=\"bi bi-arrow-clockwise\"></i>\n </button>\n ` : ''}\n ${this.showSettings ? `\n <button class=\"btn btn-link p-0 text-muted metrics-settings-btn\" type=\"button\" data-settings-trigger style=\"${this.textColor ? `color: ${this.textColor} !important` : ''}\">\n <i class=\"bi bi-gear-fill\"></i>\n </button>\n ` : ''}\n </div>\n ` : ''}\n <div class=\"card-body p-3\">\n <div data-container=\"chart-header\"></div>\n <div data-container=\"chart\"></div>\n </div>\n </div>\n `;\n }\n\n async onBeforeDestroy() {\n // Clean up settings view\n if (this._settingsView) {\n await this._settingsView.destroy();\n this._settingsView = null;\n }\n \n // Dispose of popover\n if (this._settingsPopover) {\n this._settingsPopover.dispose();\n this._settingsPopover = null;\n }\n\n if (this.chart?.off) {\n this.chart.off('metrics:loaded', this.onChildMetricsLoaded, this);\n }\n await super.onBeforeDestroy();\n }\n\n /**\n * Initialize settings popover\n * @private\n */\n _initSettingsPopover() {\n const button = this.element.querySelector('[data-settings-trigger]');\n if (!button) return;\n\n // Clean up existing\n if (this._settingsView) {\n this._settingsView.destroy();\n this._settingsView = null;\n }\n if (this._settingsPopover) {\n this._settingsPopover.dispose();\n this._settingsPopover = null;\n }\n\n // Remove any existing event listeners\n if (this._popoverShownHandler) {\n button.removeEventListener('shown.bs.popover', this._popoverShownHandler);\n }\n\n // Create settings view\n this._settingsView = new SettingsView({\n granularity: this.chartOptions.granularity,\n chartType: this.chartOptions.chartType,\n dateStart: this.chartOptions.dateStart,\n dateEnd: this.chartOptions.dateEnd,\n showDateRange: this.showDateRange\n });\n\n // Listen for apply/cancel events\n this._settingsView.on('settings:apply', (data) => this._handleSettingsApply(data));\n this._settingsView.on('settings:cancel', () => this._handleSettingsCancel());\n\n // Render the settings view\n this._settingsView.render();\n\n // Create handler for shown event\n this._popoverShownHandler = () => {\n const popoverBody = document.querySelector('.popover.show .popover-body');\n if (popoverBody && this._settingsView) {\n popoverBody.innerHTML = '';\n popoverBody.appendChild(this._settingsView.element);\n this._settingsView.bindEvents();\n }\n };\n\n // Create popover using placeholder content\n this._settingsPopover = new bootstrap.Popover(button, {\n content: '<div>Loading...</div>',\n html: true,\n placement: 'bottom',\n trigger: 'click',\n sanitize: false,\n customClass: 'metrics-chart-settings-popover'\n });\n\n // Attach event listener (not once, so it works every time)\n button.addEventListener('shown.bs.popover', this._popoverShownHandler);\n }\n\n /**\n * Handle settings apply\n * @private\n */\n async _handleSettingsApply(data) {\n // Hide popover first\n if (this._settingsPopover) {\n this._settingsPopover.hide();\n }\n\n let hasChanges = false;\n let granularityChanged = false;\n let datesExplicitlySet = false;\n\n // Check if dates were explicitly changed\n if ((data.dateStart && data.dateStart !== this.chartOptions.dateStart) || \n (data.dateEnd && data.dateEnd !== this.chartOptions.dateEnd)) {\n datesExplicitlySet = true;\n }\n\n // Apply granularity\n if (data.granularity && data.granularity !== this.chartOptions.granularity) {\n this.chartOptions.granularity = data.granularity;\n this.chart.granularity = data.granularity;\n granularityChanged = true;\n hasChanges = true;\n }\n\n // Apply chart type\n if (data.chartType && data.chartType !== this.chartOptions.chartType) {\n this.chartOptions.chartType = data.chartType;\n this.chart.chartType = data.chartType;\n hasChanges = true;\n }\n\n // Apply dates or auto-adjust based on granularity\n if (datesExplicitlySet) {\n if (data.dateStart) {\n this.chartOptions.dateStart = new Date(data.dateStart);\n this.chart.dateStart = new Date(data.dateStart);\n }\n if (data.dateEnd) {\n this.chartOptions.dateEnd = new Date(data.dateEnd);\n this.chart.dateEnd = new Date(data.dateEnd);\n }\n hasChanges = true;\n } else if (granularityChanged) {\n // Auto-adjust date range for new granularity\n const endDate = new Date();\n let startDate;\n \n switch (data.granularity) {\n case 'hours':\n startDate = new Date(endDate.getTime() - (24 * 60 * 60 * 1000));\n break;\n case 'days':\n startDate = new Date(endDate.getTime() - (30 * 24 * 60 * 60 * 1000));\n break;\n case 'weeks':\n startDate = new Date(endDate.getTime() - (12 * 7 * 24 * 60 * 60 * 1000));\n break;\n case 'months':\n startDate = new Date(endDate);\n startDate.setMonth(startDate.getMonth() - 12);\n break;\n case 'years':\n startDate = new Date(endDate);\n startDate.setFullYear(startDate.getFullYear() - 5);\n break;\n default:\n startDate = new Date(endDate.getTime() - (30 * 24 * 60 * 60 * 1000));\n }\n \n this.chartOptions.dateStart = startDate;\n this.chart.dateStart = startDate;\n this.chartOptions.dateEnd = endDate;\n this.chart.dateEnd = endDate;\n }\n\n // Save and refresh if changes were made\n if (hasChanges) {\n this._saveSettings();\n this._skipNextPopoverInit = true;\n await this.chart.refresh();\n \n // Reinitialize popover after refresh\n setTimeout(() => {\n if (this.showSettings && this.isMounted()) {\n this._initSettingsPopover();\n }\n }, 150);\n }\n }\n\n /**\n * Handle settings cancel\n * @private\n */\n _handleSettingsCancel() {\n if (this._settingsPopover) {\n this._settingsPopover.hide();\n }\n }\n\n /**\n * Handle refresh button click\n */\n async onActionRefreshChart(event, element) {\n // Add spinning animation\n const icon = element.querySelector('i');\n if (icon) {\n icon.classList.add('spin');\n }\n \n if (this.chart) {\n if (this.account) this.chart.account = this.account;\n await this.chart.refresh();\n }\n \n // Remove spinning animation\n if (icon) {\n icon.classList.remove('spin');\n }\n }\n\n refresh() {\n if (this.chart) {\n if (this.account) this.chart.account = this.account;\n this.chart.refresh();\n }\n }\n\n /**\n * Load settings from localStorage\n * @private\n */\n _loadSettings() {\n if (!this.settingsKey) return;\n\n try {\n const stored = localStorage.getItem(`metrics-chart-${this.settingsKey}`);\n if (stored) {\n const settings = JSON.parse(stored);\n\n if (settings.granularity) {\n this.chartOptions.granularity = settings.granularity;\n }\n if (settings.chartType) {\n this.chartOptions.chartType = settings.chartType;\n }\n if (settings.dateStart !== undefined) {\n this.chartOptions.dateStart = settings.dateStart;\n }\n if (settings.dateEnd !== undefined) {\n this.chartOptions.dateEnd = settings.dateEnd;\n }\n }\n } catch (error) {\n console.error('Failed to load chart settings:', error);\n }\n }\n\n /**\n * Save settings to localStorage\n * @private\n */\n _saveSettings() {\n if (!this.settingsKey) return;\n\n try {\n const settings = {\n granularity: this.chartOptions.granularity,\n chartType: this.chartOptions.chartType,\n dateStart: this.chartOptions.dateStart,\n dateEnd: this.chartOptions.dateEnd\n };\n\n localStorage.setItem(`metrics-chart-${this.settingsKey}`, JSON.stringify(settings));\n } catch (error) {\n console.error('Failed to save chart settings:', error);\n }\n }\n}\n"],"names":[],"mappings":"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"}
|