AChartEngine Live Scrolling Graph
Recently I’ve been working on an Android app where I needed to plot some values in a time-based graph with live data (e.g. the phone’s signal strength). There are quite a few open-source Android charting libraries available that I’ve tried so I’ll just post the links in case someone wants to give them a go. So far I’ve tried:
Snowdon – pretty light, nice for static graphs but too simple for my purpose
Chartdroid – intent-based charts
AFreeChart – they have an interesting example in the latest version (0.0.4) in Miscellaneous > Performance Test 01. However the sources for that activity are not included in their open source code but if you decompile the .apk you’ll be able to see the entire code, it’s not obfuscated. However, I found the library to be quite slow/sluggish for some reason, even on JellyBeans.
AChartEngine – my favorite charting library so far, the code is open source, with plenty of demos to browse through. There are also a lot of answered questions on StackOverflow which helped me a lot and I found it quite suitable for my purpose. The only thing I wish it had is bellow-the-line gradients for line charts (so far gradients are supported in bar charts) but I took a look into the code and I have an idea about how to implement it so maybe I’ll contribute in the future..
I’ll just post below an working example of using AChartEngine in a live line chart graph that scrolls to the right as values are added. It also supports zooming (with external controls).
As a picture is worth a thousand words, my live graph looks like below.
I’ve simulated slowly plotting values in range of [0-100] using random generated colors for each series and I also displayed horizontal threshold lines. Although you can use intents to display your graphs, you can also use ChartFactory to retrieve a GraphicalView that you can embed in an activity or a fragment. In my example, the graph is a Fragment (I also use the compatibility library).
The interesting bit is to get the TimeSeries scrolling as you add in more values. For that you need to set the range of the renderer so that the the x-axis (the time axis) is always centered on now, with some padding of a few seconds before and after. Same thing for the y-axis, if you want to re-arrange the graph based on the minimum and maximum of the values displayed (I’m sure the thinking behind this one can be improved…).
Also you need to take into account the zoom level so that zooming out, zooming in or resetting the zoom works properly with the new ranges. In my graph, zooming makes sense on the x-axis, where I want to display more or less time between the values (so I can see more values or less values at once).
Last, in my case I wanted to hide some of the texts in the legend area, so I use a modified version of the library where I just created an extra check if the legend text is null or empty to completely skip displaying it. This is not in the default library but feel free to use my modified jar if you want the same behavior.
As usually, the full working source code is available in my Git repo called CodeAndMagic