Android Line Chart or Line Graph using MpAndroid Library Tutorial

This tutorial explains how to implement Line Chart in a simple Android Application example.




line_chart4

Introduction

A Line chart or Line graph is a type of chart, represented by series of data points and connected by straight line.

In this tutorial, we will implement Line chart using MpAndroid library in Android application. We will cover all series of Line chart. For that, we will create a simple Android application in Android studio and also need to include MpAndroid library in Android application.

Create a new project

To implement Line chart, we are going to create a new android project. Go to File ⇒ New ⇒ New Projects in Android studio.

Add MpAndroid library

We need to add MpAndroid library in our project, so open build.gradle(Module:app) file and add following code:

repositories {
    maven { url "https://jitpack.io" }
}

dependencies {
   .....
    compile 'com.github.PhilJay:MPAndroidChart:v2.2.4'
   .....
}


 

Create Layout

To display Line chart in Android application, we need to add com.github.mikephil.charting.charts.LineChart xml tag in your layout xml file. Use the following code:

<com.github.mikephil.charting.charts.LineChart
    android:id="@+id/linechart"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

 

Initialize Line Chart

We need to initialize Line chart in MainActivity.java file to display Charts.


public class MainActivity extends AppCompatActivity {

    private LineChart mChart;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // To make full screen layout
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);


        mChart = (LineChart) findViewById(R.id.linechart);
    }
}

 

Implement Chart Gesture Listener and Selected Chart Value Listener

We are going to implement gesture and chart value listener feature in our chart. Means, we can zoom in and zoom out our chart and when we will touch to line in the chart, it displays the chart value.
Use the following code:


public class MainActivity extends AppCompatActivity implements 
               OnChartGestureListener,
                       OnChartValueSelectedListener {

    private LineChart mChart;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // To make full screen layout
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);

        mChart = (LineChart) findViewById(R.id.linechart);
        mChart.setOnChartGestureListener(this);
        mChart.setOnChartValueSelectedListener(this);
    }

    
    @Override
    public void onChartGestureStart(MotionEvent me,
                   ChartTouchListener.ChartGesture 
                        lastPerformedGesture) {

        Log.i("Gesture", "START, x: " + me.getX() + ", y: " + me.getY());
    }

    @Override
    public void onChartGestureEnd(MotionEvent me, 
                    ChartTouchListener.ChartGesture 
                                  lastPerformedGesture) {

        Log.i("Gesture", "END, lastGesture: " + lastPerformedGesture);

        // un-highlight values after the gesture is finished and no single-tap
        if(lastPerformedGesture != ChartTouchListener.ChartGesture.SINGLE_TAP)
            // or highlightTouch(null) for callback to onNothingSelected(...)
            mChart.highlightValues(null); 
    }

    @Override
    public void onChartLongPressed(MotionEvent me) {
        Log.i("LongPress", "Chart longpressed.");
    }

    @Override
    public void onChartDoubleTapped(MotionEvent me) {
        Log.i("DoubleTap", "Chart double-tapped.");
    }

    @Override
    public void onChartSingleTapped(MotionEvent me) {
        Log.i("SingleTap", "Chart single-tapped.");
    }

    @Override
    public void onChartFling(MotionEvent me1, MotionEvent me2, 
                             float velocityX, float velocityY) {
        Log.i("Fling", "Chart flinged. VeloX: " 
                + velocityX + ", VeloY: " + velocityY);
    }

    @Override
    public void onChartScale(MotionEvent me, float scaleX, float scaleY) {
        Log.i("Scale / Zoom", "ScaleX: " + scaleX + ", ScaleY: " + scaleY);
    }

    @Override
    public void onChartTranslate(MotionEvent me, float dX, float dY) {
        Log.i("Translate / Move", "dX: " + dX + ", dY: " + dY);
    }

    @Override
    public void onValueSelected(Entry e, int dataSetIndex, Highlight h) {
        Log.i("Entry selected", e.toString());
        Log.i("LOWHIGH", "low: " + mChart.getLowestVisibleXIndex() 
                 + ", high: " + mChart.getHighestVisibleXIndex());

        Log.i("MIN MAX", "xmin: " + mChart.getXChartMin() 
                 + ", xmax: " + mChart.getXChartMax()
                 + ", ymin: " + mChart.getYChartMin() 
                 + ", ymax: " + mChart.getYChartMax());
    }

    @Override
    public void onNothingSelected() {
        Log.i("Nothing selected", "Nothing selected.");
    }
}

 

Create an ArrayList of X-Axis value

Now, we will create an array to store x-axis values. This array is used to display data on a chart in Android Application.

// This is used to store x-axis values 
 private ArrayList<String> setXAxisValues(){
        ArrayList<String> xVals = new ArrayList<String>();
        xVals.add("10");
        xVals.add("20");
        xVals.add("30");
        xVals.add("30.5");
        xVals.add("40");

        return xVals;
    }

 

Create an ArrayList of Y-Axis value

We will create an array to store y-axis values. This array is used to display data on a chart in Android Application.

    // This is used to store Y-axis values
    private ArrayList<Entry> setYAxisValues(){
        ArrayList<Entry> yVals = new ArrayList<Entry>();
        yVals.add(new Entry(60, 0));
        yVals.add(new Entry(48, 1));
        yVals.add(new Entry(70.5f, 2));
        yVals.add(new Entry(100, 3));
        yVals.add(new Entry(180.9f, 4));

        return yVals;
    }

 

Populate X-axis and Y-axis data into chart

Now, we will create a setData() method. Within this method, we will populate X-axis value and Y-axis value in chart. For that, we will initialize LineDataSet and give with in Data Type. We can set custom style of Line chart eg.-

a) Fill the color below the line by calling setFillAlpha(110) or setFillColor(Color.RED),
b) Enable dashed line by calling by calling enableDashedLine(10f, 5f, 0f),
c) Set the color of line by calling setColor(Color.BLACK),
d) Set the color of circle by calling setCircleColor(Color.BLACK),
e) Set the line width by calling setLineWidth(1f),
f) Set the circle radius by calling setCircleRadius(3f),
g) Hide circle by calling setDrawCircleHole(false),
h) Set the text size of value by calling setValueTextSize(9f),
i) Enable/disable filled color below the line by calling setDrawFilled(true).

Also create a data object with the datasets and pass this data object into setData() method of Line chart.

    private void setData() {
        ArrayList<String> xVals = setXAxisValues();

        ArrayList<Entry> yVals = setYAxisValues();

        LineDataSet set1;

            // create a dataset and give it a type
            set1 = new LineDataSet(yVals, "DataSet 1");
            set1.setFillAlpha(110);
            // set1.setFillColor(Color.RED);

            // set the line to be drawn like this "- - - - - -"
            // set1.enableDashedLine(10f, 5f, 0f);
            // set1.enableDashedHighlightLine(10f, 5f, 0f);
            set1.setColor(Color.BLACK);
            set1.setCircleColor(Color.BLACK);
            set1.setLineWidth(1f);
            set1.setCircleRadius(3f);
            set1.setDrawCircleHole(false);
            set1.setValueTextSize(9f);
            set1.setDrawFilled(true);

            ArrayList<ILineDataSet> dataSets = new ArrayList<ILineDataSet>();
            dataSets.add(set1); // add the datasets

            // create a data object with the datasets
            LineData data = new LineData(xVals, dataSets);

            // set data
            mChart.setData(data);

    }

 

Call Set Data and Add Legend

Now, call setData() method in onCreate()method to add the data to the line chart and set the legends after set data.

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // To make full screen layout
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);


        mChart = (LineChart) findViewById(R.id.linechart);

        // add data
        setData();

        // get the legend (only possible after setting data)
        Legend l = mChart.getLegend();

        // modify the legend ...
        // l.setPosition(LegendPosition.LEFT_OF_CHART);
        l.setForm(Legend.LegendForm.LINE);
    }

line_chart

line_chart2

 

Set the description

We can set the description about the Line chart and also set description for no data of line chart.

 // no description text
mChart.setDescription("Demo Line Chart");
mChart.setNoDataTextDescription("You need to provide data for the chart.");

line_chart3

 

Enable Touch Gesture

We can enable touch gesture by calling setTouchEnabled(true).

// enable touch gestures
mChart.setTouchEnabled(true);

 

Enable Scaling and Dragging

We can enable scaling and dragging by calling setDragEnabled(true) and setScaleEnabled(true). This will help to scale by finger.

// enable scaling and dragging
mChart.setDragEnabled(true);
mChart.setScaleEnabled(true);

 

Define Y-axis upper and lower limit

To draw upper and lower limit line, we need to create LimitLine object with limit value and text. Pass it into addLimitLine() method of Y-axis. Also we can set limit line width, text size, set the label position and enable dash line etc.

LimitLine upper_limit = new LimitLine(130f, "Upper Limit");
upper_limit.setLineWidth(4f);
upper_limit.enableDashedLine(10f, 10f, 0f);
upper_limit.setLabelPosition(LimitLine.LimitLabelPosition.RIGHT_TOP);
upper_limit.setTextSize(10f);

LimitLine lower_limit = new LimitLine(-30f, "Lower Limit");
lower_limit.setLineWidth(4f);
lower_limit.enableDashedLine(10f, 10f, 0f);
lower_limit.setLabelPosition(LimitLine.LimitLabelPosition.RIGHT_BOTTOM);
lower_limit.setTextSize(10f);

YAxis leftAxis = mChart.getAxisLeft();
// reset all limit lines to avoid overlapping lines
leftAxis.removeAllLimitLines(); 
leftAxis.addLimitLine(upper_limit);
leftAxis.addLimitLine(lower_limit);
leftAxis.setAxisMaxValue(220f);
leftAxis.setAxisMinValue(-50f);
//leftAxis.setYOffset(20f);
leftAxis.enableGridDashedLine(10f, 10f, 0f);
leftAxis.setDrawZeroLine(false);

// limit lines are drawn behind data (and not on top)
leftAxis.setDrawLimitLinesBehindData(true);

mChart.getAxisRight().setEnabled(false);

line_chart4

 

Add Animation

We can make chart lively. The animateXY method is used to animate both axes of the chart. If you want to animate only one of the axes, you can use animateX or animateY to animate the x-axis or y-axis respectively. You have to specify the duration (in milliseconds) of the animation when you call these methods.

mChart.animateX(2500, Easing.EasingOption.EaseInOutQuart);

 

Final Code


public class MainActivity extends AppCompatActivity implements OnChartGestureListener,
        OnChartValueSelectedListener {

    private LineChart mChart;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // To make full screen layout
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);


        mChart = (LineChart) findViewById(R.id.linechart);
        mChart.setOnChartGestureListener(this);
        mChart.setOnChartValueSelectedListener(this);
        mChart.setDrawGridBackground(false);

        // add data
        setData();

        // get the legend (only possible after setting data)
        Legend l = mChart.getLegend();

        // modify the legend ...
        // l.setPosition(LegendPosition.LEFT_OF_CHART);
        l.setForm(Legend.LegendForm.LINE);

        // no description text
        mChart.setDescription("Demo Line Chart");
        mChart.setNoDataTextDescription("You need to provide data for the chart.");

        // enable touch gestures
        mChart.setTouchEnabled(true);

        // enable scaling and dragging
        mChart.setDragEnabled(true);
        mChart.setScaleEnabled(true);
        // mChart.setScaleXEnabled(true);
        // mChart.setScaleYEnabled(true);

        LimitLine upper_limit = new LimitLine(130f, "Upper Limit");
        upper_limit.setLineWidth(4f);
        upper_limit.enableDashedLine(10f, 10f, 0f);
        upper_limit.setLabelPosition(LimitLine.LimitLabelPosition.RIGHT_TOP);
        upper_limit.setTextSize(10f);

        LimitLine lower_limit = new LimitLine(-30f, "Lower Limit");
        lower_limit.setLineWidth(4f);
        lower_limit.enableDashedLine(10f, 10f, 0f);
        lower_limit.setLabelPosition(LimitLine.LimitLabelPosition.RIGHT_BOTTOM);
        lower_limit.setTextSize(10f);

        YAxis leftAxis = mChart.getAxisLeft();
        leftAxis.removeAllLimitLines(); // reset all limit lines to avoid overlapping lines
        leftAxis.addLimitLine(upper_limit);
        leftAxis.addLimitLine(lower_limit);
        leftAxis.setAxisMaxValue(220f);
        leftAxis.setAxisMinValue(-50f);
        //leftAxis.setYOffset(20f);
        leftAxis.enableGridDashedLine(10f, 10f, 0f);
        leftAxis.setDrawZeroLine(false);

        // limit lines are drawn behind data (and not on top)
        leftAxis.setDrawLimitLinesBehindData(true);

        mChart.getAxisRight().setEnabled(false);

        //mChart.getViewPortHandler().setMaximumScaleY(2f);
        //mChart.getViewPortHandler().setMaximumScaleX(2f);

        mChart.animateX(2500, Easing.EasingOption.EaseInOutQuart);

        //  dont forget to refresh the drawing
         mChart.invalidate();

    }

    private ArrayList<String> setXAxisValues(){
        ArrayList<String> xVals = new ArrayList<String>();
        xVals.add("10");
        xVals.add("20");
        xVals.add("30");
        xVals.add("30.5");
        xVals.add("40");

        return xVals;
    }

    private ArrayList<Entry> setYAxisValues(){
        ArrayList<Entry> yVals = new ArrayList<Entry>();
        yVals.add(new Entry(60, 0));
        yVals.add(new Entry(48, 1));
        yVals.add(new Entry(70.5f, 2));
        yVals.add(new Entry(100, 3));
        yVals.add(new Entry(180.9f, 4));

        return yVals;
    }

    private void setData() {
        ArrayList<String> xVals = setXAxisValues();

        ArrayList<Entry> yVals = setYAxisValues();

        LineDataSet set1;

            // create a dataset and give it a type
            set1 = new LineDataSet(yVals, "DataSet 1");

             set1.setFillAlpha(110);
            // set1.setFillColor(Color.RED);

            // set the line to be drawn like this "- - - - - -"
         //   set1.enableDashedLine(10f, 5f, 0f);
           // set1.enableDashedHighlightLine(10f, 5f, 0f);
            set1.setColor(Color.BLACK);
            set1.setCircleColor(Color.BLACK);
            set1.setLineWidth(1f);
            set1.setCircleRadius(3f);
            set1.setDrawCircleHole(false);
            set1.setValueTextSize(9f);
            set1.setDrawFilled(true);

            ArrayList<ILineDataSet> dataSets = new ArrayList<ILineDataSet>();
            dataSets.add(set1); // add the datasets

            // create a data object with the datasets
            LineData data = new LineData(xVals, dataSets);

            // set data
            mChart.setData(data);

    }


    @Override
    public void onChartGestureStart(MotionEvent me,
                   ChartTouchListener.ChartGesture 
                        lastPerformedGesture) {

        Log.i("Gesture", "START, x: " + me.getX() + ", y: " + me.getY());
    }

    @Override
    public void onChartGestureEnd(MotionEvent me, 
                    ChartTouchListener.ChartGesture 
                                  lastPerformedGesture) {

        Log.i("Gesture", "END, lastGesture: " + lastPerformedGesture);

        // un-highlight values after the gesture is finished and no single-tap
        if(lastPerformedGesture != ChartTouchListener.ChartGesture.SINGLE_TAP)
            // or highlightTouch(null) for callback to onNothingSelected(...)
            mChart.highlightValues(null); 
    }

    @Override
    public void onChartLongPressed(MotionEvent me) {
        Log.i("LongPress", "Chart longpressed.");
    }

    @Override
    public void onChartDoubleTapped(MotionEvent me) {
        Log.i("DoubleTap", "Chart double-tapped.");
    }

    @Override
    public void onChartSingleTapped(MotionEvent me) {
        Log.i("SingleTap", "Chart single-tapped.");
    }

    @Override
    public void onChartFling(MotionEvent me1, MotionEvent me2, 
                             float velocityX, float velocityY) {
        Log.i("Fling", "Chart flinged. VeloX: " 
                + velocityX + ", VeloY: " + velocityY);
    }

    @Override
    public void onChartScale(MotionEvent me, float scaleX, float scaleY) {
        Log.i("Scale / Zoom", "ScaleX: " + scaleX + ", ScaleY: " + scaleY);
    }

    @Override
    public void onChartTranslate(MotionEvent me, float dX, float dY) {
        Log.i("Translate / Move", "dX: " + dX + ", dY: " + dY);
    }

    @Override
    public void onValueSelected(Entry e, int dataSetIndex, Highlight h) {
        Log.i("Entry selected", e.toString());
        Log.i("LOWHIGH", "low: " + mChart.getLowestVisibleXIndex() 
                 + ", high: " + mChart.getHighestVisibleXIndex());

        Log.i("MIN MAX", "xmin: " + mChart.getXChartMin() 
                 + ", xmax: " + mChart.getXChartMax()
                 + ", ymin: " + mChart.getYChartMin() 
                 + ", ymax: " + mChart.getYChartMax());
    }

    @Override
    public void onNothingSelected() {
        Log.i("Nothing selected", "Nothing selected.");
    }
}

 


The following two tabs change content below.
Abhay Anand has experience in the field of Software Development. He can program Android, PHP, JavaScript, Html, Css. He develops web and Android applications. You can reach him at anand.abhay1910@gmail.com
  • prashant pandey

    It helped me a lot to learn and enhance my knowledge. Great tutorial..

    • abhayanand1910

      Glad it helped you.