`;
}
const renderChart = (id, type, data, options) => {
const ctx = document.getElementById(id)?.getContext('2d');
if(!ctx) return;
if(charts[id]) charts[id].destroy();
charts[id] = new Chart(ctx, { type, data, options });
};
function renderCharts(data) {
const labels = data.map(r => new Date(r.date));
const chartOptions = { responsive: true, maintainAspectRatio: false };
// Trend Chart
const netProfits = data.map(r => r.revenue - r.cogs - r.marketing_actual - r.hr_actual - r.ops_actual);
renderChart('findata-trend-chart', 'bar', { labels, datasets: [
{ type: 'bar', label: 'Revenue', data: data.map(r => r.revenue), backgroundColor: 'rgba(59, 130, 246, 0.5)'},
{ type: 'line', label: 'Net Profit', data: netProfits, borderColor: '#16a34a', tension: 0.2, yAxisID: 'y1' }
]}, { ...chartOptions, scales: { x:{type:'time', time:{unit:'month'}}, y: {stacked: true}, y1: {position:'right', grid:{drawOnChartArea:false}} }});
// Budget Chart
const budgetData = {
Marketing: data.reduce((s,r) => s + r.marketing_budget, 0),
HR: data.reduce((s,r) => s + r.hr_budget, 0),
Ops: data.reduce((s,r) => s + r.ops_budget, 0),
};
const actualData = {
Marketing: data.reduce((s,r) => s + r.marketing_actual, 0),
HR: data.reduce((s,r) => s + r.hr_actual, 0),
Ops: data.reduce((s,r) => s + r.ops_actual, 0),
};
renderChart('findata-budget-chart', 'bar', {
labels: Object.keys(budgetData), datasets: [
{ label: 'Budget', data: Object.values(budgetData), backgroundColor: '#94a3b8' },
{ label: 'Actual', data: Object.values(actualData), backgroundColor: '#3b82f6' }
]}, { ...chartOptions, indexAxis: 'y' });
// Expense Breakdown
renderChart('findata-expense-chart', 'doughnut', { labels: ['Marketing', 'HR', 'Ops'], datasets: [{ data: Object.values(actualData) }] }, chartOptions);
// Waterfall Chart
const totalRevenue = data.reduce((s, r) => s + r.revenue, 0);
const totalCogs = data.reduce((s, r) => s + r.cogs, 0);
const grossProfit = totalRevenue - totalCogs;
const totalOpEx = data.reduce((s, r) => s + r.marketing_actual + r.hr_actual + r.ops_actual, 0);
const netIncome = grossProfit - totalOpEx;
const waterfallData = {
labels: ["Revenue", "COGS", "Gross Profit", "OpEx", "Net Income"],
datasets: [{
data: [[0, totalRevenue], [totalRevenue, grossProfit], [0, grossProfit], [grossProfit, netIncome], [0, netIncome]],
backgroundColor: ['#22c55e', '#ef4444', '#16a34a', '#ef4444', '#16a34a']
}]
};
renderChart('findata-waterfall-chart', 'bar', waterfallData, { ...chartOptions, indexAxis: 'y', plugins: { legend: { display: false } } });
}
window.findataDownloadPDF = () => {
html2canvas(document.getElementById('findata-pdf-content'), { scale: 2 }).then(canvas => {
const pdf = new jspdf.jsPDF({ orientation: 'landscape', unit: 'pt', format: 'a4' });
pdf.addImage(canvas.toDataURL('image/png'), 'PNG', 40, 40, pdf.internal.pageSize.getWidth() - 80, 0);
pdf.save('Financial_Dashboard.pdf');
});
};
loadSampleData();
});
