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.

javascript
// 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.

javascript
// 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.

javascript
// 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.

javascript
// 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.

javascript
// 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:

javascript
// 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.

javascript
// 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.

javascript
// 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
});
Important: All PDF reports must include the disclaimer: "Results are AI-estimated wellness indicators and are not a medical diagnosis. Always consult a healthcare professional."

Report Delivery Options

javascript
// 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