Calendar/complexity_comparison.md
Janus Knudsen 72019a3d9a wip
2025-09-09 14:35:21 +02:00

5.2 KiB

EventOverlapManager Complexity Comparison

Original vs Simplified Implementation

Lines of Code Comparison

Aspect Original Simplified Reduction
Total Lines ~453 lines ~220 lines 51% reduction
Stack Management ~150 lines ~20 lines 87% reduction
State Tracking Complex Map + linked list Simple DOM queries 100% elimination

Key Simplifications

1. Eliminated Complex State Tracking

Before:

// Complex linked list tracking
private stackChains = new Map<string, { 
  next?: string, 
  prev?: string, 
  stackLevel: number 
}>();

private removeFromStackChain(eventId: string): string[] {
  // 25+ lines of linked list manipulation
  const chainInfo = this.stackChains.get(eventId);
  // Complex prev/next linking logic...
}

After:

// Simple DOM-based approach
public restackEventsInContainer(container: HTMLElement): void {
  const stackedEvents = Array.from(container.querySelectorAll('swp-event'))
    .filter(el => this.isStackedEvent(el as HTMLElement));
  
  stackedEvents.forEach((element, index) => {
    element.style.marginLeft = `${(index + 1) * 15}px`;
  });
}

2. Simplified Event Detection

Before:

public isStackedEvent(element: HTMLElement): boolean {
  const eventId = element.dataset.eventId;
  const hasMarginLeft = element.style.marginLeft !== '';
  const isInStackChain = eventId ? this.stackChains.has(eventId) : false;
  
  // Two different ways to track the same thing
  return hasMarginLeft || isInStackChain;
}

After:

public isStackedEvent(element: HTMLElement): boolean {
  const marginLeft = element.style.marginLeft;
  return marginLeft !== '' && marginLeft !== '0px';
}

3. Cleaner Group Management

Before:

public removeFromEventGroup(container: HTMLElement, eventId: string): boolean {
  // 50+ lines including:
  // - Stack chain checking
  // - Complex position calculations
  // - Multiple cleanup scenarios
  // - Affected event re-stacking
}

After:

public removeFromEventGroup(container: HTMLElement, eventId: string): boolean {
  // 20 lines of clean, focused logic:
  // - Remove element
  // - Handle remaining events
  // - Simple container cleanup
}

Benefits of Simplified Approach

Maintainability

  • No complex state synchronization
  • Single source of truth (DOM)
  • Easier to debug and understand

Performance

  • No Map lookups or linked list traversal
  • Direct DOM queries when needed
  • Simpler memory management

Reliability

  • No state desynchronization bugs
  • Fewer edge cases
  • More predictable behavior

Code Quality

  • 51% fewer lines of code
  • Simpler mental model
  • Better separation of concerns

What Was Eliminated

🗑️ Removed Complexity

  1. Linked List Management: Complex next/prev chain tracking
  2. State Synchronization: Keeping DOM and Map in sync
  3. Chain Reconstruction: Complex re-linking after removals
  4. Dual Tracking: Both style-based and Map-based state
  5. Edge Case Handling: Complex scenarios from state mismatches

🎯 Retained Functionality

  1. Column Sharing: Flexbox groups work exactly the same
  2. Event Stacking: Visual stacking with margin-left offsets
  3. Overlap Detection: Same time-based algorithm
  4. Drag and Drop: Full drag support maintained
  5. Visual Appearance: Identical user experience

Risk Assessment

⚠️ Potential Concerns

  1. DOM Query Performance: More DOM queries vs Map lookups

    • Mitigation: Queries are scoped to specific containers
    • Reality: Minimal impact for typical calendar usage
  2. State Reconstruction: Re-calculating vs cached state

    • Mitigation: DOM is the single source of truth
    • Reality: Eliminates sync bugs completely

Benefits Outweigh Risks

  • Dramatically simpler codebase
  • Eliminated entire class of state sync bugs
  • Much easier to debug and maintain
  • Better separation of concerns

Migration Strategy

  1. Created SimpleEventOverlapManager
  2. Updated EventRenderer imports
  3. Simplified drag handling methods
  4. Maintained API compatibility
  5. Testing phase completed
  6. Removed old EventOverlapManager (legacy code eliminated)

Conclusion

The simplified approach provides identical functionality with:

  • 51% less code
  • 87% simpler stack management
  • Zero state synchronization bugs
  • Much easier maintenance

Migration completed successfully - the old EventOverlapManager has been removed and the system now uses the cleaner SimpleEventOverlapManager implementation.

This is a perfect example of how complexity often accumulates unnecessarily and how a DOM-first approach can be both simpler and more reliable than complex state management.

See Also