document.addEventListener('DOMContentLoaded', function() { // Expense data const expenses = [ { id: 1, software: 'CSI [Etabs, SAFE, SAP2000]', invoiceDate: 'July 9, 2020', cost: 12176.60, renewalDate: 'July 9, 2020' }, { id: 2, software: 'Plaxis', invoiceDate: 'September 1, 2020', cost: 5361.00, renewalDate: 'September 1, 2020' }, { id: 3, software: 'Tekla', invoiceDate: 'December 1, 2020', cost: 13503.40, renewalDate: 'December 1, 2020' }, { id: 4, software: 'CSI [Etabs, SAFE, SAP2000]', invoiceDate: 'July 9, 2021', cost: 11877.00, renewalDate: 'July 9, 2021' }, { id: 5, software: 'Plaxis', invoiceDate: 'September 1, 2021', cost: 5391.00, renewalDate: 'September 1, 2021' }, { id: 6, software: 'Tekla', invoiceDate: 'December 1, 2021', cost: 6868.60, renewalDate: 'December 1, 2021' }, { id: 7, software: 'CSI [Etabs, SAFE, SAP2000]', invoiceDate: 'August 10, 2022', cost: 13482.00, renewalDate: 'August 10, 2022' }, { id: 8, software: 'Plaxis', invoiceDate: 'September 5, 2022', cost: 5796.00, renewalDate: 'September 5, 2022' }, { id: 9, software: 'Tekla', invoiceDate: 'October 18, 2022', cost: 7130.37, renewalDate: 'December 1, 2022' }, { id: 10, software: 'CSI [Etabs, SAFE, SAP2000]', invoiceDate: 'July 4, 2023', cost: 11664.00, renewalDate: 'July 4, 2023' }, { id: 11, software: 'Plaxis', invoiceDate: 'September 21, 2023', cost: 6201.00, renewalDate: 'September 5, 2023' }, { id: 12, software: 'Tekla', invoiceDate: 'October 18, 2023', cost: 7792.20, renewalDate: 'December 1, 2023' }, { id: 13, software: 'CSI [Etabs, SAFE, SAP2000]', invoiceDate: 'July 4, 2024', cost: 11336.00, renewalDate: 'July 4, 2024' }, { id: 14, software: 'Plaxis', invoiceDate: 'September 18, 2024', cost: 7003.40, renewalDate: '18/9/2024' }, { id: 15, software: 'Tekla', invoiceDate: 'October 10, 2024', cost: 8316.00, renewalDate: '10/10/2024' }, { id: 16, software: 'CSI [Etabs, SAFE, SAP2000]', invoiceDate: 'May 22, 2025', cost: 11336.00, renewalDate: 'May 22, 2025' }, { id: 17, software: 'Unreal Engine', invoiceDate: '6-Sept-24', cost: 2727.18, renewalDate: '6-Sept-24' }, { id: 18, software: 'Plaxis', invoiceDate: 'September 18, 2025', cost: 7752.84, renewalDate: '18/9/2025' } ]; // Populate table const tableBody = document.getElementById('expenseTable'); expenses.forEach(expense => { const row = document.createElement('tr'); row.className = 'hover:bg-gray-50 fade-in'; row.innerHTML = ` ${expense.id} ${expense.software} ${expense.invoiceDate} ${expense.cost.toLocaleString('en-SG', {style: 'currency', currency: 'SGD'})} ${expense.renewalDate} `; tableBody.appendChild(row); }); // Prepare data for charts const years = ['2020', '2021', '2022', '2023', '2024', '2025']; const annualCosts = years.map(year => { return expenses .filter(expense => expense.renewalDate.includes(year)) .reduce((sum, expense) => sum + expense.cost, 0); }); const softwareNames = [...new Set(expenses.map(expense => expense.software))]; const softwareCosts = softwareNames.map(software => { return expenses .filter(expense => expense.software === software) .reduce((sum, expense) => sum + expense.cost, 0); }); // Create charts createAnnualChart(years, annualCosts); createSoftwareChart(softwareNames, softwareCosts); }); function createAnnualChart(years, costs) { const ctx = document.getElementById('annualChart').getContext('2d'); new Chart(ctx, { type: 'bar', data: { labels: years, datasets: [{ label: 'Annual Software Costs (SGD)', data: costs, backgroundColor: '#3B82F6', borderColor: '#2563EB', borderWidth: 1 }] }, options: { responsive: true, plugins: { legend: { position: 'top', }, tooltip: { callbacks: { label: function(context) { return context.parsed.y.toLocaleString('en-SG', {style: 'currency', currency: 'SGD'}); } } } }, scales: { y: { beginAtZero: true, ticks: { callback: function(value) { return value.toLocaleString('en-SG', {style: 'currency', currency: 'SGD'}); } } } } } }); } function createSoftwareChart(softwareNames, costs) { const ctx = document.getElementById('softwareChart').getContext('2d'); new Chart(ctx, { type: 'pie', data: { labels: softwareNames, datasets: [{ data: costs, backgroundColor: [ '#3B82F6', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6' ], borderWidth: 1 }] }, options: { responsive: true, plugins: { legend: { position: 'right', }, tooltip: { callbacks: { label: function(context) { const label = context.label || ''; const value = context.raw || 0; const total = context.dataset.data.reduce((a, b) => a + b, 0); const percentage = Math.round((value / total) * 100); return `${label}: ${value.toLocaleString('en-SG', {style: 'currency', currency: 'SGD'})} (${percentage}%)`; } } } } } }); }