// Chart.js Glassmorphic Configuration import { Chart, registerables } from 'chart.js'; Chart.register(...registerables); // Color scheme constants export const COLORS = { revenue: { primary: 'rgba(52, 211, 153, 0.8)', secondary: 'rgba(52, 211, 153, 0.2)', gradient: ['rgba(52, 211, 153, 0.8)', 'rgba(52, 211, 153, 0.2)'] }, profit: { primary: 'rgba(168, 85, 247, 0.8)', secondary: 'rgba(168, 85, 247, 0.2)', gradient: ['rgba(168, 85, 247, 0.8)', 'rgba(168, 85, 247, 0.2)'] }, orders: { primary: 'rgba(59, 130, 246, 0.8)', secondary: 'rgba(59, 130, 246, 0.2)', gradient: ['rgba(59, 130, 246, 0.8)', 'rgba(59, 130, 246, 0.2)'] }, customers: { primary: 'rgba(251, 146, 60, 0.8)', secondary: 'rgba(251, 146, 60, 0.2)', gradient: ['rgba(251, 146, 60, 0.8)', 'rgba(251, 146, 60, 0.2)'] }, text: { primary: 'rgba(255, 255, 255, 0.9)', secondary: 'rgba(255, 255, 255, 0.6)', muted: 'rgba(255, 255, 255, 0.4)' }, grid: 'rgba(255, 255, 255, 0.1)', border: 'rgba(255, 255, 255, 0.2)' }; // Base glassmorphic chart configuration export const baseChartConfig = { responsive: true, maintainAspectRatio: false, interaction: { intersect: false, mode: 'index' }, plugins: { legend: { display: true, position: 'top', labels: { color: COLORS.text.primary, font: { size: 12, weight: '500' }, padding: 20, usePointStyle: true, pointStyle: 'circle' } }, tooltip: { enabled: true, backgroundColor: 'rgba(0, 0, 0, 0.8)', backdropFilter: 'blur(10px)', titleColor: COLORS.text.primary, bodyColor: COLORS.text.secondary, borderColor: COLORS.border, borderWidth: 1, cornerRadius: 12, padding: 12, displayColors: true, callbacks: { title: function(context) { return context[0].label; }, label: function(context) { const label = context.dataset.label || ''; const value = context.parsed.y; if (label.toLowerCase().includes('revenue') || label.toLowerCase().includes('profit')) { return `${label}: ฿${value.toLocaleString()}`; } else if (label.toLowerCase().includes('percentage') || label.toLowerCase().includes('margin')) { return `${label}: ${value.toFixed(2)}%`; } return `${label}: ${value.toLocaleString()}`; } } } }, scales: { x: { grid: { color: COLORS.grid, borderColor: COLORS.border, drawBorder: false }, ticks: { color: COLORS.text.secondary, font: { size: 11 }, maxTicksLimit: 12 } }, y: { grid: { color: COLORS.grid, borderColor: COLORS.border, drawBorder: false }, ticks: { color: COLORS.text.secondary, font: { size: 11 }, callback: function(value) { if (this.chart.config.type === 'line' && this.chart.data.datasets[0].label?.toLowerCase().includes('revenue')) { return '฿' + value.toLocaleString(); } return value.toLocaleString(); } } } }, elements: { point: { radius: 4, hoverRadius: 6, borderWidth: 2, hoverBorderWidth: 3 }, line: { borderWidth: 3, tension: 0.4 }, bar: { borderRadius: 6, borderSkipped: false } }, animation: { duration: 1000, easing: 'easeInOutQuart' } }; // Create gradient for chart backgrounds export function createGradient(ctx, colorArray, direction = 'vertical') { const gradient = direction === 'vertical' ? ctx.createLinearGradient(0, 0, 0, ctx.canvas.height) : ctx.createLinearGradient(0, 0, ctx.canvas.width, 0); gradient.addColorStop(0, colorArray[0]); gradient.addColorStop(1, colorArray[1]); return gradient; } // Line chart configuration export function createLineChartConfig(labels, datasets, options = {}) { return { type: 'line', data: { labels, datasets: datasets.map(dataset => ({ ...dataset, fill: true, backgroundColor: function(context) { const chart = context.chart; const {ctx} = chart; return createGradient(ctx, dataset.gradientColors || COLORS.revenue.gradient); }, borderColor: dataset.borderColor || COLORS.revenue.primary, pointBackgroundColor: dataset.borderColor || COLORS.revenue.primary, pointBorderColor: '#ffffff', pointHoverBackgroundColor: '#ffffff', pointHoverBorderColor: dataset.borderColor || COLORS.revenue.primary })) }, options: { ...baseChartConfig, ...options } }; } // Bar chart configuration export function createBarChartConfig(labels, datasets, options = {}) { return { type: 'bar', data: { labels, datasets: datasets.map(dataset => ({ ...dataset, backgroundColor: function(context) { const chart = context.chart; const {ctx} = chart; return createGradient(ctx, dataset.gradientColors || COLORS.orders.gradient); }, borderColor: dataset.borderColor || COLORS.orders.primary, borderWidth: 1 })) }, options: { ...baseChartConfig, ...options } }; } // Doughnut chart configuration export function createDoughnutChartConfig(labels, data, options = {}) { const backgroundColors = [ COLORS.revenue.primary, COLORS.profit.primary, COLORS.orders.primary, COLORS.customers.primary, 'rgba(236, 72, 153, 0.8)', // Pink 'rgba(34, 197, 94, 0.8)', // Green 'rgba(239, 68, 68, 0.8)', // Red 'rgba(245, 158, 11, 0.8)', // Amber 'rgba(139, 92, 246, 0.8)', // Violet 'rgba(6, 182, 212, 0.8)' // Cyan ]; return { type: 'doughnut', data: { labels, datasets: [{ data, backgroundColor: backgroundColors.slice(0, data.length), borderColor: backgroundColors.slice(0, data.length).map(color => color.replace('0.8', '1')), borderWidth: 2, hoverBorderWidth: 3 }] }, options: { ...baseChartConfig, cutout: '60%', plugins: { ...baseChartConfig.plugins, legend: { ...baseChartConfig.plugins.legend, position: 'right' } }, ...options } }; } // Mixed chart configuration (Line + Bar) export function createMixedChartConfig(labels, datasets, options = {}) { return { type: 'bar', data: { labels, datasets: datasets.map(dataset => ({ ...dataset, backgroundColor: dataset.type === 'line' ? 'transparent' : function(context) { const chart = context.chart; const {ctx} = chart; return createGradient(ctx, dataset.gradientColors || COLORS.customers.gradient); }, borderColor: dataset.borderColor || COLORS.customers.primary, borderWidth: dataset.type === 'line' ? 3 : 1, yAxisID: dataset.yAxisID || 'y' })) }, options: { ...baseChartConfig, scales: { ...baseChartConfig.scales, y1: { type: 'linear', display: true, position: 'right', grid: { drawOnChartArea: false, color: COLORS.grid }, ticks: { color: COLORS.text.secondary, font: { size: 11 } } } }, ...options } }; } // Animation helpers export const chartAnimations = { fadeIn: { duration: 800, easing: 'easeOutQuart' }, slideUp: { duration: 1000, easing: 'easeOutBack' }, bounce: { duration: 1200, easing: 'easeOutBounce' } }; // Make functions globally available for inline scripts window.COLORS = COLORS; window.createLineChartConfig = createLineChartConfig; window.createDoughnutChartConfig = createDoughnutChartConfig; window.createMixedChartConfig = createMixedChartConfig; window.chartAnimations = chartAnimations;