Vatsal12345678's picture
S. No. Software Date of Invoice Cost (Including Tax) Year
da1a664 verified
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}%)`;
}
}
}
}
}
});
}