574 lines
15 KiB
Markdown
574 lines
15 KiB
Markdown
# 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
|
||
|
||
1. **Navigate to the visualization directory**:
|
||
```bash
|
||
cd mapbox_test/mapbox_globe_14
|
||
```
|
||
|
||
2. **Start a local web server** (required for loading external scripts):
|
||
```bash
|
||
# 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
|
||
```
|
||
|
||
3. **Open in browser**:
|
||
- Navigate to `http://localhost:8000`
|
||
- The globe will load with auto-rotation enabled
|
||
- Interaction pauses rotation automatically
|
||
|
||
### 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:
|
||
|
||
1. Get a free token at [mapbox.com/signup](https://account.mapbox.com/auth/signup/)
|
||
2. Edit `src/index.js`
|
||
3. Replace the token on line 6:
|
||
```javascript
|
||
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:
|
||
|
||
```javascript
|
||
{
|
||
"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
|
||
|
||
1. **Size Metric Selector**
|
||
- Dropdown in left control panel
|
||
- Changes what circle size represents
|
||
- Options: Coverage, Cancer Rate, Lives Saved, Mortality
|
||
|
||
2. **Color Metric Selector**
|
||
- Dropdown in left control panel
|
||
- Changes what circle color represents
|
||
- Same options as size, independently selectable
|
||
|
||
3. **Pause/Resume Rotation**
|
||
- Button in control panel
|
||
- Toggles auto-rotation on/off
|
||
- Also pauses when user interacts with globe
|
||
|
||
4. **Reset View**
|
||
- Returns to default center and zoom
|
||
- Smooth 2-second animation
|
||
|
||
5. **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):
|
||
```javascript
|
||
'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):
|
||
```javascript
|
||
'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:
|
||
1. Edit the color hex codes
|
||
2. Adjust the data breakpoints (left number in each pair)
|
||
3. Maintain the same number of stops for smooth gradients
|
||
|
||
### Adjusting Circle Sizes
|
||
|
||
Size expressions are in `sizeExpressions` object:
|
||
|
||
```javascript
|
||
'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:
|
||
|
||
```javascript
|
||
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:
|
||
|
||
1. **Edit `src/data/data.js`**
|
||
2. **Add feature to the array**:
|
||
```javascript
|
||
{
|
||
"type": "Feature",
|
||
"geometry": {
|
||
"type": "Point",
|
||
"coordinates": [longitude, latitude] // Center of country
|
||
},
|
||
"properties": {
|
||
// ... all required properties
|
||
}
|
||
}
|
||
```
|
||
|
||
3. **Required properties**:
|
||
- All properties from the schema above
|
||
- Use `null` for missing data (e.g., no program)
|
||
- Use `0` for coverage if no program
|
||
|
||
4. **Finding coordinates**:
|
||
- Use [latlong.net](https://www.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**:
|
||
|
||
1. **Coverage vs. Cancer** (default)
|
||
- Size: Coverage
|
||
- Color: Cancer Rate
|
||
- Shows correlation: high coverage = low cancer
|
||
|
||
2. **Impact Opportunity**
|
||
- Size: Lives Saved
|
||
- Color: Coverage
|
||
- Shows where intervention would save most lives
|
||
|
||
3. **Burden Analysis**
|
||
- Size: Mortality
|
||
- Color: Coverage
|
||
- Shows where deaths are highest vs. prevention
|
||
|
||
4. **Equity Analysis**
|
||
- Size: Coverage
|
||
- Color: Lives Saved
|
||
- Shows disparities: who gets vaccines vs. who needs them
|
||
|
||
5. **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**:
|
||
1. Check browser console for errors (F12)
|
||
2. Verify Mapbox token is valid
|
||
3. Ensure you're running from a web server (not `file://`)
|
||
4. Check internet connection (CDN resources needed)
|
||
|
||
### Data Not Appearing
|
||
|
||
**Symptoms**: Globe loads but no circles
|
||
|
||
**Solutions**:
|
||
1. Check `src/data/data.js` is loaded correctly
|
||
2. Verify `hpvVaccineData` variable exists (console: `typeof hpvVaccineData`)
|
||
3. Check for JavaScript errors in console
|
||
4. Ensure GeoJSON structure is valid
|
||
|
||
### Performance Issues
|
||
|
||
**Symptoms**: Laggy rotation, slow interactions
|
||
|
||
**Solutions**:
|
||
1. Reduce number of stops in interpolate expressions
|
||
2. Increase zoom-based opacity thresholds (hide circles at low zoom)
|
||
3. Disable 3D extrusions if too slow
|
||
4. Update graphics drivers
|
||
5. Close other browser tabs
|
||
|
||
### 3D Mode Issues
|
||
|
||
**Symptoms**: 3D extrusions don't appear or look wrong
|
||
|
||
**Solutions**:
|
||
1. Ensure WebGL is enabled and working
|
||
2. Check `fill-extrusion` layer visibility (may be hidden)
|
||
3. Verify extrusion height values are reasonable (not NaN)
|
||
4. Try resetting view and toggling again
|
||
|
||
## Advanced Customization
|
||
|
||
### Adding New Metrics
|
||
|
||
To add a metric (e.g., "vaccine_doses_administered"):
|
||
|
||
1. **Add to data** (`src/data/data.js`):
|
||
```javascript
|
||
"properties": {
|
||
// ... existing properties
|
||
"vaccine_doses_administered": 2500000
|
||
}
|
||
```
|
||
|
||
2. **Create expression** (`src/index.js`):
|
||
```javascript
|
||
sizeExpressions['doses'] = [
|
||
'interpolate',
|
||
['linear'],
|
||
['get', 'vaccine_doses_administered'],
|
||
0, 4,
|
||
1000000, 15,
|
||
10000000, 30
|
||
];
|
||
```
|
||
|
||
3. **Add to dropdown** (`index.html`):
|
||
```html
|
||
<option value="doses">Vaccine Doses Administered</option>
|
||
```
|
||
|
||
4. **Update legend** (`src/index.js`):
|
||
```javascript
|
||
metricLabels['doses'] = {
|
||
name: 'Vaccine Doses Administered',
|
||
min: '0',
|
||
max: '10M',
|
||
gradient: 'teal-gradient' // Define in CSS
|
||
};
|
||
```
|
||
|
||
### Filtering Data
|
||
|
||
To show only specific countries:
|
||
|
||
```javascript
|
||
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):
|
||
|
||
```javascript
|
||
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:
|
||
|
||
```javascript
|
||
// 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**:
|
||
```javascript
|
||
// 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:
|
||
1. Ensure hover popups have semantic HTML
|
||
2. Consider adding ARIA labels to controls
|
||
3. Provide text summary of key findings in README
|
||
|
||
## Export and Sharing
|
||
|
||
### Screenshots
|
||
|
||
**Browser built-in**:
|
||
1. Pause rotation
|
||
2. Position desired view
|
||
3. Browser screenshot (OS-specific shortcut)
|
||
|
||
**Programmatic export**:
|
||
```javascript
|
||
// 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:
|
||
```html
|
||
<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
|
||
|
||
- [Mapbox GL JS API](https://docs.mapbox.com/mapbox-gl-js/api/)
|
||
- [Expressions](https://docs.mapbox.com/mapbox-gl-js/style-spec/expressions/)
|
||
- [Fill-extrusion layer](https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/#fill-extrusion)
|
||
|
||
### Health Data Sources
|
||
|
||
- [WHO HPV Vaccine](https://www.who.int/teams/immunization-vaccines-and-biologicals/diseases/human-papillomavirus-vaccines-(HPV))
|
||
- [GLOBOCAN Cancer Statistics](https://gco.iarc.fr/)
|
||
- [HPV Information Centre](https://hpvcentre.net/)
|
||
|
||
### 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
|