Overall Average: ${avgSystolic.toFixed(0)} / ${avgDiastolic.toFixed(0)} mmHg
Your average reading falls into the ${avgCategory.name} category.
`;
}
// --- CHARTING LOGIC ---
function createChart() {
const ctx = document.getElementById('bpChart').getContext('2d');
bpChart = new Chart(ctx, {
type: 'line',
data: {
datasets: [
{ label: 'Systolic', data: [], borderColor: '#3b82f6', backgroundColor: '#3b82f6', tension: 0.1, pointRadius: 5 },
{ label: 'Diastolic', data: [], borderColor: '#16a34a', backgroundColor: '#16a34a', tension: 0.1, pointRadius: 5 }
]
},
options: {
responsive: true,
plugins: {
title: { display: true, text: 'Blood Pressure Trend', font: { size: 18 } },
tooltip: {
callbacks: {
title: (context) => new Date(context[0].parsed.x).toLocaleDateString(),
label: (context) => `${context.dataset.label}: ${context.parsed.y} mmHg`
}
}
},
scales: {
x: { type: 'time', time: { unit: 'day' }, title: { display: true, text: 'Date' } },
y: { title: { display: true, text: 'Pressure (mmHg)' }, beginAtZero: false, suggestedMin: 60, suggestedMax: 160 }
}
}
});
updateChart();
}
function updateChart() {
if (!bpChart) return;
bpChart.data.datasets[0].data = bpReadings.map(r => ({ x: r.date.getTime(), y: r.systolic }));
bpChart.data.datasets[1].data = bpReadings.map(r => ({ x: r.date.getTime(), y: r.diastolic }));
bpChart.update();
}
// --- PDF DOWNLOAD LOGIC ---
async function downloadPDF() {
pdfLoader.classList.remove('hidden');
pdfDownloadBtn.disabled = true;
const { jsPDF } = window.jspdf;
const pdfExportContent = document.getElementById('pdf-export-area');
// 1. Prepare Chart Image
const chartImage = bpChart.toBase64Image('image/png', 1.0);
// 2. Prepare Table HTML
let readingsHtml = bpReadings.map(r => {
const category = getBPCategory(r.systolic, r.diastolic);
return `
| ${r.date.toLocaleDateString('en-US')} ${r.date.toLocaleTimeString('en-US', {hour: '2-digit', minute:'2-digit'})} |
${r.systolic} |
${r.diastolic} |
${category.name} |
`;
}).join('');
// 3. Populate export area
pdfExportContent.innerHTML = `
Blood Pressure Report
Generated on: ${new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' })}
Trend Chart
Readings Log
| Date & Time |
Systolic |
Diastolic |
Category |
${readingsHtml}
`;
await new Promise(resolve => setTimeout(resolve, 100));
try {
const canvas = await html2canvas(pdfExportContent, { scale: 2 });
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF({ orientation: "portrait", unit: "pt", format: "a4" });
const pageWidth = pdf.internal.pageSize.getWidth();
const pageHeight = pdf.internal.pageSize.getHeight();
const margin = 40;
const imgProps = pdf.getImageProperties(imgData);
const pdfImageWidth = pageWidth - (margin * 2);
const pdfImageHeight = (imgProps.height * pdfImageWidth) / imgProps.width;
let heightLeft = pdfImageHeight;
let position = margin;
pdf.addImage(imgData, 'PNG', margin, position, pdfImageWidth, pdfImageHeight);
heightLeft -= (pageHeight - 2 * margin);
while (heightLeft > 0) {
position = heightLeft - pdfImageHeight;
pdf.addPage();
pdf.addImage(imgData, 'PNG', margin, position, pdfImageWidth, pdfImageHeight);
heightLeft -= pageHeight;
}
pdf.save(`Blood-Pressure-Report-${new Date().toISOString().slice(0,10)}.pdf`);
} catch (error) {
console.error("Error generating PDF:", error);
alert("Sorry, there was an error creating the PDF.");
} finally {
pdfLoader.classList.add('hidden');
pdfDownloadBtn.disabled = false;
pdfExportContent.innerHTML = '';
}
}
// --- START THE APP ---
initialize();
});