Android之MPAndroidChart库使用说明(柱状图、折线图、饼图和组合图.)

介绍:
MPAndroidChart是一款基于Android的开源图表库,MPAndroidChart不仅可以在Android设备上绘制各种统计图表,而且可以对图表进行拖动和缩放操作,应用起来非常灵活。 MPAndroidChart同样拥有常用的图表类型:线型图、饼图、柱状图和散点图和雷达图。
适用场景:
如果您的应用涉及大量数据,利用图表,用表显示的数据可能会得到一个好得多的用户体验。

一、把MPAndroidChart导入我们的项目:
Gradle依赖:
在Project级别的build.gradle中添加如下代码:
allprojects {
    repositories {
        maven { url  "https://jitpack.io" }
    }
}
在app级别的build.gradle中添加如下代码:
dependencies {
    compile  'com.github.PhilJay:MPAndroidChart:v3.0.1'
}
然后,编译项目即可。

二、MPAndroidChart使用方式概述(参见 MPAndroidChart的git网站的Wiki ):
1、创建Chart
    使用LineChart, BarChart, PieChart或CombineChart时需要先在布局文件中进行定义,然后在后台代码中绑定;或者直接在代码中声明也行(不常用)。

2、设置Chart的样式
     当创建好一个chart后,就可以为该chart设置样式,包括chart的放缩,chart视图窗口的边距和加载动画,X/Y轴标签的样式、显示的位置、坐标轴的宽度、是否可用等,图例的位置、文字大小等等

lineChart.getDescription().setEnabled(false);//设置描述
lineChart.setPinchZoom(true);//设置按比例放缩柱状图

//x坐标轴设置
XAxis xAxis = lineChart.getXAxis();
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);//设置X轴标签显示位置
xAxis.setDrawGridLines(false);//不绘制格网线
xAxis.setGranularity(1f);//设置最小间隔,防止当放大时,出现重复标签。
xAxis.setLabelCount(12);//设置x轴显示的标签个数
xAxis.setAxisLineWidth(2f);//设置x轴宽度, ...其他样式

//y轴设置
YAxis leftAxis = lineChart.getAxisLeft();//取得左侧y轴
leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);//y轴标签绘制的位置
leftAxis.setDrawGridLines(false);//不绘制y轴格网线
leftAxis.setDrawLabels(false);//不显示坐标轴上的值, ...其他样式

lineChart.getAxisRight().setEnabled(false);

//图例设置
Legend legend = lineChart.getLegend();
legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
legend.setDrawInside(false);
legend.setDirection(Legend.LegendDirection.LEFT_TO_RIGHT);
legend.setForm(Legend.LegendForm.LINE);
legend.setTextSize(12f);//设置图例字体大小, ...其他样式

lineChart.setExtraOffsets(10, 30, 20, 10);//设置视图窗口大小
lineChart.animateX(1500);//数据显示动画,从左往右依次显示

3、添加数据
    当设置好一个chart的样式后,就可以为该chart添加数据。例如LineChart,一个Entry类代表图上的一个(x,y)坐标对。但在其他的chart类型中,例如BarChart,则是BarEntry类代表 图上的一个(x,y)坐标对。

YourData[] dataObjects = ...;
List<Entry> entries = new ArrayList<Entry>();
for (YourData data : dataObjects) {
    // turn your data into Entry objects
    entries.add(new Entry(data.getValueX(), data.getValueY()));
}

     用List<Entry>初始化一个LineDataSet对象以代表该数据集。如果一个LineChart有多个LineDataSet,每个LineDataSet可以设置自己的样式。

LineDataSet dataSet = new LineDataSet(entries, "Label"); // add entries to dataset
dataSet.setColor(...);
dataSet.setValueTextColor(...); // styling, ...

    然后,将LineDataSet添加到LineData对象中。LineData对象持有LineChart的所有数据,并允许设置额外的样式。最后,将LineData对象设置到LineChart并刷新该LineChart即可。

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

LineData lineData = new LineData(dataSets);
chart.setData(lineData);
chart.setValueTextSize(10f);//设置数值字体大小, ...other styling 
chart.invalidate(); // refresh

三、利用MPAndroidChart绘制柱状图、线图、饼图和组合图,测试设备为360N4S。
项目结构如下图所示:
(一)MainActivity的代码如下:
布局文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.charlie.mpandroidcharttest.MainActivity">

    <ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></ListView>
</RelativeLayout>

代码文件:

package com.charlie.mpandroidcharttest;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import com.charlie.mpandroidcharttest.chartactivity.BarChartActivity;
import com.charlie.mpandroidcharttest.chartactivity.CombineChartActivity;
import com.charlie.mpandroidcharttest.chartactivity.LineChartActivity;
import com.charlie.mpandroidcharttest.chartactivity.MultiLineChartActivity;
import com.charlie.mpandroidcharttest.chartactivity.PieChartActivity;
import com.charlie.mpandroidcharttest.chartactivity.PositiveNegativeBarChartActivity;
import com.charlie.mpandroidcharttest.chartactivity.ThreeBarChartActivity;
import com.charlie.mpandroidcharttest.chartactivity.TwoBarChartActivity;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {

    private ListView listView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        listView=(ListView)findViewById(R.id.listview);
        listView.setAdapter(new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,initListData()));
        listView.setOnItemClickListener(this);
    }

    private List<String> initListData(){
        List<String> data = new ArrayList<>();
        data.add("柱状图(单)");
        data.add("柱状图(双)");
        data.add("柱状图(三)");
        data.add("正负柱状图");
        data.add("折线图(单)");
        data.add("折线图(复)");
        data.add("饼图");
        data.add("组合图");
        return data;
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        Intent i;
        switch (position){
            case 0:
                i = new Intent(MainActivity.this, BarChartActivity.class);
                startActivity(i);
                break;
            case 1:
                i = new Intent(MainActivity.this, TwoBarChartActivity.class);
                startActivity(i);
                break;
            case 2:
                i = new Intent(MainActivity.this, ThreeBarChartActivity.class);
                startActivity(i);
                break;
            case 3:
                i = new Intent(MainActivity.this, PositiveNegativeBarChartActivity.class);
                startActivity(i);
                break;
            case 4:
                i = new Intent(MainActivity.this, LineChartActivity.class);
                startActivity(i);
                break;
            case 5:
                i = new Intent(MainActivity.this, MultiLineChartActivity.class);
                startActivity(i);
                break;
            case 6:
                i = new Intent(MainActivity.this, PieChartActivity.class);
                startActivity(i);
                break;
            case 7:
                i = new Intent(MainActivity.this, CombineChartActivity.class);
                startActivity(i);
                break;
        }
    }
}

(二)柱状图(包括单柱图、双柱图、三柱图和正负柱图):
1、单柱图:
先看效果图,如下:

布局如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_bar_chart"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.charlie.mpandroidcharttest.chartactivity.BarChartActivity">
    <com.github.mikephil.charting.charts.BarChart
        android:id="@+id/barChart1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</RelativeLayout>

设置好x轴和y轴要显示的数据,然后调用如下函数即可:

/**
* 单数据集。设置柱状图样式,X轴为字符串,Y轴为数值
*
* @param barChart
* @param xAxisValue
* @param yAxisValue
* @param title 图例文字
* @param xAxisTextSize x轴标签字体大小
* @param barColor
*/
public static void setBarChart(BarChart barChart, List<String> xAxisValue, List<Float> yAxisValue, String title, float xAxisTextSize, Integer barColor) {
    barChart.getDescription().setEnabled(false);//设置描述
    barChart.setPinchZoom(true);//设置按比例放缩柱状图

    //设置自定义的markerView
    MPChartMarkerView markerView = new MPChartMarkerView(barChart.getContext(), R.layout.custom_marker_view);
    barChart.setMarker(markerView);

    //x坐标轴设置
    IAxisValueFormatter xAxisFormatter = new StringAxisValueFormatter(xAxisValue);//设置自定义的x轴值格式化器
    XAxis xAxis = barChart.getXAxis();//获取x轴
    xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);//设置X轴标签显示位置
    xAxis.setDrawGridLines(false);//不绘制格网线
    xAxis.setGranularity(1f);//设置最小间隔,防止当放大时,出现重复标签。
    xAxis.setValueFormatter(xAxisFormatter);
    xAxis.setTextSize(xAxisTextSize);//设置标签字体大小
    xAxis.setLabelCount(xAxisValue.size());//设置标签显示的个数

    //y轴设置
    YAxis leftAxis = barChart.getAxisLeft();//获取左侧y轴
    leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);//设置y轴标签显示在外侧
    leftAxis.setAxisMinimum(0f);//设置Y轴最小值
    leftAxis.setDrawGridLines(false);
    leftAxis.setDrawLabels(false);//禁止绘制y轴标签
    leftAxis.setDrawAxisLine(false);//禁止绘制y轴

    barChart.getAxisRight().setEnabled(false);//禁用右侧y轴

    //图例设置
    Legend legend = barChart.getLegend();
    legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);//图例水平居中
    legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);//图例在图表上方
    legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);//图例的方向为水平
    legend.setDrawInside(false);//绘制在chart的外侧
    legend.setDirection(Legend.LegendDirection.LEFT_TO_RIGHT);//图例中的文字方向

    legend.setForm(Legend.LegendForm.SQUARE);//图例窗体的形状
    legend.setFormSize(0f);//图例窗体的大小
    legend.setTextSize(16f);//图例文字的大小
    //legend.setYOffset(-2f);

    //设置柱状图数据
    setBarChartData(barChart, yAxisValue, title, barColor);

    barChart.setExtraBottomOffset(10);//距视图窗口底部的偏移,类似与paddingbottom
    barChart.setExtraTopOffset(30);//距视图窗口顶部的偏移,类似与paddingtop
    barChart.setFitBars(true);//使两侧的柱图完全显示
    barChart.animateX(1500);//数据显示动画,从左往右依次显示
}

/**
* 设置柱图
*
* @param barChart
* @param yAxisValue
* @param title
* @param barColor
*/
private static void setBarChartData(BarChart barChart, List<Float> yAxisValue, String title, Integer barColor) {

    ArrayList<BarEntry> entries = new ArrayList<>();

    for (int i = 0, n = yAxisValue.size(); i < n; ++i) {
        entries.add(new BarEntry(i, yAxisValue.get(i)));
    }

    BarDataSet set1;

    if (barChart.getData() != null && barChart.getData().getDataSetCount() > 0) {
        set1 = (BarDataSet) barChart.getData().getDataSetByIndex(0);
        set1.setValues(entries);
        barChart.getData().notifyDataChanged();
        barChart.notifyDataSetChanged();
    } else {
        set1 = new BarDataSet(entries, title);
        if (barColor == null) {
            set1.setColor(ContextCompat.getColor(barChart.getContext(), R.color.bar));//设置set1的柱的颜色
        } else {
            set1.setColor(barColor);
        }

        ArrayList<IBarDataSet> dataSets = new ArrayList<>();
        dataSets.add(set1);

        BarData data = new BarData(dataSets);
        data.setValueTextSize(10f);
        data.setBarWidth(0.9f);
        data.setValueFormatter(new MyValueFormatter());

        barChart.setData(data);
    }
}

自定义MPChartMarkerView的代码如下:

package com.charlie.mpandroidcharttest.common;

import android.content.Context;

import com.charlie.mpandroidcharttest.R;
import com.charlie.mpandroidcharttest.util.StringUtils;
import com.github.mikephil.charting.components.MarkerView;
import com.github.mikephil.charting.data.CandleEntry;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.utils.MPPointF;

/**
* Created by JKWANG-PC on 2016/11/1.
*
* Since release v3.0.0, markers (popup views) in the chart are represented by the IMarker interface.
*/

public class MPChartMarkerView extends MarkerView {

    private ArrowTextView tvContent;

    /**
    * Constructor. Sets up the MarkerView with a custom layout resource.
    *
    * @param context
    * @param layoutResource the layout resource to use for the MarkerView
    */
    public MPChartMarkerView(Context context, int layoutResource) {
        super(context, layoutResource);

        tvContent = (ArrowTextView) findViewById(R.id.tvContent);
    }

    @Override
    public void refreshContent(Entry e, Highlight highlight) {
        if (e instanceof CandleEntry) {

            CandleEntry ce = (CandleEntry) e;

            tvContent.setText(StringUtils.double2String(ce.getHigh(), 2));
        } else {

            tvContent.setText(StringUtils.double2String(e.getY(), 2));
        }

        super.refreshContent(e, highlight);//必须加上该句话;This sentence must be added.
    }

    private MPPointF mOffset;

    @Override
    public MPPointF getOffset() {
        if(mOffset == null) {
            // center the marker horizontally and vertically
            mOffset = new MPPointF(-(getWidth() / 2), -getHeight());
        }

        return mOffset;
    }
}

自定义ArrowTextView的代码如下:

package com.charlie.mpandroidcharttest.common;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.TextView;

import com.charlie.mpandroidcharttest.R;

/**
* Created by JKWANG-PC on 2016/11/1.
* 带下箭头的文本框。
*/

public class ArrowTextView extends TextView {

    private float radius;
    private float arrowWidth;
    private float arrowHeight;
    private int color;

    public ArrowTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        ini(context, attrs);
    }

    private void ini(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ArrowTextView);
        radius = typedArray.getDimension(R.styleable.ArrowTextView_radius, 0);
        arrowWidth = typedArray.getDimension(R.styleable.ArrowTextView_arrowWidth, 0);
        arrowHeight = typedArray.getDimension(R.styleable.ArrowTextView_arrowHeight, 0);
        color = typedArray.getColor(R.styleable.ArrowTextView_bg, Color.RED);
    }

    public ArrowTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        ini(context, attrs);
    }

    public ArrowTextView(Context context) {
        super(context);
    }

    /**
    * @param arrowWidth 三角形箭头的宽度.......
    */
    public void setArrowWidth(float arrowWidth) {
        this.arrowWidth = arrowWidth;
        invalidate();

    }

    /**
    * @param arrowHeight 三角形箭头的高度......
    */
    public void setArrowHeight(float arrowHeight) {
        this.arrowHeight = arrowHeight;
        invalidate();
    }

    /**
    * @param radius 矩形四角圆角的半径..........
    */
    public void setRadius(float radius) {
        this.radius = radius;
        invalidate();

    }

    /**
    * @param color 箭头矩形的背景色.........
    */
    public void setBgColor(int color) {
        this.color = color;
        invalidate();

    }

    @Override
    protected void onDraw(Canvas canvas) {
        Paint paint = new Paint();
        paint.setColor(color == 0 ? Color.RED : color);
        paint.setAntiAlias(true);
        if (radius == 0) {
            radius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 5, getResources().getDisplayMetrics());
        }
        if (arrowWidth == 0) {
            arrowWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 20, getResources().getDisplayMetrics());
        }
        if (arrowHeight == 0) {
            arrowHeight = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 15, getResources().getDisplayMetrics());
        }
        //带圆角的矩形(下边减去三角形的高度...........)
        int width = getWidth();
        Float height = getHeight() - arrowHeight;
        canvas.drawRoundRect(new RectF(0, 0, getWidth(), height), radius, radius, paint);

        //画三角形
        Path path = new Path();
        path.setFillType(Path.FillType.EVEN_ODD);
        float xMiddle = width / 2;
        float xLeft = xMiddle - arrowWidth / 2;
        float xRight = xMiddle + arrowWidth / 2;
        float yBottom = height + arrowHeight;
        path.moveTo(xMiddle, yBottom);
        path.lineTo(xLeft, height-1);
        path.lineTo(xRight, height-1);
        path.lineTo(xMiddle, yBottom);
        path.close();
        canvas.drawPath(path, paint);
        // canvas.restore();
        // canvas.translate(left, 0);
        super.onDraw(canvas);
    }
}

attrs.xml内容如下:

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

    <declare-styleable name="ArrowTextView">
        <attr name="radius" format="dimension" />
        <attr name="arrowWidth" format="dimension" />
        <attr name="arrowHeight" format="dimension" />
        <attr name="bg" format="color" />
    </declare-styleable>
</resources>

colors.xml内容如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="bar">#6CB0DF</color>
    <color name="bar1">#B5C2CA</color>
    <color name="bar2">#F5E6BF</color>
    <color name="bar3">#81D8C8</color>

    <color name="description">#686868</color>

    <color name="line">#8CD276</color>
    <color name="linefill">#DEEFE4</color>
    <color name="line1">#E9C517</color>
    <color name="line1fill">#ECEAD0</color>
    <color name="line2">#9F8FBA</color>
    <color name="line2fill">#EBE4F8</color>
</resources>

custom_marker_view.xml布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <com.charlie.mpandroidcharttest.common.ArrowTextView
        android:id="@+id/tvContent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:paddingBottom="16px"
        android:paddingRight="5px"
        android:paddingLeft="5px"
        android:text=""
        android:textSize="36px"
        android:textColor="@color/description"
        android:maxLines="1"
        android:ellipsize="end"
        app:bg="@color/linefill"
        app:radius="5px"/>
</LinearLayout>

MyValueFormatter.java定义如下:

package com.charlie.mpandroidcharttest.common;

import com.charlie.mpandroidcharttest.util.StringUtils;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.formatter.IValueFormatter;
import com.github.mikephil.charting.utils.ViewPortHandler;

/**
* Created by JKWANG-PC on 2016/11/21.
*/

public class MyValueFormatter implements IValueFormatter {

    @Override
    public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
        return StringUtils.double2String(value, 2);
    }
}

StringAxisValueFormatter.java定义如下:

package com.charlie.mpandroidcharttest.common;

import com.github.mikephil.charting.components.AxisBase;
import com.github.mikephil.charting.formatter.IAxisValueFormatter;

import java.util.List;

/**
* Created by Charlie on 2016/9/23.
* 对字符串类型的坐标轴标记进行格式化
*/
public class StringAxisValueFormatter implements IAxisValueFormatter {

    //区域值
    private List<String> mStrs;

    /**
    * 对字符串类型的坐标轴标记进行格式化
    * @param strs
    */
    public StringAxisValueFormatter(List<String> strs){
        this.mStrs =strs;
    }

    @Override
    public String getFormattedValue(float v, AxisBase axisBase) {
        return mStrs.get((int)v);
    }
}

StringUtils.java定义如下:

package com.charlie.mpandroidcharttest.util;

import java.text.NumberFormat;

/**
* Created by Charlie on 2016/10/8.
* 通用字符串管理类
*/
public class StringUtils {

    /**
    * 将double转为数值,并最多保留num位小数。例如当num为2时,1.268为1.27,1.2仍为1.2;1仍为1,而非1.00;100.00则返回100。
    *
    * @param d
    * @param num 小数位数
    * @return
    */
    public static String double2String(double d, int num) {
        NumberFormat nf = NumberFormat.getNumberInstance();
        nf.setMaximumFractionDigits(num);//保留两位小数
        nf.setGroupingUsed(false);//去掉数值中的千位分隔符

        String temp = nf.format(d);
        if (temp.contains(".")) {
            String s1 = temp.split("\\.")[0];
            String s2 = temp.split("\\.")[1];
            for (int i = s2.length(); i > 0; --i) {
                if (!s2.substring(i - 1, i).equals("0")) {
                    return s1 + "." + s2.substring(0, i);
                }
            }
            return s1;
        }
        return temp;
    }

    /**
    * 将double转为数值,并最多保留num位小数。
    *
    * @param d
    * @param num 小数个数
    * @param defValue 默认值。当d为null时,返回该值。
    * @return
    */
    public static String double2String(Double d, int num, String defValue){
        if(d==null){
            return defValue;
        }

        return double2String(d,num);
    }
}

2、双柱图:
先看效果图,如下:

布局同1单柱图。设置好x轴和y轴要显示的数据,然后调用如下函数即可:

/**
* 设置双柱状图样式
*
* @param barChart
* @param xAxisValue
* @param yAxisValue1
* @param yAxisValue2
* @param bartilte1
* @param bartitle2
*/
public static void setTwoBarChart(BarChart barChart, List<Integer> xAxisValue, List<Float> yAxisValue1, List<Float> yAxisValue2, String bartilte1, String bartitle2) {
    barChart.getDescription().setEnabled(false);//设置描述
    barChart.setPinchZoom(true);//设置按比例放缩柱状图
    barChart.setExtraBottomOffset(10);
    barChart.setExtraTopOffset(30);

    MPChartMarkerView markerView = new MPChartMarkerView(barChart.getContext(), R.layout.custom_marker_view);
    barChart.setMarker(markerView);

    //x坐标轴设置
    XAxis xAxis = barChart.getXAxis();
    xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
    xAxis.setDrawGridLines(false);
    xAxis.setGranularity(1f);
    xAxis.setLabelCount(xAxisValue.size());
    xAxis.setCenterAxisLabels(true);//设置标签居中
    xAxis.setValueFormatter(new IAxisValueFormatter() {
        @Override
        public String getFormattedValue(float v, AxisBase axisBase) {
            return String.valueOf((int) v);
        }
    });

    //y轴设置
    YAxis leftAxis = barChart.getAxisLeft();
    leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
    leftAxis.setDrawGridLines(false);
    leftAxis.setDrawLabels(false);
    leftAxis.setDrawAxisLine(false);

    //设置坐标轴最大最小值
    Float yMin1 = Collections.min(yAxisValue1);
    Float yMin2 = Collections.min(yAxisValue2);
    Float yMax1 = Collections.max(yAxisValue1);
    Float yMax2 = Collections.max(yAxisValue2);
    Float yMin = Double.valueOf((yMin1 < yMin2 ? yMin1 : yMin2) * 0.1).floatValue();
    Float yMax = Double.valueOf((yMax1 > yMax2 ? yMax1 : yMax2) * 1.1).floatValue();
    leftAxis.setAxisMaximum(yMax);
    leftAxis.setAxisMinimum(yMin);

    barChart.getAxisRight().setEnabled(false);

    //图例设置
    Legend legend = barChart.getLegend();
    legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
    legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
    legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
    legend.setDrawInside(false);
    legend.setDirection(Legend.LegendDirection.LEFT_TO_RIGHT);
    legend.setForm(Legend.LegendForm.SQUARE);
    legend.setTextSize(12f);

    //设置柱状图数据
    setTwoBarChartData(barChart, xAxisValue, yAxisValue1, yAxisValue2, bartilte1, bartitle2);

    barChart.animateX(1500);//数据显示动画,从左往右依次显示
    barChart.invalidate();
}

/**
* 设置柱状图数据源
*/
private static void setTwoBarChartData(BarChart barChart, List<Integer> xAxisValue, List<Float> yAxisValue1, List<Float> yAxisValue2, String bartilte1, String bartitle2) {
    float groupSpace = 0.04f;
    float barSpace = 0.03f;
    float barWidth = 0.45f;
    // (0.45 + 0.03) * 2 + 0.04 = 1,即一个间隔为一组,包含两个柱图 -> interval per "group"

    ArrayList<BarEntry> entries1 = new ArrayList<>();
    ArrayList<BarEntry> entries2 = new ArrayList<>();

    for (int i = 0, n = yAxisValue1.size(); i < n; ++i) {
        entries1.add(new BarEntry(xAxisValue.get(i), yAxisValue1.get(i)));
        entries2.add(new BarEntry(xAxisValue.get(i), yAxisValue2.get(i)));
    }

    BarDataSet dataset1, dataset2;

    if (barChart.getData() != null && barChart.getData().getDataSetCount() > 0) {
        dataset1 = (BarDataSet) barChart.getData().getDataSetByIndex(0);
        dataset2 = (BarDataSet) barChart.getData().getDataSetByIndex(1);
        dataset1.setValues(entries1);
        dataset2.setValues(entries2);
        barChart.getData().notifyDataChanged();
        barChart.notifyDataSetChanged();
    } else {
        dataset1 = new BarDataSet(entries1, bartilte1);
        dataset2 = new BarDataSet(entries2, bartitle2);

        dataset1.setColor(Color.rgb(129, 216, 200));
        dataset2.setColor(Color.rgb(181, 194, 202));

        ArrayList<IBarDataSet> dataSets = new ArrayList<>();
        dataSets.add(dataset1);
        dataSets.add(dataset2);

        BarData data = new BarData(dataSets);
        data.setValueTextSize(10f);
        data.setBarWidth(0.9f);
        data.setValueFormatter(new IValueFormatter() {
            @Override
            public String getFormattedValue(float value, Entry entry, int i, ViewPortHandler viewPortHandler) {
                return StringUtils.double2String(value, 2);
            }
        });

        barChart.setData(data);
    }

    barChart.getBarData().setBarWidth(barWidth);
    barChart.getXAxis().setAxisMinimum(xAxisValue.get(0));
    // barData.getGroupWith(...) is a helper that calculates the width each group needs based on the provided parameters
    barChart.getXAxis().setAxisMaximum(barChart.getBarData().getGroupWidth(groupSpace, barSpace) * xAxisValue.size() + xAxisValue.get(0));
    barChart.groupBars(xAxisValue.get(0), groupSpace, barSpace);
}

3、三柱图:
先看效果图,如下:

布局同1单柱图。设置好x轴和y轴要显示的数据,然后调用如下函数即可:

/**
* 设置三柱状图样式
*
* @param barChart
* @param xAxisValue
* @param yAxisValue1
* @param yAxisValue2
* @param yAxisValue3
* @param bartilte1
* @param bartitle2
* @param bartitle3
*/
public static void setThreeBarChart(BarChart barChart, List<Integer> xAxisValue, List<Float> yAxisValue1, List<Float> yAxisValue2, List<Float> yAxisValue3, String bartilte1, String bartitle2, String bartitle3) {
    barChart.getDescription().setEnabled(false);//设置描述
    barChart.setPinchZoom(false);//设置不按比例放缩柱状图
    barChart.setExtraBottomOffset(10);
    barChart.setExtraTopOffset(30);

    MPChartMarkerView markerView = new MPChartMarkerView(barChart.getContext(), R.layout.custom_marker_view);
    barChart.setMarker(markerView);

    //x坐标轴设置
    XAxis xAxis = barChart.getXAxis();
    xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
    xAxis.setGranularity(1f);
    xAxis.setLabelCount(xAxisValue.size());
    xAxis.setCenterAxisLabels(true);
    xAxis.setDrawGridLines(false);
    xAxis.setValueFormatter(new IAxisValueFormatter() {
        @Override
        public String getFormattedValue(float v, AxisBase axisBase) {
            return String.valueOf((int) v);
        }
    });

    //y轴设置
    YAxis leftAxis = barChart.getAxisLeft();
    leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
    leftAxis.setDrawGridLines(false);
    leftAxis.setDrawLabels(false);
    leftAxis.setDrawAxisLine(false);

    Float yMin1 = Collections.min(yAxisValue1);
    Float yMin2 = Collections.min(yAxisValue2);
    Float yMin3 = Collections.min(yAxisValue3);
    Float yMax1 = Collections.max(yAxisValue1);
    Float yMax2 = Collections.max(yAxisValue2);
    Float yMax3 = Collections.max(yAxisValue3);
    Float yMinTemp = yMin1 < yMin2 ? yMin1 : yMin2;
    Float yMin = yMinTemp < yMin3 ? yMinTemp : yMin3;
    Float yMaxTemp = yMax1 > yMax2 ? yMax1 : yMax2;
    Float yMax = yMaxTemp > yMax3 ? yMaxTemp : yMax3;
    leftAxis.setAxisMinimum(Double.valueOf(yMin * 0.9).floatValue());
    leftAxis.setAxisMaximum(Double.valueOf(yMax * 1.1).floatValue());

    barChart.getAxisRight().setEnabled(false);

    //图例设置
    Legend legend = barChart.getLegend();
    legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
    legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
    legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
    legend.setDrawInside(false);
    legend.setDirection(Legend.LegendDirection.LEFT_TO_RIGHT);
    legend.setForm(Legend.LegendForm.SQUARE);
    legend.setTextSize(12f);

    //设置柱状图数据
    setThreeBarChartData(barChart, xAxisValue, yAxisValue1, yAxisValue2, yAxisValue3, bartilte1, bartitle2, bartitle3);

    barChart.animateX(1500);//数据显示动画,从左往右依次显示
    barChart.invalidate();
}

/**
* 设置三柱图数据源
*
* @param barChart
* @param xAxisValue
* @param yAxisValue1
* @param yAxisValue2
* @param yAxisValue3
* @param bartilte1
* @param bartitle2
* @param bartitle3
*/
private static void setThreeBarChartData(BarChart barChart, List<Integer> xAxisValue, List<Float> yAxisValue1, List<Float> yAxisValue2, List<Float> yAxisValue3, String bartilte1, String bartitle2, String bartitle3) {
    float groupSpace = 0.04f;
    float barSpace = 0.02f;
    float barWidth = 0.3f;
    // (0.3 + 0.02) * 3 + 0.04 = 1,即一个间隔为一组,包含三个柱图 -> interval per "group"

    ArrayList<BarEntry> first_entries = new ArrayList<>();
    ArrayList<BarEntry> second_entries = new ArrayList<>();
    ArrayList<BarEntry> third_entries = new ArrayList<>();

    for (int i = 0, n = xAxisValue.size(); i < n; ++i) {
        first_entries.add(new BarEntry(xAxisValue.get(i), yAxisValue1.get(i)));
        second_entries.add(new BarEntry(xAxisValue.get(i), yAxisValue2.get(i)));
        third_entries.add(new BarEntry(xAxisValue.get(i), yAxisValue3.get(i)));
    }

    BarDataSet first_set, second_set, third_set;

    if (barChart.getData() != null && barChart.getData().getDataSetCount() > 0) {
        first_set = (BarDataSet) barChart.getData().getDataSetByIndex(0);
        second_set = (BarDataSet) barChart.getData().getDataSetByIndex(1);
        third_set = (BarDataSet) barChart.getData().getDataSetByIndex(2);
        first_set.setValues(first_entries);
        second_set.setValues(second_entries);
        third_set.setValues(third_entries);
        barChart.getData().notifyDataChanged();
        barChart.notifyDataSetChanged();
    } else {
        first_set = new BarDataSet(first_entries, bartilte1);
        second_set = new BarDataSet(second_entries, bartitle2);
        third_set = new BarDataSet(third_entries, bartitle3);

        first_set.setColor(ContextCompat.getColor(barChart.getContext(), R.color.bar1));
        second_set.setColor(ContextCompat.getColor(barChart.getContext(), R.color.bar2));
        third_set.setColor(ContextCompat.getColor(barChart.getContext(), R.color.bar3));

        ArrayList<IBarDataSet> dataSets = new ArrayList<>();
        dataSets.add(first_set);
        dataSets.add(second_set);
        dataSets.add(third_set);

        BarData data = new BarData(dataSets);
        data.setValueTextSize(10f);
        data.setBarWidth(0.9f);
        data.setValueFormatter(new IValueFormatter() {
            @Override
            public String getFormattedValue(float value, Entry entry, int i, ViewPortHandler viewPortHandler) {
                return StringUtils.double2String(value, 2);
            }
        });

        barChart.setData(data);
    }

    barChart.getBarData().setBarWidth(barWidth);
    barChart.getXAxis().setAxisMinimum(xAxisValue.get(0));
    barChart.getXAxis().setAxisMaximum(barChart.getBarData().getGroupWidth(groupSpace, barSpace) * xAxisValue.size() + xAxisValue.get(0));
    barChart.groupBars(xAxisValue.get(0), groupSpace, barSpace);
}

4、正负柱图:
先看效果图,如下:

布局同1单柱图。设置好x轴和y轴要显示的数据,然后调用如下函数即可:

/**
* 设置正负值在0轴上下方的柱图
*
* @param barChart
* @param xAxisValue x轴的值。必须与yAxisValue的值个数相同
* @param yAxisValue y轴的值。必须与xAxisValue的值个数相同
* @param title
*/
public static void setPositiveNegativeBarChart(BarChart barChart, List<String> xAxisValue, List<Float> yAxisValue, String title) {
    barChart.setDrawBarShadow(false);
    barChart.setDrawValueAboveBar(true);
    barChart.getDescription().setEnabled(false);
    // scaling can now only be done on x- and y-axis separately
    barChart.setPinchZoom(false);
    barChart.setDrawGridBackground(false);
    barChart.setExtraBottomOffset(10);
    barChart.setExtraTopOffset(30);

    MPChartMarkerView markerView = new MPChartMarkerView(barChart.getContext(), R.layout.custom_marker_view);
    barChart.setMarker(markerView);

    XAxis xAxis = barChart.getXAxis();
    xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
    xAxis.setDrawGridLines(false);
    xAxis.setDrawAxisLine(false);
    xAxis.setTextColor(Color.DKGRAY);
    xAxis.setTextSize(13f);
    xAxis.setAxisMinimum(0f);
    xAxis.setAxisMaximum(xAxisValue.size());
    xAxis.setLabelCount(xAxisValue.size());
    xAxis.setCenterAxisLabels(true);
    xAxis.setGranularity(1f);

    YAxis left = barChart.getAxisLeft();
    left.setDrawLabels(false);
    left.setSpaceTop(25f);
    left.setSpaceBottom(25f);
    left.setDrawAxisLine(false);
    left.setDrawGridLines(false);
    left.setDrawZeroLine(true); // draw a zero line
    left.setZeroLineColor(Color.DKGRAY);
    left.setZeroLineWidth(1f);
    barChart.getAxisRight().setEnabled(false);

    Legend legend = barChart.getLegend();
    legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
    legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
    legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
    legend.setDrawInside(false);
    legend.setDirection(Legend.LegendDirection.LEFT_TO_RIGHT);

    legend.setForm(Legend.LegendForm.SQUARE);
    legend.setFormSize(0f);
    legend.setTextSize(16f);
    legend.setYOffset(-2f);

    // THIS IS THE ORIGINAL DATA YOU WANT TO PLOT
    final List<Data> data = new ArrayList<>();
    for (int i = 0, n = xAxisValue.size(); i < n; ++i) {
        data.add(new Data(0.5f + i, yAxisValue.get(i), xAxisValue.get(i)));
    }

    xAxis.setValueFormatter(new IAxisValueFormatter() {
        @Override
        public String getFormattedValue(float value, AxisBase axis) {
            return data.get(Math.min(Math.max((int) value, 0), data.size() - 1)).xAxisValue;
        }
    });

    setData(barChart, data, title);
}

private static void setData(BarChart barChart, List<Data> dataList, String title) {

    ArrayList<BarEntry> values = new ArrayList<BarEntry>();
    List<Integer> colors = new ArrayList<Integer>();

    int green = Color.rgb(195, 221, 155);
    int red = Color.rgb(237, 189, 189);

    for (int i = 0; i < dataList.size(); i++) {

        Data d = dataList.get(i);
        BarEntry entry = new BarEntry(d.xValue, d.yValue);
        values.add(entry);

        // specific colors
        if (d.yValue >= 0)
            colors.add(red);
        else
            colors.add(green);
    }

    BarDataSet set;

    if (barChart.getData() != null &&
            barChart.getData().getDataSetCount() > 0) {
        set = (BarDataSet) barChart.getData().getDataSetByIndex(0);
        set.setValues(values);
        barChart.getData().notifyDataChanged();
        barChart.notifyDataSetChanged();
    } else {
        set = new BarDataSet(values, title);
        set.setColors(colors);
        set.setValueTextColors(colors);

        BarData data = new BarData(set);
        data.setValueTextSize(13f);
        data.setValueFormatter(new PositiveNegativeBarChartValueFormatter());
        data.setBarWidth(0.8f);

        barChart.setData(data);
        barChart.invalidate();
    }
}

/**
* positive-negative data model representing data.
*/
private static class Data {

    public String xAxisValue;
    public float yValue;
    public float xValue;

    public Data(float xValue, float yValue, String xAxisValue) {
        this.xAxisValue = xAxisValue;
        this.yValue = yValue;
        this.xValue = xValue;
    }
}

private static class PositiveNegativeBarChartValueFormatter implements IValueFormatter {

    private DecimalFormat mFormattedStringCache;

    public PositiveNegativeBarChartValueFormatter() {
        mFormattedStringCache = new DecimalFormat("######.00");
    }

    @Override
    public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
        return mFormattedStringCache.format(value);
    }
}

(三)折线图(包括单折线图、多折线图):
1、单折线图:
先看效果图,如下:

布局如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_line_chart"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.charlie.mpandroidcharttest.chartactivity.LineChartActivity">
    <com.github.mikephil.charting.charts.LineChart
        android:id="@+id/lineChart"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</RelativeLayout>

设置好x轴和y轴要显示的数据,然后调用函数setLineChart ()即可:

public static final int[] LINE_COLORS = {
        Color.rgb(140, 210, 118), Color.rgb(159, 143, 186), Color.rgb(233, 197, 23)
};//绿色,紫色,黄色

public static final int[] LINE_FILL_COLORS = {
        Color.rgb(222, 239, 228), Color.rgb(246, 234, 208), Color.rgb(235, 228, 248)
};

/**
* 单线单y轴图。
*
* @param lineChart
* @param xAxisValue
* @param yAxisValue
* @param title
* @param showSetValues 是否在折线上显示数据集的值。true为显示,此时y轴上的数值不可见,否则相反。
*/
public static void setLineChart(LineChart lineChart, List<String> xAxisValue, List<Float> yAxisValue, String title, boolean showSetValues) {
    List<List<Float>> entriesList = new ArrayList<>();
    entriesList.add(yAxisValue);

    List<String> titles = new ArrayList<>();
    titles.add(title);

    setLinesChart(lineChart, xAxisValue, entriesList, titles, showSetValues,null);
}

/**
* 绘制线图,默认最多绘制三种颜色。所有线均依赖左侧y轴显示。
*
* @param lineChart
* @param xAxisValue x轴的轴
* @param yXAxisValues y轴的值
* @param titles 每一个数据系列的标题
* @param showSetValues 是否在折线上显示数据集的值。true为显示,此时y轴上的数值不可见,否则相反。
* @param lineColors 线的颜色数组。为null时取默认颜色,此时最多绘制三种颜色。
*/
public static void setLinesChart(LineChart lineChart, List<String> xAxisValue, List<List<Float>> yXAxisValues, List<String> titles, boolean showSetValues, int[] lineColors) {
    lineChart.getDescription().setEnabled(false);//设置描述
    lineChart.setPinchZoom(true);//设置按比例放缩柱状图

    MPChartMarkerView markerView = new MPChartMarkerView(lineChart.getContext(), R.layout.custom_marker_view);
    lineChart.setMarker(markerView);

    //x坐标轴设置
    IAxisValueFormatter xAxisFormatter = new StringAxisValueFormatter(xAxisValue);
    XAxis xAxis = lineChart.getXAxis();
    xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
    xAxis.setDrawGridLines(false);
    xAxis.setGranularity(1f);
    xAxis.setLabelCount(xAxisValue.size());
    /*xAxis.setAxisLineWidth(2f);*/
    xAxis.setValueFormatter(xAxisFormatter);

    //y轴设置
    YAxis leftAxis = lineChart.getAxisLeft();
    leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
    leftAxis.setDrawGridLines(false);
    if (showSetValues) {
        leftAxis.setDrawLabels(false);//折线上显示值,则不显示坐标轴上的值
    }
    //leftAxis.setDrawZeroLine(true);
    /*leftAxis.setAxisMinimum(0f);*/
    /*leftAxis.setAxisLineWidth(2f);*/

    lineChart.getAxisRight().setEnabled(false);

    //图例设置
    Legend legend = lineChart.getLegend();
    legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
    legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
    legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
    legend.setDrawInside(false);
    legend.setDirection(Legend.LegendDirection.LEFT_TO_RIGHT);
    legend.setForm(Legend.LegendForm.LINE);
    legend.setTextSize(12f);

    //设置折线图数据
    setLinesChartData(lineChart, yXAxisValues, titles, showSetValues,lineColors);

    lineChart.setExtraOffsets(10, 30, 20, 10);
    lineChart.animateX(1500);//数据显示动画,从左往右依次显示
}

private static void setLinesChartData(LineChart lineChart, List<List<Float>> yXAxisValues, List<String> titles, boolean showSetValues, int[] lineColors) {

    List<List<Entry>> entriesList = new ArrayList<>();
    for (int i = 0; i < yXAxisValues.size(); ++i) {
        ArrayList<Entry> entries = new ArrayList<>();
        for (int j = 0, n = yXAxisValues.get(i).size(); j < n; j++) {
            entries.add(new Entry(j, yXAxisValues.get(i).get(j)));
        }
        entriesList.add(entries);
    }

    if (lineChart.getData() != null && lineChart.getData().getDataSetCount() > 0) {

        for (int i = 0; i < lineChart.getData().getDataSetCount(); ++i) {
            LineDataSet set = (LineDataSet) lineChart.getData().getDataSetByIndex(i);
            set.setValues(entriesList.get(i));
            set.setLabel(titles.get(i));
        }

        lineChart.getData().notifyDataChanged();
        lineChart.notifyDataSetChanged();
    } else {
        ArrayList<ILineDataSet> dataSets = new ArrayList<>();

        for (int i = 0; i < entriesList.size(); ++i) {
            LineDataSet set = new LineDataSet(entriesList.get(i), titles.get(i));
            if(lineColors!=null){
                set.setColor(lineColors[i % entriesList.size()]);
                set.setCircleColor(lineColors[i % entriesList.size()]);
                set.setCircleColorHole(Color.WHITE);
            } else {
                set.setColor(LINE_COLORS[i % 3]);
                set.setCircleColor(LINE_COLORS[i % 3]);
                set.setCircleColorHole(Color.WHITE);
            }

            if (entriesList.size() == 1) {
                set.setDrawFilled(true);
                set.setFillColor(LINE_FILL_COLORS[i % 3]);
            }
            dataSets.add(set);
        }

        LineData data = new LineData(dataSets);
        if (showSetValues) {
            data.setValueTextSize(10f);
            data.setValueFormatter(new IValueFormatter() {
                @Override
                public String getFormattedValue(float value, Entry entry, int i, ViewPortHandler viewPortHandler) {
                    return StringUtils.double2String(value, 1);
                }
            });
        } else {
            data.setDrawValues(false);
        }

        lineChart.setData(data);
    }
}

2、多折线图:
以三条线为例,先看效果图,如下:

布局同单线图,设置好x轴和y轴要显示的数据,然后调用函数setLinesChart()即可。

(四)饼图:
先看效果图,如下:

布局如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_pie_chart"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.charlie.mpandroidcharttest.chartactivity.PieChartActivity">
    <com.github.mikephil.charting.charts.PieChart
        android:id="@+id/pieChart"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></com.github.mikephil.charting.charts.PieChart>
</RelativeLayout>

设置好x轴和y轴要显示的数据,然后调用如下函数即可:

public static final int[] PIE_COLORS = {
        Color.rgb(181, 194, 202), Color.rgb(129, 216, 200), Color.rgb(241, 214, 145),
        Color.rgb(108, 176, 223), Color.rgb(195, 221, 155), Color.rgb(251, 215, 191),
        Color.rgb(237, 189, 189), Color.rgb(172, 217, 243)
};

/**
* 设置饼图样式
*
* @param pieChart
* @param pieValues
* @param title
* @param showLegend 是否显示图例
*/
public static void setPieChart(PieChart pieChart, Map<String, Float> pieValues, String title, boolean showLegend) {
    pieChart.setUsePercentValues(true);//设置使用百分比
    pieChart.getDescription().setEnabled(false);//设置描述
    pieChart.setExtraOffsets(20, 15, 20, 15);
    pieChart.setCenterText(title);//设置环中的文字
    pieChart.setCenterTextSize(22f);//设置环中文字的大小
    pieChart.setDrawCenterText(true);//设置绘制环中文字
    pieChart.setRotationAngle(120f);//设置旋转角度

    //图例设置
    Legend legend = pieChart.getLegend();
    if (showLegend) {
        legend.setEnabled(true);
        legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
        legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
        legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
        legend.setDrawInside(false);
        legend.setDirection(Legend.LegendDirection.LEFT_TO_RIGHT);
    } else {
        legend.setEnabled(false);
    }

    //设置饼图数据
    setPieChartData(pieChart, pieValues);

    pieChart.animateX(1500, Easing.EasingOption.EaseInOutQuad);//数据显示动画
}

/**
* 设置饼图数据源
*/
private static void setPieChartData(PieChart pieChart, Map<String, Float> pieValues) {
    ArrayList<PieEntry> entries = new ArrayList<>();

    Set set = pieValues.entrySet();
    Iterator it = set.iterator();
    while (it.hasNext()) {
        Map.Entry entry = (Map.Entry) it.next();
        entries.add(new PieEntry(Float.valueOf(entry.getValue().toString()), entry.getKey().toString()));
    }

    PieDataSet dataSet = new PieDataSet(entries, "");
    dataSet.setSliceSpace(3f);//设置饼块之间的间隔
    dataSet.setSelectionShift(5f);//设置饼块选中时偏离饼图中心的距离

    dataSet.setColors(PIE_COLORS);//设置饼块的颜色
    dataSet.setValueLinePart1OffsetPercentage(80f);//数据连接线距图形片内部边界的距离,为百分数
    dataSet.setValueLinePart1Length(0.3f);
    dataSet.setValueLinePart2Length(0.4f);
    dataSet.setValueLineColor(Color.BLUE);//设置连接线的颜色
    dataSet.setYValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);

    PieData pieData = new PieData(dataSet);
    pieData.setValueFormatter(new PercentFormatter());
    pieData.setValueTextSize(11f);
    pieData.setValueTextColor(Color.DKGRAY);

    pieChart.setData(pieData);
    pieChart.highlightValues(null);
    pieChart.invalidate();
}

(五)组合图:
以线柱图为例,先看效果图,如下:

布局如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_combine_chart"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.charlie.mpandroidcharttest.chartactivity.CombineChartActivity">
    <com.github.mikephil.charting.charts.CombinedChart
        android:id="@+id/combineChart"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></com.github.mikephil.charting.charts.CombinedChart>
</RelativeLayout>

设置好x轴和y轴要显示的数据,然后调用如下函数即可:

/**
* 设置柱线组合图样式,柱图依赖左侧y轴,线图依赖右侧y轴
*/
public static void setCombineChart(CombinedChart combineChart, final List<String> xAxisValues, List<Float> lineValues, List<Float> barValues, String lineTitle, String barTitle) {
    combineChart.getDescription().setEnabled(false);//设置描述
    combineChart.setPinchZoom(true);//设置按比例放缩柱状图

    MPChartMarkerView markerView = new MPChartMarkerView(combineChart.getContext(), R.layout.custom_marker_view);
    combineChart.setMarker(markerView);

    //设置绘制顺序,让线在柱的上层
    combineChart.setDrawOrder(new CombinedChart.DrawOrder[]{
            CombinedChart.DrawOrder.BAR, CombinedChart.DrawOrder.LINE
    });

    //x坐标轴设置
    XAxis xAxis = combineChart.getXAxis();
    xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
    xAxis.setDrawGridLines(false);
    xAxis.setGranularity(1f);
    xAxis.setLabelCount(xAxisValues.size() + 2);
    xAxis.setValueFormatter(new IAxisValueFormatter() {
        @Override
        public String getFormattedValue(float v, AxisBase axisBase) {
            if (v < 0 || v > (xAxisValues.size() - 1))//使得两侧柱子完全显示
                return "";
            return xAxisValues.get((int) v);
        }
    });

    //y轴设置
    YAxis leftAxis = combineChart.getAxisLeft();
    leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
    leftAxis.setDrawGridLines(false);
    /*leftAxis.setAxisMinimum(0f);*/

    Float yMin = Double.valueOf(Collections.min(barValues) * 0.9).floatValue();
    Float yMax = Double.valueOf(Collections.max(barValues) * 1.1).floatValue();
    leftAxis.setAxisMaximum(yMax);
    leftAxis.setAxisMinimum(yMin);

    YAxis rightAxis = combineChart.getAxisRight();
    rightAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
    rightAxis.setDrawGridLines(false);

    //图例设置
    Legend legend = combineChart.getLegend();
    legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
    legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
    legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
    legend.setDrawInside(false);
    legend.setDirection(Legend.LegendDirection.LEFT_TO_RIGHT);
    legend.setForm(Legend.LegendForm.SQUARE);
    legend.setTextSize(12f);

    //设置组合图数据
    CombinedData data = new CombinedData();
    data.setData(generateLineData(lineValues, lineTitle));
    data.setData(generateBarData(barValues, barTitle));

    combineChart.setData(data);//设置组合图数据源

    //使得两侧柱子完全显示
    xAxis.setAxisMinimum(combineChart.getCombinedData().getXMin() - 1f);
    xAxis.setAxisMaximum(combineChart.getCombinedData().getXMax() + 1f);

    combineChart.setExtraTopOffset(30);
    combineChart.setExtraBottomOffset(10);
    combineChart.animateX(1500);//数据显示动画,从左往右依次显示
    combineChart.invalidate();
}

/**
* 生成线图数据
*/
private static LineData generateLineData(List<Float> lineValues, String lineTitle) {
    ArrayList<Entry> lineEntries = new ArrayList<>();

    for (int i = 0, n = lineValues.size(); i < n; ++i) {
        lineEntries.add(new Entry(i, lineValues.get(i)));
    }

    LineDataSet lineDataSet = new LineDataSet(lineEntries, lineTitle);
    lineDataSet.setColor(Color.rgb(233, 196, 21));
    lineDataSet.setLineWidth(2.5f);//设置线的宽度
    lineDataSet.setCircleColor(Color.rgb(244, 219, 100));//设置圆圈的颜色
    lineDataSet.setCircleColorHole(Color.WHITE);//设置圆圈内部洞的颜色
    //lineDataSet.setValueTextColor(Color.rgb(254,116,139));
    lineDataSet.setAxisDependency(YAxis.AxisDependency.RIGHT);//设置线数据依赖于右侧y轴
    lineDataSet.setDrawValues(false);//不绘制线的数据

    LineData lineData = new LineData(lineDataSet);
    lineData.setValueTextSize(10f);
    lineData.setValueFormatter(new IValueFormatter() {
        @Override
        public String getFormattedValue(float value, Entry entry, int i, ViewPortHandler viewPortHandler) {
            return StringUtils.double2String(value, 2);
        }
    });

    return lineData;
}

/**
* 生成柱图数据
*
* @param barValues
* @return
*/
private static BarData generateBarData(List<Float> barValues, String barTitle) {

    ArrayList<BarEntry> barEntries = new ArrayList<>();

    for (int i = 0, n = barValues.size(); i < n; ++i) {
        barEntries.add(new BarEntry(i, barValues.get(i)));
    }

    BarDataSet barDataSet = new BarDataSet(barEntries, barTitle);
    barDataSet.setColor(Color.rgb(159, 143, 186));
    barDataSet.setValueTextColor(Color.rgb(159, 143, 186));
    barDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);

    BarData barData = new BarData(barDataSet);
    barData.setValueTextSize(10f);
    barData.setBarWidth(0.9f);
    barData.setValueFormatter(new IValueFormatter() {
        @Override
        public String getFormattedValue(float value, Entry entry, int i, ViewPortHandler viewPortHandler) {
            return StringUtils.double2String(value, 2);
        }
    });

    return barData;
}

总结
1、MPAndroidChart各种Chart有一定的类似,只要把一个搞懂了其它的差不多。
2、使用chart时,一般都要经过以下几个步骤:(1)定义该chart;(2)设置chart的样式:包括chart的样式、坐标轴的样式和图例的样式等 ;(3)为chart添加数据:先定义相应的Entry列表,并添加到DataSet中,然后再添加到ChartData对象中,最后再赋值给该Chart并刷新即可。
3、项目已上传至https://github.com/WJKCharlie/MPAndroidChartTest。可前往下载代码自行查看。
  • 21
    点赞
  • 111
    收藏
    觉得还不错? 一键收藏
  • 31
    评论
数据来源:中经数据 主要指标110多个(全部都是纯粹的 市辖区 指标),大致是: GDP GDP增速 第一产业增加值占GDP比重 第二产业增加值占GDP比重 第三产业增加值占GDP比重 人均GDP 社会消费品零售总额 固定资产投资(不含农户) 新设外商投资企业数_外商直接投资 实际利用外资金额(美元) 一般公共预算收入 一般公共预算支出 一般公共预算支出_教育 一般公共预算支出_科学技术 金融机构人民币各项存款余额_个人储蓄存款 金融机构人民币各项存款余额 金融机构人民币各项贷款余额 规模以上工业企业单位数 规模以上工业企业单位数_内资企业 规模以上工业企业单位数_港澳台商投资企业 规模以上工业企业单位数_外商投资企业 规模以上工业总产值 规模以上工业总产值_内资企业 规模以上工业总产值_港澳台商投资企业 规模以上工业总产值_外商投资企业 规模以上工业企业流动资产合计 规模以上工业企业固定资产合计 规模以上工业企业利润总额 规模以上工业企业应交增值税 规模以上工业企业主营业务税金及附加 户籍人口数 年均户籍人口数 户籍人口自然增长率 第一产业就业人员占全部城镇单位就业人员比重 第二产业就业人员占全部城镇单位就业人员比重 第三产业就业人员占全部城镇单位就业人员比重 城镇非私营单位就业人员数 城镇非私营单位就业人员数_第一产业 城镇非私营单位就业人员数_第二产业 城镇非私营单位就业人员数_第三产业 城镇非私营单位就业人员数_农、林、牧、渔业 城镇非私营单位就业人员数_采矿业 城镇非私营单位就业人员数_制造业 城镇非私营单位就业人员数_电力、热力、燃气及水生产和供应业 城镇非私营单位就业人员数_建筑业 城镇非私营单位就业人员数_批发和零售业 城镇非私营单位就业人员数_交通运输、仓储和邮政业 城镇非私营单位就业人员数_住宿和餐饮业 城镇非私营单位就业人员数_信息传输、软件和信息技术服务业 城镇非私营单位就业人员数_金融业 城镇非私营单位就业人员数_房地产业 城镇非私营单位就业人员数_租赁和商务服务业 城镇非私营单位就业人员数_科学研究和技术服务业 城镇非私营单位就业人员数_水利、环境和公共设施管理业 城镇非私营单位就业人员数_居民服务、修理和其他服务业 城镇非私营单位就业人员数_教育 城镇非私营单位就业人员数_卫生和社会工作 城镇非私营单位就业人员数_文化、体育和娱乐业 城镇非私营单位就业人员数_公共管理、社会保障和社会组织 城镇非私营单位在岗职工平均人数 城镇就业人员数_私营企业和个体 城镇非私营单位在岗职工工资总额 城镇非私营单位在岗职工平均工资 城镇登记失业人员数 建成区面积 建设用地面积 建设用地面积_居住用地 液化石油气供气总量 液化石油气供气总量_居民家庭 人工煤气、天然气供气总量 人工煤气、天然气供气总量_居民家庭 液化石油气用气人口 人工煤气、天然气用气人口 城市公共汽电车运营车辆数 城市出租汽车运营车辆数 城市公共汽电车客运总量 道路面积 排水管道长度 建成区绿化覆盖面积 建成区绿化覆盖率 绿地面积 公园绿地面积 维护建设资金支出 土地面积 生活用水供水量 供水总量 全社会用电量 城乡居民生活用电量 工业生产用电量 房地产开发投资 房地产开发投资_住宅 限额以上批发和零售业法人单位数 限额以上批发和零售业商品销售总额 普通中学学校数 中等职业教育学校数 普通小学学校数 普通高等学校专任教师数 普通中学专任教师数 中等职业教育专任教师数 普通小学专任教师数 普通高等学校在校生数 普通中学在校生数 中等职业教育在校生数 普通小学在校生数 电视节目综合人口覆盖率 公共书馆总藏量_书 医疗卫生机构数_医院和卫生院 卫生人员数_执业(助理)医师 医疗卫生机构床位数_医院和卫生院 城镇职工基本养老保险参保人数 职工基本医疗保险参保人数 失业保险参保人数
MPAndroidChart是一款功能强大的Android,它支持多种类型的表,如折线图柱状图饼图、散点等,并且可以进行多种自定义设置和交互操作。以下是MPAndroidChart使用详解: 1. 导入 在项目的build.gradle文件中添加以下依赖: ``` dependencies { implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0' } ``` 2. 添加布局 在布局文件中添加一个空的布局,用于显示表: ``` <LinearLayout android:id="@+id/chart_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" /> ``` 3. 初始化表 在代码中获取布局并初始化表: ``` // 获取布局 LinearLayout chartLayout = findViewById(R.id.chart_layout); // 创建表 LineChart chart = new LineChart(this); // 添加到布局中 chartLayout.addView(chart); ``` 4. 设置数据 设置表的数据源: ``` List<Entry> entries = new ArrayList<>(); entries.add(new Entry(0, 2)); entries.add(new Entry(1, 4)); entries.add(new Entry(2, 6)); entries.add(new Entry(3, 8)); entries.add(new Entry(4, 10)); LineDataSet dataSet = new LineDataSet(entries, "Label"); LineData lineData = new LineData(dataSet); chart.setData(lineData); ``` 5. 自定义样式 可以对表进行多种自定义设置,如例、坐标轴、标签等: ``` // 设置例 Legend legend = chart.getLegend(); legend.setEnabled(false); // 设置X轴 XAxis xAxis = chart.getXAxis(); xAxis.setPosition(XAxis.XAxisPosition.BOTTOM); // 设置Y轴 YAxis yAxis = chart.getAxisLeft(); yAxis.setAxisMinimum(0f); yAxis.setAxisMaximum(12f); yAxis.setGranularity(1f); yAxis.setValueFormatter(new ValueFormatter() { @Override public String getFormattedValue(float value) { return String.valueOf((int) value); } }); // 设置标签 chart.getDescription().setEnabled(false); ``` 6. 添加交互操作 可以为表添加多种交互操作,如缩放、拖动等: ``` // 缩放 chart.setScaleEnabled(true); chart.setPinchZoom(true); // 拖动 chart.setDragEnabled(true); ``` 以上就是MPAndroidChart使用详解,希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 31
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值