Created
January 16, 2023 15:15
-
-
Save developerchunk/0ae8cf8382512914d64a4181c12da764 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@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