File size: 6,556 Bytes
da1a664 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
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 = `
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">${expense.id}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${expense.software}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${expense.invoiceDate}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${expense.cost.toLocaleString('en-SG', {style: 'currency', currency: 'SGD'})}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${expense.renewalDate}</td>
`;
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}%)`;
}
}
}
}
}
});
} |