# Vaccine & Infection Time Series Visualization Specification

## Overview
Generate progressive vaccine and infectious disease visualizations that combine Mapbox GL JS globe projections with time series data, interactive timelines, and embedded charts showing vaccination impact over time (2000-2023).

## Core Requirements

### Data Structure
Each visualization must include:
- **Geographic scope**: 60+ countries with accurate centroids
- **Temporal range**: 2000-2023 (24 years of data)
- **Vaccine metrics**: Coverage rates (dose 1, dose 2, booster if applicable)
- **Disease metrics**: Cases, deaths, incidence rates
- **Contextual data**: Income level, WHO region, population

### Time Series Features
1. **Timeline Slider**
   - HTML5 range input (year 2000-2023)
   - Auto-play functionality with play/pause button
   - Year display showing current selected year
   - Animation speed: 1 second per year
   - Loop option to restart from 2000

2. **Map Filtering**
   - Use `map.setFilter()` to show data for selected year
   - Smooth transitions between years
   - Color/size updates based on that year's metrics

3. **Hover Charts** (Chart.js integration)
   - Display on country hover with 200ms delay
   - Dual-axis line chart:
     - Left axis: Vaccination coverage (%) - line chart
     - Right axis: Cases/deaths - area or bar chart
   - Time range: Full 2000-2023 series
   - Interactive tooltips showing exact values
   - Legend at bottom
   - Responsive sizing (400x250px)

### Data Format Options

**Flattened Approach** (Recommended for Mapbox filtering):
```javascript
{
  "type": "FeatureCollection",
  "features": [
    // One feature per country-year combination
    {
      "type": "Feature",
      "geometry": { "type": "Point", "coordinates": [lng, lat] },
      "properties": {
        "name": "Nigeria",
        "iso3": "NGA",
        "year": 2015,
        "region": "AFRO",
        "income_level": "lower-middle",
        "population": 182202000,
        "coverage_dose1": 52,
        "coverage_dose2": 35,
        "cases": 45000,
        "deaths": 850,
        "incidence_per_100k": 24.7,
        // Time series for chart (stored as JSON strings)
        "years_array": "[2000,2001,...,2023]",
        "coverage1_array": "[30,35,...,68]",
        "coverage2_array": "[20,25,...,54]",
        "cases_array": "[150000,140000,...,15000]",
        "deaths_array": "[2500,2200,...,120]"
      }
    }
  ]
}
```

### Vaccine Types to Explore

Each iteration should pick ONE vaccine/disease combination:

1. **Measles** (MCV1/MCV2)
   - High global coverage (83% MCV1, 74% MCV2)
   - Recent outbreaks despite vaccination
   - 60 million deaths averted 2000-2023

2. **Polio** (OPV/IPV)
   - Near-eradication story
   - 99.9% reduction since 1988
   - Last endemic countries: Afghanistan, Pakistan

3. **HPV** (Human Papillomavirus)
   - Newer vaccine (2006+)
   - Prevents cervical cancer
   - Gender equity issues (girls vs boys)
   - Wide coverage disparities (0-95%)

4. **DTP3** (Diphtheria, Tetanus, Pertussis)
   - WHO zero-dose indicator
   - Proxy for health system strength
   - 84% global coverage (2023)

5. **COVID-19** (mRNA/Viral Vector)
   - Rapid vaccine development (2020-2021)
   - Unprecedented global campaign
   - Equity challenges (COVAX)

6. **Rotavirus**
   - Prevents severe diarrhea
   - High impact in low-income countries
   - 58 countries introduced 2006-2023

7. **Pneumococcal (PCV)**
   - Prevents pneumonia
   - Leading killer of children <5
   - 154 countries introduced

8. **Hepatitis B (HepB)**
   - Birth dose critical
   - 84% global coverage
   - Prevents liver cancer

### Visualization Layers

1. **Base Layer**: Globe with dark theme
   - Atmosphere effects (medical or dark theme)
   - Auto-rotation (pausable)
   - Zoom range: 1.5 (globe) to 6 (continental)

2. **Coverage Layer**: Circle layer
   - Size: Population
   - Color: Vaccination coverage (coverageReverse scale)
   - Opacity: Data availability (higher for complete data)
   - Stroke: White, zoom-responsive

3. **Outbreak Layer**: Conditional circles (optional)
   - Filter: Only show where cases > threshold
   - Color: Red/orange (outbreak severity)
   - Pulse animation for major outbreaks

### Chart.js Configuration

```javascript
{
  type: 'line',
  data: {
    labels: years, // [2000, 2001, ..., 2023]
    datasets: [
      {
        label: 'Vaccination Coverage (%)',
        data: coverageData,
        borderColor: 'rgb(75, 192, 192)',
        backgroundColor: 'rgba(75, 192, 192, 0.1)',
        yAxisID: 'y',
        tension: 0.3,
        fill: true
      },
      {
        label: 'Cases',
        data: casesData,
        borderColor: 'rgb(255, 99, 132)',
        backgroundColor: 'rgba(255, 99, 132, 0.3)',
        yAxisID: 'y1',
        type: 'bar',
        opacity: 0.6
      }
    ]
  },
  options: {
    responsive: true,
    maintainAspectRatio: true,
    interaction: {
      mode: 'index',
      intersect: false
    },
    scales: {
      y: {
        type: 'linear',
        position: 'left',
        title: { display: true, text: 'Coverage (%)' },
        min: 0,
        max: 100,
        ticks: { color: '#9ca3af' }
      },
      y1: {
        type: 'linear',
        position: 'right',
        title: { display: true, text: 'Cases' },
        grid: { drawOnChartArea: false },
        ticks: { color: '#9ca3af' }
      }
    },
    plugins: {
      title: {
        display: true,
        text: 'Vaccination Impact Over Time',
        color: '#e5e7eb'
      },
      legend: {
        position: 'bottom',
        labels: { color: '#e5e7eb' }
      }
    }
  }
}
```

### Timeline Control UI

```html
<div class="timeline-control">
  <div class="header">
    <h3>Timeline</h3>
    <div class="year-display">
      Year: <span id="current-year">2023</span>
    </div>
  </div>

  <input id="year-slider"
         type="range"
         min="0"
         max="23"
         step="1"
         value="23">

  <div class="controls">
    <button id="play-pause" class="btn">▶️ Play</button>
    <button id="reset" class="btn">Reset</button>
    <label>
      <input type="checkbox" id="loop-checkbox" checked> Loop
    </label>
  </div>

  <div class="stats">
    <div class="stat">
      <span class="label">Global Coverage:</span>
      <span id="global-coverage">83%</span>
    </div>
    <div class="stat">
      <span class="label">Total Cases:</span>
      <span id="total-cases">10.3M</span>
    </div>
  </div>
</div>
```

### Styling Requirements

```css
.timeline-control {
  position: absolute;
  bottom: 30px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(10, 14, 26, 0.95);
  padding: 20px 30px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(10px);
  min-width: 500px;
  z-index: 1000;
}

.year-display {
  font-size: 24px;
  font-weight: bold;
  color: #60a5fa;
  text-align: center;
  margin-bottom: 15px;
}

#year-slider {
  width: 100%;
  height: 8px;
  background: linear-gradient(90deg, #ef4444 0%, #f59e0b 50%, #10b981 100%);
  border-radius: 5px;
  outline: none;
  -webkit-appearance: none;
}

#year-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 20px;
  height: 20px;
  background: #60a5fa;
  border-radius: 50%;
  cursor: pointer;
  box-shadow: 0 0 10px rgba(96, 165, 250, 0.5);
}

.controls {
  display: flex;
  gap: 10px;
  margin-top: 15px;
  justify-content: center;
  align-items: center;
}

.btn {
  padding: 8px 16px;
  background: rgba(96, 165, 250, 0.2);
  border: 1px solid #60a5fa;
  color: #60a5fa;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
  transition: all 0.2s;
}

.btn:hover {
  background: rgba(96, 165, 250, 0.3);
  box-shadow: 0 0 15px rgba(96, 165, 250, 0.3);
}

/* Chart popup styling */
.measles-popup {
  padding: 15px;
  background: rgba(10, 14, 26, 0.98);
  border-radius: 8px;
  min-width: 420px;
}

.measles-popup h3 {
  margin: 0 0 15px 0;
  color: #e5e7eb;
  font-size: 18px;
  border-bottom: 2px solid rgba(96, 165, 250, 0.5);
  padding-bottom: 10px;
}

.measles-popup canvas {
  border-radius: 4px;
}
```

### Progressive Learning Path

**Iteration 1 - Foundation:**
- Basic timeline slider with manual control
- Static map showing current year data
- Simple hover popup with text data only
- Learn: Mapbox filtering, basic timeline UI

**Iteration 2 - Interactivity:**
- Auto-play functionality with play/pause
- Chart.js integration showing simple line chart
- Smooth transitions between years
- Learn: Chart.js basics, animation timing, DOM manipulation

**Iteration 3 - Advanced:**
- Dual-axis charts (coverage vs cases)
- Outbreak pulse animations
- Global statistics updating in real-time
- Advanced Chart.js options (themes, interactions)
- Optimized performance (chart caching, delayed popups)
- Learn: Complex Chart.js configurations, performance optimization

## Technical Requirements

### Dependencies
```html
<!-- Mapbox GL JS v3.0.1 -->
<script src='https://api.mapbox.com/mapbox-gl-js/v3.0.1/mapbox-gl.js'></script>
<link href='https://api.mapbox.com/mapbox-gl-js/v3.0.1/mapbox-gl.css' rel='stylesheet' />

<!-- Chart.js v4.4.1 -->
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js"></script>
```

### Shared Architecture
Use existing shared modules:
```javascript
import { MAPBOX_CONFIG } from '../../shared/mapbox-config.js';
import { LayerFactory, COLOR_SCALES } from '../../shared/layer-factory.js';
```

### Data Generation Pattern
Create new data generator function:
```javascript
function generateTimeSeriesData(vaccineType, yearRange) {
  const countries = [...]; // 60+ countries
  const features = [];

  for (const country of countries) {
    for (let year = yearRange.start; year <= yearRange.end; year++) {
      features.push({
        type: "Feature",
        geometry: { type: "Point", coordinates: country.centroid },
        properties: {
          name: country.name,
          year: year,
          coverage_dose1: generateCoverageForYear(country, year),
          cases: generateCasesForYear(country, year),
          // Time series arrays (same for all years of same country)
          years_array: JSON.stringify([2000, ..., 2023]),
          coverage1_array: JSON.stringify([...coverage values]),
          cases_array: JSON.stringify([...case values])
        }
      });
    }
  }

  return { type: "FeatureCollection", features };
}
```

### Performance Optimizations

1. **Chart Instance Management**
```javascript
let activeChart = null;
let chartCounter = 0;

function createPopupChart(feature) {
  // Destroy previous chart
  if (activeChart) {
    activeChart.destroy();
  }

  const canvasId = `chart-${chartCounter++}`;
  // ... create popup and chart
  activeChart = new Chart(ctx, config);
}
```

2. **Popup Delay** (Prevent flickering)
```javascript
let popupTimeout;

map.on('mouseenter', 'layer', (e) => {
  popupTimeout = setTimeout(() => {
    createPopupChart(e.features[0]);
  }, 200); // 200ms delay
});

map.on('mouseleave', 'layer', () => {
  clearTimeout(popupTimeout);
});
```

3. **Data Filtering** (Performance)
```javascript
// Pre-filter features by year before adding to source
const currentYearFeatures = allFeatures.filter(f => f.properties.year === currentYear);
map.getSource('vaccine-data').setData({
  type: "FeatureCollection",
  features: currentYearFeatures
});
```

## Output Structure

```
vaccine_timeseries_[N]/
├── index.html                 # Main page with timeline UI
├── src/
│   ├── index.js              # Map initialization, timeline logic
│   ├── chart-handler.js      # Chart.js popup management
│   └── data/
│       └── timeseries-data.js # Time series GeoJSON data
├── README.md                 # Analysis and insights
└── CLAUDE.md                 # Technical documentation
```

## Naming Convention

**Folder**: `vaccine_timeseries_[number]_[vaccine]`
- Examples: `vaccine_timeseries_1_measles`, `vaccine_timeseries_2_polio`

**Title Pattern**: `[Vaccine Name] Vaccination Impact Timeline (2000-2023)`

## Quality Standards

### Data Quality
- ✅ Realistic trends (improving coverage over time, except COVID dip 2020-2021)
- ✅ Inverse correlation (higher coverage → fewer cases)
- ✅ Regional variations (AFRO lower, EURO higher)
- ✅ Income-based disparities
- ✅ All null values handled with coalesce

### Code Quality
- ✅ Shared module imports
- ✅ Chart instance cleanup
- ✅ Error handling for missing data
- ✅ Accessibility (ARIA labels on controls)
- ✅ Responsive design (timeline scales on mobile)

### User Experience
- ✅ Smooth animations (no jank)
- ✅ Clear visual feedback (year changes)
- ✅ Intuitive controls (play/pause, reset)
- ✅ Fast load time (<3s)
- ✅ Works offline after initial load

## Documentation Requirements

### README.md Must Include
1. **Key Findings**: 3-5 insights from the data
2. **Data Sources**: WHO, UNICEF, CDC references
3. **Temporal Trends**: Coverage and disease burden changes
4. **Regional Disparities**: AFRO vs EURO vs WPRO comparisons
5. **Policy Implications**: What the data shows about vaccine impact

### CLAUDE.md Must Include
1. **Setup Instructions**: How to run locally
2. **Timeline Controls**: How to use the slider
3. **Chart Interactions**: How to view country-level trends
4. **Data Structure**: Explanation of time series format
5. **Customization Guide**: How to add new vaccines or years

## Web Learning Strategy

Each iteration should learn from these progressively:

**Iteration 1**:
- Official Mapbox timeline example
- Basic Chart.js documentation
- WHO data portal overview

**Iteration 2**:
- Advanced Chart.js configurations (dual-axis)
- Stack Overflow popup chart patterns
- Timeline animation best practices

**Iteration 3**:
- Performance optimization techniques
- Advanced Mapbox expressions
- Data visualization best practices for health data

## Success Criteria

A successful visualization will:
1. ✅ Show clear correlation between vaccination and disease reduction
2. ✅ Enable exploration of any country's 24-year history
3. ✅ Provide smooth, intuitive timeline navigation
4. ✅ Display rich, readable charts on hover
5. ✅ Render correctly on all modern browsers
6. ✅ Tell a compelling story about vaccine impact
7. ✅ Use accurate, realistic data patterns
8. ✅ Perform smoothly (60fps animations)

## Vaccine-Specific Guidance

### Measles
- Coverage threshold: 95% for herd immunity
- Highlight 2019-2023 outbreak resurgence
- Show impact of COVID-19 disruptions (2020-2021 dip)

### Polio
- Focus on eradication progress (endemic → zero)
- Wild poliovirus vs vaccine-derived distinction
- Celebrate last case milestones

### HPV
- Recent introduction (most countries 2006+)
- Gender policy variations (girls-only vs both)
- Cancer prevention lag (10-20 years)

### DTP3
- Zero-dose children as equity indicator
- Consistent high coverage (plateau effect)
- Health system strength proxy

### COVID-19
- Unprecedented scale and speed
- Booster dose complexity (3rd, 4th doses)
- Equity challenges (high-income vs low-income)

---

**Version**: 1.0
**Created**: 2025-01-08
**Purpose**: Generate interactive vaccine impact visualizations with time series data and embedded analytics
