Charts
Chartsanimated

Punch card

A day-by-hour punch card where dot radius encodes activity, popping in by row.

Installation

caveui components are copy-paste Jetpack Compose built entirely on Material 3 — there's no caveui dependency to add. Make sure Material 3 is on your classpath (it ships with the Compose BOM), then copy the Usage snippet below into your project.

kotlin
// build.gradle.kts (module)
dependencies {
    implementation(platform("androidx.compose:compose-bom:2025.06.00"))
    implementation("androidx.compose.material3:material3")
}

Usage

kotlin
@Composable
fun PunchCard(
    grid: List<List<Float>> = remember { samplePunch(5, 8) },
    accent: Color = Color(0xFF10B981),
    modifier: Modifier = Modifier,
) {
    val pop by animateFloatAsState(1f, spring(0.6f, 160f), label = "pop")
    Canvas(modifier.size(180.dp, 116.dp)) {
        val rows = grid.size
        val cols = grid[0].size
        val cw = size.width / cols
        val ch = size.height / rows
        grid.forEachIndexed { r, row ->
            row.forEachIndexed { c, v ->
                drawCircle(
                    accent.copy(alpha = 0.85f),
                    (ch / 2 * 0.85f) * v * pop,
                    Offset(c * cw + cw / 2, r * ch + ch / 2),
                )
            }
        }
    }
}