KMPCharts/.paul/PROJECT.md
dtrentin b9ee5ddfa3 Initial commit: chart-realtime KMP library v0.4.1-SNAPSHOT
- 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>
2026-05-21 01:48:51 +02:00

4.3 KiB

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