PDF Reports
The Vitals SDK provides the ability to generate comprehensive PDF reports from measurement sessions, including aggregated vitals summaries, signal quality indicators, and visual representations of the data.
Overview
PDF reports are useful for:
- Sharing measurement results with users
- Archiving wellness data for longitudinal tracking
- Providing documentation for research studies
- Generating patient-facing wellness summaries
- Creating compliance documentation
Window Summary Export
Export detailed window-level summaries showing aggregated vitals over each measurement window.
// Generate window summary report
const reportConfig = {
sessionId: 'session-12345',
includeWindows: true,
windowAggregation: 'average', // 'average', 'median', 'max', 'min'
includeCharts: true
};
const report = await vitals.generateReport(reportConfig);
// Returns:
{
sessionId: 'session-12345',
userId: 'user-67890',
startTime: '2024-02-23T10:30:00Z',
endTime: '2024-02-23T10:31:30Z',
duration: 90, // seconds
windows: [
{
windowId: 1,
startTime: '2024-02-23T10:30:00Z',
endTime: '2024-02-23T10:30:45Z',
duration: 45,
vitals: {
heartRate: { avg: 72.5, min: 68, max: 78 },
hrv: { avg: 45.2, min: 38, max: 52 },
respiratoryRate: { avg: 16.3, min: 14, max: 18 },
stressIndex: { avg: 45, min: 38, max: 55 },
spo2: { avg: 97.2, min: 96, max: 98 }
},
quality: {
signalQuality: 0.78,
usableFrameRatio: 0.85,
windowStatus: 'complete'
}
},
// ... more windows
]
}Aggregated Vitals Summary
Generate overall summaries across all measurement windows.
// Aggregated summary configuration
const summaryConfig = {
sessionId: 'session-12345',
aggregation: {
method: 'weighted-average', // 'average', 'median', 'weighted-average'
weightBy: 'confidence' // 'confidence', 'duration', 'quality'
},
includeStatistics: true,
includeTrends: true
};
const summary = await vitals.generateSummary(summaryConfig);
// Returns:
{
sessionId: 'session-12345',
measurementPeriod: {
start: '2024-02-23T10:30:00Z',
end: '2024-02-23T10:31:30Z',
totalDuration: 90,
numberOfWindows: 2
},
aggregatedVitals: {
heartRate: {
overall: 73.2,
standardDeviation: 4.5,
min: 68,
max: 78,
trend: 'stable',
unit: 'BPM'
},
hrv: {
overall: 46.8,
standardDeviation: 8.2,
min: 38,
max: 52,
trend: 'slightly_increasing',
unit: 'ms'
},
respiratoryRate: {
overall: 16.5,
standardDeviation: 1.8,
min: 14,
max: 18,
trend: 'stable',
unit: 'RPM'
},
stressIndex: {
overall: 47,
standardDeviation: 12,
min: 38,
max: 55,
trend: 'decreasing',
level: 'moderate'
},
spo2: {
overall: 97.0,
standardDeviation: 1.0,
min: 96,
max: 98,
trend: 'stable',
unit: '%'
}
}
}Signal Confidence Indicator
Include visual indicators of signal quality and measurement confidence.
// Confidence indicator configuration
const confidenceConfig = {
showOverallQuality: true,
showPerMetricConfidence: true,
includeQualityChart: true,
qualityScale: 'visual', // 'visual', 'numerical', 'both'
colorScheme: {
excellent: '#10b981', // Green
good: '#3b82f6', // Blue
fair: '#f59e0b', // Orange
poor: '#ef4444' // Red
}
};
// Confidence indicator in report
const confidenceIndicator = {
overallQuality: {
score: 0.78,
level: 'good',
color: '#3b82f6'
},
perMetricConfidence: {
heartRate: { score: 0.85, level: 'good' },
hrv: { score: 0.78, level: 'good' },
respiratoryRate: { score: 0.72, level: 'fair' },
stressIndex: { score: 0.80, level: 'good' },
spo2: { score: 0.65, level: 'fair' }
},
qualityChart: {
// Base64 encoded chart image
image: 'data:image/png;base64,...'
}
};Session ID Reference
Each report includes session metadata and identifiers for traceability.
// Session metadata in report
const sessionMetadata = {
sessionId: 'session-12345',
userId: 'user-67890',
deviceId: 'device-abc',
timestamp: {
start: '2024-02-23T10:30:00Z',
end: '2024-02-23T10:31:30Z',
duration: 90
},
configuration: {
windowDuration: 45,
qualityThresholds: { snr: { minimum: 8 } },
preset: 'balanced'
},
environment: {
browser: 'Chrome 120.0',
os: 'Windows 11',
camera: '720p @ 30fps',
lighting: 'good'
}
};Timestamp Logging
Detailed timestamp information for all measurements and events.
// Timestamp logging configuration
const timestampConfig = {
format: 'ISO8601', // 'ISO8601', 'unix', 'both'
timezone: 'UTC', // 'UTC', 'local', or specific timezone
includeEvents: true, // Log session events
includeMeasurements: true,
precision: 'millisecond'
};
// Example timestamp logging
const timestampLog = {
sessionStart: '2024-02-23T10:30:00.123Z',
firstMeasurement: '2024-02-23T10:30:05.456Z',
windows: [
{
windowId: 1,
start: '2024-02-23T10:30:00.000Z',
end: '2024-02-23T10:30:45.000Z',
measurements: [
{ timestamp: '2024-02-23T10:30:05.456Z', heartRate: 70.2 },
{ timestamp: '2024-02-23T10:30:10.123Z', heartRate: 71.5 },
// ... more measurements
]
}
],
events: [
{ timestamp: '2024-02-23T10:30:00.000Z', event: 'session_started' },
{ timestamp: '2024-02-23T10:30:00.500Z', event: 'camera_connected' },
{ timestamp: '2024-02-23T10:30:01.234Z', event: 'first_measurement' },
{ timestamp: '2024-02-23T10:31:30.789Z', event: 'session_completed' }
]
};Sample Report Layout
A typical PDF report includes the following sections:
// Sample report structure
const reportLayout = {
// Page 1: Header & Overview
header: {
title: 'Wellness Measurement Report',
logo: 'data:image/svg+xml;base64,...',
sessionId: 'session-12345',
date: '2024-02-23'
},
overview: {
duration: '1 minute 30 seconds',
windows: 2,
overallQuality: 'Good (78%)'
},
// Page 2: Aggregated Results
aggregatedResults: {
heartRate: { value: '73.2 BPM', trend: 'Stable' },
hrv: { value: '46.8 ms', trend: 'Slightly Increasing' },
respiratoryRate: { value: '16.5 RPM', trend: 'Stable' },
stressIndex: { value: '47 (Moderate)', trend: 'Decreasing' },
spo2: { value: '97.0%', trend: 'Stable' }
},
// Page 3: Window Details
windowDetails: [
{
window: 1,
duration: '45 seconds',
vitals: {
heartRate: '72.5 BPM',
hrv: '45.2 ms',
respiratoryRate: '16.3 RPM'
},
quality: '78% (Good)'
},
// ... more windows
],
// Page 4: Quality & Metadata
qualityMetrics: {
signalQuality: '78%',
usableFrameRatio: '85%',
averageSNR: '12.5'
},
metadata: {
browser: 'Chrome 120.0',
os: 'Windows 11',
camera: '720p @ 30fps',
lighting: 'Good'
},
// Page 5: Disclaimers
disclaimers: [
'Results are AI-estimated wellness indicators and are not a medical diagnosis.',
'Always consult a healthcare professional for medical advice.',
'This system is not FDA or CE certified.'
]
};Generating PDF Reports
Use the SDK to generate PDF reports programmatically.
// Generate PDF report
async function generatePDFReport(sessionId, options = {}) {
const config = {
sessionId,
format: 'pdf',
includeCharts: options.includeCharts ?? true,
includeRawData: options.includeRawData ?? false,
includeDisclaimers: true,
language: 'en',
theme: 'dark'
};
try {
const report = await vitals.generateReport(config);
// Download PDF
const blob = new Blob([report.data], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = `vitals-report-${sessionId}.pdf`;
link.click();
URL.revokeObjectURL(url);
return { success: true, url };
} catch (error) {
console.error('Report generation failed:', error);
return { success: false, error };
}
}
// Usage
const result = await generatePDFReport('session-12345', {
includeCharts: true
});Custom Report Templates
Create custom report templates for different use cases.
// Custom report template
const customTemplate = {
name: 'clinical-summary',
sections: [
{
type: 'header',
title: 'Clinical Wellness Summary',
includeLogo: true
},
{
type: 'overview',
showDuration: true,
showQuality: true,
showConfidence: true
},
{
type: 'vitals-table',
metrics: ['heartRate', 'hrv', 'respiratoryRate', 'spo2'],
includeTrends: true,
includeRanges: true
},
{
type: 'quality-section',
showSignalQuality: true,
showUsableFrameRatio: true,
showSNR: true
},
{
type: 'charts',
includeHeartRateChart: true,
includeHRVChart: true,
includeQualityChart: true
},
{
type: 'disclaimers',
customMessage: 'This report is for wellness purposes only.'
}
],
styling: {
fontFamily: 'Arial',
primaryColor: '#3b82f6',
accentColor: '#60a5fa',
backgroundColor: '#0a0e17'
}
};
// Apply custom template
const report = await vitals.generateReport({
sessionId: 'session-12345',
template: customTemplate
});Report Delivery Options
// Report delivery options
const deliveryOptions = {
// Direct download
download: {
enabled: true,
filename: `vitals-report-${sessionId}.pdf`
},
// Email delivery
email: {
enabled: true,
recipient: 'user@example.com',
subject: 'Your Wellness Measurement Report',
template: 'email-report-template'
},
// Cloud storage
storage: {
enabled: true,
provider: 's3', // 's3', 'gcs', 'azure'
bucket: 'vitals-reports',
path: `reports/${userId}/${sessionId}.pdf`,
retention: 90 // days
},
// Database storage
database: {
enabled: true,
storeMetadata: true,
storeRawData: false
}
};
// Generate and deliver report
await vitals.generateAndDeliverReport(sessionId, deliveryOptions);Next Steps
- Explore the Admin API for report management
- Check the support page for assistance
- Review Getting Started for basic usage