Recently, we worked on a project that required us to add graphs with gradients to an Android application. Below is an example of one such graph that we needed to create:
There are lots of examples online that show how to create graphs with gradated backgrounds, but we quickly discovered that it’s nearly impossible to find information on how to incorporate a gradient effect as part of the axis, trend line, or doughnut. We finally figured out how to do it, so let’s go over the steps and it’ll hopefully make things easier for you if you’d like to try a similar project.
MPAndroidChart
Our go-to tool for graphing in Android applications is typically MPAndroidChart. It’s a versatile and powerful open source charting library that’s fairly straight forward to use. (The line graph shown in our screenshot was created with it.) Now, say we want to create a chart that shows how many minutes someone is active each hour of the day. The MPAndroidChart documentation found here offers good instructions on setting up the main parts of the graph. But how do you add vertical shading to the data?
If you delve deeper into the library, you’ll discover that the line chart uses Android’s Paint to render its lines. Among other things, you can set a shader in a Paint object to paint everything using that specific shader. To learn more about Android graphics and shaders, take a look at this post. Armed with this knowledge, we can now add a shader to the Paint object for our graph, which will give us a line gradient.
Paint paint = lineChart.getRenderer().getPaintRender();
int height = 200;
LinearGradient linGrad = new LinearGradient(0, 0, 0, height,
getResources().getColor(R.color.lineGraphHigh),
getResources().getColor(R.color.lineGraphLow),
Shader.TileMode.REPEAT);
paint.setShader(linGrad);
This gets us most of what we need. The chart renders, and if our graph has a height of 200px, it’ll also produce a gradient that changes from dark blue (our lineGraphLow color) to yellow (our lineGraphHigh color). However, one problem is that most Android applications need to adjust the size it objects on the screen to account for various screen sizes. In our test app, we used a weightSum along with layout_weights in a LinearLayout object. A fixed shading height would therefore result in a repeated pattern if the graph height extends beyond 200 pixels. In order to solve this, we need to obtain the height of our graph.
int height = lineChart.getHeight();
By adding this code snippet to a call that’s part of onStart, you’ll end up with a height of zero and no gradient.
So, we need to populate our chart data and get the size after the view has rendered, which can be done via the POST method on the view.
@Override
public void onStart(){
super.onStart();
getView().post(new Runnable() {
@Override
public void run() {
drawLineGraph();
}
});
}
/**
* The code for creating the line graph
*/
private void drawLineGraph(){
setupLineChart();
// Get the paint renderer to create the line shading.
Paint paint = lineChart.getRenderer().getPaintRender();
int height = lineChart.getHeight();
LinearGradient linGrad = new LinearGradient(0, 0, 0, height,
getResources().getColor(R.color.lineGraphHigh),
getResources().getColor(R.color.lineGraphLow),
Shader.TileMode.REPEAT);
paint.setShader(linGrad);
setupLineChartData();
// Don't forget to refresh the drawing
lineChart.invalidate();
}
Now we have a dynamically resizable graph that gives us a line with shading that changes from dark blue to yellow!
DecoView
After accomplishing part one, we also wanted to add a shaded arc graph to another part of our application. Unfortunately, MPAndroidChart couldn’t do what we wanted, so we turned to DecoView. DecoView is a focused library that allows you to create animated circular graphs. Alas, again, the documentation didn’t clearly explain how to add a gradient to a graph.
For DecoView, you add a series to define arcs for a graph. The series are added via a Builder object that can take either one or two colors in the constructor. All of the examples only show one color, but if you add in a second, you actually end up with a gradient. Then you simply add in a range that specifies the values that correspond to the starting and ending color.
int seriesIndex = decoView.addSeries(
new SeriesItem.Builder(getResources().getColor(R.color.lineGraphLow),
getResources().getColor(R.color.lineGraphHigh))
.setRange(0, stepGoal, 0)
.setInitialVisibility(false)
.setLineWidth(getDimension(18f))
.build());
The end result is a arc graph with a gradient that changes from blue to yellow. You can find documentation for DecoView here , and an example app with both of these graphs over here.