Home

Awesome

Android Arsenal [ android-arsenal.com] (https://github.com/vbauer/android-arsenal.com)

MPAndroidChart

A simple charting library for Android, supporting line-, bar-, scatter-, candlestick- and piecharts, as well as scaling, dragging, selecting and animations. Supporting Android 2.2 (API level 8) and upwards.

Remember: It's all about the looks.

The experimental branch might contain new features that are still buggy. It is recommended to be safe and only make use of the code on the master branch.

Forks, pull-requests or any other forms of contribution are always welcome.

Donations

If you would like to support this project's further development, the creator of this project or the continuous maintenance of this project, feel free to donate. Your donation is highly appreciated.

PayPal

Donate

Gittip

<a href="https://www.gittip.com/PhilJay/"> <img alt="Support via Gittip" src="https://rawgithub.com/twolfson/gittip-badge/0.2.0/dist/gittip.png"/> </a>

Gratipay

Demo

For a brief overview of the most important features, please download the PlayStore Demo MPAndroidChart Example.apk and try it out. The corresponding code for the demo-application is also included in this repository inside the MPChartExample folder.

ScreenShot

Questions & Issues

If you are having questions or problems, feel free to contact me. Since I would very much like that other users of this library can also benefit from your question, I am asking you to contact me via e-mail only as a last option. Instead, you should:

You can let me know via e-mail that you have opened a stackoverflow question so that I might get to answering it more quickly. Thank you.

Features

Core features:

Chart types:

alt tag

alt tag

alt tag

alt tag

alt tag

alt tag

alt tag

Usage

In order to use the library, there are 2 options:

1. jar file only

2. clone whole repository

For getting started, rely on the "MPChartExample" folder and check out the examples in that project. The example project is also available in the Google PlayStore.

Furthermore, here is some code to begin with.

Setup:

For using a <code>LineChart, BarChart, ScatterChart, CandleStickChart or PieChart </code>, define it in .xml:

    <com.github.mikephil.charting.charts.LineChart
        android:id="@+id/chart"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    LineChart chart = (LineChart) findViewById(R.id.chart);

or create it in code (and then add it to a layout):

    LineChart chart = new LineChart(Context);

Styling:

Getters and convenience:

Gestures & Selecting:

Other:

Adding data:

If you want to add values (data) to the chart, it has to be done via the

    setData(ChartData data);

method. The baseclass <code>ChartData</code> class encapsulates all data and information that is needed for the chart during rendering. For each type of chart, a different subclass of ChartData (e.g. LineData) exists that should be used for setting data for the chart. In the constructor, you can hand over an <code>ArrayList<? extends DataSet></code> as the values to display, and an additional <code>ArrayList</code> of <code>String</code> that will describe the labels on the x-axis. Example with the class LineData (extends ChartData), which is used for adding data to a LineChart:

    public LineData(ArrayList<String> xVals, ArrayList<LineDataSet> sets) { ... }

So, what is a <code>DataSet</code> and why do you need it? That is actually pretty simple. One <code>DataSet</code> object represents a group of entries (datatype <code>Entry</code>) inside the chart that belong together. It is designed to logically separate different groups of values in the chart. For each type of chart, a differnt object that extends DataSet (e.g. LineDataSet) exists that allows specific styling.

As an example, you might want to display the quarterly revenue of two different companies over one year in a LineChart. In that case, it would be recommended to create two different <code>LineDataSet</code> objects, each containing four values (one for each quarter). As an <code>ArrayList<String></code> to describe the labels on the x-axis, you would simply provide the four Strings "1.Q", "2.Q", "3.Q", "4.Q".

Of course, it is also possible to provide just one <code>LineDataSet</code> object containing all 8 values for the two companys.

So how to setup a <code>LineDataSet</code> object?

    public LineDataSet(ArrayList<Entry> yVals, String label) { ... }

When looking at the constructor, it is visible that the <code>LineDataSet</code> needs an <code>ArrayList</code> of type <code>Entry</code> and a String used to describe the LineDataSet and as a label used for the Legend. Furthermore this label can be used to find the LineDataSet amongst other LineDataSet objects in the LineData object.

The <code>ArrayList</code> of type <code>Entry</code> encapsulates all values of the chart. A <code>Entry</code> object is an additional wrapper around a value and holds the value itself, and it's position on the x-axis (the index inside the <code>ArrayList</code> of <code>String</code> of the <code>LineData</code> object the value is mapped to):

    public Entry(float val, int xIndex) { ... }

Putting it all together (example of two companies with quarterly revenue over one year):

At first, create the lists of type <code>Entry</code> that will hold your values:

    ArrayList<Entry> valsComp1 = new ArrayList<Entry>();
    ArrayList<Entry> valsComp2 = new ArrayList<Entry>();

Then, fill the lists with <code>Entry</code> objects. Make sure the entry objects contain the correct indices to the x-axis. (of course, a loop can be used here, in that case, the counter variable of the loop could be the index on the x-axis).

    Entry c1e1 = new Entry(100.000f, 0); // 0 == quarter 1
    valsComp1.add(c1e1);
    Entry c1e2 = new Entry(50.000f, 1); // 1 == quarter 2 ...
    valsComp1.add(c1e2);
    // and so on ...
    
    Entry c2e1 = new Entry(120.000f, 0); // 0 == quarter 1
    valsComp2.add(c2e1);
    Entry c2e2 = new Entry(110.000f, 1); // 1 == quarter 2 ...
    valsComp2.add(c2e2);
    //...

Now that we have our lists of <code>Entry</code> objects, the <code>LineDataSet</code> objects can be created:

    LineDataSet setComp1 = new LineDataSet(valsComp1, "Company 1");
    LineDataSet setComp2 = new LineDataSet(valsComp2, "Company 2");

Last but not least, we create a list of <code>DataSets</code> and a list of x legend entries and build our <code>ChartData</code> object:

    ArrayList<LineDataSet> dataSets = new ArrayList<LineDataSet>();
    dataSets.add(setComp1);
    dataSets.add(setComp2);
    
    ArrayList<String> xVals = new ArrayList<String>();
    xVals.add("1.Q"); xVals.add("2.Q"); xVals.add("3.Q"); xVals.add("4.Q"); 
    
    LineData data = new LineData(xVals, dataSets);
    mLineChart.setData(data);

Setting colors:

Since release v1.4.0, the ColorTemplate object that was responsible for setting colors in previous releases is no longer needed. Nevertheless, it still holds all predefined color arrays (e.g. ColorTemplate.VORDIPLOM_COLORS and provides convenience methods for transforming colors from the resources (resource integers) into "real" colors.

Instead of the ColorTemplate, colors can now be specified directly via DataSet object, which allows separate styling for each DataSet.

In this short example, we have our two different LineDataSet objects representing the quarterly revenues of two companies (previously mentioned in the Adding data tutorial), for which we now want to set different colors.

What we want:

This is what the code looks like:

  LineDataSet setComp1 = new LineDataSet(valsComp1, "Company 1");
  
  // sets colors for the dataset, resolution of the resource name to a "real" color is done internally
  setComp1.setColors(new int[] { R.color.red1, R.color.red2, R.color.red3, R.color.red4 }, Context);
  
  LineDataSet setComp2 = new LineDataSet(valsComp2, "Company 2");
  setComp2.setColors(new int[] { R.color.green1, R.color.green2, R.color.green3, R.color.green4 }, Context);

Besides that, there are many other ways for setting colors for a DataSet. Here is the full documentation:

ColorTemplate example:

LineDataSet set = new LineDataSet(...);
set.setColors(ColorTemplate.VORDIPLOM_COLORS);

If no colors are set for a DataSet, default colors are used.

Displaying / styling legends:

By default, all chart types support legends and will automatically generate and draw a legend after setting data for the chart. If a legend should be drawn or not can be enabled/disabled using the

method.

The number of entries the automatically generated legend contains depends on the number of different colors (across all DataSet objects) as well as on the DataSet labels. The labels of the Legend depend on the labels set for the used DataSet objects in the chart. If no labels for the DataSet objects have been specified, the chart will automatically generate them. If multiple colors are used for one DataSet, those colors are grouped and only described by one label.

For customizing the Legend, use you can retreive the Legend object from the chart after setting data using the getLegend() method.

    // setting data...
    chart.setData(....);
    
    Legend l = chart.getLegend();
    l.setFormSize(10f); // set the size of the legend forms/shapes
    l.setForm(LegendForm.CIRCLE); // set what type of form/shape should be used
    l.setPosition(LegendPosition.BELOW_CHART_LEFT);
    l.setTypeface(...);
    l.setXEntrySpace(5f); // set the space between the legend entries on the x-axis
    l.setYEntrySpace(5f); // set the space between the legend entries on the y-axis
    // and many more...

Displaying / styling labels:

Labels (classes XLabel and YLabel) are used to describe the values of the chart on the x- and y-axis. While the x-axis labels display what is handed over to the ChartData object as an ArrayList<String> ("xVals"), the y-axis labels depend on the actual values that are set for the chart.

Labels can be enabled/disabled, using the methods:

the chart provides. In order to apply a different styling to the labels, the methods getYLabels() and getXLabels() can be used to acquire the labels object and modify it.

Example:

XLabels xl = mChart.getXLabels();
xl.setPosition(XLabelPosition.BOTTOM); // set the position
xl.setTypeface(...); // set a different font
xl.setTextSize(12f); // set the textsize
xl.setSpaceBetweenLabels(3); // set how many characters of space should be between the labels
//... and more

YLabels yl = mChart.getYLabels();
yl.setPosition(YLabelPosition.BOTH_SIDED); // set the position
yl.setTypeface(...); // set a different font
yl.setTextSize(12f); // set the textsize
yl.setLabelCount(6); // set how many label entries should be displayed
//... and more

Limit Lines:

Limit lines (class LimitLine) are (as the name might indicate) plain and simple lines that can be set for all Line-, Bar- and ScatterData objects. They can be used to provide additional information for the user.

As an example, your chart might display various blood pressure measurement results the user logged with an application. In order to inform the user that a systolic blood pressure of over 140 mmHg is considered to be a health risk, you could add a LimitLine at 140 to provide that information.


LineData ld = new LineData(...);

LimitLine ll = new LimitLine(140f);
ll.setLineColor(Color.RED);
ll.setLineWidth(4f);
// .. and more styling options

ld.addLimitLine(ll);

Dynamically adding data (real time):

For adding new data to the chart dynamically, there are various methods that allow to either add Entry objects to an existing DataSet or DataSet objects to an existing ChartData object.

Class DataSet (and all subclasses):

Class ChartData (and all subclasses):

In addition to that, there are also methods for removing data dynamically.

Class DataSet (and all subclasses):

Class ChartData (and all subclasses):

Animations:

All chart types support animations that can be used to create / build up the chart in an awesome looking way. Three different kinds of animation methods exist that animate either both, or x- and y-axis separately:

mChart.animateX(3000f); // animate horizontal 3000 milliseconds
// or:
mChart.animateY(3000f); // animate vertical 3000 milliseconds
// or:
mChart.animateXY(3000f, 3000f); // animate horizontal and vertical 3000 milliseconds

If animate(...) (of any kind) is called, no further calling of invalidate() is necessary to refresh the chart.

In order to support animations below Honeycomb, this library makes use of the awesome nineoldandroids library developed by Jake Wharton.

More documentation and example code coming soon.

This chart library is intended to fill the gap between popular charting libraries like "GraphView" or "achartengine".

License

Copyright 2014 Philipp Jahoda

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Special thanks to mikegr and ph1lb4 for their contributions to this project.