Skip to content

ADR 013 Gantt Chart Rendering Strategy

Claude product-architect (Opus 4.6) edited this page Mar 5, 2026 · 2 revisions

ADR-013: Gantt Chart Rendering Strategy

Status

Accepted

Context

EPIC-06 requires an interactive Gantt chart for visualizing the home building project timeline. The chart must display work item task bars with duration, dependency arrows (FS/SS/FF/SF), critical path highlighting, a today marker, milestone markers, and household item delivery dates (visually distinct from work items). It must also support drag-and-drop date adjustment.

The key constraints are:

  1. No native binary frontend dependencies -- project policy (see Dependency Policy in CLAUDE.md) prohibits native binary dependencies for frontend tooling due to ARM64 emulation crashes in the CI/sandbox environment.
  2. CSS Modules styling -- the project uses CSS Modules (ADR-006), and the Gantt chart must integrate cleanly with this approach.
  3. React 19 compatibility -- some third-party charting libraries have known compatibility issues with React 19.
  4. Small dataset -- a typical home build project has 50--200 work items, making performance optimization less critical than it would be for enterprise-scale datasets.
  5. Accessibility -- the chart must support ARIA attributes for screen readers.
  6. Responsive design -- the chart must adapt to desktop, tablet, and mobile viewports.

Alternatives Considered

Library License React 19 Native Deps CSS Modules Bundle Size Notes
dhtmlxGantt Commercial (GPL for FOSS) Unknown No Limited (uses own CSS) ~200 KB min Feature-rich but heavy; commercial license for production use; opinionated styling makes CSS Modules integration difficult
frappe-gantt MIT No (jQuery-era API) No No (manipulates DOM directly) ~50 KB min Lightweight but no React wrapper; no dependency type support beyond FS; no critical path
Bryntum Gantt Commercial Yes No Limited ~500 KB min Most feature-complete; expensive commercial license ($2,000+); overkill for <5 users
Custom SVG N/A Yes No Yes 0 (custom) Full control over rendering, interactions, and accessibility; requires more implementation effort

Decision

Build a custom SVG-based Gantt chart rendered by React, with no third-party Gantt library.

The chart will be composed of standard React components that render SVG elements:

  • TimeGrid: SVG group rendering date columns, grid lines, and zoom-level-appropriate labels (days, weeks, months)
  • TaskBar: SVG rect for each work item, colored by status, with text label
  • DependencyArrow: SVG path for each dependency, using arrow markers, with different styles per dependency type
  • MilestoneMarker: SVG diamond shape at the milestone's target date
  • TodayLine: SVG vertical line at the current date
  • DeliveryMarker: SVG indicator for household item delivery dates (visually distinct shape/color)

Interactions (drag-and-drop, zoom, scroll, tooltips) will be handled via React event handlers on SVG elements. The zoom level determines the time unit granularity (day/week/month).

Consequences

What becomes easier

  • Full control over accessibility: ARIA attributes (role, aria-label, aria-describedby) can be placed on every SVG element. Screen readers can navigate task bars, read dependency relationships, and understand the critical path.
  • CSS Modules integration: SVG elements accept className props, so CSS Modules work naturally. No need to fight a library's CSS.
  • No licensing costs or concerns: No commercial license needed for a self-hosted, open-source-friendly project.
  • No dependency risk: No third-party release cycle to track. No risk of React 19 incompatibility or native binary issues.
  • Performance is naturally sufficient: With 50--200 items, SVG rendering is fast. No virtualization needed at this scale.
  • Responsive layout: Custom components can adapt their layout and zoom level based on viewport width using standard React patterns.

What becomes harder

  • Higher implementation effort: Every visual element (grid, bars, arrows, markers, zoom, scroll, drag-and-drop) must be implemented from scratch. This is the most significant trade-off.
  • Manual interaction handling: Drag-and-drop on SVG requires calculating coordinate transforms, handling mouse/touch events, and managing drag state. This is non-trivial but well-documented.
  • Time grid calculation: Converting between dates and pixel positions, handling different zoom levels, and rendering appropriate grid labels requires careful math.
  • Dependency arrow routing: Drawing arrows between task bars that avoid overlapping other bars requires basic path routing logic.

Mitigations

  • The dataset size (50--200 items) eliminates the need for virtualization or canvas rendering.
  • SVG-based drag-and-drop is a well-understood pattern with many reference implementations.
  • The scheduling engine (ADR-014) handles all date calculation; the Gantt chart is a pure visualization layer.
  • Incremental delivery: the chart can ship with basic rendering first, then add drag-and-drop and zoom in later stories.

Clone this wiki locally