// ROCA GOLF — v3.0 · Wrapper de Chart.js re-tematizado al design system de la app. // Carga: index.php incluye chart.umd.js (global `Chart`) y chartjs-plugin-datalabels // (global `ChartDataLabels`) antes de este script. // Lee la paleta desde las CSS vars → respeta claro/oscuro automáticamente. function rgTheme() { const cs = getComputedStyle(document.documentElement); const v = (name, fb) => { const x = (cs.getPropertyValue(name) || '').trim(); return x || fb; }; return { green: v('--rg-green-700', '#1a4d2e'), green2: v('--rg-green-600', '#2d6a44'), green3: v('--rg-green-500', '#4a8a63'), gold: v('--rg-gold', '#c9a961'), ink: v('--rg-ink', '#14110d'), muted: v('--rg-muted', '#8a8580'), line: v('--rg-line', '#e0dbd2'), paper: v('--rg-paper', '#ffffff'), over: v('--rg-flag-over', '#b22222'), font: v('--rg-font', 'Inter, system-ui, sans-serif'), mono: v('--rg-font-mono', 'JetBrains Mono, monospace'), }; } // Formatea números como moneda compacta para ejes/labels: $1.2M, $340K, $900 function rgMoneyShort(n) { n = Number(n) || 0; const a = Math.abs(n); if (a >= 1e6) return '$' + (n / 1e6).toFixed(1).replace(/\.0$/, '') + 'M'; if (a >= 1e3) return '$' + Math.round(n / 1e3) + 'K'; return '$' + Math.round(n); } // Opciones base comunes (grid, fuente, tooltip en MXN, leyenda). function rgBaseOptions(t, { money = true, legend = true, stacked = false } = {}) { return { responsive: true, maintainAspectRatio: false, interaction: { mode: 'index', intersect: false }, plugins: { legend: { display: legend, labels: { color: t.muted, font: { family: t.font, size: 11 }, usePointStyle: true, boxWidth: 8 } }, datalabels: { display: false }, tooltip: { backgroundColor: t.ink, titleColor: '#fff', bodyColor: '#fff', borderColor: t.line, borderWidth: 0, padding: 10, cornerRadius: 8, titleFont: { family: t.font, weight: '600' }, bodyFont: { family: t.mono }, callbacks: money ? { label: (c) => `${c.dataset.label ? c.dataset.label + ': ' : ''}$${(Number(c.parsed.y)||0).toLocaleString('es-MX', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}` } : {}, }, }, scales: { x: { stacked, grid: { display: false }, ticks: { color: t.muted, font: { family: t.font, size: 10.5 } }, border: { color: t.line } }, y: { stacked, grid: { color: t.line, drawTicks: false }, border: { display: false }, ticks: { color: t.muted, font: { family: t.mono, size: 10 }, callback: (val) => money ? rgMoneyShort(val) : val } }, }, }; } // Componente: monta un Chart.js sobre un , se destruye en cleanup. function RgChart({ type, data, options = {}, height = 250, useDatalabels = false }) { const canvasRef = useRef(null); const chartRef = useRef(null); useEffect(() => { if (!canvasRef.current || typeof Chart === 'undefined') return; const plugins = (useDatalabels && typeof ChartDataLabels !== 'undefined') ? [ChartDataLabels] : []; chartRef.current = new Chart(canvasRef.current.getContext('2d'), { type, data, options, plugins }); return () => { if (chartRef.current) { chartRef.current.destroy(); chartRef.current = null; } }; }, [type, JSON.stringify(data), JSON.stringify(options), useDatalabels]); if (typeof Chart === 'undefined') { return
No se pudo cargar la librería de gráficas.
; } return
; } Object.assign(window, { RgChart, rgTheme, rgBaseOptions, rgMoneyShort });