# Agentic Flow Chart Module - Refactoring Progress

A flexible flowchart visualization system with animation support for creating animated diagrams of agent workflows, decision trees, and process flows.

## Current Module Structure - FINAL

```
agentic_flow_chart/
├── mod.rs (26 lines) - Module exports and public API
├── types.rs (69 lines) - Core enums and basic types
├── node.rs (138 lines) - FlowNode struct and content system
├── edge.rs (34 lines) - FlowEdge struct and routing hints
├── model.rs (235 lines) - Data model, style, and animation config
├── shapes.rs (157 lines) - Shape generation & polyline utilities
├── layout.rs (173 lines) - Layout calculation algorithms
├── routing.rs (395 lines) - Edge routing engine
├── animation.rs (284 lines) - Animation state computation
├── renderer.rs (555 lines) ⭐ NEW - Pure rendering engine
└── chart.rs (696 lines) - Main AgenticFlowChart (coordination only)
```

**Total: 2762 lines** (was 1973 in original single file)
**chart.rs reduced by 65%** (1973 → 696 lines)

## Refactoring Progress

### Phase 1: Model Extraction ✅ COMPLETE

**What was extracted:**
- `FlowChartModel` - Core data (nodes, edges, flow_path, direction, label_ids)
- `FlowChartStyle` - Visual styling (colors, sizes, gaps, thickness)
- `FlowChartAnimation` - Animation config (progress, reveal, animation styles)

**Benefits:**
- Clear separation of data vs behavior
- Builder pattern for each concern
- Easier to serialize/deserialize state
- Foundation for pipeline architecture

## Refactoring Complete ✅

All phases complete! The module now follows a clean pipeline architecture.

### Phase 4: Extract Renderer ✅ COMPLETE

**What was extracted:**
- `FlowRenderer` struct with pure rendering logic
- `RenderContext` - decoupled rendering parameters
- All rendering methods:
  - Node rendering (draw_node with Write/Drop/Instant styles)
  - Edge rendering (static and flow edges)
  - Indication highlights
  - Node content (text labels)
  - Pulse visualization
- Helper functions (emit_polyline, emit_arrowhead, translate_points)

**Benefits:**
- ~500 lines extracted from chart.rs
- Rendering is now a pure function
- Clear separation: chart.rs = coordination, renderer.rs = drawing
- RenderContext decouples renderer from AgenticFlowChart struct
- Easy to test rendering independently

**Integration:**
- project() is now a clean 3-step pipeline:
  1. Compute layouts
  2. Compute animation state
  3. Render
- All rendering logic delegated to FlowRenderer::render()
- Backward compatible - no API changes

### Phase 3: Extract Animation Engine ✅ COMPLETE

**What was extracted:**
- `FlowAnimationState` struct - computed animation state for a frame
- `AnimationEngine` with static methods for computing animation
- Reveal threshold calculation (resolved_reveal_thresholds logic)
- Active hop state computation
- Pulse position calculation
- Node write progress and indicate intensity helpers
- Edge progressive drawing logic

**Benefits:**
- ~300 lines extracted from chart.rs
- Animation state computed once per frame, reused everywhere
- No more scattered animation logic or repeated calculations
- Deterministic, testable animation system
- Easy to debug timing issues

**Integration:**
- project() now calls `AnimationEngine::compute()` once at the start
- All animation queries use the computed `FlowAnimationState`
- Static helper methods for node-specific calculations
- Backward compatible - no API changes

### Phase 2: Extract Routing Engine ✅ COMPLETE

**What was extracted:**
- `EdgeRouter` struct with `route()` method
- All routing algorithms (horizontal, vertical, loop routing)
- Manual routing with EdgeStep directions
- Route scoring and optimization
- Helper functions (anchor_for_step, opposite_step, best_route, etc.)

**Benefits:**
- ~400 lines extracted from chart.rs
- Routing logic is now isolated and testable
- Easy to add new routing algorithms (A*, grid routing, etc.)
- Clear separation between routing and rendering

**Integration:**
- chart.rs now has a simple `edge_route()` wrapper that calls `EdgeRouter::route()`
- All routing complexity moved to routing.rs
- Backward compatible - no API changes

### What's Been Modularized So Far

1. **types.rs** (69 lines)
   - All enums: FlowChartDirection, FlowNodeShape, EdgeStep
   - Animation styles: NodeAnimationStyle, EdgeAnimationStyle
   - FlowNodeArrival, NodeLayout

2. **node.rs** (138 lines)
   - FlowNode struct with builder pattern
   - FlowNodeContent trait
   - ProjectedFlowNodeContent wrapper

3. **edge.rs** (34 lines)
   - FlowEdge struct with routing hints

5. **model.rs** (235 lines)
   - FlowChartModel - data container
   - FlowChartStyle - styling configuration
   - FlowChartAnimation - animation state

6. **routing.rs** (395 lines) ⭐ NEW
   - EdgeRouter struct
   - All routing algorithms
   - Route scoring and optimization

7. **shapes.rs** (157 lines)
   - Shape generation (shape_mesh, shape_outline)
   - Polyline utilities (partial_polyline, polyline_length)
   - Grid routing helper (next_level_val)

9. **animation.rs** (284 lines) ⭐ NEW
   - FlowAnimationState struct
   - AnimationEngine with compute() method
   - All animation logic (thresholds, hop state, pulse position)

10. **renderer.rs** (555 lines) ⭐ NEW
   - FlowRenderer with render() method
   - RenderContext struct (decoupled parameters)
   - All rendering logic (nodes, edges, indications, pulse)
   - Helper functions (emit_polyline, emit_arrowhead)

11. **layout.rs** (173 lines)
   - Layout calculation algorithms
   - Custom placement logic
   - Layout extent calculations

### What's in chart.rs Now (696 lines) - FINAL

chart.rs is now pure coordination:

1. **Core Struct & Builders** (~350 lines)
   - AgenticFlowChart struct definition
   - Builder methods
   - Public API

2. **Coordination Logic** (~200 lines)
   - node_layouts() - delegates to layout engine
   - edge_route() - delegates to routing engine
   - project() - 3-line pipeline
   - Helper methods (connection_pairs, node_center, etc.)

3. **Utilities** (~146 lines)
   - Bounded implementation
   - Content projection helpers
   - Arrival time calculations

**The project() method is now:**
```rust
fn project(&self, ctx: &mut ProjectionCtx) {
    let layouts = self.node_layouts();
    let anim_state = AnimationEngine::compute(...);
    let render_ctx = RenderContext { ... };
    FlowRenderer::render(ctx, &render_ctx, &layouts, &anim_state, ...);
}
```

This is exactly the pipeline architecture we wanted!

## Next Steps

**STOP HERE** - The refactoring is complete!

The architecture is now production-ready:
- Model → Layout → Animation → Routing → Render
- Each system is isolated, testable, and reusable
- chart.rs is pure coordination (696 lines)
- No over-engineering, no unnecessary abstractions

Time to ship demos and build features!
        style: &FlowChartStyle,
    ) -> Option<Vec<Vec3>> { ... }
}
```

**Impact:** ~300 lines extracted, animation becomes deterministic

### Phase 4: Extract Renderer
```rust
pub struct FlowAnimationState {
    pub node_thresholds: Vec<f32>,
    pub edge_thresholds: Vec<f32>,
}

pub struct AnimationEngine;

impl AnimationEngine {
    pub fn compute(...) -> FlowAnimationState;
}
```

**Impact:** ~300 lines extracted, animation becomes deterministic

### Phase 4: Extract Renderer
```rust
pub struct FlowRenderer;

impl FlowRenderer {
    pub fn render(
        ctx: &mut ProjectionCtx,
        model: &FlowChartModel,
        layout: &[NodeLayout],
        anim: &FlowAnimationState,
        style: &FlowChartStyle,
    );
}
```

**Impact:** ~500 lines extracted, rendering becomes pure function

### End Goal: Pipeline Architecture

```rust
fn project(&self, ctx: &mut ProjectionCtx) {
    // Pure pipeline: Model → Layout → Animation → Routing → Render
    let layouts = FlowLayoutEngine::compute(&self.model, &self.style);
    let anim = AnimationEngine::compute(&self.model, &self.animation);
    
    FlowRenderer::render(ctx, &self.model, &layouts, &anim, &self.style);
}
```

## Benefits of This Architecture

1. **Testability** - Each system can be tested independently
2. **Predictability** - Pure functions, explicit dependencies
3. **Extensibility** - Easy to add new routing algorithms, animation styles
4. **Debuggability** - Clear data flow, no hidden coupling
5. **Performance** - Can cache intermediate results (layouts, routes)
6. **Maintainability** - Each file has single responsibility

## Usage Example

```rust
use murali::frontend::collection::ai::agentic_flow_chart::*;

let nodes = vec![
    FlowNode::new("Start").with_shape(FlowNodeShape::Pill),
    FlowNode::new("Process").with_shape(FlowNodeShape::Rounded),
    FlowNode::new("End").with_shape(FlowNodeShape::Pill),
];

let chart = AgenticFlowChart::new(nodes)
    .with_edges(vec![
        FlowEdge::new(0, 1),
        FlowEdge::new(1, 2),
    ])
    .with_flow_path(vec![0, 1, 2])
    .with_direction(FlowChartDirection::Vertical)
    .with_node_animation_style(NodeAnimationStyle::Write)
    .with_progressive_edges(true);
```

## Key Insights from ChatGPT

> "Right now your system is: 'Object with behavior'  
> You want to move toward: 'Pipeline of systems'  
> Model → Layout → Animation → Routing → Render"

This aligns perfectly with:
- ECS (Entity Component System) thinking
- GPU pipeline architecture
- Manim-style mental model

The refactoring is moving us from implicit, scattered logic to explicit, composable systems.

