# chart-realtime ## What This Is Standalone KMP module (Android-first) providing a high-performance Compose-based real-time line chart for sensor data visualization. Renders N simultaneous signals at 200Hz+ using Canvas with FIFO circular buffers and Level-of-Detail decimation. Packaged as a dependency consumable by any Android/KMP app. ## Core Value Android developers can plot multiple high-frequency sensor signals (200Hz+) on a single chart without dropping frames or overloading the device. ## Current State | Attribute | Value | |-----------|-------| | Type | Application (library module) | | Version | 0.0.0 | | Status | Initializing | | Last Updated | 2026-05-20 | ## Requirements ### Core Features - **Multi-signal real-time rendering** — N signals on same chart, each with own color/style, added/removed dynamically - **FIFO circular buffer** — pre-allocated, lock-free write (data thread) / safe read (render thread), maxBufferSeconds configurable by caller - **Level-of-Detail decimation** — min/max envelope per pixel column when buffer > pixel width; O(pixels) render cost regardless of buffer size - **Flexible axis control** — X axis: seconds from t0 (T0.FirstSample or T0.Fixed); Y axis: YRange.Auto(padding) or YRange.Fixed(min, max) - **Render rate decoupling** — data ingestion at any rate; rendering via withFrameNanos at display refresh rate (throttleable via targetFps param) - **Flow-based API** — addSignal(name, flow, config) + manual push(name, timestampMs, value) ### Validated (Shipped) None yet. ### Active (In Progress) None yet. ### Planned (Next) - Phase 1: KMP module scaffold + Gradle config - Phase 2: CircularBuffer + LodDecimator + unit tests - Phase 3: RealtimeChartState + Flow integration - Phase 4: Canvas rendering engine (RenderLoop, AxisRenderer, SignalRenderer) - Phase 5: Demo Android app (5+ signals at 200Hz) - Phase 6: Material3 polish + API documentation ### Out of Scope - iOS support (deferred to future milestone) - Touch interaction / zoom / pan - SciChart/paid-lib integration - Network data sources (consumer provides Flow) ## Target Users **Primary:** Android/KMP developers building sensor dashboards (IoT, medical, industrial) - Need 200Hz+ real-time plotting - Want drop-in Compose composable - Expect Material3 visual consistency ## Constraints ### Technical Constraints - KMP commonMain for all rendering logic (Compose Multiplatform Canvas) - No object allocation in draw loop (pre-allocated FloatArray paths) - Single draw call per signal (drawLines with FloatArray) - Lock-free circular buffer (data thread != render thread) - maxBufferSeconds: caller responsibility, no hard cap enforced by lib ### Business Constraints - Standalone publishable module (Maven local / GitHub Packages) - No paid/commercial dependencies ## Key Decisions | Decision | Rationale | Date | Status | |----------|-----------|------|--------| | Canvas custom rendering over existing libs | Vico/MPAndroidChart cannot handle 200Hz+ without axis jumps or FPS drops | 2026-05-20 | Active | | Render/data rate decoupling via withFrameNanos | 200Hz data != 60fps display; buffer absorbs delta | 2026-05-20 | Active | | LoD min/max decimation | 1h buffer at 200Hz = 720k pts; screen = ~800px; must reduce O(n)→O(px) | 2026-05-20 | Active | | maxBufferSeconds configurable, user responsibility | Avoid arbitrary caps; user knows their memory budget | 2026-05-20 | Active | | Android-first, iOS deferred | Reduce scope, ship faster | 2026-05-20 | Active | ## Success Metrics | Metric | Target | Current | Status | |--------|--------|---------|--------| | Sustained FPS at 200Hz, 5 signals | ≥55fps | - | Not started | | Memory per signal per hour at 200Hz | ≤3MB | - | Not started | | Demo app compiles and runs | Yes | - | Not started | | API: add signal in ≤3 lines of code | Yes | - | Not started | ## Tech Stack | Layer | Technology | Notes | |-------|------------|-------| | Language | Kotlin (KMP) | commonMain + androidMain | | UI | Jetpack Compose / Compose Multiplatform | Canvas DrawScope | | Build | Gradle + Version Catalog | Convention plugin if needed | | DI | None (library, no DI framework) | Consumer wires state | | Testing | kotlin.test + JUnit5 (androidTest) | Buffer + LoD unit tests | | Demo | Android app module | 5+ signals, 200Hz simulation | --- *PROJECT.md — Updated when requirements or context change* *Last updated: 2026-05-20*