infinite-agents-public/mapbox_test/mapbox_globe_6/CLAUDE.md

541 lines
15 KiB
Markdown

# CLAUDE.md - Globe Visualization 6 Development Context
## Project Overview
This is **Iteration 6** in a progressive Mapbox GL JS learning series. Each iteration builds upon previous learnings while introducing new techniques from web research. This iteration focuses on **interactive filtering and UI controls** for data exploration.
## Development Assignment
**Task**: Create an interactive globe visualization demonstrating advanced filtering techniques learned from Mapbox documentation.
**Theme**: Global University Rankings & Research Output
- 120 top research universities worldwide
- Multi-dimensional data: ranking, publications, citations, funding, Nobel prizes
- Interactive filtering by region and research metrics
- Real-time statistics dashboard
## Web Research Integration
**Source**: Mapbox GL JS Filter Markers Example
**URL**: https://docs.mapbox.com/mapbox-gl-js/example/filter-markers/
### Techniques Extracted from Web Source:
#### 1. Core Filtering Method
```javascript
// From web source - basic pattern
map.setLayoutProperty(layerID, 'visibility', checked ? 'visible' : 'none');
// Enhanced approach learned
map.setFilter('layer-id', filterExpression);
```
The web source demonstrated layer visibility toggling. I learned the more sophisticated `setFilter()` approach which filters features within a layer rather than hiding the entire layer.
#### 2. Filter Expression Syntax
```javascript
// From web source - equality filter
['==', 'icon', symbol]
// My applications
['==', 'region', selectedRegion] // Equality
['<=', ['get', 'ranking'], maxRank] // Less than or equal
['>=', ['get', 'publications'], minPubs] // Greater than or equal
['in', ['get', 'region'], ['literal', regions]] // Multiple values
```
#### 3. Checkbox UI Pattern
```javascript
// From web source
checkbox.addEventListener('change', (e) => {
map.setLayoutProperty(
layerID,
'visibility',
e.target.checked ? 'visible' : 'none'
);
});
// My adaptation
checkbox.addEventListener('change', () => {
updateFilterState();
applyFilters();
});
```
#### 4. Feature Property Access
```javascript
// Learned pattern for accessing feature properties in expressions
['get', 'propertyName'] // Retrieves property value from feature
```
### My Enhancements Beyond Web Source:
1. **Compound Filter Expressions**:
- Used `all` operator to combine multiple filter conditions
- Implemented range filtering with `>=` and `<=`
- Multi-value filtering with `in` and `literal`
2. **Range Sliders**:
- Extended beyond checkboxes to continuous controls
- Real-time value display and updates
- Multiple independent metric thresholds
3. **Filter Coordination**:
- Mutual exclusivity for "All" vs specific regions
- State management across 6 filter dimensions
- Reset functionality restoring all defaults
4. **Statistics Calculation**:
- Query rendered features after filtering
- Aggregate calculations (sum, average)
- Live dashboard updates
5. **Multi-Layer Filtering**:
- Coordinated filters across universities and labels layers
- Maintained label visibility rules while respecting filters
## Technical Implementation Details
### Filter Architecture
**Filter State Object**:
```javascript
let currentFilters = {
regions: ['all'], // Selected regions
rankingRange: [1, 120], // Min/max ranking
minPublications: 0, // Publication threshold
minCitations: 0, // Citation threshold
minFunding: 0, // Funding threshold
minNobelPrizes: 0 // Nobel prize threshold
};
```
**Filter Expression Builder**:
```javascript
function applyFilters() {
let filterExpression = ['all']; // AND combiner
// Region filter (OR within selected)
if (!selectedRegions.includes('all')) {
filterExpression.push([
'in',
['get', 'region'],
['literal', selectedRegions]
]);
}
// Ranking filter
filterExpression.push(['<=', ['get', 'ranking'], maxRank]);
// Metric thresholds
if (minPubs > 0) {
filterExpression.push(['>=', ['get', 'publications'], minPubs]);
}
// Apply to layer
map.setFilter('universities-layer', filterExpression);
// Update statistics
updateStatistics();
}
```
### UI Control Implementation
**Checkbox Filters** (7 regions):
```javascript
regions.forEach((region, index) => {
const checkbox = createElement('input', {
type: 'checkbox',
id: `region-${index}`,
value: region,
checked: region === 'All'
});
checkbox.addEventListener('change', () => {
// Handle "All" mutual exclusivity
if (region === 'All' && checkbox.checked) {
uncheckOtherRegions();
} else if (checkbox.checked) {
uncheckAll();
}
applyFilters();
});
});
```
**Range Sliders** (5 metrics):
```javascript
slider.addEventListener('input', (e) => {
const value = parseInt(e.target.value);
currentFilters.metric = value;
displayElement.textContent = formatValue(value);
applyFilters(); // Immediate update
});
```
### Statistics Dashboard
**Query Filtered Features**:
```javascript
function updateStatistics() {
const features = map.queryRenderedFeatures({
layers: ['universities-layer']
});
const stats = {
count: features.length,
avgResearch: average(features, 'researchScore'),
totalPubs: sum(features, 'publications'),
totalCitations: sum(features, 'citations'),
totalNobel: sum(features, 'nobelPrizes')
};
updateDashboard(stats);
}
```
This queries only the currently visible (filtered) features, enabling real-time statistics that update with every filter change.
## Data Structure
### University Data Model
```javascript
{
type: "Feature",
geometry: {
type: "Point",
coordinates: [longitude, latitude]
},
properties: {
name: "University Name",
country: "Country",
region: "Region",
ranking: 1-120, // Global position
publications: 5500-19800, // Annual papers
citations: 122000-456000, // Total citations
funding: 400-4200, // Annual funding ($M)
nobelPrizes: 0-161, // Total Nobel laureates
researchScore: 55-99 // Composite score
}
}
```
### Data Coverage
**120 Universities Across 6 Regions**:
- North America: 27 (USA, Canada)
- Europe: 25 (UK, Germany, France, Switzerland, etc.)
- Asia-Pacific: 42 (China, Japan, Singapore, Australia, India, etc.)
- Middle East: 9 (Israel, Qatar, UAE, Saudi Arabia, Turkey)
- Africa: 6 (South Africa, Egypt, Kenya, Nigeria)
- Latin America: 11 (Brazil, Argentina, Chile, Mexico, Colombia)
**Data Realism**:
- Rankings based on major global university rankings
- Publications scaled to realistic annual output
- Citations reflect cumulative academic impact
- Funding approximates actual research budgets
- Nobel prizes are historically accurate
### Metric Distributions
- **Research Score**: 55-99 (composite excellence measure)
- **Publications**: 5,500-19,800 (annual research output)
- **Citations**: 122,000-456,000 (total academic citations)
- **Funding**: $400M-$4,200M (annual research funding)
- **Nobel Prizes**: 0-161 (total affiliated laureates)
## Visual Design System
### Color Scheme - Research Excellence
8-stop gradient from deep red (emerging) to royal blue (exceptional):
```javascript
'circle-color': [
'interpolate',
['linear'],
['get', 'researchScore'],
55, '#8b0000', // Deep red
65, '#dc143c', // Crimson
75, '#ff6347', // Tomato
80, '#ffa500', // Orange
85, '#ffd700', // Gold
90, '#32cd32', // Lime green
95, '#00bfff', // Deep sky blue
99, '#0066ff' // Royal blue
]
```
### Size Encoding - Ranking Position
Inverse relationship (better rank = larger circle):
```javascript
'circle-radius': [
'interpolate',
['linear'],
['get', 'ranking'],
1, 18, // Top rank
10, 14,
25, 11,
50, 9,
75, 7,
100, 5,
120, 4 // Lower rank
]
```
### Stroke Styling
Dynamic stroke color matches research score:
```javascript
'circle-stroke-color': [
'interpolate',
['linear'],
['get', 'researchScore'],
55, '#ff4444', // Red
80, '#ffaa00', // Orange
95, '#00ffff' // Cyan
]
```
## Globe Configuration
### Atmosphere Settings
```javascript
map.setFog({
color: 'rgba(8, 16, 32, 0.95)', // Dark base
'high-color': 'rgba(25, 60, 120, 0.5)', // Blue horizon
'horizon-blend': 0.3, // Blend distance
'space-color': '#000510', // Deep space
'star-intensity': 0.7 // Star brightness
});
```
### Auto-Rotation
```javascript
let userInteracting = false;
function rotateGlobe() {
if (!userInteracting && !rotationPaused) {
const center = map.getCenter();
center.lng += 0.05; // Slow rotation
map.setCenter(center);
}
requestAnimationFrame(rotateGlobe);
}
```
Pauses during user interaction, resumes when idle.
## UI/UX Design Patterns
### Glassmorphism Theme
```css
.panel {
background: rgba(0, 0, 0, 0.9);
backdrop-filter: blur(15px);
border: 1px solid rgba(255, 255, 255, 0.15);
}
```
Creates semi-transparent panels with blur effect for modern aesthetic.
### Responsive Layout
**Desktop**:
- Controls panel: Right side
- Statistics: Bottom left
- Legend: Bottom right
- Title: Top center
**Mobile** (< 768px):
- Controls: Bottom overlay (scrollable)
- Statistics: Top left (compact)
- Legend: Hidden
- Title: Reduced size
### Interactive Feedback
- Slider values update in real-time
- Statistics dashboard refreshes with filters
- Hover popups show detailed metrics
- Cursor changes on interactive elements
- Smooth transitions on all updates
## Performance Considerations
### Efficient Filtering
- **No data reloading**: Filters operate on existing source
- **Expression-based**: Computed on GPU where possible
- **Debounced updates**: Statistics calculated after filter application
- **Feature querying**: Only visible features processed
### Optimized Rendering
- **Single data source**: All 120 universities in one GeoJSON
- **Layer reuse**: Same source for circles and labels
- **Conditional labels**: Only top 30 show text
- **Stroke width**: Modest 2px to reduce overdraw
### Memory Management
- **Static data**: Universities loaded once
- **No data duplication**: Filters reference same source
- **Minimal DOM**: Controls generated once
- **Event delegation**: Where possible
## Validation Checklist
- [x] Uses Mapbox GL JS v3.0.1
- [x] Globe projection enabled
- [x] Atmosphere effects configured
- [x] 120 universities with accurate coordinates
- [x] 6 data metrics per university
- [x] Region checkbox filters (7 options)
- [x] Ranking range slider
- [x] 4 metric threshold sliders
- [x] Compound filter expressions with `all`, `in`, `>=`, `<=`
- [x] Real-time statistics dashboard
- [x] Interactive popups with full details
- [x] Reset filters functionality
- [x] Pause/resume rotation control
- [x] Top 30 university labels
- [x] 8-stop color gradient for research scores
- [x] Inverse size scaling for rankings
- [x] Auto-rotation with interaction pause
- [x] Responsive design (desktop & mobile)
- [x] Web source attribution in README
## Learning Outcomes
**Completing this iteration demonstrates understanding of**:
1. **Filter Expressions**: Syntax and composition with Mapbox expressions
2. **Dynamic Filtering**: Real-time layer updates with `setFilter()`
3. **Compound Conditions**: Using `all`, `in`, `>=`, `<=` operators
4. **UI Controls**: Checkboxes and sliders for filter input
5. **Feature Querying**: `queryRenderedFeatures()` for statistics
6. **State Management**: Coordinating multiple filter dimensions
7. **Interactive Exploration**: User-driven data discovery
8. **Real-time Updates**: Synchronizing UI, filters, and statistics
9. **Filter Coordination**: Multiple layers with shared filter logic
10. **Practical Application**: Adapting web examples to complex use cases
## Progressive Learning Demonstrated
**Building on Previous Iterations**:
- **Iter 1**: Basic globe setup, circle layers
- **Iter 2**: Color gradients, visual styling
- **Iter 3**: Data-driven expressions
- **Iter 4**: Multi-layer composition
- **Iter 6**: Interactive filtering & exploration **Current**
**New Capabilities Added**:
- Multi-criteria filtering system
- Checkbox and slider UI controls
- Compound filter expressions
- Real-time statistics calculation
- Coordinated filter state management
- Reset and rotation control
**Synthesis Achievement**:
Combines visual techniques (Iter 1-3), layer composition (Iter 4), and interactive controls (Iter 6) into a comprehensive data exploration tool.
## Development Notes
### Filter Expression Best Practices
1. **Use `all` for AND logic**: Combine multiple conditions
2. **Use `in` for OR logic**: Match any of multiple values
3. **Use `literal` for arrays**: Wrap array values in filter expressions
4. **Use `get` for properties**: Access feature properties safely
5. **Order matters**: Put most selective filters first for performance
### Common Pitfalls Avoided
- Reloading data on filter change (inefficient)
- Using `setFilter()` on existing source (efficient)
- Hiding entire layer with visibility (limited flexibility)
- Filtering features within layer (precise control)
- Calculating statistics from raw data (inaccurate)
- Querying rendered features (matches visible state)
- Conflicting filter states (confusing UX)
- Coordinated state management (clear behavior)
### Extension Opportunities
**Future enhancements**:
- Animated transitions between filter states
- Saved filter presets (e.g., "Elite Tier", "High Impact")
- Export filtered data to CSV/JSON
- Comparison mode (before/after filtering)
- URL parameters for shareable filtered views
- Multi-map views showing different filter perspectives
- 3D extrusions for research output metrics
- Connection lines between collaborating institutions
## Files Created
1. **index.html** - Main visualization with complete UI
2. **src/index.js** - Filtering logic and interactivity
3. **src/data/data.js** - 120 universities with 6 metrics each
4. **README.md** - Comprehensive documentation
5. **CLAUDE.md** - This development context file
## Local Development
### Running the Visualization
```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
```
Then open: http://localhost:8000
### Browser Requirements
- Modern browser with WebGL support
- Recommended: Chrome 90+, Firefox 88+, Safari 14+, Edge 90+
- Minimum screen resolution: 1024x768
### Testing Checklist
- [ ] Globe renders with atmosphere
- [ ] 120 universities visible on load
- [ ] Region checkboxes filter correctly
- [ ] "All" checkbox mutual exclusivity works
- [ ] All 5 sliders update filters in real-time
- [ ] Statistics dashboard shows correct values
- [ ] Hover popups display university details
- [ ] Labels appear for top 30 only
- [ ] Reset button restores all defaults
- [ ] Pause rotation button toggles correctly
- [ ] Auto-rotation works and pauses on interaction
- [ ] Responsive layout on mobile (< 768px)
---
*This iteration successfully demonstrates mastery of Mapbox filtering techniques learned from official documentation, applied to a comprehensive research dataset with sophisticated multi-dimensional exploration capabilities.*