开源图表框架MPAndroidChart - LineChart的简单使用

效果图及属性标识

关于MPAndroidChart

GitHub地址:MPAndroidChart

以下是官方描述:

A powerful ? Android chart view / graph view library, supporting line- bar- pie- radar- bubble- and candlestick charts as well as scaling, panning and animations.

译:一个强大的?Android图表视图/图形视图库,支持线-条-饼-雷达-气泡-烛台图表以及缩放,平移和动画。

添加依赖

在项目的 build.gradle 文件中添加所需工件的依赖项:

1
2
3
4
5

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

在应用或模块的 build.gradle 文件中添加所需工件的依赖项:

1
2
3
4
5

dependencies {
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
}

LineChart 控件的使用

在xml中使用

activity_line_chart.xml

1
2
3
4
5
6
7
8
9
10
11

<?xml version="1.0" encoding="utf-8"?>
<com.github.mikephil.charting.charts.LineChart xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/lineChart"
android:layout_width="match_parent"
android:layout_height="match_parent">

</com.github.mikephil.charting.charts.LineChart>

在Activity中使用

LineChartActivity.kt

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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
import android.graphics.Color
import com.example.firstlinecode.R
import com.example.firstlinecode.base.BaseActivity
import com.example.firstlinecode.utils.getMainHandler
import com.github.mikephil.charting.components.AxisBase
import com.github.mikephil.charting.components.Legend
import com.github.mikephil.charting.components.Legend.*
import com.github.mikephil.charting.components.XAxis
import com.github.mikephil.charting.data.Entry
import com.github.mikephil.charting.data.LineData
import com.github.mikephil.charting.data.LineDataSet
import com.github.mikephil.charting.formatter.ValueFormatter
import kotlinx.android.synthetic.main.activity_line_chart.*
import java.util.*
import kotlin.concurrent.timerTask

class LineChartActivity : BaseActivity() {

private val timer: Timer = Timer()

override fun getLayoutResId() = R.layout.activity_line_chart

override fun initView() {
initLineChart()
}

/**
* 初始化 LineChart 的属性
*/
private fun initLineChart() {
lineChart.run {
// 将此设置为true,可以通过双击图表来放大,默认值:启用
isDoubleTapToZoomEnabled = false
// 设置是否启用X轴的缩放,默认值:启用
isScaleXEnabled = false
// 设置是否启用Y轴的缩放,默认值:启用
isScaleYEnabled = false
}
// 图例,即默认显示在图表左下角的那个东西
lineChart.legend.run {
// 设置图例的水平对齐方式,默认为:LegendHorizontalAlignment.LEFT
horizontalAlignment = LegendHorizontalAlignment.RIGHT
// 设置图例的垂直对齐方式,默认为:LegendVerticalAlignment.BOTTOM
verticalAlignment = LegendVerticalAlignment.TOP
// 设置在图表内部绘制,默认为 false
setDrawInside(true)
// 图例中单个的形状,默认是正方形,是个枚举且有六个取值:NONE、EMPTY、DEFAULT、SQUARE、CIRCLE、LINE
form = Legend.LegendForm.CIRCLE
// 默认是横向排列的,和 LinearLayout 类似
orientation = LegendOrientation.VERTICAL
}
// 描述,即右下角所展示的文字
val description = lineChart.description
// 如果不想显示描述,可以通过禁用或者将描述的文字设置为空字符串(默认启用,且默认值为:"Description Label")
description.text = "水电费统计表"
// description.isEnabled = false
// description.text = ""
// 描述的默认对齐方式为右边,是个枚举类且有三个取值:LEFT、 CENTER、 RIGHT
// description.textAlign = Paint.Align.RIGHT
// 通过查看源码,xAxis、axisLeft、axisRight 属性在创建 LineChart 的时候就被初始化了,所以是不为空的
lineChart.xAxis.run {
// 设置绘制网格线(默认为:true)
setDrawGridLines(false)
// 设置x标签的位置,是个枚举类型且有五个取值:TOP、 BOTTOM、 BOTH_SIDED、 TOP_INSIDE、 BOTTOM_INSIDE
// 一般情况下都是设置为底部
position = XAxis.XAxisPosition.BOTTOM
// X轴的最小值
axisMinimum = 0f
// X轴的最大值
axisMaximum = 10f
// 标签的个数
labelCount = 10
// 设置用于格式化轴标签的格式化程序,如果没有设置的话会有默认的格式化程序,但这不是我们想要的
valueFormatter = object : ValueFormatter() {
/**
* 可以通过重写此方法格式化X轴的标签,给哪个轴设置就格式化哪个轴。
*/
override fun getAxisLabel(value: Float, axis: AxisBase): String {
val realValue = value.toInt()
// 如果不在我们的数值范围,那就设置为空字符串,这样在这个位置上就不会显示任何文字
// Kotlin 允许 if 语句有返回值,返回值就是 if 语句每个条件中最后一行代码的返回值
// 因为我们数据的下标是从 0 开始的,所以需要 +1
return if (realValue <= -1 || realValue >= 10) "" else (realValue + 1).toString()
}
}
}
// 左边的 Y 轴:没有网格线,最小值是 0 ,最大值是 100
lineChart.axisLeft.run {
// 将此设置为true以启用为该轴绘制网格线,默认值:启用
setDrawGridLines(false)
axisMinimum = 0f
axisMaximum = 100f
}
// 我们一般使用的折线图都是没有右边的 Y 轴的,所以我们禁用掉,否则看起来不太好看
lineChart.axisRight.isEnabled = false
}

override fun initData() {
// 这里我们是为了让数据动起来,一般情况下都是静态的图表
timer.schedule(timerTask {
// 如果当前 Activity 已经销毁了就不用再创建数据和更新UI了
if (isDestroyed.not()) {
// 切换回主线程执行更新UI的操作
getMainHandler().post {
createLineChartData()
}
}
}, 0, 1000)
}

/**
* 创建并设置 LineChart 的数据,否则是默认样式
*/
private fun createLineChartData() {
// Entry 描述了一个坐标的概念,具有 x和y的属性。相当于数学坐标系中的(x, y)
// 而用 List 存储的 Entry 则描述了一条线,因为线是由无数个点连成的(在这里是关键点的坐标,
// 坐标与坐标之间绘制时会自动帮我们连起来)
// 我们定义了两个存储 Entry 的 List ,所以最终绘制出来就会是一个有两条折线的图表
val lineEntryListOne = mutableListOf<Entry>()
val lineEntryListTwo = mutableListOf<Entry>()
// 使用 repeat 函数可以进行多次的循环,相当于Java中的 for (int i=0; i<10; i++)
repeat(10) {
// 此处的 it 是在此上下文的别名,相当于我们使用Java中 for 循环的临时变量 i
// Y 轴生成 [70, 100) 区间的随机数
lineEntryListOne.add(Entry(it.toFloat(), (60 until 85).random().toFloat()))
lineEntryListTwo.add(Entry(it.toFloat(), (60 until 85).random().toFloat()))
}
// 折线图数据集的基础数据集,需要将这两条线的数据使用 LineDataSet 对象包装起来
val lineDataSetOne = LineDataSet(lineEntryListOne, "水费")
val lineDataSetTwo = LineDataSet(lineEntryListTwo, "电费")
lineDataSetOne.run {
// 这条折线的颜色
color = Color.RED
// 关键坐标点的圆心颜色
setCircleColor(Color.RED)
// 默认半径为 4f ,最小半径为 1f ,如果小于 1f 会抛出异常
circleRadius = 2.toFloat()
// 不绘制圆外围的圆环
setDrawCircleHole(false)
// 设置LineDataSet的绘图模式为贝塞尔模式,默认为 LineDataSet.Mode.LINEAR ,
// 是个枚举类型且有四个取值:LINEAR、STEPPED、CUBIC_BEZIER、HORIZONTAL_BEZIER
mode = LineDataSet.Mode.HORIZONTAL_BEZIER
}
lineDataSetTwo.run {
color = Color.YELLOW
setCircleColor(Color.YELLOW)
circleRadius = 2.toFloat()
setDrawCircleHole(false)
mode = LineDataSet.Mode.HORIZONTAL_BEZIER
}
// 数据对象,该对象封装与线图关联的所有数据,就是整个图表的数据
val lineData = LineData(lineDataSetOne, lineDataSetTwo)
// 为图表设置一个新的数据对象。数据对象包含所有的值 和显示所需的信息
lineChart.data = lineData
// 设置不绘制所有坐标上的值,这个并不是唯一的解决方法
lineData.setDrawValues(false)
// 进行界面的重绘,以展示新的数据
lineChart.invalidate()
}

override fun onDestroy() {
super.onDestroy()
timer.cancel()
}
}

总结

LineChart的使用并不复杂,只需要理解清楚Entry、List、LineDataSet、LineData之间的关系即可。

请同学们点赞、评论、打赏+关注啦~


开源图表框架MPAndroidChart - LineChart的简单使用
https://blog.funkt.cn/2021/01/22/1352426209933348864/
作者
anjiemo
发布于
2021年1月22日
许可协议
未经作者授权,禁止转载