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

15 KiB

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

// 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

// 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

// 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

// 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:

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:

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):

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):

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:

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

{
    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):

'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):

'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:

'circle-stroke-color': [
    'interpolate',
    ['linear'],
    ['get', 'researchScore'],
    55, '#ff4444',   // Red
    80, '#ffaa00',   // Orange
    95, '#00ffff'    // Cyan
]

Globe Configuration

Atmosphere Settings

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

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

.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

  • Uses Mapbox GL JS v3.0.1
  • Globe projection enabled
  • Atmosphere effects configured
  • 120 universities with accurate coordinates
  • 6 data metrics per university
  • Region checkbox filters (7 options)
  • Ranking range slider
  • 4 metric threshold sliders
  • Compound filter expressions with all, in, >=, <=
  • Real-time statistics dashboard
  • Interactive popups with full details
  • Reset filters functionality
  • Pause/resume rotation control
  • Top 30 university labels
  • 8-stop color gradient for research scores
  • Inverse size scaling for rankings
  • Auto-rotation with interaction pause
  • Responsive design (desktop & mobile)
  • 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

# 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.