Use chart(s) easily in Android
If you look for chart library to your Android application then you will find MPAndroidChart in your search result at the very beginning of the list. :)
It is a really useful library and not a rocket science thing to use it. However if you want to change anything of the chart or customise it then you will miss some documentation and it could be more hours until you will find the solution. Because of this I want to collect some useful information and examples into my article. In my article I will use my demo repository:
First let's see what is need to use the library:
Add to your build.gradle files
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
}
Be careful if you are using the latest Android Studio then it might be some related code in the settings.gradle file too. (I have deleted the unnecessary code from it.)
Now we can use the library. The library supports to use a chart view in the XML file or we can use it in our code. There are some different kind of charts but I will write only from LineChart (there is minimal differences how to use them).
Ok, if we have a (Chart)View then we will have some data what we will show on the chart.
val chartData = dataSet.mapIndexed { index, value ->
Entry(index.toFloat(), value.toFloat())
}
val chartDataSet = LineDataSet(chartData, "data")
val data = LineData(chartDataSet)
chart.data = data
chart.notifyDataSetChanged()
Entry is the data format what the library uses. If we have a LineChart then x will depend on y value. Entry has two properties x and y :)
public Entry(float x, float y) {
super(y);
this.x = x;
}
Yes, we can see x and y are float value :(
Unfortunately the library is using the worst floating point type.
(double would be better because it is more precise and we will be able to convert date as x value but I will write about it later)
Ok, after it we need to create LineDataSet and a LineData objects and after it we have a chart…
This chart is the default line chart. Let's customise it.
1. Remove second y Axis
chart.axisRight.isEnabled = false
Anyway if we want to remove left one then change axisRight to axisLeft.
2. Change x axis position to bottom
chart.xAxis.position = XAxis.XAxisPosition.BOTTOM
3. Remove description label
chart.description.isEnabled = false
chart.description is a special object we can customise or modify description label with help of it.
4. Remove legend
chart.legend.isEnabled = false
With Legend object we can customise it fully. Anyway legend could be useful especial if we want to draw more dataset in same chart.
5. Remove circles
chartDataSet.setDrawCircles(false)
We need turn off circles in the dataSet object. If we want to change the size of them we can set it here:
chartDataSet.circleRadius = 0.0F
With 0 float value will set the circles size zero. Be careful circle size = 0 doesn't mean they are completely removed. If you want to remove them then use the setDrawCircles(false)!
6. Change chart colour
chartDataSet.color = Color.GREEN
If we want to draw or fill area under the line (chart) then we can use the next:
chartDataSet.setDrawFilled(true)
chartDataSet.fillColor = Color.GREEN
If we need some opacity to the chart then we can set it easily:
chartDataSet.fillAlpha = 50
7. Change chart smoother
chartDataSet.mode = LineDataSet.Mode.CUBIC_BEZIER
The property CUBIC_BEZIER will change the line chart smoother. However if we are using STEPPED then it will be more angular.
CUBIC_BEZIER
STEPPED
8. Change the y Axis range
chart.axisLeft.axisMaximum = 80.0F
chart.axisLeft.axisMinimum = 10.0F
We can set a range in the y Axis. By default library will calculate the optimal range.
And we can set how manny line will be in the y Axis (we can increase the fine level or decrease it)
chart.axisLeft.labelCount = 5
In this case chart will calculate where will be the lines and the fine of the grid.
9. Use time on x Axis
When we want to display not a number on the x Axis (like any String) then we should use a ValueFormatter.
chart.xAxis.valueFormatter = MyOwnValueFormatter()
Let's see an example for the ValueFormatter:
private class MyValueFormatter() : ValueFormatter() {
override fun getFormattedValue(value: Float): String {
return NumberUtil.format(value)
}
}
When we implement a ValueFormatter we should use getFormattedValue. The parameter will be the x Axis's value, and we should convert or format it. When we need to display time related values it means we should convert a Date() object to a number. Yes we can use timestamp -> Date().time
val timeStampe = Date().time
Time is a Long property. What does it mean ? We will be not able to convert to Float without loss. :(
What can we do ?
We need to convert the timestamps somehow into other displayable numbers.
val baseTimestamp = timestamps[0]
val listOfConverted = timestamps.map { it - baseTimestamp }
Let's shift the timestamps with the first value. First value will be a base number and we will subtract it from the others (in this case the transaction will be reproducible and we are able to revers it). We can display the result of the conversion.
Be careful it is possible if you want to display a huge time frame then it is possible the trick of above will not help.
private class TimeValueFormatter(private val timeOffset: Long) : ValueFormatter() {
override fun getFormattedValue(value: Float): String {
val fullValue = timeOffset + value.toLong()
return DateUtil.getFormattedDateFromTimeStamp("HH:mm", fullValue)
}
}
I hope this short article could help you if you want to use a chart in your application. MPAndroidChart has many-many other features. This is a really great library!
Thanks for reading my article! If you found this post useful? Kindly tap the 👏 button below and follow :) .