Tuesday, 23 August 2011

Exploring Android Charting and Graphs solutions

1. Google chart API
2. Achartengine
3. ChartDroid

I tried creating a Pie Chart while using the solutions. Google charting API being the easiest one to integrate is taken first

Google Charting API support

Using Google charting API, we can create charts and graphs directly by providing data to the Google charting service
The call to the Google's charting API looks like below:
More on Google charting API can be found here
For creating a pie chart using Google charting solution, I created the following URI
1
http://chart.apis.google.com/chart?cht=p3&chd=t:30,60,10&chs=250x100&chl=cars|bikes|trucks
Within my activity's onCreate() I included the code below
1
2
3
4
5
6
7
8
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WebView googleChartView = new WebView(this);
setContentView(googleChartView);
String mUrl = "http://chart.apis.google.com/chart?cht=p3&chd=t:30,60,10&chs=250x100&chl=cars|bikes|trucks";
googleChartView.loadUrl(mUrl);
}
In the onCreate() method, I am creating a WebView and just loading it with the URL response.
It needs an internet access so I included the code below within AndroidManifest.xml
1
<uses-permission android:name="android.permission.INTERNET" />
That's it!!! we are done with the first approach. The screen shot for the application I build using Google chart API looks like below:
Google Charting API PIE Chart
Google Charting API PIE Chart
The only issue I had with this approach is that the device should have internet access available which in my case may not be always there. This small limitation made me look into other approaches and I came across another solution Achartengine.

Achartengine

This Achart's charting support comes in the form of a download-able Jar.
I added this into the lib folder of my application.
Library Folder
Android App Structure
I created a class with a method that gives out a Pie chart intent as below
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class AChartExample {
 
public Intent execute(Context context) {
int[] colors = new int[] { Color.RED, Color.YELLOW, Color.BLUE };
DefaultRenderer renderer = buildCategoryRenderer(colors);
 
CategorySeries categorySeries = new CategorySeries("Vehicles Chart");
categorySeries.add("cars ", 30);
categorySeries.add("trucks", 20);
categorySeries.add("bikes ", 60);
 
return ChartFactory.getPieChartIntent(context, categorySeries, renderer);
}
 
protected DefaultRenderer buildCategoryRenderer(int[] colors) {
DefaultRenderer renderer = new DefaultRenderer();
for (int color : colors) {
SimpleSeriesRenderer r = new SimpleSeriesRenderer();
r.setColor(color);
renderer.addSeriesRenderer(r);
}
return renderer;
}
}
Within the execute method a SimpleSeriesRender is created with the required color that is required in the pie chart.
These renderers are then added to the DefaultRender.
Next step is to create a CategorySeries with the appropriate data. Once this is done we can get achartingengine specific intent back with the following call

ChartFactory.getPieChartIntent(context, categorySeries, renderer);

With this intent we launch our activity and the code goes as below
1
2
Intent achartIntent = new AChartExample().execute(this);
startActivity(achartIntent);
The screen shot below shows the generated PIE chart using Achart library
Achart

The other charting solution I explored is chartDroid

Chartdroid

This solution needs the ChartDroid Application to be installed along with the application which intends to use the charting solution.
Although, we can install the application programmaticly from the Android apps market place, I directly installed the application into my device to explore it further.To install it download the apk from here and install it to the device.
The Chartdroid's charting solution requires a content provider to be created. Below is the content provider's code that I created
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class ChartDroidDataProvider extends ContentProvider {
 
static final String AUTHORITY =  "com.xyz.contentprovider.chardroid";
 
@Override
public String getType(Uri uri) {
return "vnd.android.cursor.dir/vnd.com.googlecode.chartdroid.graphable";
}
 
public static final Uri PROVIDER_URI = new Uri.Builder().scheme(
ContentResolver.SCHEME_CONTENT).authority(AUTHORITY).build();
 
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
 
// Fetch the actual data
 
MatrixCursor c = new MatrixCursor(new String[]                  { BaseColumns._ID,
"COLUMN_AXIS_INDEX", "COLUMN_SERIES_INDEX",
"COLUMN_DATUM_VALUE", "COLUMN_DATUM_LABEL" });
 
c.newRow().add(1).add(0).add(1).add(30).add(null);
c.newRow().add(2).add(0).add(1).add(10).add(null);
c.newRow().add(3).add(0).add(1).add(60).add(null);
 
return c;
}
 
}
In the code above, I have excluded some methods which are the default IDE's implementations. The query method provides the data along with other details which are required to build a chart. The data can come from database as well. In the simplistic case of generating a PIE chart I created a MatixCursor to serve as my PIE chart data. In the cursor, I am adding three rows which takes data values as 30,10 and 60 respectively and the labels as null.
For detailed information on the other parameters please look here
Now, to display the Chartdroid activity with the PIE Chart backed by data from the content provider created above an Intent is to be created.
The implementation goes like below:
1
2
3
4
5
6
Intent chartDroidIntent = new Intent(Intent.ACTION_VIEW,
ChartDroidDataProvider.PROVIDER_URI);
chartDroidIntent.putExtra(Intent.EXTRA_TITLE, "Chart droid");
chartDroidIntent
.addCategory("com.googlecode.chartdroid.intent.category.PIE_CHART");
startActivity(chartDroidIntent);
In the code above adding category is important as it decides what form of charting is required. In my case it's PIE_CHART.
Also, we can pass in most of the data in form of Intent's extras, except the actual data. In example above the title information is going as the extra.
Launching the ChartDroid's activity gives the results as below:
Chartdroid
Chartdroid
Complete source code for the application can be downloaded here

1 comment:

  1. If we change the labels from null to some string , it is not displaying . even if we change the label it is still showing project1...

    So please tell how to solve this issue..

    Thanks in advance.

    ReplyDelete