# chart-realtime KMP real-time line chart for Android. Renders multiple sensor signals at 200Hz+ without frame drops. ## Features - Multiple signals on one chart, added/removed dynamically - FIFO circular buffer — lock-free writes at 200Hz+, safe render reads at 60fps - Level-of-Detail decimation — renders O(pixels) regardless of buffer size (1h+ of data) - X axis: scrolling window, seconds from configurable t0 - Y axis: auto-fit or fixed range - Material3 default theme, fully customizable via `ChartTheme` ## Installation ```kotlin // settings.gradle.kts include(":chart-realtime") ``` Or Maven local: ```bash ./gradlew :chart-realtime:publishToMavenLocal ``` ```kotlin // build.gradle.kts implementation("eu.henesis:chart-realtime:0.1.0-SNAPSHOT") ``` ## Quick start (3 lines) ```kotlin val state = remember { RealtimeChartState(ChartConfig()) } LaunchedEffect(state) { state.addSignal("ecg", SignalConfig(color = Color.Green)) sensorFlow.collect { v -> state.push("ecg", System.currentTimeMillis(), v) } } RealtimeChart(state = state, modifier = Modifier.fillMaxSize()) ``` ## Configuration ```kotlin ChartConfig( xWindowSeconds = 10f, // visible window width yRange = YRange.Auto(), // or YRange.Fixed(-1f, 1f) t0 = T0.FirstSample, // or T0.Fixed(epochMs) targetFps = null, // null = display refresh rate maxBufferSeconds = 3600f, // 1h history per signal theme = ChartTheme( // optional visual override backgroundColor = Color(0xFF1A1A2E), gridColor = Color(0x22FFFFFF), axisColor = Color(0xFFBBBBBB), ), ) ``` ## Flow API ```kotlin // From Flow (auto-timestamp) state.collectFrom("accel_x", accelerometerFlow, viewModelScope) // From Flow> (explicit timestamp) state.collectFrom("ecg", ecgFlow, viewModelScope) // ecgFlow emits (timestampMs, value) ``` ## Performance notes - Data thread pushes at any rate; render thread reads at display refresh (or `targetFps`) - Buffer sized to `maxBufferSeconds × 1000 samples/s` per signal - LoD decimation reduces >pixel-count data to min/max per pixel column - Pre-allocated arrays — zero GC on hot render path (except LoD scratch, see TODO in `LodDecimator.kt`) ## Requirements - Android minSdk 26 - Jetpack Compose / Compose Multiplatform 1.8+ - Kotlin 2.1+