`;
pdfContentWrapper.appendChild(summarySection);
// Add distribution charts
const chartsSection = document.createElement('div');
chartsSection.classList.add('grid', 'grid-cols-2', 'gap-6', 'mb-6');
chartsSection.innerHTML = `
Power Consumption by Area/Server (KWH)
Cost of Operations by Area/Server ($)
`;
pdfContentWrapper.appendChild(chartsSection);
// Populate PDF charts (re-use logic but target PDF elements)
const totalRecords = operationsRecords.length;
const uptimeCategories = { 'Excellent (99.9%+)': 0, 'Good (99-99.9%)': 0, 'Fair (95-99%)': 0, 'Poor (<95%)': 0 };
operationsRecords.forEach(record => {
if (record.uptimePercentage >= 99.9) { uptimeCategories['Excellent (99.9%+)']++; }
else if (record.uptimePercentage >= 99) { uptimeCategories['Good (99-99.9%)']++; }
else if (record.uptimePercentage >= 95) { uptimeCategories['Fair (95-99%)']++; }
else { uptimeCategories['Poor (<95%)']++; }
});
renderBarChart(chartsSection.querySelector('#pdfUptimeDistributionChart'), uptimeCategories, 'uptime_category');
const powerConsumptionByArea = operationsRecords.reduce((acc, record) => { acc[record.areaOrServerName] = (acc[record.areaOrServerName] || 0) + record.powerConsumptionKWH; return acc; }, {});
renderBarChart(chartsSection.querySelector('#pdfPowerConsumptionByAreaChart'), powerConsumptionByArea, 'kwh');
const pueByAreaSum = {}; const pueByAreaCount = {};
operationsRecords.forEach(record => { pueByAreaSum[record.areaOrServerName] = (pueByAreaSum[record.areaOrServerName] || 0) + record.coolingEfficiencyPUE; pueByAreaCount[record.areaOrServerName] = (pueByAreaCount[record.areaOrServerName] || 0) + 1; });
const avgPUEByArea = {};
for (const area in pueByAreaSum) { if (pueByAreaCount[area] > 0) { avgPUEByArea[area] = pueByAreaSum[area] / pueByAreaCount[area]; } else { avgPUEByArea[area] = 0; } }
renderBarChart(chartsSection.querySelector('#pdfPueDistributionChart'), avgPUEByArea, 'pue');
const incidentsByType = operationsRecords.filter(record => record.incidentCount > 0 && record.majorIncidentType !== 'N/A').reduce((acc, record) => { acc[record.majorIncidentType] = (acc[record.majorIncidentType] || 0) + record.incidentCount; return acc; }, {});
renderBarChart(chartsSection.querySelector('#pdfIncidentsByTypeChart'), incidentsByType, 'count');
const costByArea = operationsRecords.reduce((acc, record) => { acc[record.areaOrServerName] = (acc[record.areaOrServerName] || 0) + record.totalCostOfOperationsUSD; return acc; }, {});
renderBarChart(chartsSection.querySelector('#pdfCostOfOperationsByAreaChart'), costByArea, 'currency');
// Add detailed operations list table
const operationsListSection = document.createElement('div');
operationsListSection.innerHTML = `
Detailed Operations Records
| ID |
Date |
Area/Server Name |
Server Count |
Uptime (%) |
Power (KWH) |
PUE |
Incidents |
Major Incident Type |
Total Cost ($) |
${dashboardOperationsTableBody.innerHTML}
`;
pdfContentWrapper.appendChild(operationsListSection);
// Options for html2pdf
const options = {
margin: 10,
filename: 'Data_Center_Operations_Dashboard.pdf',
image: { type: 'jpeg', quality: 0.98 },
html2canvas: { scale: 2, logging: true, dpi: 192, letterRendering: true },
jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' },
pagebreak: { mode: ['avoid-all', 'css', 'legacy'] }
};
// Generate PDF from the temporary content wrapper
html2pdf().from(pdfContentWrapper).set(options).save();
// Clean up the temporary div (optional, as it's not appended to the DOM)
pdfContentWrapper.remove();
}
/**
* Loads initial sample data for the dashboard.
* Relevant to USA context.
*/
function loadSampleData() {
operationsRecords = [
{ id: 'DC001', date: '2024-07-01', areaOrServerName: 'Main Hall A', serverCount: 100, uptimePercentage: 99.95, powerConsumptionKWH: 5000, coolingEfficiencyPUE: 1.45, incidentCount: 1, majorIncidentType: 'Hardware Failure', totalCostOfOperationsUSD: 12000.00 },
{ id: 'DC002', date: '2024-07-01', areaOrServerName: 'Server Rack 12', serverCount: 20, uptimePercentage: 99.8, powerConsumptionKWH: 800, coolingEfficiencyPUE: 1.60, incidentCount: 0, majorIncidentType: 'N/A', totalCostOfOperationsUSD: 2500.00 },
{ id: 'DC003', date: '2024-07-02', areaOrServerName: 'Cooling Unit 3', serverCount: 0, uptimePercentage: 95.0, powerConsumptionKWH: 1500, coolingEfficiencyPUE: 2.10, incidentCount: 1, majorIncidentType: 'Cooling System Issue', totalCostOfOperationsUSD: 3000.00 },
{ id: 'DC004', date: '2024-07-02', areaOrServerName: 'Main Hall B', serverCount: 80, uptimePercentage: 99.99, powerConsumptionKWH: 4500, coolingEfficiencyPUE: 1.38, incidentCount: 0, majorIncidentType: 'N/A', totalCostOfOperationsUSD: 10000.00 },
{ id: 'DC005', date: '2024-07-03', areaOrServerName: 'Network Core', serverCount: 5, uptimePercentage: 99.0, powerConsumptionKWH: 200, coolingEfficiencyPUE: 1.25, incidentCount: 1, majorIncidentType: 'Network Outage', totalCostOfOperationsUSD: 5000.00 },
{ id: 'DC006', date: '2024-07-03', areaOrServerName: 'Server Rack 25', serverCount: 15, uptimePercentage: 99.5, powerConsumptionKWH: 600, coolingEfficiencyPUE: 1.55, incidentCount: 0, majorIncidentType: 'N/A', totalCostOfOperationsUSD: 1800.00 }
];
}