- RealtimeChart composable with Canvas-based rendering - TieredBuffer: 3-tier ring buffer (5min full-rate, 10min @10Hz, 45min @1Hz) for 1h data support with ~5MB footprint - LodDecimator: MEAN / MIN_MAX / MIN_MAX(default) / LTTB render-time decimation - AxisRenderer: X/Y axis with INSIDE/BESIDE/HIDDEN label modes, T0-relative timestamps, scientific notation - SignalRenderer: clipRect-bounded path rendering with LoD - ChartTheme: Material3-compatible dynamic theming (light/dark) - package: dev.dtrentin.chart Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
124 lines
4.1 KiB
Markdown
124 lines
4.1 KiB
Markdown
# Roadmap: chart-realtime
|
|
|
|
## Overview
|
|
|
|
Build a standalone KMP real-time chart module from scaffold to polished publishable library. Six phases: module setup → core data structures → state API → rendering engine → demo validation → polish. Phases 2+3 parallelizable; Phase 4 is the critical path.
|
|
|
|
## Current Milestone
|
|
|
|
**v0.1.0 — MVP**
|
|
Status: Not started
|
|
Phases: 0 of 6 complete
|
|
|
|
## Phases
|
|
|
|
| Phase | Name | Plans | Status | Completed |
|
|
|-------|------|-------|--------|-----------|
|
|
| 1 | Module Scaffold | 2 | Not started | - |
|
|
| 2 | Buffer + LoD | 2 | Not started | - |
|
|
| 3 | State API | 2 | Not started | - |
|
|
| 4 | Render Engine | 3 | Not started | - |
|
|
| 5 | Demo App | 1 | Not started | - |
|
|
| 6 | Polish + Docs | 2 | Not started | - |
|
|
|
|
## Phase Details
|
|
|
|
### Phase 1: Module Scaffold
|
|
|
|
**Goal:** Buildable KMP module structure + Gradle config ready for code
|
|
**Depends on:** Nothing
|
|
**Research:** Unlikely (standard KMP module setup)
|
|
|
|
**Scope:**
|
|
- KMP module `:chart-realtime` with commonMain / androidMain
|
|
- Version catalog entries (Compose, coroutines, kotlin.test)
|
|
- Demo app module `:app` depending on `:chart-realtime`
|
|
- Empty placeholder classes to confirm build passes
|
|
|
|
**Plans:**
|
|
- [ ] 01-01: KMP module + Gradle + version catalog
|
|
- [ ] 01-02: Demo app module + dependency wiring
|
|
|
|
### Phase 2: Buffer + LoD
|
|
|
|
**Goal:** Core data structures fully tested — CircularBuffer and LodDecimator
|
|
**Depends on:** Phase 1 (module builds)
|
|
**Research:** Unlikely (known algorithms)
|
|
|
|
**Scope:**
|
|
- `CircularBuffer` — pre-allocated FloatArray[timestamp, value], lock-free write, indexed read
|
|
- `LodDecimator` — min/max envelope per pixel column, O(n) single pass
|
|
- Unit tests for both (edge cases: empty, full, wrap-around, single point, fewer pts than pixels)
|
|
|
|
**Plans:**
|
|
- [ ] 02-01: CircularBuffer implementation + tests
|
|
- [ ] 02-02: LodDecimator implementation + tests
|
|
|
|
### Phase 3: State API
|
|
|
|
**Goal:** Public API surface complete — RealtimeChartState usable by consumers
|
|
**Depends on:** Phase 2 (CircularBuffer ready)
|
|
**Research:** Unlikely
|
|
|
|
**Scope:**
|
|
- `ChartConfig` data class (xWindowSeconds, yRange, t0, targetFps, maxBufferSeconds)
|
|
- `SignalConfig` data class (name, color, strokeWidth, visible)
|
|
- `YRange` sealed class (Auto, Fixed)
|
|
- `T0` sealed class (FirstSample, Fixed)
|
|
- `RealtimeChartState` — holds N CircularBuffers, addSignal/removeSignal, push(), collectFrom()
|
|
|
|
**Plans:**
|
|
- [ ] 03-01: Config models + sealed classes
|
|
- [ ] 03-02: RealtimeChartState + Flow collector
|
|
|
|
### Phase 4: Render Engine
|
|
|
|
**Goal:** Chart renders correctly at 200Hz with stable axes and smooth frame rate
|
|
**Depends on:** Phase 2 (LoD) + Phase 3 (State)
|
|
**Research:** Unlikely (Canvas API known)
|
|
|
|
**Scope:**
|
|
- `RenderLoop` — withFrameNanos, targetFps throttle, reads state snapshot
|
|
- `AxisRenderer` — X/Y gridlines, tick interval math, labels (DrawScope)
|
|
- `SignalRenderer` — FloatArray path build from LodDecimator output, drawLines
|
|
- `RealtimeChart()` composable — assembles all renderers, exposes ChartConfig + RealtimeChartState
|
|
|
|
**Plans:**
|
|
- [ ] 04-01: RenderLoop + AxisRenderer
|
|
- [ ] 04-02: SignalRenderer + path building
|
|
- [ ] 04-03: RealtimeChart composable integration
|
|
|
|
### Phase 5: Demo App
|
|
|
|
**Goal:** Running Android app proves 200Hz+ with 5+ signals without frame drops
|
|
**Depends on:** Phase 4 (rendering complete)
|
|
**Research:** Unlikely
|
|
|
|
**Scope:**
|
|
- Simulated sensor data source (coroutine emitting at 200Hz)
|
|
- 5 signals with distinct colors on single chart
|
|
- ChartConfig controls: xWindow, yRange mode, signal toggle
|
|
- Verify ≥55fps sustained via Android Studio profiler
|
|
|
|
**Plans:**
|
|
- [ ] 05-01: Demo app with 5-signal 200Hz simulation
|
|
|
|
### Phase 6: Polish + Docs
|
|
|
|
**Goal:** Publishable library with Material3 theming and minimal API docs
|
|
**Depends on:** Phase 5 (demo validated)
|
|
**Research:** Unlikely
|
|
|
|
**Scope:**
|
|
- Material3 default colors/typography for axis labels
|
|
- ChartTheme override support
|
|
- KDoc on all public API surface
|
|
- README with usage example (3-line integration)
|
|
- Maven local publish config
|
|
|
|
**Plans:**
|
|
- [ ] 06-01: Material3 theming + ChartTheme
|
|
- [ ] 06-02: KDoc + README + publish config
|
|
|
|
---
|
|
*Roadmap created: 2026-05-20*
|