All-in-One Dashboard

Financial Performance

Data Management

Alerts Overview

Create New Alert

AI Data Visualizer

Upload a CSV file. The AI will analyze its contents and suggest a chart for you.

${new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(netProfit)}

`; this.generateCharts(); }, generateCharts() { // Chart logic simplified for brevity. Assuming full logic from original dashboard is here. const generateChart = (id, type, data, options) => { if(this.charts[id]) this.charts[id].destroy(); this.charts[id] = new Chart(id, { type, data, options }); }; generateChart('finance-monthly-chart', 'bar', {labels:['Apr','May'], datasets:[{label:'Revenue', data:[25000, 40000]},{label:'Expense', data:[30300, 28000]}]}, {responsive:true, maintainAspectRatio: false, scales:{x:{type:'category'}}, plugins:{title:{display:true, text:'Monthly Overview'}}}); generateChart('finance-client-chart', 'doughnut', {labels:['Innovate Corp', 'QuantumLeap'], datasets:[{data:[25000,40000]}]}, {responsive:true, maintainAspectRatio: false, plugins:{title:{display:true, text:'Revenue by Client'}}}); generateChart('finance-expense-chart', 'pie', {labels:['Salaries', 'Software'], datasets:[{data:[28000, 2300]}]}, {responsive:true, maintainAspectRatio: false, plugins:{title:{display:true, text:'Expense Breakdown'}}}); }, setupAccordions() { document.querySelectorAll('.finance-accordion-btn').forEach(button => button.addEventListener('click', function() { const panel = this.nextElementSibling; panel.style.maxHeight = panel.style.maxHeight ? null : panel.scrollHeight + "px"; })); }, downloadPDF() { html2canvas(document.getElementById('finance-dashboard-output')).then(c => { const pdf = new jsPDF(); pdf.addImage(c.toDataURL('image/png'), 'PNG', 10, 10, 190, 0); pdf.save('finance_dashboard.pdf'); }); } }; // ================================================================================= // == ALERT MODULE ================================================================= // ================================================================================= const alertModule = { alerts: [], severityOrder: { "Critical": 1, "High": 2, "Medium": 3, "Low": 4 }, init() { this.alerts = [{id: 1, message: "API Gateway latency high", source: "API", severity: "High", status: "New", timestamp: new Date(Date.now() - 3e5)}, {id: 2, message: "DB CPU at 98%", source: "Database", severity: "Critical", status: "Acknowledged", timestamp: new Date(Date.now() - 1e5)}]; this.renderControls(); this.renderAlerts(); this.setupEventListeners(); }, renderControls() { document.getElementById('alert-kpi-grid').innerHTML = `
0
New
0
Acknowledged
0
Resolved
`; document.getElementById('alert-controls-grid').innerHTML = `
`; document.getElementById('alert-add-grid').innerHTML = `
`; }, renderAlerts() { const sev = document.getElementById('alert-filter-sev').value; const stat = document.getElementById('alert-filter-stat').value; const sort = document.getElementById('alert-sort').value; let filtered = this.alerts.filter(a => (sev==='all' || a.severity===sev) && (stat==='all' || a.status===stat)); filtered.sort((a,b) => sort === 'newest' ? b.timestamp - a.timestamp : this.severityOrder[a.severity] - this.severityOrder[b.severity]); document.getElementById('alerts-list').innerHTML = filtered.map(a => `
${a.message}
${a.source} • ${new Date(a.timestamp).toLocaleTimeString()}
${a.status === 'New' ? '':''}${a.status === 'Acknowledged' ? '':''}
`).join(''); this.updateKPIs(); }, updateKPIs() { document.getElementById('alert-kpi-new').textContent = this.alerts.filter(a=>a.status==='New').length; document.getElementById('alert-kpi-ack').textContent = this.alerts.filter(a=>a.status==='Acknowledged').length; document.getElementById('alert-kpi-res').textContent = this.alerts.filter(a=>a.status==='Resolved').length; }, addAlert() { this.alerts.unshift({id: Date.now(), message: document.getElementById('alert-add-msg').value, source: document.getElementById('alert-add-src').value, severity: document.getElementById('alert-add-sev').value, status: 'New', timestamp: new Date()}); this.renderAlerts(); }, handleAction(e) { const action = e.target.dataset.action; if(!action) return; const id = parseInt(e.target.closest('.alert-card').dataset.id); const index = this.alerts.findIndex(a => a.id === id); if (index > -1) { if (action === 'ack') this.alerts[index].status = 'Acknowledged'; else if (action === 'res') this.alerts[index].status = 'Resolved'; else if (action === 'del') this.alerts.splice(index, 1); this.renderAlerts(); } }, setupEventListeners() { document.getElementById('alert-controls-grid').addEventListener('change', () => this.renderAlerts()); document.getElementById('alerts-list').addEventListener('click', (e) => this.handleAction(e)); }, downloadPDF() { html2canvas(document.getElementById('alerts-dashboard-output')).then(c => { const pdf = new jsPDF(); pdf.addImage(c.toDataURL('image/png'), 'PNG', 10, 10, 190, 0); pdf.save('alerts_dashboard.pdf'); }); } }; // ================================================================================= // == DATA VIZ MODULE ============================================================== // ================================================================================= const vizModule = { parsedData: {}, chartInstance: null, init() { document.getElementById('viz-csv-file').addEventListener('change', (e) => this.handleFileUpload(e)); }, handleFileUpload(event) { Papa.parse(event.target.files[0], { header: true, skipEmptyLines: true, dynamicTyping: true, complete: (res) => { this.parsedData = { data: res.data, headers: res.meta.fields, columnAnalysis: {} }; this.analyzeColumns(); const suggestion = this.generateSuggestion(); this.displaySuggestion(suggestion); document.getElementById('viz-config-container').style.display = 'block'; document.getElementById('viz-chart-panel').style.display = 'none'; }}); }, analyzeColumns() { /* Full analysis logic from original dashboard */ this.parsedData.headers.forEach(h => this.parsedData.columnAnalysis[h] = typeof this.parsedData.data[0][h] === 'number' ? 'N' : 'C'); }, generateSuggestion() { /* Full suggestion logic from original dashboard */ const findCols = t => Object.keys(this.parsedData.columnAnalysis).filter(h => this.parsedData.columnAnalysis[h]===t); if(findCols('C').length >= 1 && findCols('N').length >= 1) return {type:'bar', C: findCols('C')[0], N: findCols('N')[0]}; return null; }, displaySuggestion(suggestion) { const container = document.getElementById('viz-ai-suggestion'); if (suggestion) { container.innerHTML = `

AI Suggestion: We recommend a Bar Chart.

Or, configure manually...

`; document.getElementById('viz-accept-btn').onclick = () => this.generateVisualization(suggestion); document.getElementById('viz-manual-link').onclick = () => this.showManualConfig(true); } else { container.innerHTML = `

AI could not suggest a chart. Please configure manually.

`; this.showManualConfig(true); } container.style.display = 'block'; document.getElementById('viz-manual-config').style.display = 'none'; }, showConfig() { document.getElementById('viz-config-container').style.display = 'block'; document.getElementById('viz-chart-panel').style.display = 'none'; }, showManualConfig(show) { document.getElementById('viz-manual-config').style.display = show ? 'block' : 'none'; if(show) document.getElementById('viz-ai-suggestion').style.display = 'none'; /* Manual config form rendering would be here*/}, generateVisualization(config) { let chartData, title = `Chart of ${config.N} by ${config.C}`; const grouped = this.parsedData.data.reduce((acc, row) => { acc[row[config.C]] = (acc[row[config.C]] || 0) + row[config.N]; return acc; }, {}); chartData = { labels: Object.keys(grouped), datasets: [{ data: Object.values(grouped) }] }; if (this.chartInstance) this.chartInstance.destroy(); this.chartInstance = new Chart('viz-chart', { type: config.type, data: chartData, options: {responsive:true, maintainAspectRatio: false} }); document.getElementById('viz-title').textContent = title; document.getElementById('viz-config-container').style.display = 'none'; document.getElementById('viz-chart-panel').style.display = 'block'; }, downloadPDF() { html2canvas(document.getElementById('viz-output')).then(c => { const pdf = new jsPDF(); pdf.addImage(c.toDataURL('image/png'), 'PNG', 10, 10, 190, 0); pdf.save('data_viz.pdf'); }); } }; // --- Initialize All Modules --- financeModule.init(); alertModule.init(); vizModule.init(); });
Scroll to Top