Jetpack Compose Pie Chart with Source Code

jetpack compose pie chart

This is a pie chart designed with Android Jetpack Compose. It doesn’t use any chart library like MPAndroidChart. Instead, it is made with Canvas API.

Pie chart is nothing but a combination of arcs. I have drawn them using the drawArc method of Canvas API. I set the different colors to different arcs. It also displays a legend below the pie chart. For every arc, the startAngle is the sum of the previous sweepAngle values.

The Jetpack Compose pie chart takes multiple parameters like values, colors, legend, and size. The values are the chart values. The colors are list of colors for each arc. Make sure that the size of values and colors should be same. Legend describes the chart. The size is the Canvas size.

To convert the values to angles, first, all the values are added. Then, each proportion value is calculated by the value * 100 / sumOfAllValues. To convert each proportion to angle, 360 * proportion / 100. These angles are used to draw the arcs. Inside Canvas, the initial startAngle is set at -90f. Inside the for loop, the startAngle equlals to the sum of all the sweepAngles. I set the useCenter to true so that the arcs are drawn perfectly.

If you want to use this code, you need to download the latest version of Android Studio. Jetpack Compose doesn’t work in the older versions.

Final output:

If the video isn’t working, watch it on the YouTube.

Helpful links to understand the code:

Here are the Gradle files used in the project.

Here is the source code:

MainActivity.kt:

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material.Divider
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp


/*
You can use the following code for commercial purposes with some restrictions.
Read the full license here: https://semicolonspace.com/semicolonspace-license/
For more designs with source code,
visit: https://semicolonspace.com/jetpack-compose-samples/
 */
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            BlogPostsTheme(darkTheme = false) {
                Column(
                    modifier = Modifier
                        .fillMaxSize()
                        .background(color = Color.White),
                    verticalArrangement = Arrangement.Center,
                    horizontalAlignment = Alignment.CenterHorizontally
                ) {
                    PieChart1()
                }
            }
        }
    }
}

@Composable
fun PieChart1(
    values: List<Float> = listOf(15f, 35f, 50f),
    colors: List<Color> = listOf(Color(0xFF58BDFF), Color(0xFF125B7F), Color(0xFF092D40)),
    legend: List<String> = listOf("Mango", "Banana", "Apple"),
    size: Dp = 200.dp
) {

    // Sum of all the values
    val sumOfValues = values.sum()

    // Calculate each proportion value
    val proportions = values.map {
        it * 100 / sumOfValues
    }

    // Convert each proportions to angle
    val sweepAngles = proportions.map {
        360 * it / 100
    }

    Canvas(
        modifier = Modifier
            .size(size = size)
    ) {

        var startAngle = -90f

        for (i in sweepAngles.indices) {
            drawArc(
                color = colors[i],
                startAngle = startAngle,
                sweepAngle = sweepAngles[i],
                useCenter = true
            )
            startAngle += sweepAngles[i]
        }

    }

    Spacer(modifier = Modifier.height(32.dp))

    Column {
        for (i in values.indices) {
            DisplayLegend1(color = colors[i], legend = legend[i])
        }
    }

}

@Composable
fun DisplayLegend1(color: Color, legend: String) {

    Row(
        horizontalArrangement = Arrangement.Center,
        verticalAlignment = Alignment.CenterVertically
    ) {
        Divider(
            modifier = Modifier.width(16.dp),
            thickness = 4.dp,
            color = color
        )

        Spacer(modifier = Modifier.width(4.dp))

        Text(
            text = legend,
            color = Color.Black
        )
    }
}

Related:

Leave a Comment