Skip to content

Instantly share code, notes, and snippets.

@developerchunk
Created January 16, 2023 15:15
Show Gist options
  • Save developerchunk/0ae8cf8382512914d64a4181c12da764 to your computer and use it in GitHub Desktop.
Save developerchunk/0ae8cf8382512914d64a4181c12da764 to your computer and use it in GitHub Desktop.
@Composable
fun PieChart(
data: Map<String, Int>,
radiusOuter: Dp = 140.dp,
chartBarWidth: Dp = 35.dp,
animDuration: Int = 1000,
) {
val totalSum = data.values.sum()
val floatValue = mutableListOf<Float>()
// To set the value of each Arc according to
// the value given in the data, we have used a simple formula.
// For a detailed explanation check out the Medium Article.
// The link is in the about section and readme file of this GitHub Repository
data.values.forEachIndexed { index, values ->
floatValue.add(index, 360 * values.toFloat() / totalSum.toFloat())
}
// add the colors as per the number of data(no. of pie chart entries)
// so that each data will get a color
val colors = listOf(
Purple200,
Purple500,
Teal200,
Purple700,
Blue
)
var animationPlayed by remember { mutableStateOf(false) }
var lastValue = 0f
// it is the diameter value of the Pie
val animateSize by animateFloatAsState(
targetValue = if (animationPlayed) radiusOuter.value * 2f else 0f,
animationSpec = tween(
durationMillis = animDuration,
delayMillis = 0,
easing = LinearOutSlowInEasing
)
)
// if you want to stabilize the Pie Chart you can use value -90f
// 90f is used to complete 1/4 of the rotation
val animateRotation by animateFloatAsState(
targetValue = if (animationPlayed) 90f * 11f else 0f,
animationSpec = tween(
durationMillis = animDuration,
delayMillis = 0,
easing = LinearOutSlowInEasing
)
)
// to play the animation only once when the function is Created or Recomposed
LaunchedEffect(key1 = true) {
animationPlayed = true
}
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
) {
// Pie Chart using Canvas Arc
Box(
modifier = Modifier.size(animateSize.dp),
contentAlignment = Alignment.Center
) {
Canvas(
modifier = Modifier
.size(radiusOuter * 2f)
.rotate(animateRotation)
) {
// draw each Arc for each data entry in Pie Chart
floatValue.forEachIndexed { index, value ->
drawArc(
color = colors[index],
lastValue,
value,
useCenter = false,
style = Stroke(chartBarWidth.toPx(), cap = StrokeCap.Butt)
)
lastValue += value
}
}
}
// To see the data in more structured way
// Compose Function in which Items are showing data
DetailsPieChart(
data = data,
colors = colors
)
}
}
@Composable
fun DetailsPieChart(
data: Map<String, Int>,
colors: List<Color>
) {
Column(
modifier = Modifier
.padding(top = 80.dp)
.fillMaxWidth()
) {
// create the data items
data.values.forEachIndexed { index, value ->
DetailsPieChartItem(
data = Pair(data.keys.elementAt(index), value),
color = colors[index]
)
}
}
}
@Composable
fun DetailsPieChartItem(
data: Pair<String, Int>,
height: Dp = 45.dp,
color: Color
) {
Surface(
modifier = Modifier
.padding(vertical = 10.dp, horizontal = 40.dp),
color = Color.Transparent
) {
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
Box(
modifier = Modifier
.background(
color = color,
shape = RoundedCornerShape(10.dp)
)
.size(height)
)
Column(modifier = Modifier.fillMaxWidth()) {
Text(
modifier = Modifier.padding(start = 15.dp),
text = data.first,
fontWeight = FontWeight.Medium,
fontSize = 22.sp,
color = Color.Black
)
Text(
modifier = Modifier.padding(start = 15.dp),
text = data.second.toString(),
fontWeight = FontWeight.Medium,
fontSize = 22.sp,
color = Color.Gray
)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment