Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A Look At Data Analysis With Charts and Graphs in Android* Apps

14 Aug 2014 1  
This article will discuss different options available for presenting data and analysis, using charts and graphs in a typical line of business Android* app.

This article is in the Product Showcase section for our sponsors at CodeProject. These articles are intended to provide you with information on products and services that we consider useful and of value to developers.

Abstract

This article will discuss different options available for presenting data and analysis, using charts and graphs in a typical line of business Android* app. We will cover different pros and cons for selecting one solution over the other, and other technical considerations when choosing a charting library or API. Finally, we will discuss in detail how to add a pie chart, a line chart and a bar chart natively in Android, using the popular AChartEngine* library.

Contents

Abstract
Charting Options and Considerations for Android Apps
AChartEngine Overview and Usage
A Retail Business Restaurant Sample App – Little Chef.
Menu Categories as a Pie Chart
Sales Trend using a Line chart
Sales Comparison using a Bar chart
Embedding Multiple Charts in an Activity
Summary

Charting Options and Considerations for Android Apps

If you want to present any kind of data or analysis in your app, a good visual representation is very important. It can make a big difference in user satisfaction. Picking the right type of chart or graph is equally important.

For Android apps, there is currently no standard or platform library to show charts. Depending on app requirements, we could use a web based chart library like Google Charts*, but, it requires your app to be online and able to use the Google Chart APIs to show the charts. If your app already depends on other Google services that require network access, Google Chart APIs can be a great choice. The Google Charts link is below.
https://developers.google.com/chart/

Below is a comprehensive gallery with several types of charts available.
https://google-developers.appspot.com/chart/interactive/docs/gallery

If you are familiar with HTML5, there are even more options for charting. Some of the HTML5 libraries can be packaged with your app, making them ideal for offline access too. This can be a great choice if you intend to develop a cross platform app. The article below covers one such library.
https://software.intel.com/en-us/android/articles/develop-html5-chart-applications-for-android-and-win8-devices

Before you finalize on a web based or even an offline HTML5 charting library, you may want to consider the limitations of Android WebView*, which often hosts these solutions.
http://developer.android.com/guide/webapps/webview.html

Other technical factors to consider are performance, advanced charting customizations, exposure to full Android API's, custom user interactions (eg. gestures) or other accessibility issues. Some of the above mentioned libraries may be lacking in these features. Low level advanced customizations may only be possible with native Android solutions, sometimes having to directly program with OpenGL/GPU, depending on your app requirements.

There are times when a web based or HTML5 solution may not satisfy your app requirements or you would rather have the charting done natively using plain old Android views and activities. This may allow your app to be tightly integrated with other components of your Android app – seamlessly allowing you to coordinate, share, persist, and restore data between activities or chart components as needed. This will also allow your app to do advanced low level charting or graphics customizations as needed. Another advantage is the flexibility and ability to access the full breadth of android APIs directly from your native Android charting component.

There are several third party libraries available for adding charts to your Android app. AChartEngine is one such library, currently very popular with Android developers based on community involvement and usage.
https://code.google.com/p/achartengine/

It is in active development, with support for several chart types. In this article we will use this library to show how to add some basic charts to your android app – a pie chart, line chart and a bar/column chart.

AChartEngine Overview and Usage

Android APIs allow us build a full blown charting solution from the ground up. AChartEngine does exactly that and more. It is one of the popular native charting libraries for Android with a full blown feature set. It supports several types of charts, and allows us to customize the charts as needed. It even has zoom-in/zoom-outcontrols to go with the charts, along with other standard charting features.

The main site for AChartEngine is https://code.google.com/p/achartengine/

The following article, referenced by the main site, goes into more detail.
http://jaxenter.com/effort-free-graphs-on-android-with-achartengine-46199.html

AChartEngine has a convenient factory class ChartFactory, that returns the chart wrapped into an Android view or activity as needed. This chart view can then be embedded in other activities, just like any other Android views.

Installation and usage of AChartEngine library is similar to other Android libraries. Simply download the jar, and place it in your project's libs folder. Eclipse* or Gradle* based builds will automatically compile and build the library.

The process of creating a chart with AChartEngine library is straightforward and consistent across different chart types. We can get a simple chart going by following these basic steps:

  1. Create a series data set and a series renderer. AChartEngine has generic classes defined for holding data (eg. XYMultipleSeriesDataset) and renderers (eg. XYMultipleSeriesRenderer).

    For a basic line chart:

    		XYMultipleSeriesDataset mDataset;
    
    			XYMultipleSeriesRenderer mRenderer;
    
    		double[] xvals = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
    
    			double[] yvals = new double[]{25, 45, 50, 65, 80, 84, 96, 106, 123, 118, 134, 121};
    
    		XYSeries series = new XYSeries("Sales Data");
    
    		for (int i = 0; i < 12; i++)
    
    			series.add(xvals[i], yvals[i]);
    
    		XYSeriesRenderer renderer = new XYSeriesRenderer();
    
    		mDataset.addSeries(series);
    
    			mRenderer.addSeriesRenderer(renderer);
    Code Snippet 1. Creating a Series Dataset and Renderer ++
  2. Configure the render with your chart title, color, point style and any other customizations. Please note we can configure at the individual renderer level (corresponds to particular data series), as well as for the full chart (eg. chart title). >
    		renderer.setColor(Color.GREEN);
    
    		renderer.setPointStyle(PointStyle.CIRCLE);
    
    		mRenderer.setChartTitle("Sales Trend Chart");
    Code Snippet 2. Configuring Pie Chart Series Renderer and Main Renderer ++
  3. Use the built-in ChartFactory class to get the chart as a view (or full activity), by providing the above configured multiple series dataset and renderer. Please note, you will have to pass in the Android Context (from your Android activity) as well.
    		mChartView = ChartFactory.getLineChartView(context, mDataset, mRenderer);
    Code Snippet 3. Using the ChartFactory ++
  4. Create a Layout to hold the chart, such as LinearLayout, in your Android activity layout xml and add the view to the layout.
    		layout = (LinearLayout) findViewById(R.id.chart);
    
    		layout.addView(mChartView);
    Code Snippet 4. Adding the Chart to An Android Layout ++

We now have a basic line chart, embedded inside a linear layout of an Android activity.

A Retail Business Restaurant Sample App – Little Chef.

To demonstrate the usage of charts, we use a sample restaurant app (Little Chef).

This application allows the user to browse through different menu categories and choices.

Figure 1. A Restaurant Sample App - Little Chef

The restaurant app can be used by a chef or the owner, to see different menu categories and choices expressed as a pie chart, or sales trend in a line chart, or sales comparison using a bar/column chart. The following screenshot shows the chart view:

Figure 2. Restaurant Sample App Using AChartEngine Library to Show Charts

In the sample app, the restaurant owner can navigate to the charts view from the home screen. Several charts can be embedded in the same Android Activity or in a separate activity per chart as needed.

Menu Categories as a Pie Chart

To demonstrate the usage of a pie chart, we will show different menu categories and the number of items in each category, as a pie chart.
First, define a placeholder for the chart in Android layout. We can optionally add a title label as shown in the following snippet.

<TextView

	android:layout_width="261dp"

	android:layout_height="104dp"

	android:textAppearance="?android:attr/textAppearanceLarge"

	android:text="Menu Items Pie Chart"

	android:gravity="center"

	android:id="@+id/textView" />

<LinearLayout

	android:orientation="vertical"

	android:layout_width="600dp"

	android:layout_height="400dp"

	android:id="@+id/chart1"

	android:layout_gravity="center_horizontal"

	android:background="@android:color/transparent"></LinearLayout>
Code Snippet 5. Pie Chart Layout for Sample App ++

We are using id "chart1" as a reference to the linear layout, which hosts our pie chart.

To draw a pie chart with AChartEngine, we need to use a RoundChart. The basics of "round" charts are similar to XYChart, except for some configurations and settings.
As described in AChartEngine usage section, we first need to define and initialize our data series and renderer. For Pie Chart, we use CategorySeries and DefaultRenderer classes respectively. Please refer to following code snippet.

int[] COLORS = new int[]{Color.GREEN, Color.BLUE, Color.MAGENTA, Color.CYAN};

	CategorySeries mSeries = new CategorySeries("");

	DefaultRenderer mRenderer = new DefaultRenderer();

Map<String, Integer> mcount = new HashMap<String, Integer>();

	for (MenuFactory.MenuItem m : menuItems) {

	if (!mcount.containsKey(m.category)) mcount.put(m.category, 1);

	else mcount.put(m.category, mcount.get(m.category) + 1);

	}

for (Map.Entry<String, Integer> m : mcount.entrySet()) {

	mSeries.add(m.getKey(), m.getValue());

	SimpleSeriesRenderer renderer = new SimpleSeriesRenderer();

	renderer.setColor(COLORS[(mSeries.getItemCount() - 1) % COLORS.length]);

	mRenderer.addSeriesRenderer(renderer);

	}

mRenderer.setChartTitle("Menu Item Categories");

	mRenderer.setLabelsColor(Color.BLACK);
Code Snippet 6. Pie Chart Data Initialization For Sample App ++

As seen in the above code snippet, a SimpleSeriesRenderer is used to render each individual pie data. We configure the color of each pie component on this renderer. All of the individual renderers are added to our main renderer object. On the main renderer object, we configure the chart title and the color of the labels.

Use the ChartFactory class to get a pie chart as an Android view, passing in the context, data series and renderer objects.

mChartView = ChartFactory.getPieChartView(context, mSeries, mRenderer);

LinearLayout layout = (LinearLayout) findViewById(R.id.chart1);

layout.addView(mChartView);
Code Snippet 7. Adding Pie Chart to Android Layout in Sample App ++

Finally, the pie chart can be embedded into the chart1 linear layout as shown in the code snippet.
The resulting chart is shown in the following screenshot.

Figure 3. Menu Categories as Pie Chart

Sales Trends Using a Line Chart

In the restaurant sample app, we can show the past year sales trend as a line chart.

Define a placeholder for the chart in the Android layout. We use the linear layout, and assign an id (eg. chart2).

<TextView

	android:layout_width="268dp"

	android:layout_height="104dp"

	android:textAppearance="?android:attr/textAppearanceLarge"

	android:text="Sales Trend"

	android:gravity="center"

	android:id="@+id/textView2" />

<LinearLayout

	android:orientation="vertical"

	android:layout_width="600dp"

	android:layout_height="400dp"

	android:id="@+id/chart2"

	android:layout_gravity="center_horizontal"></LinearLayout>
Code Snippet 8. Line Chart Layout for Sample App ++

To draw a pie chart with AChartEngine, we need to use a RoundChart. The basics of "round" charts are similar to XYChart, except for some configurations and settings.

Define and initialize our data series and renderer. For Line Chart, we use XYMultipleSeriesDataset and XYMultipleSeriesRenderer classes respectively. Please refer to the following code snippet.

XYMultipleSeriesDataset mDataset = new XYMultipleSeriesDataset();

	XYMultipleSeriesRenderer mRenderer = new XYMultipleSeriesRenderer();

double[] xvals = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};

	double[] yvals = new double[]{25, 45, 50, 65, 80, 84, 96, 106, 123, 118, 134, 121};

XYSeries series = new XYSeries("Sales Data");

	for (int i = 0; i < 12; i++)

	series.add(xvals[i], yvals[i]);

	XYSeriesRenderer renderer = new XYSeriesRenderer();

	renderer.setColor(Color.GREEN);

	renderer.setPointStyle(PointStyle.CIRCLE);

	renderer.setFillPoints(true);

	renderer.setDisplayChartValues(true);

mDataset.addSeries(series);

	mRenderer.addSeriesRenderer(renderer);

mRenderer.setChartTitle("Sales Trend Chart");

	mRenderer.setXTitle("Month");

	mRenderer.setYTitle("Sales in 1000s");

	mRenderer.setXAxisMin(0.5);

	mRenderer.setXAxisMax(12.5);

	mRenderer.setYAxisMin(20);

	mRenderer.setYAxisMax(140);

	mRenderer.setAxesColor(Color.GRAY);

	mRenderer.setLabelsColor(Color.LTGRAY);

	mRenderer.setXLabels(1);

	mRenderer.setYLabels(10);

	mRenderer.addXTextLabel(1, "Jan");

	mRenderer.addXTextLabel(3, "Mar");

	mRenderer.addXTextLabel(5, "May");

	mRenderer.addXTextLabel(7, "Jul");

	mRenderer.addXTextLabel(10, "Oct");

	mRenderer.addXTextLabel(12, "Dec");
Code Snippet 9. Line Chart Dataset and Render Setup for Sample App ++

Sample sales data is used for this example, but the app can request an abstract backend database or model to return the sales data. This code snippet shows additional customizations we could add to line charts. We added text labels for months, and configured colors and a title among others. Please refer to the code snippet for all customizations.

Use the ChartFactory class to get a line chart as an Android view, passing in the context, data series and renderer objects.

mChartView = ChartFactory.getLineChartView(context, mDataset, mRenderer);

LinearLayout layout = (LinearLayout) findViewById(R.id.chart2);

layout.addView(mChartView);
Code Snippet 10. Adding the Line Chart to Android Layout for Sample App ++

Finally, the pie chart can be embedded into the chart2 linear layout as shown in the code snippet.

The resulting chart is shown in the following screenshot.

Figure 4. Sales Trend Using a Line Chart

Sales Comparison Using a Bar Chart

AChartEngine lets us add as many data series as needed. Further, we can customize the look of each data series by configuring their corresponding renderers.

The process of adding a bar chart is similar to previous charts. We will plot sales data for 2 years for comparison.

Just as before, define a placeholder for the chart in the Android layout. We use linear layout, and assign an id (eg. chart3).

<TextView

	android:layout_width="344dp"

	android:layout_height="122dp"

	android:textAppearance="?android:attr/textAppearanceLarge"

	android:text="Sales Comparison Chart"

	android:gravity="center"

	android:id="@+id/textView3" />

<LinearLayout

	android:orientation="vertical"

	android:layout_width="600dp"

	android:layout_height="400dp"

	android:id="@+id/chart3"

	android:layout_gravity="center_horizontal"></LinearLayout>
Code Snippet 11. Bar Chart Layout for Sample App ++

Define and initialize our data series and renderer. Similar to Line Chart, for Bar Chart we use XYMultipleSeriesDataset and XYMultipleSeriesRenderer classes respectively. Please refer to the following code snippet.

 XYMultipleSeriesDataset mDataset = new XYMultipleSeriesDataset();

	XYMultipleSeriesRenderer mRenderer = new XYMultipleSeriesRenderer();

 

double[] xvals = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};

	double[] yvals = new double[]{25, 45, 50, 65, 80, 84, 96, 106, 123, 118, 134, 121};

	double[] yvals2 = new double[]{35, 55, 40, 75, 65, 90, 106, 100, 130, 125, 144, 131};

XYSeries series = new XYSeries("2012 Sales Data");

	for (int i = 0; i < 12; i++)

	series.add(xvals[i], yvals[i]);

	XYSeriesRenderer renderer = new XYSeriesRenderer();

	renderer.setDisplayChartValues(true);

mDataset.addSeries(series);

	mRenderer.addSeriesRenderer(renderer);

series = new XYSeries("2013 Sales Data");

	for (int i = 0; i < 12; i++)

	series.add(xvals[i], yvals2[i]);

	renderer = new XYSeriesRenderer();

	renderer.setColor(Color.GREEN);

	renderer.setDisplayChartValues(true);

mDataset.addSeries(series);

	mRenderer.addSeriesRenderer(renderer);

mRenderer.setChartTitle("Sales Chart Comparison 2012 - 2013");

	mRenderer.setXTitle("Month");

	mRenderer.setYTitle("Sales in 1000s");

	mRenderer.setXAxisMin(0.5);

	mRenderer.setXAxisMax(12.5);

	mRenderer.setYAxisMin(20);

	mRenderer.setYAxisMax(140);

	mRenderer.setAxesColor(Color.GRAY);

	mRenderer.setLabelsColor(Color.LTGRAY);

	mRenderer.setXLabels(1);

	mRenderer.setYLabels(10);

	mRenderer.addXTextLabel(1, "Jan");

	mRenderer.addXTextLabel(3, "Mar");

	mRenderer.addXTextLabel(5, "May");

	mRenderer.addXTextLabel(7, "Jul");

	mRenderer.addXTextLabel(10, "Oct");

	mRenderer.addXTextLabel(12, "Dec");
Code Snippet 12. Configuring Dataset and Render For Bar Chart for Sample App ++

We can create and configure each series separately as shown in the code snippet. Additional customizations are selected, similar to the line chart in the previous section. Since both line and bar charts belong to the same base type of XYChart, there are a lot of similarities. For these types of charts, switching from one type to another involves just changing the call to ChartFactory.

Use the ChartFactory class to get a bar chart as an Android view, passing in the context, data series and renderer objects.

mChartView = ChartFactory.getBarChartView(context, mDataset, mRenderer, BarChart.Type.DEFAULT);

LinearLayout layout = (LinearLayout) findViewById(R.id.chart3);

layout.addView(mChartView);
Code Snippet 13. Adding the Bar Chart to Android Layout in Sample App ++

Finally, the bar chart can be embedded into chart3 linear layout as shown in code snippet.
The resulting chart is shown in the following screenshot.

Figure 5. Sales Comparison Using a Bar Chart

Embedding Multiple Charts in an Activity

Using Android's UI layout techniques we could add multiple AChartEngine charts into the same activity, or any placeholder locations in the layout. The following code snippet shows how to add all the previously discussed charts into a single activity layout.

<?xml version="1.0" encoding="utf-8"?>

	<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"

	android:layout_width="fill_parent"

	android:layout_height="fill_parent"

	android:orientation="vertical"

	android:fillViewport="true">

 

<LinearLayout

	android:layout_height="wrap_content"

	android:layout_width="fill_parent"

	android:orientation="vertical"

	android:weightSum="1"

	android:gravity="center"

	android:background="@android:color/transparent">

<TextView

	android:layout_width="261dp"

	android:layout_height="104dp"

	android:textAppearance="?android:attr/textAppearanceLarge"

	android:text="Menu Items Pie Chart"

	android:gravity="center"

	android:id="@+id/textView" />

<LinearLayout

	android:orientation="vertical"

	android:layout_width="600dp"

	android:layout_height="400dp"

	android:id="@+id/chart1"

	android:layout_gravity="center_horizontal"

	android:background="@android:color/transparent"></LinearLayout>

<TextView

	android:layout_width="268dp"

	android:layout_height="104dp"

	android:textAppearance="?android:attr/textAppearanceLarge"

	android:text="Sales Trend"

	android:gravity="center"

	android:id="@+id/textView2" />

<LinearLayout

	android:orientation="vertical"

	android:layout_width="600dp"

	android:layout_height="400dp"

	android:id="@+id/chart2"

	android:layout_gravity="center_horizontal"></LinearLayout>

<TextView

	android:layout_width="344dp"

	android:layout_height="122dp"

	android:textAppearance="?android:attr/textAppearanceLarge"

	android:text="Sales Comparison Chart"

	android:gravity="center"

	android:id="@+id/textView3" />

<LinearLayout

	android:orientation="vertical"

	android:layout_width="600dp"

	android:layout_height="400dp"

	android:id="@+id/chart3"

	android:layout_gravity="center_horizontal"></LinearLayout>

	</LinearLayout>

	</ScrollView>
Code Snippet 14. Layout For Showing Multiple Charts in a Sample App ++

The resulting view is shown in the following screenshot (portrait mode). Scroll view automatically handles the touch scroll navigation.

Figure 6. Embedded Multiple Charts in an Android Activity

Summary

This article discussed different charting options available in Android, weighing pros and cons of each. We used one of the popular charting libraries in Android, AChartEngine, to show how to add a pie chart, line chart and a bar chart, using a sample restaurant app. Different chart customizations and layout issues were discussed.

About the Author

Ashok Emani is a Software Engineer in the Intel Software and Services Group. He currently works on the Intel® Atom™ processor scale enabling projects.

Notices

INFORMATION IN THIS DOCUMENT IS PROVIDED IN CONNECTION WITH INTEL PRODUCTS. NO LICENSE, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, TO ANY INTELLECTUAL PROPERTY RIGHTS IS GRANTED BY THIS DOCUMENT. EXCEPT AS PROVIDED IN INTEL'S TERMS AND CONDITIONS OF SALE FOR SUCH PRODUCTS, INTEL ASSUMES NO LIABILITY WHATSOEVER AND INTEL DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY, RELATING TO SALE AND/OR USE OF INTEL PRODUCTS INCLUDING LIABILITY OR WARRANTIES RELATING TO FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR INFRINGEMENT OF ANY PATENT, COPYRIGHT OR OTHER INTELLECTUAL PROPERTY RIGHT.

UNLESS OTHERWISE AGREED IN WRITING BY INTEL, THE INTEL PRODUCTS ARE NOT DESIGNED NOR INTENDED FOR ANY APPLICATION IN WHICH THE FAILURE OF THE INTEL PRODUCT COULD CREATE A SITUATION WHERE PERSONAL INJURY OR DEATH MAY OCCUR.

Intel may make changes to specifications and product descriptions at any time, without notice. Designers must not rely on the absence or characteristics of any features or instructions marked "reserved" or "undefined." Intel reserves these for future definition and shall have no responsibility whatsoever for conflicts or incompatibilities arising from future changes to them. The information here is subject to change without notice. Do not finalize a design with this information.

The products described in this document may contain design defects or errors known as errata which may cause the product to deviate from published specifications. Current characterized errata are available on request.

Contact your local Intel sales office or your distributor to obtain the latest specifications and before placing your product order.

Copies of documents which have an order number and are referenced in this document, or other Intel literature, may be obtained by calling 1-800-548-4725, or go to: http://www.intel.com/design/literature.htm
Software and workloads used in performance tests may have been optimized for performance only on Intel microprocessors. Performance tests, such as SYSmark* and MobileMark*, are measured using specific computer systems, components, software, operations, and functions. Any change to any of those factors may cause the results to vary. You should consult other information and performance tests to assist you in fully evaluating your contemplated purchases, including the performance of that product when combined with other products.
Any software source code reprinted in this document is furnished under a software license and may only be used or copied in accordance with the terms of that license.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here