Matrices generated for ${numAssets} assets using ${N} data points per asset.
`;
document.getElementById('ccmg-results-display').style.display = 'block';
if (downloadPdfButton) downloadPdfButton.disabled = false;
ccmg_openTab('ccmg-results-tab', document.getElementById('ccmg-tab-btn-results'));
}
function ccmg_displayMatrixTable(containerId, labels, matrix, precision = 4) {
const container = document.getElementById(containerId);
if (!container) return;
let tableHTML = '
| | ';
labels.forEach(label => {
tableHTML += `${label} | `;
});
tableHTML += '
';
matrix.forEach((row, i) => {
tableHTML += `| ${labels[i]} | `;
row.forEach(cellValue => {
tableHTML += `${isNaN(cellValue) ? "N/A" : cellValue.toFixed(precision)} | `;
});
tableHTML += '
';
});
tableHTML += '
';
container.innerHTML = tableHTML;
}
async function ccmg_generatePdf() {
const downloadButton = document.getElementById('ccmg-btn-download-pdf');
if(downloadButton) downloadButton.disabled = true;
if (!window.jspdf || !window.jspdf.jsPDF || !(new window.jspdf.jsPDF()).autoTable) {
alert("PDF generation libraries not fully loaded. Please ensure you are connected to the internet.");
if(downloadButton) downloadButton.disabled = false; return;
}
if (!ccmg_calculationResults) {
alert("No matrix results to download. Please generate matrices first.");
if(downloadButton) downloadButton.disabled = false; return;
}
const { jsPDF } = window.jspdf;
const doc = new jsPDF();
let currentY = 20;
const pageW = doc.internal.pageSize.getWidth();
const margin = 14;
const R = ccmg_calculationResults;
doc.setFontSize(18);
doc.setTextColor(getComputedStyle(document.documentElement).getPropertyValue('--ccmg-primary-color').trim());
doc.text("Correlation & Covariance Matrix Report", pageW / 2, currentY, { align: 'center' });
currentY += 15;
doc.setFontSize(12);
doc.setTextColor(getComputedStyle(document.documentElement).getPropertyValue('--ccmg-text-color').trim());
doc.text(`Analysis for ${R.assetLabels.length} assets, using ${R.numDataPoints} data points per asset.`, margin, currentY);
currentY += 7;
doc.text("Asset Labels: " + R.assetLabels.join(", "), margin, currentY);
currentY += 15;
function formatMatrixForPdf(matrix, labels, precision) {
const head = [[' '].concat(labels)];
const body = matrix.map((row, i) => {
return [labels[i]].concat(row.map(cell => isNaN(cell) ? "N/A" : cell.toFixed(precision)));
});
return { head, body };
}
// Covariance Matrix
doc.setFontSize(14);
doc.text("Covariance Matrix:", margin, currentY);
currentY += 8;
const covPdfTable = formatMatrixForPdf(R.covarianceMatrix, R.assetLabels, 4);
doc.autoTable({
startY: currentY, head: covPdfTable.head, body: covPdfTable.body,
theme: 'grid',
headStyles: { fillColor: [234,242,248], textColor: [52,152,219], fontStyle: 'bold' },
styles: { font: 'helvetica', fontSize: R.assetLabels.length > 2 ? 8 : 9 }, // Smaller font for larger matrices
columnStyles: { 0: { fontStyle: 'bold' } }
});
currentY = doc.lastAutoTable.finalY + 15;
// Check for page break
if (currentY > doc.internal.pageSize.getHeight() - 80) { // Approximate space needed for next table + note
doc.addPage();
currentY = margin + 10;
}
// Correlation Matrix
doc.setFontSize(14);
doc.text("Correlation Matrix:", margin, currentY);
currentY += 8;
const corrPdfTable = formatMatrixForPdf(R.correlationMatrix, R.assetLabels, 4);
doc.autoTable({
startY: currentY, head: corrPdfTable.head, body: corrPdfTable.body,
theme: 'grid',
headStyles: { fillColor: [234,242,248], textColor: [52,152,219], fontStyle: 'bold' },
styles: { font: 'helvetica', fontSize: R.assetLabels.length > 2 ? 8 : 9 },
columnStyles: { 0: { fontStyle: 'bold' } }
});
currentY = doc.lastAutoTable.finalY + 10;
doc.setFontSize(8);
doc.setTextColor(127, 140, 141);
doc.text("Note: Calculations use sample covariance/variance (N-1 denominator). Returns are assumed to be percentages.", margin, doc.internal.pageSize.getHeight() - 15, {maxWidth: pageW - 2*margin});
const toolName = "CorrCovMatrixGenerator";
const date = new Date().toISOString().slice(0,10);
doc.save(`${toolName}_Report_${date}.pdf`);
if(downloadButton) downloadButton.disabled = false;
}
document.addEventListener('DOMContentLoaded', function() {
try {
ccmg_openTab('ccmg-input-tab', document.getElementById('ccmg-tab-btn-input'));
document.getElementById('ccmg-results-display').style.display = 'none';
const downloadPdfButton = document.getElementById('ccmg-btn-download-pdf');
if(downloadPdfButton) downloadPdfButton.disabled = true;
ccmg_clearError('input');
ccmg_clearError('results');
} catch(e) {
console.error("Initialization error for Matrix Generator:", e);
const container = document.querySelector('.ccmg-container');
if(container) container.innerHTML = "
Tool failed to initialize. Please check console.
";
}
});