Android MPAndroidChart绘制统计图

引入MPAndroidChart

1
2
3
4
5
allprojects {
repositories {
maven { url "https://jitpack.io" }
}
}

1
2
3
dependencies {
implementation 'com.github.PhilJay:MPAndroidChart:v3.0.3'
}

线型图

最简单的线型图

    在布局文件中添加<com.github.mikephil.charting.charts.LineChart/>标签

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<com.github.mikephil.charting.charts.LineChart
android:id="@+id/lineChart"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>

    获取View,设置数据,一个简单的线型图就成了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class LineActivity extends AppCompatActivity {
private LineChart lineChart;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_line);
init();//初始化
}

private void init() {
lineChart = findViewById(R.id.lineChart);//获取到线型图的View

lineChart.setData(setData());//设置显示数据
}

private LineData setData() {
// 创建一个Entry类型的集合,并添加数据
List<Entry> entries = new ArrayList<>();
for (int i = 0; i < 10; i++) {
// 添加Entry对象,传入纵轴的索引和纵轴的值
entries.add(new Entry(i,new Random().nextInt(100)));
}
// 实例化LineDataSet类,并将Entry集合中的数据和这组数据名(或者说这个图形名),通过这个类可以对线段进行设置
LineDataSet lineDataSet = new LineDataSet(entries,"线型图测试");
// 这个就是线型图所需的数据了
LineData lineData = new LineData(lineDataSet);
return lineData;
}
}

    但是现在不好看

设置属性

    主要用于演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
public class LineActivity extends AppCompatActivity {
private LineChart lineChart;
private final String[] strings = new String[]{"测试1","测试2","测试3","测试4","测试5","测试6","测试7","测试8","测试9","测试10"};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_line);
init();//初始化
}

private void init() {
lineChart = findViewById(R.id.lineChart);//获取到线型图的View

lineChart.setData(setData());//设置显示数据
lineChart.invalidate();//刷新数据
lineChart.setDescription(null);//设置右下角说明性文字不显示

// 图形边框的设置
lineChart.setDrawBorders(true);//设置四周的边框显示
lineChart.setBorderWidth(1);//设置边框宽度
lineChart.setBorderColor(Color.RED);//设置边框颜色为红色

// 设置触控的操作
lineChart.setTouchEnabled(true);//设置为false时将不响应任何触控
lineChart.setScaleEnabled(true);//设置允许缩放
lineChart.setPinchZoom(true);//设置允许x和y轴同时缩放(默认禁止x轴y轴同时进行缩放)
lineChart.setDragEnabled(true);//设置图形内部可拖动(类似QQ图片放大后向上划或者向下划)

// 设置x轴
XAxis xAxis = lineChart.getXAxis();//获取到x轴对象
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);//设置x轴的位置,图形上方或下方
xAxis.setDrawGridLines(false);//设置纵轴的背景表格线不显示
xAxis.setDrawAxisLine(true);//设置x轴的轴线显示
xAxis.setAxisLineWidth(1);//设置x轴轴线的宽度
xAxis.setAxisMinimum(0);//设置x轴的最小刻度
xAxis.setDrawLabels(true);//显示轴上的刻度
xAxis.setLabelCount(strings.length);//强制设置x轴刻度个数
xAxis.setGranularity(1);//缩放的时候有用,比如放大的时候,我不想把横轴再细分
xAxis.setEnabled(true);//显示x轴
// 设置每个纵轴的名字
xAxis.setValueFormatter(new ValueFormatter() {
@Override
public String getFormattedValue(float value) {
return strings[(int) (value % strings.length)];
}
});

// 设置右边y轴
YAxis yAxisRight = lineChart.getAxisRight();//获取到右边的y轴的对象
yAxisRight.setAxisMinimum(0);//设置y轴的最小刻度
yAxisRight.setDrawGridLines(false);//设置横轴的背景表格线不显示,左右两边需要同时设置
yAxisRight.setDrawAxisLine(true);//设置右边y轴的轴线显示
yAxisRight.setAxisLineWidth(1);//设置右边y轴轴线的宽度
yAxisRight.setEnabled(false);//设置右边的轴线不显示

// 设置左边y轴
YAxis yAxisLeft = lineChart.getAxisLeft();//获取到左边的y轴的对象
yAxisLeft.setAxisMinimum(0);//设置y轴的最小刻度
yAxisLeft.setDrawGridLines(false);//设置横轴的背景表格线不显示,左右两边需要同时设置
yAxisLeft.setDrawAxisLine(true);//设置左边y轴的轴线显示
yAxisLeft.setAxisLineWidth(1);//设置左边y轴轴线的宽度
yAxisLeft.setEnabled(true);//设置左边的轴线显示
}

private LineData setData() {
// 创建一个Entry类型的集合,并添加数据
List<Entry> entries = new ArrayList<>();
for (int i = 0; i < 10; i++) {
// 添加Entry对象,传入纵轴的索引和纵轴的值
entries.add(new Entry(i,new Random().nextInt(100)));
}
// 实例化LineDataSet类,并将Entry集合中的数据和这组数据名(或者说这个图形名),通过这个类可以对线段进行设置
LineDataSet lineDataSet = new LineDataSet(entries,"线型图测试");
lineDataSet.setCircleColor(Color.RED);//设置折折线点的颜色
lineDataSet.setColor(Color.BLUE);//设置折线的颜色
// lineDataSet.setAxisDependency(YAxis.AxisDependency.RIGHT);//如果使用了y轴右轴,必须设置这个
// 得到设置完毕的线型图数据
LineData lineData = new LineData(lineDataSet);
// lineData.notifyDataChanged();//刷新数据
// lineData.addDataSet();//添加一组线型图
return lineData;
}
}

    现在的效果

常规配置

    再来看一下常规配置的效果和代码(布局不变)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
public class LineActivity extends AppCompatActivity {
private LineChart lineChart;
private final String[] strings = new String[]{"测试1","测试2","测试3","测试4","测试5","测试6","测试7","测试8","测试9","测试10"};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_line);

lineChart = findViewById(R.id.lineChart);
lineChart.setTouchEnabled(false);
lineChart.setDescription(null);
lineChart.setData(new LineData());//添加一个空数据
addData("数据1",Color.BLACK);//向空数据中添加数据
addData("数据2",Color.BLUE);//向空数据中添加数据
setAxis();
}

private void setAxis() {
XAxis xAxis = lineChart.getXAxis();//x轴
xAxis.setDrawGridLines(false);//取消背景表格
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);//位于底部
xAxis.setDrawAxisLine(true);//显示轴线
xAxis.setAxisMinimum(0);//最小刻度
xAxis.setLabelCount(strings.length);//强制刻度的个数
xAxis.setGranularity(1);//设置缩放时纵轴之间的最小值差
xAxis.setAxisLineWidth(1);//设置轴线的宽度
xAxis.setValueFormatter(new ValueFormatter() {
@Override
public String getFormattedValue(float value) {
return strings[(int) (value % strings.length)];
}
});//x轴的每个数据的数据名
xAxis.setEnabled(true);//显示x轴

YAxis yAxisRight = lineChart.getAxisRight();//右边的y轴
yAxisRight.setAxisMinimum(0);//最小刻度
yAxisRight.setDrawGridLines(false);//不显示背景表格线
yAxisRight.setAxisLineWidth(1);//轴线宽度
yAxisRight.setDrawAxisLine(true);
yAxisRight.setEnabled(false);

YAxis yAxisLeft = lineChart.getAxisLeft();//左边的y轴
yAxisLeft.setDrawGridLines(false);//不显示背景表格线
yAxisLeft.setAxisMinimum(0);//最小刻度
yAxisLeft.setAxisLineWidth(1);//轴线宽度
yAxisLeft.setDrawAxisLine(true);
yAxisLeft.setEnabled(true);
}

private void addData(String dataName,int color) {
LineData lineData = lineChart.getData();
List<Entry> entries = new ArrayList<>();
for (int i = 0; i < strings.length; i++) {
entries.add(new Entry(i,new Random().nextInt(100)));//添加一个0-100的随机数给纵轴
}
LineDataSet lineDataSet = new LineDataSet(entries,dataName);
lineDataSet.setColor(color);//设置线段的颜色
lineDataSet.setCircleColor(Color.RED);//设置圆点的颜色
lineDataSet.setValueTextColor(Color.RED);
lineData.addDataSet(lineDataSet);//添加数据
lineChart.notifyDataSetChanged();//刷新数据
lineChart.invalidate();//刷新数据
}
}

柱状图

最简单的柱状图

    在布局文件中添加<com.github.mikephil.charting.charts.BarChart/>标签

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<com.github.mikephil.charting.charts.BarChart
android:id="@+id/barChart"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>

    获取View,设置数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class BarActivity extends AppCompatActivity {
private BarChart barChart;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bar);
barChart = findViewById(R.id.barChart);
barChart.setData(setData());
}

private BarData setData() {
List<BarEntry> barEntries = new ArrayList<>();
for (int i = 0; i < strings.length; i++) {
barEntries.add(new BarEntry(i,new Random().nextInt(100)));
}

BarDataSet barDataSet = new BarDataSet(barEntries,"测试数据");
BarData barData = new BarData(barDataSet);
return barData;
}
}

    基础效果

设置属性

    其实属性都差不多,只要英语学的好,记得很快

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
public class BarActivity extends AppCompatActivity {
private BarChart barChart;
private final String[] strings = new String[]{"测试1","测试2","测试3","测试4","测试5","测试6","测试7","测试8","测试9","测试10"};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bar);
barChart = findViewById(R.id.barChart);
barChart.setData(new BarData());
setData("数据1",Color.BLACK);
}

private void setData(String dataName,int color) {
BarData barData = barChart.getData();//获取到它的数据
barChart.setDescription(null);
barChart.setScaleEnabled(false);//禁止缩放
barChart.setDrawBarShadow(false);//不显示阴影

XAxis xAxis = barChart.getXAxis();//x轴
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);//设置x轴位于图形的底部
xAxis.setDrawGridLines(false);//隐藏纵轴的背景线
xAxis.setAxisLineWidth(1);//设置x轴轴线的宽度
xAxis.setAxisLineColor(Color.BLACK);//设置轴线的颜色
xAxis.setDrawAxisLine(true);//绘制轴线
xAxis.setAxisMinimum(0);//最小刻度
xAxis.setGranularity(1);//放大时坐标之间的差值
xAxis.setLabelCount(strings.length);//强制设置数轴个数
xAxis.setValueFormatter(new ValueFormatter() {
@Override
public String getFormattedValue(float value) {
return strings[(int) (value % strings.length)];
}
});
xAxis.setEnabled(true);

YAxis yAxisRight = barChart.getAxisRight();//右边的y轴
yAxisRight.setAxisLineWidth(1);
yAxisRight.setDrawGridLines(false);
yAxisRight.setAxisMinimum(0);
yAxisRight.setDrawAxisLine(true);
yAxisRight.setLabelCount(strings.length);
yAxisRight.setEnabled(false);

YAxis yAxisLeft = barChart.getAxisLeft();
yAxisLeft.setDrawAxisLine(true);
yAxisLeft.setAxisLineWidth(1);
yAxisLeft.setAxisMinimum(0);
yAxisLeft.setDrawGridLines(false);
yAxisLeft.setLabelCount(strings.length);
yAxisLeft.setEnabled(true);

List<BarEntry> barEntries = new ArrayList<>();
for (int i = 0; i < strings.length; i++) {
barEntries.add(new BarEntry(i,new Random().nextInt(100)));
}

BarDataSet barDataSet = new BarDataSet(barEntries,dataName);
barDataSet.setValueTextColor(Color.RED);
barDataSet.setColor(color);//柱子的颜色
barData.addDataSet(barDataSet);//添加一组数据
barChart.notifyDataSetChanged();//刷新数据
barChart.invalidate();
}
}

    分组显示柱子,设置多柱图
    设置多柱图一定要给X轴轴线设置最小值并根据x轴的个数比例设置最大值,否则柱子将会失去宽度比例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
public class BarActivity extends AppCompatActivity {
private BarChart barChart;
private final String[] strings = new String[]{"测试1","测试2","测试3","测试4","测试5","测试6","测试7","测试8","测试9","测试10"};
private float groupSpace = 0.04f,barSpace = 0.03f,barWidth = 0.45f;//组间隔、组内柱子间隔、柱子宽度

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bar);
barChart = findViewById(R.id.barChart);
barChart.setData(new BarData());
setData("数据1",Color.BLACK);
setData("数据2",Color.BLUE);

barChart.getBarData().setBarWidth(barWidth);//设置柱子的宽度
barChart.groupBars(0, groupSpace, barSpace);//设置柱子分组
}

private void setData(String dataName,int color) {
BarData barData = barChart.getData();//获取到它的数据
barChart.setDescription(null);
barChart.setScaleEnabled(false);//禁止缩放
barChart.setDrawBarShadow(false);//不显示阴影

XAxis xAxis = barChart.getXAxis();//x轴
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);//设置x轴位于图形的底部
xAxis.setDrawGridLines(false);//隐藏纵轴的背景线
xAxis.setAxisLineWidth(1);//设置x轴轴线的宽度
xAxis.setAxisLineColor(Color.BLACK);//设置轴线的颜色
xAxis.setDrawAxisLine(true);//绘制轴线
xAxis.setAxisMinimum(0);//最小刻度
xAxis.setAxisMaximum(10);//最大刻度
xAxis.setGranularity(1);//放大时坐标之间的差值
xAxis.setLabelCount(strings.length);//强制设置数轴个数
xAxis.setValueFormatter(new ValueFormatter() {
@Override
public String getFormattedValue(float value) {
if ((int)value == -1){
// 他妈的开了标签居中显示后,这个值时不时的会等于-1,关键是这个-1一点也用不到
value = 1;
}
return strings[(int) value % strings.length];
}
});
xAxis.setCenterAxisLabels(true);//标签居中显示
xAxis.setEnabled(true);

YAxis yAxisRight = barChart.getAxisRight();//右边的y轴
yAxisRight.setAxisLineWidth(1);//y轴的轴线宽度
yAxisRight.setDrawGridLines(false);//不显示横轴的背景线
yAxisRight.setAxisMinimum(0);//最小刻度
yAxisRight.setDrawAxisLine(true);//绘制轴线
yAxisRight.setEnabled(false);//是否显示

YAxis yAxisLeft = barChart.getAxisLeft();
yAxisLeft.setDrawAxisLine(true);
yAxisLeft.setAxisLineWidth(1);
yAxisLeft.setAxisMinimum(0);
yAxisLeft.setDrawGridLines(false);
yAxisLeft.setEnabled(true);

List<BarEntry> barEntries = new ArrayList<>();
for (int i = 0; i < strings.length; i++) {
barEntries.add(new BarEntry(i,new Random().nextInt(100)));
}

BarDataSet barDataSet = new BarDataSet(barEntries,dataName);
barDataSet.setValueTextColor(Color.RED);//值的颜色
barDataSet.setColor(color);//柱子的颜色
barData.addDataSet(barDataSet);//添加一组数据
barChart.notifyDataSetChanged();//刷新数据
barChart.invalidate();//刷新数据
}
}

    效果

饼状图

基础饼状图

    在布局文件中添加<com.github.mikephil.charting.charts.PieChart/>标签

    随随便便加个数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class PieActivity extends AppCompatActivity {
private PieChart pieChart;
private final String[] strings = new String[]{"测试1","测试2","测试3","测试4","测试5","测试6","测试7","测试8","测试9","测试10"};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pie);
pieChart = findViewById(R.id.pieChart);
pieChart.setData(setData());
pieChart.notifyDataSetChanged();
pieChart.invalidate();
}

private PieData setData() {
List<PieEntry> pieEntries = new ArrayList<>();
for (int i = 0; i < strings.length; i++) {
pieEntries.add(new PieEntry(i,new Random().nextInt(100)));
}
PieDataSet pieDataSet = new PieDataSet(pieEntries,"测试");
PieData pieData = new PieData(pieDataSet);
return pieData;
}
}

    效果不好看

常规属性配置

    没研究的配置还有很多,参考https://blog.csdn.net/shineflowers/article/details/44701645

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
public class PieActivity extends AppCompatActivity {
private PieChart pieChart;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pie);
pieChart = findViewById(R.id.pieChart);
pieChart.setDescription(null);//设置右下角说明性文字不显示

pieChart.setHoleRadius(0);//设置中间空心的圆半径为0
pieChart.setTransparentCircleRadius(0);//设置中间半透明的圆半径为0
pieChart.setTransparentCircleAlpha(0);//或者可以把它改成透明

pieChart.setUsePercentValues(true);//设置使用百分比(不知道为什么不显示百分号,妈的)
pieChart.setRotationEnabled(true);//设置是否可以旋转

pieChart.setExtraOffsets(20, 15, 20, 15);//左上右下四个方向的边距
pieChart.setCenterText("年度支出");//设置圆环中央的文字,前提是setHoleRadius不为0
pieChart.setRotationAngle(120);//设置旋转角度
pieChart.animateX(1000, Easing.EaseInOutQuad);//数据显示动画
addData();//添加数据显示
pieChart.invalidate();//刷新数据
}

private void addData() {
// 添加数据
List<PieEntry> pieEntries = new ArrayList<>();
// 每添加一个PieEntry就相当于添加了一个扇区
pieEntries.add(new PieEntry(new Random().nextInt(100),"第一季度"));
pieEntries.add(new PieEntry(new Random().nextInt(100),"第二季度"));
pieEntries.add(new PieEntry(new Random().nextInt(100),"第三季度"));
pieEntries.add(new PieEntry(new Random().nextInt(100),"第四季度"));

PieDataSet pieDataSet = new PieDataSet(pieEntries,"年支出比");
pieDataSet.setValueTextColor(Color.BLACK);//设置字体颜色
pieDataSet.setValueTextSize(15);//设置字体大小
pieDataSet.setSliceSpace(1);//设置扇区间的间隔
pieDataSet.setSelectionShift(5);//设置扇区被选中时向外偏移的距离

// 数据连接线
pieDataSet.setValueLinePart1OffsetPercentage(50f);//数据连接线起始点距扇形中心的距离,为百分数
pieDataSet.setValueLinePart1Length(0.5f);//第1端连接线长度
pieDataSet.setValueLinePart2Length(1.3f);//第2段连接线长度
pieDataSet.setValueLineColor(Color.BLACK);//设置数据连接线颜色
pieDataSet.setYValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);//连接线所在的位置

setColor(pieDataSet);//设置扇区的颜色
// 设置数据
PieData pieData = new PieData(pieDataSet);
pieData.setValueFormatter(new PercentFormatter(pieChart));//给百分比显示添加百分号
pieChart.setData(pieData);
}

private void setColor(PieDataSet pieDataSet) {
// 设置每个扇区不同颜色,因为共4条数据,所以这里只设置了4种颜色
List<Integer> colors = new ArrayList<>();
colors.add(Color.BLUE);
colors.add(Color.DKGRAY);
colors.add(Color.GRAY);
colors.add(Color.RED);
pieDataSet.setColors(colors);//设置扇区颜色
}
}

    效果展示

雷达图

雷达图以后再说,妈的累死了

参考地址: https://blog.csdn.net/wjk343977868/article/details/53316981