« Back to History
dashboard.js
|
20260721_154032.php
Initial Bulk Import
Copy Code
// /erp/assets/js/dashboard.js // dashboard charting logic. Requires Chart.js (UMD) loaded before this file runs (we use defer). (function(){ const API = '/erp/api/yarn_top.php'; const fmt = n => Number(n||0).toLocaleString(undefined,{maximumFractionDigits:3}); window._charts = window._charts || {}; function makeBar(id, labels, values, opts = {}) { const ctx = document.getElementById(id); if (!ctx) return; if (window._charts[id]) { try { window._charts[id].destroy(); } catch(e){} } const colors = labels.map((_,i)=>`hsl(${(i*36)%360} 80% 55%)`); const max = Math.max(...values, 0); window._charts[id] = new Chart(ctx, { type: 'bar', data: { labels: labels, datasets: [{ data: values, backgroundColor: colors, borderRadius: opts.borderRadius ?? 6, barPercentage: opts.barPercentage ?? 0.7, categoryPercentage: opts.categoryPercentage ?? 0.9, maxBarThickness: opts.maxBarThickness ?? 72 }]}, options: { maintainAspectRatio: false, plugins: { legend: { display: false }, tooltip: { callbacks: { title: (ctx) => ctx[0] ? ctx[0].label : '', label: (ctx) => fmt(ctx.parsed.y) + ' kg' } }}, scales: { y: { beginAtZero: true, suggestedMax: max ? max * 1.2 : undefined, ticks: { color:'#444', font:{size:11} }, grid:{color:'rgba(0,0,0,0.05)'} }, x: { ticks: { color:'#111', font:{size:11, weight:'600'}, autoSkip:false, maxRotation:60, minRotation:60 }, grid:{display:false} } }, layout: { padding: { top:6, right:6, left:6, bottom:6 } } } }); } async function loadYarnTop(){ try { const resp = await fetch(API + '?stock_type=Yarn&limit=10&show_zero=without_zero', { credentials: 'same-origin' }); const ct = resp.headers.get('Content-Type') || ''; const text = await resp.text(); if (!ct.toLowerCase().includes('application/json')) { console.error('yarn_top non-json response', text.slice(0,1500)); drawFallbackYarn(); return; } const j = JSON.parse(text); if (!j.ok) { console.error('yarn_top ok:false', j); drawFallbackYarn(); return; } const rows = j.rows || []; if (!rows.length) { drawFallbackYarn(); return; } const labels = rows.map(r => ((r.denier||'') + ' ' + (r.color||'')).trim()); const values = rows.map(r => Number(r.cur_weight || 0)); makeBar('yarnChart', labels, values, { maxBarThickness: 72 }); const el = document.getElementById('yarn-total'); if (el) el.textContent = 'Total Weight: ' + fmt(j.tot_weight || 0) + ' kg'; } catch (err) { console.error('yarn_top fetch error', err); drawFallbackYarn(); } } function drawFallbackYarn(){ const labels = ['No data','Demo A','Demo B','Demo C','Demo D','Demo E','Demo F','Demo G','Demo H','Demo I']; const values = [0,900,860,800,720,660,520,480,379,334]; makeBar('yarnChart', labels, values); const el = document.getElementById('yarn-total'); if (el) el.textContent = 'Total Weight: — (fallback)'; } function drawDemoSmall(){ const demoLabels = ['GP','NP','CH','RP','BT','MN']; const demoVals = [420,360,310,270,225,190]; const ids = ['beamChart','sareeChart','pissChart','warperChart','zariChart','metalChart']; ids.forEach(id => makeBar(id, demoLabels, demoVals, { maxBarThickness: 48 })); // doughnut for eff const effEl = document.getElementById('effChart'); if (effEl) { try { if (window._charts['effChart']) window._charts['effChart'].destroy(); } catch(e){} window._charts['effChart'] = new Chart(effEl, { type:'doughnut', data:{ labels:['Eff','Remain'], datasets:[{ data:[68.84,31.16], backgroundColor:['#198754','#ddd'] }] }, options:{ cutout:'75%', plugins:{ legend:{display:false}, tooltip:{enabled:false} } } }); } } // Wait until Chart available (vendor may load via index.php loader) function waitInit(tries=30){ if (window.Chart) { drawDemoSmall(); loadYarnTop(); return; } if (tries<=0) { console.error('Chart.js not available'); drawFallbackYarn(); drawDemoSmall(); return; } setTimeout(()=>waitInit(tries-1), 150); } waitInit(); })();