Using MPChartLib with Jetpack Compose

Yeetivity
4 min readSep 27, 2023

--

Image with various graphs and charts, for design purposes
Image by Freepik

MPChartLib is a great library when it comes to creating scrollable, zoomable, and real-time graphs for Android. However, with its last update in 2021 it is safe to say that its not the most recent library out there.

Unfortunately, it is still one of the best libraries out there. I say unfortunately, because its integration with newer frontend toolboxes such as Jetpack Compose is not great to say the least. However, it is possible! My finding is that there aren’t a lot of digital resources explaining how to do it though.

That is why in this blog, I will show you some examples of how I have used MPChartLib in my project to create zoomable and real-time graphs.

1 | Add the correct dependencies

In your build.gradle (app) add the following dependency (note that I am using the Kotlin DSL syntax, you might need Groovy syntax)

depencencies {
...
implementation("com.github.PhilJay:MPAndroidChart:v3.1.0")
}

You might also have to change your settings.gradleto include the jitpack.io url:

dependencyResolutionManagement {
...
repositories {
...
maven( "https://jitpack.io")
}
}

2 | Create your Jetpack Composable

After importing the necassary dependency, you can start using MPChartLib. Normally you would add this to an XML, and then use that in your activity or another class to manipulate the graphs. However, because we use Jetpack Compose we will have to add the chart to a composable. For this we can use the AndroidView() composable.

The code below shows how you can create a linegraph, but a similar structure holds for other graphs provided by MPChartLib

import androidx.compose.ui.viewinterop.AndroidView
import com.github.mikephil.charting.charts.LineChart
import com.github.mikephil.charting.charts.data.Entry
import com.github.mikephil.charting.charts.data.LineData
import com.github.mikephil.charting.charts.data.LineDataSet
...

@Composable
fun LineGraph(
xData: List<Float>,
yData: List<Float>,
dataLabel: String,
modifier: Modifier = Modifier
){
AndroidView(
modifier = modifier.fillMaxSize(),
factory = { context ->
val chart = LineChart(context) // Initialise the chart
val entries: List<Entry> = xData.zip(yData) { x, y -> Entry(x, y) } // Convert the x and y data into entries
val dataSet = LineDataSet(entries, dataLabel) // Create a dataset of entries
chart.data = LineData(dataSet) // Pass the dataset to the chart

// Refresh and return the chart
chart.invalidate()
chart
}
)
}

3 | Add Interaction

You’ve now created the LineChart, but maybe you also want to make sure that you can scale and zoom within the graph. You can do that by adding the following code to your factory:

@Composable
fun LineGraph(
xData: List<Float>,
yData: List<Float>,
dataLabel: String,
modifier: Modifier = Modifier
){
AndroidView(
...
factory = { context ->
...

// Enable touch gestures
chart.setTouchEnabled(true)
chart.isDragEnabled = true
chart.isScaleXEnabled = true
chart.isScaleYEnabled = false

// Refresh and return the chart
chart.invalidate()
chart
}
)
}

4 | Add styling

Simarly to adding gesture behaviour to the graph, we can also style the graph in the way that we want. I like to add the styling as an input to the composable, so that I can use the composable as is, and it is decoupled from the rest of my code, but you can ofcourse also hardcode your styling.

...
import com.github.mikephil.charting.components.XAxis

@Composable
fun LineGraph(
...
lineColor: Color = Color.Red,
fillColor: Color = Color.Red,
fillAlpha: Int = 255,
axisTextColor: Color = Color.White,
backgroundColor: Color = Color.DarkGray,
drawValues: Boolean = false,
drawMarkers: Boolean = false,
drawFilled: Boolean = true,
descriptionEnabled: Boolean = false,
legendEnabled: Boolean = true,
yAxisRightEnabled: Boolean = false,
xAxisPosition: XAxisPosition = XAxis.XAxisPosition.BOTTOM
){
...
}

Now if we want to use this in our actual graph we have to realise two things; 1. If we want to change the appearance of a line, we are actually doing this within the dataset that we are creating. 2. If we want to change the appearance of the complete graph (e.g. the axis position), we are doing this on the graph itself.

Now lets look at the code to do this:

@Composable
fun LineGraph(
...
){
AndroidView(
modifier = modifier
.fillMaxSize()
.background(backgroundColor),
factory = { context ->
...
val dataSet = LineDataSet(entries, dataLabel).apply {
// Here we apply styling to the dataset
color = lineColor.toArgb()
setDrawValues(drawValues)
setDrawCircles(drawMarkers)
setDrawFilled(drawFilled)
fillColor = fillColor.toArgb()
fillAlpha = fillAlpha
}
chart.data = LineData(dataSet) // Pass the dataset to the chart

/*
* Extra chart styling
*/
chart.description.isEnabled = descriptionEnabled
chart.legend.isEnabled = legendEnabled

chart.axisLeft.textColor = axisTextColor.toArgb()
chart.axisRight.isEnabled = false
chart.xAxis.textColor = axisTextColor.toArgb()
chart.xAxis.position = xAxisPosition

// Refresh and return the chart
chart.invalidate()
chart
}
)
}

Ofcourse there is a lot more customisation you can do. To do that I recommend to dive into the MPChartLib documentation, and compare it to the way done here, which should be enough for you to figure out how to do it in Kotlin and compose!

--

--

Responses (1)