# Atomizer Dashboard

**Last Updated**: November 23, 2025

---

## Overview

The Atomizer Dashboard is a real-time web-based interface for monitoring and analyzing multi-objective optimization studies. Built with React, TypeScript, and Tailwind CSS, it provides comprehensive visualization and interaction capabilities for NSGA-II based structural optimization.

---

## Architecture

### Frontend Stack
- **Framework**: React 18 with TypeScript
- **Build Tool**: Vite
- **Styling**: Tailwind CSS with custom dark/light theme support
- **Charts**: Recharts for data visualization
- **State Management**: React hooks (useState, useEffect)
- **WebSocket**: Real-time optimization updates

### Backend Stack
- **Framework**: FastAPI (Python)
- **Database**: Optuna SQLite studies
- **API**: RESTful endpoints with WebSocket support
- **CORS**: Configured for local development

### Ports
- **Frontend**: `http://localhost:3003` (Vite dev server)
- **Backend**: `http://localhost:8000` (FastAPI/Uvicorn)

---

## Key Features

### 1. Multi-Objective Visualization

#### Pareto Front Plot
- 2D scatter plot showing trade-offs between objectives
- Color-coded by constraint satisfaction (green = feasible, red = infeasible)
- Interactive hover tooltips with trial details
- Automatically extracts Pareto-optimal solutions using NSGA-II

#### Parallel Coordinates Plot
**Research-Based Multi-Dimensional Visualization**

Structure: **Design Variables → Objectives → Constraints**

Features:
- **Light Theme**: White background with high-visibility dark text and colors
- **Color-Coded Axes**:
  - Blue background: Design variables
  - Green background: Objectives
  - Yellow background: Constraints
- **Interactive Selection**:
  - Hover over lines to highlight individual trials
  - Click to select/deselect trials
  - Multi-select with visual feedback (orange highlight)
- **Type Badges**: Labels showing DESIGN VAR, OBJECTIVE, or CONSTRAINT
- **Units Display**: Automatic unit labeling (mm, MPa, Hz, g, etc.)
- **Min/Max Labels**: Range values displayed on each axis
- **Feasibility Coloring**:
  - Green: Feasible solutions
  - Red: Infeasible solutions (constraint violations)
  - Blue: Hover highlight
  - Orange: Selected trials

**Implementation**: [ParallelCoordinatesPlot.tsx](atomizer-dashboard/frontend/src/components/ParallelCoordinatesPlot.tsx:1)

**Line colors**:
```typescript
if (isSelected) return '#FF6B00';      // Orange for selected
if (!trial.feasible) return '#DC2626'; // Red for infeasible
if (isHovered) return '#2563EB';       // Blue for hover
return '#10B981';                       // Green for feasible
```

### 2. Optimizer Strategy Panel
Displays algorithm information:
- **Algorithm**: NSGA-II, TPE, or custom
- **Type**: Single-objective or Multi-objective
- **Objectives Count**: Number of optimization objectives
- **Design Variables Count**: Number of design parameters

### 3. Convergence Monitoring
- **Convergence Plot**: Best value vs. trial number
- **Real-time Updates**: WebSocket-driven live updates
- **Pruned Trials**: Visual indication of pruned trials

### 4. Parameter Space Exploration
- **2D Scatter Plot**: Design variable relationships
- **Color Mapping**: Objective values mapped to color intensity
- **Interactive Tooltips**: Trial details on hover

### 5. Trial History Table
- Comprehensive list of all trials
- Sortable columns
- Status indicators (COMPLETE, PRUNED, FAIL)
- Parameter values and objective values
- User attributes (constraints)

---

## API Endpoints

### Studies

#### GET `/api/optimization/studies`
List all available optimization studies.

**Response**:
```json
[
  {
    "id": "drone_gimbal_arm_optimization",
    "name": "drone_gimbal_arm_optimization",
    "direction": ["minimize", "maximize"],
    "n_trials": 100,
    "best_value": [3245.67, 165.3],
    "sampler": "NSGAIISampler"
  }
]
```

#### GET `/api/optimization/studies/{study_id}/trials`
Get all trials for a study.

**Response**:
```json
{
  "trials": [
    {
      "number": 0,
      "values": [3456.2, 145.6],
      "params": {
        "beam_half_core_thickness": 7.5,
        "beam_face_thickness": 2.1,
        "holes_diameter": 30.0,
        "hole_count": 11
      },
      "state": "COMPLETE",
      "user_attrs": {
        "max_stress": 95.3,
        "max_displacement": 1.2,
        "frequency": 145.6,
        "mass": 3456.2,
        "constraint_satisfied": true
      }
    }
  ]
}
```

#### GET `/api/optimization/studies/{study_id}/metadata`
Get study metadata including objectives and design variables.

**Response**:
```json
{
  "objectives": [
    {
      "name": "mass",
      "type": "minimize",
      "unit": "g"
    },
    {
      "name": "frequency",
      "type": "maximize",
      "unit": "Hz"
    }
  ],
  "design_variables": [
    {
      "name": "beam_half_core_thickness",
      "unit": "mm",
      "min": 5.0,
      "max": 10.0
    }
  ],
  "sampler": "NSGAIISampler"
}
```

#### GET `/api/optimization/studies/{study_id}/pareto-front`
Get Pareto-optimal solutions for multi-objective studies.

**Response**:
```json
{
  "is_multi_objective": true,
  "pareto_front": [
    {
      "trial_number": 0,
      "values": [3245.67, 165.3],
      "params": {...},
      "user_attrs": {...},
      "constraint_satisfied": true
    }
  ]
}
```

### WebSocket

#### WS `/ws/optimization/{study_id}`
Real-time trial updates during optimization.

**Message Format**:
```json
{
  "type": "trial_complete",
  "trial": {
    "number": 5,
    "values": [3456.2, 145.6],
    "params": {...}
  }
}
```

---

## Running the Dashboard

### Backend

```bash
cd atomizer-dashboard/backend
python -m uvicorn api.main:app --reload --port 8000
```

### Frontend

```bash
cd atomizer-dashboard/frontend
npm run dev
```

Access at: `http://localhost:3003`

---

## Configuration

### Vite Proxy ([vite.config.ts](atomizer-dashboard/frontend/vite.config.ts:1))

```typescript
export default defineConfig({
  plugins: [react()],
  server: {
    host: '0.0.0.0',
    port: 3003,
    proxy: {
      '/api': {
        target: 'http://127.0.0.1:8000',
        changeOrigin: true,
        secure: false,
        ws: true,  // WebSocket support
      }
    }
  }
})
```

### CORS ([backend/api/main.py](atomizer-dashboard/backend/api/main.py:1))

```python
app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:3003"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
```

---

## Component Structure

```
atomizer-dashboard/
├── frontend/
│   ├── src/
│   │   ├── components/
│   │   │   ├── ParallelCoordinatesPlot.tsx    # Multi-objective visualization
│   │   │   ├── ParetoPlot.tsx                  # Pareto front scatter plot
│   │   │   ├── OptimizerPanel.tsx              # Strategy information
│   │   │   ├── common/
│   │   │   │   └── Card.tsx                    # Reusable card component
│   │   │   └── dashboard/
│   │   │       ├── MetricCard.tsx              # KPI display
│   │   │       └── StudyCard.tsx               # Study selector
│   │   ├── pages/
│   │   │   └── Dashboard.tsx                   # Main dashboard page
│   │   ├── hooks/
│   │   │   └── useWebSocket.ts                 # WebSocket connection
│   │   ├── api/
│   │   │   └── client.ts                       # API client
│   │   └── types/
│   │       └── index.ts                        # TypeScript types
│   └── vite.config.ts
└── backend/
    └── api/
        ├── main.py                              # FastAPI app
        └── routes/
            └── optimization.py                  # Optimization endpoints
```

---

## Data Flow

1. **Optimization Engine** runs trials and stores results in Optuna SQLite database
2. **Backend API** reads from database and exposes REST endpoints
3. **Frontend** fetches data via `/api/optimization/*` endpoints
4. **WebSocket** pushes real-time updates to connected clients
5. **React Components** render visualizations based on fetched data

---

## Troubleshooting

### Dashboard Page Crashes

**Issue**: `TypeError: Cannot read properties of undefined (reading 'split')`

**Fix**: Ensure all data is validated before rendering. ParallelCoordinatesPlot now includes:
```typescript
if (!paretoData || paretoData.length === 0) return <EmptyState />;
if (!objectives || !designVariables) return <EmptyState />;
```

### No Data Showing

1. Check backend is running: `curl http://localhost:8000/api/optimization/studies`
2. Verify study exists in Optuna database
3. Check browser console for API errors
4. Ensure WebSocket connection is established

### CORS Errors

- Backend must allow origin `http://localhost:3003`
- Frontend proxy must target `http://127.0.0.1:8000` (not `localhost`)

---

## Best Practices

### For Multi-Objective Studies

1. **Always use metadata endpoint** to get objective/variable definitions
2. **Extract constraints from user_attrs** for parallel coordinates
3. **Filter Pareto front** using `paretoData.pareto_front` array
4. **Validate constraint_satisfied** field before coloring

### For Real-Time Updates

1. **Use WebSocket** for live trial updates
2. **Debounce state updates** to avoid excessive re-renders
3. **Close WebSocket** connection on component unmount

### For Performance

1. **Limit displayed trials** for large studies (e.g., show last 1000)
2. **Use React.memo** for expensive components
3. **Virtualize large lists** if showing >100 trials in tables

---

## Future Enhancements

- [ ] 3D Pareto front visualization for 3+ objectives
- [ ] Advanced filtering and search in trial history
- [ ] Export results to CSV/JSON
- [ ] Custom parallel coordinates brushing/filtering
- [ ] Multi-study comparison view
- [ ] Hypervolume indicator tracking
- [ ] Interactive design variable sliders
- [ ] Constraint importance analysis

---

## References

- **Optuna Documentation**: https://optuna.readthedocs.io/
- **NSGA-II Algorithm**: Deb et al. (2002)
- **Parallel Coordinates**: Inselberg & Dimsdale (1990)
- **React Documentation**: https://react.dev/
- **FastAPI Documentation**: https://fastapi.tiangolo.com/
