Android OnClick Event Handler for Custom Layout LineChart in AChartEngine

October 22, 2012
By

This article is  an extension to the article titled “Android Drawing Line Chart in a Custom XML Layout using AChartEngine“, where we have discussed how to draw a line chart in a custom layout. In this article, we will see how to a add click event handler for the line points in AChartEngine.

This application is developed in Eclipse ( 4.2.0 ) with ADT plugin ( 20.0.3 ) and Android SDK (R20.0.3).


1. Create an Android application project namely “AChartEngineLineChartCustomLayoutClick”

Create a new Android application project "AChartEngineLineChartCustomLayoutClick"

Figure 1 : Create a new Android application project "AChartEngineLineChartCustomLayoutClick"


2. Design an application launcher icon

Design Application launcher icon

Figure 2 : Design Application launcher icon


3. Create a blank activity to define the class MainActivity

Create a blank activity

Figure 3 : Create a blank activity


4. Enter MainActivity details

Enter MainActivity Details

Figure 4 : Enter MainActivity Details


5. Delete Android Support Library from this project, if exists

By default Eclipse ( 4.2.0) adds Android Support Library to  Android application project. For this application, we don’t need to use this support library. So the library file libs/android-support-v4.jar may be removed manually via ProjectExplorer by simply right click on the file and then clicking the menu item “delete”.


6. Download the latest version of AChartEngine library ( jar file ) from here


7. Copy the downloaded library file to “libs” directory of the project


8. Update the file res/values/strings.xml


<resources>

    <string name="app_name">AChartEngineLineChartCustomLayoutClick</string>
    <string name="hello_world">Hello world!</string>
    <string name="menu_settings">Settings</string>
    <string name="title_activity_main">AChartEngineLineChartCustomLayoutClick</string>
    <string name="str_tv_title">AChartEngine Click Demo</string>

</resources>


9. Update the layout of the MainActivity in the file res/layout/activity_main.xml


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/str_tv_title"
        android:gravity="center_horizontal" />

    <LinearLayout
        android:id="@+id/chart_container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/tv_title" >
    </LinearLayout>

</RelativeLayout>

10. Update the file res/values/styles.xml


<resources>
    <style name="AppTheme" parent="android:Theme" />
</resources>


11. Update the file res/values-v11/styles.xml


<resources>
    <style name="AppTheme" parent="android:Theme.Holo" />
</resources>


12. Update the file res/values-v14/styles.xml


<resources>
    <style name="AppTheme" parent="android:Theme.Holo" />
</resources>


13. Update the class MainActivity in the file src/in/wptrafficanalyzer/achartenginelinechartcustomlayoutclick/MainActivity.java


package in.wptrafficanalyzer.achartenginelinechartcustomlayoutclick;

import org.achartengine.ChartFactory;
import org.achartengine.GraphicalView;
import org.achartengine.chart.PointStyle;
import org.achartengine.model.SeriesSelection;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.model.XYSeries;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.Toast;

public class MainActivity extends Activity {

    private GraphicalView mChart;

    private String[] mMonth = new String[] {
        "Jan", "Feb" , "Mar", "Apr", "May", "Jun",
        "Jul", "Aug" , "Sep", "Oct", "Nov", "Dec"
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        openChart();
    }

    private void openChart(){
        int[] x = { 0,1,2,3,4,5,6,7 };
        int[] income = { 2000,2500,2700,3000,2800,3500,3700,3800};
        int[] expense = {2200, 2700, 2900, 2800, 2600, 3000, 3300, 3400 };

        // Creating an  XYSeries for Income
        XYSeries incomeSeries = new XYSeries("Income");
        // Creating an  XYSeries for Expense
        XYSeries expenseSeries = new XYSeries("Expense");
        // Adding data to Income and Expense Series
        for(int i=0;i<x.length;i++){
            incomeSeries.add(x[i], income[i]);
            expenseSeries.add(x[i],expense[i]);
        }

        // Creating a dataset to hold each series
        XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
        // Adding Income Series to the dataset
        dataset.addSeries(incomeSeries);
        // Adding Expense Series to dataset
        dataset.addSeries(expenseSeries);

        // Creating XYSeriesRenderer to customize incomeSeries
        XYSeriesRenderer incomeRenderer = new XYSeriesRenderer();
        incomeRenderer.setColor(Color.WHITE);
        incomeRenderer.setPointStyle(PointStyle.CIRCLE);
        incomeRenderer.setFillPoints(true);
        incomeRenderer.setLineWidth(2);
        incomeRenderer.setDisplayChartValues(true);

        // Creating XYSeriesRenderer to customize expenseSeries
        XYSeriesRenderer expenseRenderer = new XYSeriesRenderer();
        expenseRenderer.setColor(Color.YELLOW);
        expenseRenderer.setPointStyle(PointStyle.CIRCLE);
        expenseRenderer.setFillPoints(true);
        expenseRenderer.setLineWidth(2);
        expenseRenderer.setDisplayChartValues(true);

        // Creating a XYMultipleSeriesRenderer to customize the whole chart
        XYMultipleSeriesRenderer multiRenderer = new XYMultipleSeriesRenderer();
        multiRenderer.setXLabels(0);
        multiRenderer.setChartTitle("Income vs Expense Chart");
        multiRenderer.setXTitle("Year 2012");
        multiRenderer.setYTitle("Amount in Dollars");
        multiRenderer.setZoomButtonsVisible(true);
        for(int i=0;i<x.length;i++){
            multiRenderer.addXTextLabel(i, mMonth[i]);
        }

        // Adding incomeRenderer and expenseRenderer to multipleRenderer
        // Note: The order of adding dataseries to dataset and renderers to multipleRenderer
        // should be same
        multiRenderer.addSeriesRenderer(incomeRenderer);
        multiRenderer.addSeriesRenderer(expenseRenderer);

        // Getting a reference to LinearLayout of the MainActivity Layout
        LinearLayout chartContainer = (LinearLayout) findViewById(R.id.chart_container);

        // Creating a Line Chart
        mChart = (GraphicalView) ChartFactory.getLineChartView(getBaseContext(), dataset, multiRenderer);

        multiRenderer.setClickEnabled(true);//
        multiRenderer.setSelectableBuffer(10);
        mChart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SeriesSelection seriesSelection = mChart.getCurrentSeriesAndPoint();

                if (seriesSelection != null) {
                    int seriesIndex = seriesSelection.getSeriesIndex();
                    String selectedSeries="Income";
                    if(seriesIndex==0)
                        selectedSeries = "Income";
                    else
                        selectedSeries = "Expense";
                    // Getting the clicked Month
                    String month = mMonth[(int)seriesSelection.getXValue()];
                    // Getting the y value
                    int amount = (int) seriesSelection.getValue();
                    Toast.makeText(
                        getBaseContext(),
                        selectedSeries + " in "  + month + " : " + amount ,
                        Toast.LENGTH_SHORT).show();
                }
            }
        });

        // Adding the Line Chart to the LinearLayout
        chartContainer.addView(mChart);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}


14. Run the application

LineChart with Click Event Listener in Action

Figure 5 : LineChart with Click Event Listener in Action


15. Download


16. Reference

http://developer.android.com/guide/index.html


How to hire me?

I am George Mathew, working as software architect and Android app developer at wptrafficanalyzer.in

You can hire me on hourly basis or on project basis for Android applications development.

For hiring me, please mail your requirements to info@wptrafficanalyzer.in.

My other blogs
store4js.blogspot.com


Android Knowledge Quiz

Ready to test your knowledge in Android? Take this quiz :



Tags: , , , ,

2 Responses to Android OnClick Event Handler for Custom Layout LineChart in AChartEngine

  1. Sathya on December 4, 2012 at 4:08 pm

    Thanks for the example.

  2. vipul thakur on February 25, 2015 at 12:51 pm

    very helpful..and simple..thank you

Leave a Reply

Your email address will not be published. Required fields are marked *

Be friend at g+

Subscribe for Lastest Updates

FBFPowered by ®Google Feedburner