# 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

Timeline

Year: 2023
Global Coverage: 83%
Total Cases: 10.3M
``` ### 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 ``` ### 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