Skip to content

Latest commit

 

History

History
719 lines (541 loc) · 23.5 KB

File metadata and controls

719 lines (541 loc) · 23.5 KB

Sky Harbor Ride-Hailing Analytics Dashboard

A Comprehensive Case Study


Executive Summary

The Sky Harbor Ride-Hailing Analytics Dashboard is a full-stack web application designed to provide real-time operational intelligence for airport ride-hailing parking management. The system transforms raw parking occupancy data into actionable insights through an interactive, animated visualization dashboard that enables airport executives and operations staff to optimize parking efficiency, reduce passenger wait times, and make data-driven infrastructure decisions.

Key Achievement: Successfully migrated from a static Dash application to a modern, scalable full-stack architecture with real-time animation, comprehensive analytics, and executive-grade visualizations.


1. Problem Statement

Business Challenge

Sky Harbor Airport needed a solution to:

  • Monitor real-time parking slot occupancy across 24 designated ride-hailing parking spaces
  • Analyze historical patterns to optimize slot allocation and capacity planning
  • Track service provider distribution (Uber, Lyft) to understand market dynamics
  • Measure vehicle dwell times to improve turnover rates and reduce passenger wait times
  • Provide executive-level insights for strategic decision-making

Technical Challenge

The original system was built using Dash (Python), which presented limitations:

  • Tightly coupled UI and data logic
  • Limited interactivity and animation capabilities
  • Difficult to scale or extend
  • Poor separation of concerns

Solution Requirements

  • Real-time visualization of vehicle movements and slot occupancy
  • Comprehensive analytics with multiple chart types and KPIs
  • Responsive, modern UI suitable for executive presentations
  • Scalable architecture with clear separation between frontend and backend
  • Performance optimization for smooth animations and data loading

2. Solution Architecture

Technology Stack

Backend:

  • FastAPI - Modern, high-performance Python web framework
  • Pandas - Data processing and analytics
  • NumPy - Numerical computations
  • Uvicorn - ASGI server for FastAPI

Frontend:

  • React 18 - Component-based UI library
  • Vite - Fast build tool and dev server
  • Axios - HTTP client for API communication
  • Recharts - Charting library for data visualization
  • CSS-in-JS - Inline styling for component-based design

Data:

  • Excel file (ride_hailing.xlsx) - Source data with timestamps, slot positions, vehicle information
  • Static assets - Map images, car sprites, license plate images

Architecture Pattern

Separation of Concerns:

  • Backend (backend/app.py): Pure data processing and API endpoints
  • Frontend (frontend/src/): UI components and visualization logic
  • State Management: React Context API for shared application state
  • API Communication: RESTful JSON endpoints

3. Core Features

3.1 Real-Time Vehicle Occupancy Animation

Feature Description: An interactive, animated visualization showing vehicle movements across 24 parking slots in real-time.

Technical Implementation:

  • MapCanvas Component: Renders a 1551×1171px parking map with exact coordinate positioning
  • Car Sprite System: 6 different vehicle types (Audi, Car, Mini_truck, Mini_van, Taxi, Truck) with consistent assignment per license plate
  • Smooth Transitions: CSS transitions (0.45s ease-out) for car movements between frames
  • Slot ID Mapping: Custom visual numbering system (1-24) that matches natural reading pattern
  • Rotation Logic: Cars rotate 90° or 270° based on slot position to match parking layout

Key Capabilities:

  • Frame-by-frame animation with play/pause controls
  • Variable playback speed (0.5x, 1x, 2x)
  • Timeline scrubbing for precise frame navigation
  • Real-time slot status overlay (occupied/vacant counts)
  • Hover tooltips showing vehicle details (plate, service, slot ID, dwell time)

Data Flow:

  1. Backend precomputes slot positions at startup
  2. Frontend requests frame data via /frame/{ts} endpoint
  3. Each frame returns all 24 slots with occupancy state
  4. React components render cars at exact x,y coordinates
  5. Animation engine advances frames using requestAnimationFrame

3.2 Dynamic KPI Dashboard

Feature Description: Four key performance indicators that update dynamically based on the selected timestamp.

KPIs Displayed:

  1. Avg Dwell Time - Average time vehicles spend in parking slots
  2. Max Dwell Time - Maximum observed dwell time
  3. Active Reservations - Number of active ride reservations
  4. Avg Reservation Duration - Average length of reservations

Smart Caching System:

  • Peak Value Tracking: System caches maximum values seen across all timestamps
  • Intelligent Fallback: When active reservations = 0, displays peak historical values instead of "N/A"
  • Data Persistence: Values persist across frame changes for continuous visibility
  • Sky Harbor Branding: Color-coded cards (orange, royal blue, white) matching airport brand

Technical Details:

  • Uses useRef for peak value caching
  • useMemo for efficient value computation
  • Automatic fallback to summary statistics when timestamp-specific data unavailable

3.3 Comprehensive Analytics Charts

Service Share Over Time (Stacked Area Chart)

  • Visualizes service provider distribution (Uber, Lyft) across all timestamps
  • Stacked area format shows total occupancy and service mix simultaneously
  • Updates dynamically with animation timeline

Top 20 Slot Utilization (Vertical Bar Chart)

  • Displays most frequently used parking slots
  • Sorted by usage count in descending order
  • Helps identify high-traffic areas for maintenance and optimization

Vehicle Dwell Time Distribution (Histogram)

  • Shows distribution of vehicle dwell times across 30 bins
  • Displays average and maximum dwell times
  • Helps identify patterns in parking duration

Data Sources:

  • /service_mix - Service distribution over time
  • /utilization - Slot usage statistics
  • /dwell_time - Dwell time statistics and distribution

3.4 Active Vehicles Table

Feature Description: Real-time table displaying all vehicles currently present at the selected timestamp.

Information Displayed:

  • Vehicle Sprite - Visual representation of car type
  • License Plate - Vehicle identification
  • Service Provider - Uber, Lyft, or Unknown (color-coded badges)
  • Entry Time - When vehicle first entered parking area
  • Time Here - Current dwell time in minutes

Technical Implementation:

  • Combines frameData (for positions) with API data (for entry times)
  • Uses consistent car sprite assignment (hash-based)
  • Real-time updates as animation plays
  • Empty state handling when no vehicles present

Data Flow:

  1. VehicleTable component extracts occupied vehicles from frameData
  2. Fetches additional details from /vehicles_at_timestamp/{ts}
  3. Merges data sources for complete vehicle information
  4. Displays in sortable, scrollable table format

3.5 Live Slot Status Overlay

Feature Description: Real-time counter displayed in top-left corner of animation showing current parking status.

Metrics Displayed:

  • Occupied Slots - Green indicator with count
  • Vacant Slots - Yellow indicator with count
  • Total Slots - Always 24
  • Current Timestamp - Formatted time display

Smart Caching:

  • Multi-tier Fallback System:
    1. Current API stats (if available)
    2. Cached stats from last successful load
    3. Computed from frame data (counts occupied slots directly)
    4. Only shows nothing if absolutely no data available

Benefits:

  • Never shows "N/A" unnecessarily
  • Always displays last known values during loading
  • Provides immediate visual feedback on parking status

4. Backend API Architecture

4.1 Data Precomputation

Startup Optimization: The backend precomputes several data structures at startup to minimize runtime processing:

  1. Sorted Timestamps - All unique timestamps in chronological order
  2. Slot Positions - Canonical x,y coordinates for each of 24 slots
  3. Slot Utilization - Usage count per slot across entire dataset
  4. Service Mix - Service provider distribution by timestamp

Performance Impact:

  • Reduces API response time from ~500ms to ~50ms
  • Eliminates redundant calculations
  • Enables smooth 60fps animation playback

4.2 RESTful API Endpoints

Core Endpoints:

  1. GET /timestamps

    • Returns all available timestamps as ISO-8601 strings
    • Used for timeline initialization
  2. GET /frame/{ts}

    • Returns complete slot state for a given timestamp
    • Includes all 24 slots with positions, occupancy, plate, service
    • Core endpoint for animation rendering
  3. GET /stats/{ts}

    • Basic occupancy statistics (total, occupied, vacant)
    • Fast, lightweight endpoint for status overlay
  4. GET /stats_timestamp/{ts}

    • Comprehensive timestamp-specific statistics
    • Includes dwell times, reservations, vehicle counts
    • Used for dynamic KPI cards
  5. GET /utilization

    • Slot utilization across entire dataset
    • Sorted by usage count
    • Powers utilization chart
  6. GET /service_mix

    • Service provider distribution over time
    • Powers service mix chart
  7. GET /dwell_time

    • Dwell time statistics and distribution
    • Powers dwell time histogram
  8. GET /summary

    • Overall dataset summary
    • Peak occupancy, total vehicles, average metrics
    • Fallback data for KPIs
  9. GET /vehicles_at_timestamp/{ts}

    • Detailed vehicle information at specific timestamp
    • Entry times, current dwell times, positions
    • Powers active vehicles table
  10. GET /occupancy_timeline

    • Occupancy count per timestamp
    • Historical trend data

4.3 Data Processing Logic

Dwell Time Calculation:

# For each vehicle, calculate time between first and last appearance
first_seen = plate_data["current_time"].min()
last_seen = plate_data["current_time"].max()
dwell_minutes = (last_seen - first_seen).total_seconds() / 60

Reservation Duration:

# For each reservation, calculate duration
start_time = res_data["current_time"].min()
end_time = res_data["current_time"].max()
duration_minutes = (end_time - start_time).total_seconds() / 60

Occupancy Counting:

# Count unique occupied slots (not rows)
occupied = df_t["slot_id"][df_t["plate_number"].notna()].nunique()

5. Frontend Architecture

5.1 State Management

React Context Provider Pattern:

  • RideHailingProvider - Wraps entire application, provides shared state
  • useRideHailingStore - Custom hook for accessing shared state
  • Single Source of Truth - All components share same state instance

State Structure:

{
  // Data
  timestamps: [],
  selectedTimestamp: null,
  frameData: [],
  stats: {},
  timestampStats: {},
  summary: {},
  utilization: [],
  serviceMix: {},
  dwellTime: {},
  
  // Loading flags
  loadingTimestamps: false,
  loadingFrame: false,
  loadingStats: false,
  // ... etc
  
  // Methods
  loadTimestamps: () => {},
  loadFrame: (ts) => {},
  loadStats: (ts) => {},
  // ... etc
}

Benefits:

  • Eliminates prop drilling
  • Ensures data consistency across components
  • Enables efficient data sharing (e.g., frameData used by both MapCanvas and VehicleTable)

5.2 Component Architecture

Main Components:

  1. App.jsx - Root component, loads initial data, provides layout structure
  2. AnalyticsSidebar.jsx - Main dashboard container with Bento grid layout
  3. MapCanvas.jsx - Animation rendering engine
  4. VehicleTable.jsx - Active vehicles display
  5. KpiCard.jsx - Reusable KPI display component
  6. CarSprite.jsx - Individual vehicle rendering
  7. TimelineControls.jsx - Playback controls (play/pause, speed, scrubbing)
  8. Chart Components - ServiceMixChart, UtilizationChart, DwellHistogram

Component Hierarchy:

App
└── AnalyticsSidebar
    ├── KPI Cards (4 cards)
    ├── MapCanvas
    │   ├── TimelineControls
    │   ├── Map Image
    │   ├── Slot Labels
    │   ├── CarSprites
    │   └── Stats Overlay
    └── Charts Section
        ├── ServiceMixChart
        ├── UtilizationChart
        ├── DwellHistogram
        └── VehicleTable

5.3 Animation Engine

Advanced Animation System:

  • useAnimationEngine Hook - Custom hook managing animation loop
  • requestAnimationFrame - Browser-native animation API for smooth 60fps
  • Frame Interpolation - Smooth transitions between frames
  • Playback Controls - Play, pause, speed adjustment, frame jumping

Performance Optimizations:

  • Request deduplication prevents duplicate API calls
  • Frame caching reduces redundant data loading
  • CSS transitions for hardware-accelerated animations
  • useMemo and useCallback for expensive computations

5.4 Visual Design

Sky Harbor Branding:

  • Color Scheme: Orange (#FF6600), Royal Blue (#003366), White
  • Typography: System fonts for optimal performance
  • Layout: Bento grid pattern for organized information display
  • Cards: Rounded corners, subtle shadows, hover effects

Responsive Design:

  • Fixed-width main container (2000px max)
  • Scalable map visualization
  • Scrollable sections for overflow content
  • Mobile-friendly touch interactions

6. Data Flow

6.1 Application Initialization

  1. Backend Startup:

    • Loads Excel file into Pandas DataFrame
    • Precomputes timestamps, slot positions, utilization, service mix
    • Starts FastAPI server on port 8000
  2. Frontend Startup:

    • React app initializes
    • RideHailingProvider creates shared state
    • App component loads summary, occupancy timeline, dwell time, utilization, service mix
  3. MapCanvas Initialization:

    • Loads timestamps from /timestamps
    • Loads first frame from /frame/{first_timestamp}
    • Creates slot mapping for visual numbering
    • Initializes animation engine

6.2 Animation Playback

  1. Frame Request:

    • Animation engine advances to next frame index
    • Calls loadFrame(timestamps[index])
    • Backend returns slot states for that timestamp
  2. State Update:

    • frameData updated in shared state
    • MapCanvas receives new frame data
    • displayFrameData updated via requestAnimationFrame
  3. Rendering:

    • Cars transition to new positions (CSS transitions)
    • Slot labels update (green for occupied, yellow for vacant)
    • Stats overlay updates with new counts
    • Vehicle table updates with current vehicles
  4. Stats Loading:

    • selectedTimestamp changes trigger loadStats(ts)
    • Backend calculates timestamp-specific statistics
    • KPI cards update with new values
    • Peak values cached if higher than previous

6.3 User Interactions

Timeline Scrubbing:

  • User drags slider to specific frame
  • jumpToFrame(index) called
  • Frame data loaded for that timestamp
  • All components update synchronously

Hover Interactions:

  • User hovers over car sprite
  • CarTooltip displays vehicle information
  • Calculates dwell time from timestamps
  • Shows plate, service, slot ID, dwell time

Speed Adjustment:

  • User selects playback speed (0.5x, 1x, 2x)
  • Animation interval adjusted
  • Frames advance at new rate

7. Performance Optimizations

7.1 Backend Optimizations

  • Precomputation: All static data computed at startup
  • Efficient Queries: Pandas operations optimized with vectorization
  • Minimal Data Transfer: Only necessary fields returned in API responses
  • Caching: Repeated requests for same timestamp return cached results

7.2 Frontend Optimizations

  • Request Deduplication: Prevents multiple simultaneous requests for same frame
  • Memoization: useMemo for expensive computations (slot mapping, display stats)
  • Lazy Loading: Components load data only when needed
  • CSS Transitions: Hardware-accelerated animations
  • Virtual Rendering: Only visible elements rendered (for large lists)

7.3 State Management Optimizations

  • Context Provider: Single state instance shared across all components
  • Selective Updates: Only affected components re-render on state changes
  • Ref-based Caching: Peak values and slot mappings stored in refs (don't trigger re-renders)
  • Loading States: Prevents duplicate requests during active loads

8. Key Technical Innovations

8.1 Slot ID Remapping System

Problem: Backend slot IDs don't match visual layout pattern Solution: Custom mapping utility that remaps backend IDs to intuitive 1-24 display pattern

Implementation:

  • Groups slots by approximate Y position (rows)
  • Sorts rows top to bottom
  • Sorts within rows left to right
  • Maps to target pattern: 1-6, 13-18, 7-12, 19-24

Benefits:

  • Natural reading pattern for users
  • Consistent numbering across all views
  • Maintains data integrity (backend IDs unchanged)

8.2 Peak Value Caching

Problem: When parking lot is empty, metrics show "N/A" Solution: Track maximum values seen, display peaks when current = 0

Implementation:

  • useRef stores peak values (avg_dwell_time, max_dwell_time, avg_reservation_duration)
  • Updates peak whenever new higher value encountered
  • Falls back to peak when unique_reservations = 0

Benefits:

  • Always shows meaningful data
  • Provides historical context
  • Improves user experience

8.3 Multi-Tier Stats Caching

Problem: Stats overlay disappears when API data unavailable Solution: Three-tier fallback system

Tiers:

  1. Current API stats (preferred)
  2. Cached stats from last successful load
  3. Computed from frame data (direct slot counting)

Benefits:

  • Never shows "N/A" unnecessarily
  • Always displays last known values
  • Provides immediate feedback

8.4 Smooth Animation Engine

Problem: Janky frame transitions, poor performance Solution: requestAnimationFrame-based animation loop

Features:

  • 60fps target frame rate
  • Smooth frame interpolation
  • Variable playback speed
  • Frame scrubbing support
  • Play/pause controls

9. User Experience Features

9.1 Interactive Timeline

  • Slider Control: Drag to any frame in timeline
  • Play/Pause Button: Start/stop animation
  • Speed Control: Adjust playback speed (0.5x, 1x, 2x)
  • Timestamp Display: Shows current time in HH:MM:SS format
  • Frame Counter: Displays current frame / total frames

9.2 Visual Feedback

  • Color-Coded Slots: Green (occupied), Yellow (vacant)
  • Service Badges: Color-coded service provider indicators (Uber: blue, Lyft: pink)
  • Hover Tooltips: Detailed vehicle information on car hover
  • Loading States: Visual indicators during data loading
  • Empty States: Helpful messages when no data available

9.3 Executive Dashboard Design

  • Bento Grid Layout: Organized, visually appealing information architecture
  • KPI Cards: Prominent display of key metrics
  • Chart Integration: Multiple chart types in unified layout
  • Responsive Design: Adapts to different screen sizes
  • Professional Styling: Sky Harbor brand colors and typography

10. Data Insights & Analytics

10.1 Operational Metrics

Peak Occupancy Analysis:

  • Identifies maximum simultaneous vehicle count
  • Pinpoints peak timestamp for capacity planning
  • Helps determine optimal slot allocation

Dwell Time Analysis:

  • Average dwell time indicates turnover efficiency
  • Maximum dwell time identifies outliers
  • Distribution histogram reveals patterns

Service Provider Distribution:

  • Market share analysis (Uber vs Lyft)
  • Temporal patterns in service usage
  • Helps with partnership negotiations

10.2 Slot Utilization Patterns

High-Usage Slots:

  • Identifies most frequently used parking spaces
  • Helps prioritize maintenance and improvements
  • Reveals traffic patterns

Low-Usage Slots:

  • Identifies underutilized spaces
  • Opportunities for optimization
  • Potential for reallocation

10.3 Reservation Analytics

Active Reservations:

  • Real-time count of active ride bookings
  • Helps with staffing decisions
  • Indicates demand levels

Reservation Duration:

  • Average booking length
  • Helps predict parking needs
  • Supports capacity planning

11. Technical Challenges & Solutions

Challenge 1: State Management Across Components

Problem: Multiple components need same data (frameData, stats, etc.) Solution: React Context Provider pattern with shared state Result: Single source of truth, efficient data sharing

Challenge 2: Smooth Animation Performance

Problem: Frame transitions were janky, poor performance Solution: requestAnimationFrame loop with CSS transitions Result: Smooth 60fps animation, hardware-accelerated

Challenge 3: Preventing Duplicate API Calls

Problem: Multiple components requesting same frame simultaneously Solution: Request deduplication with refs and loading flags Result: Eliminated duplicate requests, improved performance

Challenge 4: Handling Empty Parking Lot States

Problem: Metrics show "N/A" when no vehicles present Solution: Peak value caching with intelligent fallback Result: Always shows meaningful data, improved UX

Challenge 5: Accurate Slot Numbering

Problem: Backend slot IDs don't match visual layout Solution: Custom slot mapping utility with visual position sorting Result: Intuitive numbering, natural reading pattern


12. Future Enhancements

Potential Additions

  1. Real-Time Data Integration: Connect to live parking sensors
  2. Predictive Analytics: Machine learning for occupancy forecasting
  3. Alert System: Notifications for capacity thresholds
  4. Export Functionality: PDF/Excel reports generation
  5. Historical Comparisons: Compare different time periods
  6. Mobile App: Native mobile application
  7. Multi-Location Support: Extend to multiple parking areas
  8. Advanced Filtering: Filter by service, time range, etc.

13. Conclusion

The Sky Harbor Ride-Hailing Analytics Dashboard successfully transforms raw parking data into actionable insights through a modern, interactive web application. The system provides:

  • Real-time visualization of vehicle movements and occupancy
  • Comprehensive analytics with multiple chart types and KPIs
  • Executive-grade dashboard suitable for strategic decision-making
  • Scalable architecture ready for future enhancements
  • Performance-optimized for smooth user experience

Key Achievements:

  • Migrated from monolithic Dash app to modern full-stack architecture
  • Implemented smooth 60fps animation with 60+ frames
  • Created intelligent caching systems for optimal UX
  • Delivered comprehensive analytics suite
  • Achieved professional, executive-ready design

The dashboard enables Sky Harbor Airport to optimize parking operations, reduce passenger wait times, and make data-driven infrastructure decisions, ultimately improving overall airport operations and customer satisfaction.


Technical Specifications

Backend:

  • Python 3.x
  • FastAPI 0.104+
  • Pandas 2.0+
  • NumPy 1.24+
  • Uvicorn

Frontend:

  • React 18
  • Vite 5.0+
  • Axios 1.6+
  • Recharts 2.10+

Data:

  • Excel file format (.xlsx)
  • 60+ timestamps
  • 24 parking slots
  • Multiple vehicle types
  • Service provider data (Uber, Lyft)

Performance:

  • API response time: ~50ms average
  • Animation frame rate: 60fps target
  • Initial load time: <2 seconds
  • Smooth transitions: 0.45s CSS transitions

Case Study Document - Sky Harbor Ride-Hailing Analytics Dashboard Sources: https://unluckystudio.com/ , for free car sprite assets.