-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
enhancementNew feature or requestNew feature or request
Description
Chart Component Refactoring
Problem
ShotHistoryView.tsx is a 3,039-line monolith that contains inline Recharts rendering logic, custom tooltips, chart constants, and stage coloring — all duplicated from what now exists in the shared charts/ directory.
During the Control Center implementation (#169 Phase 3), we extracted reusable chart components into apps/web/src/components/charts/:
| File | Purpose |
|---|---|
chartConstants.ts |
Colors, themes, stage ranges, speed options |
CustomTooltip.tsx |
Shared tooltip component for Recharts |
EspressoChart.tsx |
Reusable espresso shot chart with pressure/flow/weight/temp traces |
index.ts |
Barrel exports |
These components are used by LiveShotView.tsx for real-time shot monitoring. However, ShotHistoryView.tsx still uses its own inline versions of the same logic — it imports recharts directly and has its own tooltip, color constants, and chart rendering code.
Goals
- Eliminate duplication —
ShotHistoryViewshould import from@/components/charts/instead of maintaining parallel implementations - Reduce file size — Target: from 3,039 lines to under 1,500 lines by extracting chart logic and splitting into sub-components
- Zero visual regression — Shot history charts must look identical before and after refactoring
- Establish chart conventions — All future chart rendering goes through the shared
charts/components
Current Architecture
ShotHistoryView.tsx (3,039 lines)
├── Inline Recharts imports (recharts directly)
├── Inline color constants (duplicated from chartConstants.ts)
├── Inline tooltip component (duplicated from CustomTooltip.tsx)
├── Inline chart rendering logic (duplicated from EspressoChart.tsx)
├── Shot list / selection UI
├── Shot analysis display
├── Profile overlay logic
├── Stage highlighting
└── Export / comparison features
charts/
├── chartConstants.ts ← shared, used by LiveShotView only
├── CustomTooltip.tsx ← shared, used by LiveShotView only
├── EspressoChart.tsx ← shared, used by LiveShotView only
└── index.ts
Target Architecture
ShotHistoryView.tsx (~800-1000 lines)
├── Shot list / selection logic
├── Shot analysis display
├── Orchestration (which sub-view to show)
└── Export / comparison features
charts/
├── chartConstants.ts ← shared by LiveShotView + ShotHistoryView
├── CustomTooltip.tsx ← shared by LiveShotView + ShotHistoryView
├── EspressoChart.tsx ← shared by LiveShotView + ShotHistoryView
├── ChartOverlay.tsx ← NEW: profile target curve overlay component
├── StageHighlight.tsx ← NEW: extraction stage coloring/bands
├── index.ts ← updated barrel exports
ShotHistoryView/
├── ShotHistoryView.tsx ← main orchestrator (slim)
├── ShotList.tsx ← shot selection sidebar/list
├── ShotDetail.tsx ← individual shot analysis display
├── ShotComparison.tsx ← side-by-side shot comparison
└── index.ts
Implementation Plan
Step 1: Audit & Map Duplications
- Catalog all inline chart constants in
ShotHistoryView.tsxand compare withchartConstants.ts - Catalog all inline tooltip logic and compare with
CustomTooltip.tsx - Catalog all inline Recharts usage and compare with
EspressoChart.tsx - Identify
ShotHistoryView-specific chart features not yet in shared components (profile overlays, stage bands, comparison mode) - Create a mapping document: what moves where
Step 2: Extend Shared Chart Components
- Extend
chartConstants.tswith any missing constants fromShotHistoryView - Extend
CustomTooltip.tsxto handleShotHistoryView's tooltip variations (or make it configurable via props) - Extend
EspressoChart.tsxwith props for profile overlay, stage highlighting, and static (non-live) data display - Create
ChartOverlay.tsx— profile target curve overlay (currently inline in ShotHistoryView) - Create
StageHighlight.tsx— extraction stage coloring bands (if complex enough to warrant extraction) - Update
charts/index.tsbarrel exports
Step 3: Split ShotHistoryView into Sub-Components
- Extract
ShotList.tsx— shot selection list/sidebar with search, filtering, date grouping - Extract
ShotDetail.tsx— individual shot analysis view (chart + metadata + analysis text) - Extract
ShotComparison.tsx— side-by-side comparison mode (if it exists) - Create
ShotHistoryView/index.tsbarrel export - Slim down
ShotHistoryView.tsxto orchestration only
Step 4: Wire Up & Replace
- Replace all inline Recharts usage in ShotHistoryView with
EspressoChartfrom shared components - Replace inline tooltip with shared
CustomTooltip - Replace inline color constants with shared
chartConstants - Remove all direct
rechartsimports from ShotHistoryView - Verify TypeScript compiles with zero errors
Step 5: Visual Regression Testing
- Screenshot before: Shot history list view
- Screenshot before: Individual shot chart (with profile overlay)
- Screenshot before: Shot with stage highlighting
- Screenshot before: Mobile shot history
- Refactor code
- Screenshot after: Compare all above views pixel-by-pixel
- Verify dark mode and light mode both render correctly
- Verify desktop two-column and mobile single-column layouts
Step 6: Cleanup
- Remove dead code from ShotHistoryView
- Run
bun run build— verify production build succeeds - Run TypeScript strict check — zero errors
- Update any imports elsewhere in the app that reference ShotHistoryView
- Update i18n keys if any component boundaries changed
Constraints
- No new dependencies — use only existing Recharts + shared chart components
- No API changes — this is purely a frontend refactoring
- No behavior changes — all chart interactions (zoom, hover, click) must work identically
- Incremental commits — each step should be a separate commit for easy bisection
Definition of Done
-
ShotHistoryView.tsxis under 1,500 lines (ideally under 1,000) - Zero direct
rechartsimports inShotHistoryView(uses sharedcharts/only) - All chart rendering goes through shared components
- Visual regression: zero pixel differences in charts (verified via screenshots)
-
bun run buildsucceeds, TypeScript zero errors - All existing backend tests still pass (512+)
- Code review: no duplicated chart logic anywhere in the codebase
References
- Control Center spec:
CONTROL_CENTER_SPEC.md§9 (Chart Reuse Strategy) - Shared chart components:
apps/web/src/components/charts/ - Target file:
apps/web/src/components/ShotHistoryView.tsx(3,039 lines) - Related: Integrate @nickwilsonr/meticulous-addon via MQTT for Machine Status and Fine-Grained Control - Meticulous Control Center #169 (Control Center — introduced the shared chart components)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request