15 KiB
CLAUDE.md - HPV Vaccine Globe Visualization Setup Guide
Quick Start
Prerequisites
- Modern web browser with WebGL support
- No build tools or dependencies required
- All assets loaded from CDN
Running Locally
-
Navigate to the visualization directory:
cd mapbox_test/mapbox_globe_14 -
Start a local web server (required for loading external scripts):
# Option 1: Python 3 python3 -m http.server 8000 # Option 2: Python 2 python -m SimpleHTTPServer 8000 # Option 3: Node.js npx http-server -p 8000 # Option 4: PHP php -S localhost:8000 -
Open in browser:
- Navigate to
http://localhost:8000 - The globe will load with auto-rotation enabled
- Interaction pauses rotation automatically
- Navigate to
File Structure
mapbox_globe_14/
├── index.html # Main HTML with UI and styling
├── src/
│ ├── index.js # Mapbox logic and interactions
│ └── data/
│ └── data.js # HPV vaccine and cancer data (146 countries)
├── README.md # User documentation and insights
└── CLAUDE.md # This file (setup guide)
Mapbox Access Token
Current token: pk.eyJ1IjoibGludXhpc2Nvb2wiLCJhIjoiY2w3ajM1MnliMDV4NDNvb2J5c3V5dzRxZyJ9.wJukH5hVSiO74GM_VSJR3Q
This is a public token with restricted permissions. If you need to replace it:
- Get a free token at mapbox.com/signup
- Edit
src/index.js - Replace the token on line 6:
mapboxgl.accessToken = 'YOUR_TOKEN_HERE';
Data Overview
Dataset: 146 Countries
The visualization includes comprehensive HPV vaccination and cervical cancer data for:
- High-income: 52 countries
- Upper-middle income: 48 countries
- Lower-middle income: 38 countries
- Low-income: 8 countries
Data Properties
Each country feature includes:
{
"name": "Country name",
"hpv_coverage_2024": 75, // % of target population vaccinated
"vaccine_program_started": 2008, // Year program began (null if no program)
"target_age": "9-14", // Typical vaccination age range
"cervical_cancer_incidence": 13.1, // Cases per 100,000 women
"cervical_cancer_mortality": 7.3, // Deaths per 100,000 women
"income_level": "high", // Economic classification
"lives_saved_projected": 8500, // Lives savable with full coverage
"gender_policy": "girls-only", // Vaccination policy
"annual_deaths": 4300 // Current annual deaths
}
Data Sources
- HPV Coverage: WHO, GAVI, national health ministries (2024)
- Cancer Statistics: GLOBOCAN 2022, WHO IARC
- Program Details: HPV Information Centre
- Projections: WHO cervical cancer elimination models
Interactive Features
Controls
-
Size Metric Selector
- Dropdown in left control panel
- Changes what circle size represents
- Options: Coverage, Cancer Rate, Lives Saved, Mortality
-
Color Metric Selector
- Dropdown in left control panel
- Changes what circle color represents
- Same options as size, independently selectable
-
Pause/Resume Rotation
- Button in control panel
- Toggles auto-rotation on/off
- Also pauses when user interacts with globe
-
Reset View
- Returns to default center and zoom
- Smooth 2-second animation
-
Toggle 3D Cancer Burden
- Switches between 2D circles and 3D extrusions
- 3D mode shows column heights = annual deaths
- Automatically adjusts camera pitch
Hover Interactions
Hover over any country to see:
- Country name
- HPV coverage percentage with status indicator
- Program details (start year, target age, gender policy)
- Cervical cancer incidence rate
- Annual deaths (current)
- Potential lives saved (with full coverage)
- Income level
Popup colors:
- Green text = good outcome (high coverage, low cancer)
- Yellow text = moderate
- Pink/Red text = poor outcome (low coverage, high cancer)
Customization Guide
Changing Color Schemes
Color gradients are defined in src/index.js in the colorExpressions object:
Coverage gradient (purple theme):
'coverage': [
'interpolate',
['linear'],
['get', 'hpv_coverage_2024'],
0, '#4a0e4e', // Dark purple
50, '#b366ff', // Medium purple
90, '#ebccff' // Light purple
]
Cancer gradient (green-to-red diverging):
'cancer-rate': [
'interpolate',
['linear'],
['get', 'cervical_cancer_incidence'],
2, '#66ffb3', // Green (low = good)
20, '#ff9933', // Orange (moderate)
44, '#cc0000' // Dark red (high = bad)
]
To modify:
- Edit the color hex codes
- Adjust the data breakpoints (left number in each pair)
- Maintain the same number of stops for smooth gradients
Adjusting Circle Sizes
Size expressions are in sizeExpressions object:
'coverage': [
'interpolate',
['linear'],
['get', 'hpv_coverage_2024'],
0, 4, // Coverage 0% = 4px radius
60, 17, // Coverage 60% = 17px radius
95, 30 // Coverage 95% = 30px radius
]
Guidelines:
- Minimum radius: 4px (visible but not obtrusive)
- Maximum radius: 30-35px (prominent but not overlapping)
- 6-8 stops provide smooth scaling
Modifying Globe Appearance
In src/index.js, find the map.setFog() call:
map.setFog({
color: 'rgba(25, 15, 35, 0.9)', // Atmosphere base color
'high-color': 'rgba(80, 50, 120, 0.5)', // Upper atmosphere
'horizon-blend': 0.06, // Blend smoothness
'space-color': 'rgba(8, 5, 15, 1)', // Background space
'star-intensity': 0.8 // Star brightness
});
Purple/pink theme (current):
- Connects to cervical cancer awareness ribbons
- Professional medical visualization aesthetic
Alternative themes:
- Blue space theme:
color: 'rgba(20, 30, 50, 0.9)' - Warm theme:
color: 'rgba(40, 30, 20, 0.9)' - Cool theme:
color: 'rgba(15, 30, 40, 0.9)'
Adding New Data Points
To add countries:
-
Edit
src/data/data.js -
Add feature to the array:
{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [longitude, latitude] // Center of country }, "properties": { // ... all required properties } } -
Required properties:
- All properties from the schema above
- Use
nullfor missing data (e.g., no program) - Use
0for coverage if no program
-
Finding coordinates:
- Use latlong.net for country centers
- Format:
[longitude, latitude](not lat, lng!)
Visualization Modes
16 Possible Combinations
With 4 size metrics × 4 color metrics = 16 visualization modes:
Recommended combinations:
-
Coverage vs. Cancer (default)
- Size: Coverage
- Color: Cancer Rate
- Shows correlation: high coverage = low cancer
-
Impact Opportunity
- Size: Lives Saved
- Color: Coverage
- Shows where intervention would save most lives
-
Burden Analysis
- Size: Mortality
- Color: Coverage
- Shows where deaths are highest vs. prevention
-
Equity Analysis
- Size: Coverage
- Color: Lives Saved
- Shows disparities: who gets vaccines vs. who needs them
-
3D Cancer Burden (toggle mode)
- Enable 3D extrusions
- Height = Annual deaths
- Color = Cancer incidence
- Dramatic visualization of global burden
Interpreting Patterns
Purple gradient (coverage):
- Dark purple = No program or very low coverage
- Light purple = Excellent coverage (>85%)
Green-to-red gradient (cancer/mortality):
- Green = Low incidence/mortality (success)
- Yellow = Moderate (average)
- Red = High incidence/mortality (crisis)
Teal gradient (lives saved):
- Dark teal = Small potential impact
- Light teal = Large potential impact
Performance Notes
Optimization
The visualization is optimized for performance:
- 60fps auto-rotation on modern hardware
- <50ms metric switching (no data reload)
- Smooth 3D transitions (1 second)
Data Size
- 146 features = ~35KB uncompressed JSON
- 3 layers (circles, extrusions, labels)
- No pagination needed at this scale
Browser Requirements
Minimum:
- WebGL support (2015+ browsers)
- 1GB RAM
- 1024×768 resolution
Recommended:
- WebGL 2.0
- 4GB+ RAM
- 1920×1080+ resolution
- Hardware acceleration enabled
Troubleshooting
Globe Not Loading
Symptoms: Black screen or error message
Solutions:
- Check browser console for errors (F12)
- Verify Mapbox token is valid
- Ensure you're running from a web server (not
file://) - Check internet connection (CDN resources needed)
Data Not Appearing
Symptoms: Globe loads but no circles
Solutions:
- Check
src/data/data.jsis loaded correctly - Verify
hpvVaccineDatavariable exists (console:typeof hpvVaccineData) - Check for JavaScript errors in console
- Ensure GeoJSON structure is valid
Performance Issues
Symptoms: Laggy rotation, slow interactions
Solutions:
- Reduce number of stops in interpolate expressions
- Increase zoom-based opacity thresholds (hide circles at low zoom)
- Disable 3D extrusions if too slow
- Update graphics drivers
- Close other browser tabs
3D Mode Issues
Symptoms: 3D extrusions don't appear or look wrong
Solutions:
- Ensure WebGL is enabled and working
- Check
fill-extrusionlayer visibility (may be hidden) - Verify extrusion height values are reasonable (not NaN)
- Try resetting view and toggling again
Advanced Customization
Adding New Metrics
To add a metric (e.g., "vaccine_doses_administered"):
-
Add to data (
src/data/data.js):"properties": { // ... existing properties "vaccine_doses_administered": 2500000 } -
Create expression (
src/index.js):sizeExpressions['doses'] = [ 'interpolate', ['linear'], ['get', 'vaccine_doses_administered'], 0, 4, 1000000, 15, 10000000, 30 ]; -
Add to dropdown (
index.html):<option value="doses">Vaccine Doses Administered</option> -
Update legend (
src/index.js):metricLabels['doses'] = { name: 'Vaccine Doses Administered', min: '0', max: '10M', gradient: 'teal-gradient' // Define in CSS };
Filtering Data
To show only specific countries:
map.addLayer({
id: 'hpv-circles',
type: 'circle',
source: 'hpv-data',
filter: [
'>', ['get', 'hpv_coverage_2024'], 50 // Only show coverage >50%
],
// ... rest of layer config
});
Filter examples:
- High coverage only:
['>', ['get', 'hpv_coverage_2024'], 70] - Low-income countries:
['==', ['get', 'income_level'], 'low'] - No program:
['==', ['get', 'hpv_coverage_2024'], 0] - High burden:
['>', ['get', 'annual_deaths'], 2000]
Animation Ideas
Time-series animation (showing program adoption over time):
function animateTimeline() {
let year = 2006;
const interval = setInterval(() => {
map.setFilter('hpv-circles', [
'<=',
['get', 'vaccine_program_started'],
year
]);
year++;
if (year > 2024) clearInterval(interval);
}, 500); // Advance one year every 500ms
}
Pulsing circles for high-impact countries:
// Add to layer paint properties
'circle-opacity': [
'interpolate',
['linear'],
['%', ['/', ['+', ['get', 'lives_saved_projected'], ['*', ['time'], 0.001]], 1000], 1],
0, 0.6,
1, 1
]
Accessibility Notes
Color Blindness
Current gradients:
- Purple scale: Distinguishable by value (dark to light)
- Green-red scale: NOT colorblind-safe
Colorblind-safe alternative:
// Replace green-red with blue-orange
'cancer-rate': [
'interpolate',
['linear'],
['get', 'cervical_cancer_incidence'],
2, '#0571b0', // Blue (low)
20, '#fdae61', // Orange (moderate)
44, '#ca0020' // Dark red (high)
]
Screen Readers
The visualization is primarily visual. For accessibility:
- Ensure hover popups have semantic HTML
- Consider adding ARIA labels to controls
- Provide text summary of key findings in README
Export and Sharing
Screenshots
Browser built-in:
- Pause rotation
- Position desired view
- Browser screenshot (OS-specific shortcut)
Programmatic export:
// Add this function to src/index.js
function exportImage() {
map.once('idle', () => {
const canvas = map.getCanvas();
const dataURL = canvas.toDataURL('image/png');
const link = document.createElement('a');
link.download = 'hpv-vaccine-globe.png';
link.href = dataURL;
link.click();
});
}
Embedding
To embed in another page:
<iframe
src="path/to/mapbox_globe_14/index.html"
width="100%"
height="600px"
frameborder="0"
title="HPV Vaccine Impact Globe">
</iframe>
Learning Outcomes
Mapbox Techniques Demonstrated
✅ Fill-extrusion layers (3D columns) ✅ Toggleable layer visibility (comparison mode) ✅ Case expressions (conditional styling) ✅ Multi-metric interpolate expressions (4×4 matrix) ✅ Semantic color theory (health data visualization) ✅ Dynamic camera controls (pitch adjustment) ✅ Zoom-based adaptive styling (opacity, stroke width) ✅ Interactive popups with rich HTML
Data Visualization Principles
✅ Dual encoding (size + color independently selectable) ✅ Diverging vs. sequential scales (quality vs. magnitude) ✅ Visual hierarchy (primary, secondary, tertiary encoding) ✅ Storytelling through data (equity narrative) ✅ Multi-dimensional exploration (16 visualization modes)
Support and Resources
Mapbox Documentation
Health Data Sources
Contact
For issues, questions, or contributions related to this visualization, please refer to the main repository documentation.
Development Status: Complete and production-ready Last Updated: 2024 Iteration: 14 of Mapbox Globe progressive learning series