Cards
Cardsanimated

Donut Breakdown

A segmented donut reveals category share with a legend on the side.

Traffic
Direct 50%
Social 30%
Referral 20%

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 DonutBreakdownCard() {
  val data = listOf(
    0.5f to Color(0xFF6366F1),
    0.3f to Color(0xFF10B981),
    0.2f to Color(0xFFF43F5E),
  )
  val grow = remember { Animatable(0f) }
  LaunchedEffect(Unit) {
    grow.animateTo(1f, tween(1100, easing = FastOutSlowInEasing))
  }
  Card(
    shape = RoundedCornerShape(20.dp),
    modifier = Modifier.width(260.dp),
  ) {
    Row(
      Modifier.padding(20.dp),
      verticalAlignment = Alignment.CenterVertically,
    ) {
      Canvas(Modifier.size(76.dp)) {
        var start = -90f
        data.forEach { (frac, c) ->
          val sweep = 360f * frac * grow.value
          drawArc(
            color = c,
            startAngle = start,
            sweepAngle = sweep,
            useCenter = false,
            style = Stroke(12.dp.toPx()),
          )
          start += 360f * frac
        }
      }
      Spacer(Modifier.width(16.dp))
      Column {
        Text(text = "Traffic", fontWeight = FontWeight.SemiBold)
        Text(
          text = "Direct 50%",
          style = MaterialTheme.typography.bodySmall,
        )
        Text(
          text = "Social 30%",
          style = MaterialTheme.typography.bodySmall,
        )
        Text(
          text = "Referral 20%",
          style = MaterialTheme.typography.bodySmall,
        )
      }
    }
  }
}