# ProfilerDiagram Component

Svelte 5 component wrapper for the `profiler-lib` visualization library. Provides lifecycle management and reactive integration for displaying Feldera DBSP circuit profiles.

## Usage

```svelte
<script lang="ts">
  import ProfilerDiagram from '$lib/components/profiler/ProfilerDiagram.svelte'
  import type { JsonProfiles, Dataflow } from 'profiler-lib'

  // Fetch profile data from pipeline manager API
  const profileData: JsonProfiles = await pipelineManagerClient.getPipelineProfile(pipelineId)

  // Fetch dataflow graph (currently requires manual SQL compilation)
  const dataflowData: Dataflow = await fetchDataflowGraph()
</script>

<div style="width: 100%; height: 100vh;">
  <ProfilerDiagram {profileData} {dataflowData} />
</div>
```

## Props

| Prop           | Type           | Required | Description                                                   |
| -------------- | -------------- | -------- | ------------------------------------------------------------- |
| `profileData`  | `JsonProfiles` | Yes      | Profile data from pipeline manager's circuit profile endpoint |
| `dataflowData` | `Dataflow`     | Yes      | Dataflow graph from SQL compiler with `--dataflow` flag       |
| `class`        | `string`       | No       | Optional CSS class for styling the wrapper container          |

## Features

### Automatic Lifecycle Management

- **Reactive initialization**: Automatically initializes profiler when data changes
- **Resource cleanup**: Properly disposes profiler instance on unmount or data change
- **Error handling**: Catches and displays initialization errors

### Layout

The component provides a complete UI layout:

```
┌─────────────────────────────────────┐
│  Error Banner (if any)              │
├────────────┬────────────────────────┤
│            │                        │
│  Sidebar   │   Graph Visualization  │
│            │                        │
│  ┌─────┐   │                        │
│  │Ctrl │   │   [Cytoscape Canvas]   │
│  │     │   │                        │
│  └─────┘   │                        │
│            │                        │
│  ┌─────┐   │                        │
│  │Mini │   │                        │
│  │ map │   │                        │
│  └─────┘   │                        │
└────────────┴────────────────────────┘
```

**Sidebar** (left):

- Metric selector dropdown (time%, memory, etc.)
- Worker thread checkboxes
- Navigator minimap

**Main Area** (right):

- Interactive graph with pan/zoom
- Color-coded nodes (performance heatmap)
- Hover tooltips with metrics and SQL source

## Styling

The component includes default styles but can be customized:

```svelte
<ProfilerDiagram {profileData} {dataflowData} class="custom-profiler" />

<style>
  :global(.custom-profiler) {
    /* Override wrapper styles */
  }

  :global(.custom-profiler .profiler-graph) {
    /* Override graph container */
  }
</style>
```

### CSS Variables (Future Enhancement)

Consider adding CSS custom properties for theming:

- `--profiler-bg-color`
- `--profiler-border-color`
- `--profiler-sidebar-width`

## Data Requirements

### Profile Data (`JsonProfiles`)

Obtained from pipeline manager API:

```typescript
GET / v0 / pipelines / { pipeline_name } / circuit_profile
```

Contains:

- `worker_profiles[]`: Per-worker performance measurements
- `graph`: Circuit structure (nodes, edges, hierarchies)

### Dataflow Graph (`Dataflow`)

Generated by SQL compiler:

```bash
cd sql-to-dbsp-compiler
./SQL-compiler/sql-to-dbsp \
  --input program.sql \
  --dataflow output.json
```

Contains:

- `sources[]`: SQL source code lines
- `mir`: MIR node operations with source positions
- Mappings between SQL code and circuit operators

**Note**: Currently requires manual compilation. Future enhancement: fetch from pipeline manager API.

## Integration Example

```svelte
<script lang="ts">
  import { onMount } from 'svelte'
  import ProfilerDiagram from '$lib/components/profiler/ProfilerDiagram.svelte'
  import type { JsonProfiles, Dataflow } from 'profiler-lib'

  let profileData = $state<JsonProfiles | null>(null)
  let dataflowData = $state<Dataflow | null>(null)
  let loading = $state(true)
  let error = $state<string | null>(null)

  onMount(async () => {
    try {
      // Fetch both datasets in parallel
      const [profile, dataflow] = await Promise.all([
        fetch(`/v0/pipelines/${pipelineId}/circuit_profile`).then((r) => r.json()),
        fetch(`/dataflow/${pipelineId}.json`).then((r) => r.json())
      ])

      profileData = profile
      dataflowData = dataflow
    } catch (e) {
      error = e instanceof Error ? e.message : 'Failed to load profiler data'
    } finally {
      loading = false
    }
  })
</script>

{#if loading}
  <div class="loading">Loading profiler...</div>
{:else if error}
  <div class="error">{error}</div>
{:else if profileData && dataflowData}
  <ProfilerDiagram {profileData} {dataflowData} />
{/if}
```

## User Interactions

Once rendered, users can:

1. **Select Metrics**: Choose which performance metric colors nodes (dropdown)
2. **Filter Workers**: Show/hide individual worker threads (checkboxes)
3. **Navigate Graph**: Pan/zoom with mouse, use minimap for overview
4. **Expand Nodes**: Double-click to expand/collapse hierarchical regions
5. **Inspect Details**: Hover over nodes to see:
   - All metrics across visible workers
   - SQL source code that generated the operator
   - Node metadata (ID, operation type, parent)
6. **Trace Paths**: Hover highlights forward (red) and backward (blue) edges

## Performance Notes

- **Initial layout**: ELK algorithm is high-quality but slower than force-directed
- **Incremental updates**: Uses ZSet diffing for efficient re-rendering
