Android LineChart 折线图Demo

2023-04-27,,

1 首先在 build.gradle 里导入包

implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'

2.新建 启动Activity

LineChartActivity 如下

 1 **
2 * @Author: Bytezero_zhengLei
3 * @Time: 2023/3/24 10:12
4 * @Project_Name: LineChartActivity.java
5 * @Email: 420498246@qq.com
6 * @Description:
7 * @TODO: 折线图
8 */
9
10 public class LineChartActivity extends AppCompatActivity {
11
12 private LineChart lineChart;
13 List<IncomeBean> list = new ArrayList<>();
14
15 @Override
16 protected void onCreate(Bundle savedInstanceState) {
17 super.onCreate(savedInstanceState);
18 setContentView(R.layout.activity_line_chart);
19
20 lineChart = (LineChart) findViewById(R.id.linechart);
21
22 lineChart = MPAndroidUtil.initChart(this, lineChart);
23
24
25
26
27 for (int i =0; i <10; i ++){
28 IncomeBean incomeBean = new IncomeBean(36.5,"2020-01-01 00:00:00");
29 list.add(incomeBean);
30
31 }
32
33 // 开始画折线图
34 setLineChart(list, "BMI" + "kg/²", getResources().getColor(R.color.bule_title));
35 }
36
37
38 //设置折线
39
40
41 public void setLineChart(List<IncomeBean> mLineChart, String string, int color) {
42 lineChart = MPAndroidUtil.initChart(this, lineChart);
43 lineChart.setData(MPAndroidUtil.showLineChart(mLineChart, string, color));
44 //设置一页最大显示个数为6,超出部分就滑动
45 float ratio = (float) mLineChart.size() / (float) 6;
46 //显示的时候是按照多大的比率缩放显示,1f表示不放大缩小
47 // lineChart.zoom(ratio, 1f, 0, 0);
48 // 设置填充图
49 Drawable drawable = getResources().getDrawable(R.drawable.fade_blue);
50 MPAndroidUtil.setChartFillDrawable(drawable, lineChart);
51 // 设置点击的弹窗
52 MPAndroidUtil.setMarkerView1(lineChart);
53
54
55 /* lineChart.getLineData().addDataSet(MPAndroidUtil.addLine(list1, "地位条", getResources().getColor(R.color.text_orange)));
56 lineChart.invalidate();*/
57
58 }
59 }

3.新建数据 IncomeBean

 1 /**
2 * @Author: Bytezero_zhengLei
3 * @Time: 2023/3/24 10:24
4 * @Project_Name: IncomeBean.java
5 * @Email: 420498246@qq.com
6 * @Description:
7 * @TODO:
8 */
9
10 public class IncomeBean implements Serializable {
11 public String tradeDate;// 时间
12 public double value;// 数值
13
14 public IncomeBean(double mValue, String mTradeDate) {
15 tradeDate = mTradeDate;
16 value = mValue;
17 }
18
19 @Override
20 public String toString() {
21 return "IncomeBean{" +
22 "tradeDate='" + tradeDate + '\'' +
23 ", value=" + value +
24 '}';
25 }
26 }

4.制定折线图的属性  MPAndroidUtil

  1 /**
2 * @Author: Bytezero_zhengLei
3 * @Time: 2023/3/24 10:20
4 * @Project_Name: MPAndroidUtil.java
5 * @Email: 420498246@qq.com
6 * @Description:
7 * @TODO:
8 */
9
10 public class MPAndroidUtil {
11 private static final String TAG = "MPAndroidUtil";
12 private static XAxis xAxis = null; //X轴
13 private static YAxis leftYAxis; //左侧Y轴
14 private static YAxis rightYaxis; //右侧Y轴
15 private static Legend legend; //图例
16
17
18 /**
19 * 初始化图表 折线图
20 */
21 public static LineChart initChart(Context context, LineChart lineChart) {
22
23 /***图表设置***/
24 //是否展示网格线
25 lineChart.setDrawGridBackground(false);
26 //是否显示边界
27 lineChart.setDrawBorders(false);
28 //是否可以拖动
29 lineChart.setDragEnabled(false);
30 //是否有触摸事件
31 lineChart.setTouchEnabled(true);
32 // 关闭双击放大功能
33 lineChart.setDoubleTapToZoomEnabled(false);
34 //设置XY轴动画效果
35 lineChart.animateY(2500);
36 lineChart.animateX(1500);
37
38 lineChart.setBackgroundColor(context.getResources().getColor(R.color.white));
39
40
41 /***XY轴的设置***/
42 xAxis = null;
43 xAxis = lineChart.getXAxis();
44 leftYAxis = lineChart.getAxisLeft();
45 rightYaxis = lineChart.getAxisRight();
46 //X轴设置显示位置在底部
47 xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
48 xAxis.setAxisMinimum(0f);
49 xAxis.setGranularity(1f);
50 //保证Y轴从0开始,不然会上移一点
51 leftYAxis.setAxisMinimum(0f);
52 rightYaxis.setAxisMinimum(0f);
53
54 // 但还是显示了网格线,而且不是我们想要的 虚线 。其实那是 X Y轴自己的网格线,禁掉即可
55 xAxis.setDrawGridLines(false);
56 rightYaxis.setDrawGridLines(false);
57 leftYAxis.setDrawGridLines(true);
58 //设置X Y轴网格线为虚线(实体线长度、间隔距离、偏移量:通常使用 0)
59 leftYAxis.enableGridDashedLine(10f, 10f, 0f);
60 // 目标效果图没有右侧Y轴,所以去掉右侧Y轴
61 rightYaxis.setEnabled(false);
62
63 /***折线图例 标签 设置***/
64 legend = lineChart.getLegend();
65 //legend.setEnabled(false);
66 //设置显示类型,LINE CIRCLE SQUARE EMPTY 等等 多种方式,查看LegendForm 即可
67 legend.setForm(Legend.LegendForm.LINE);
68 legend.setTextSize(12f);
69 //显示位置 左下方
70 legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
71 legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
72 legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
73 //是否绘制在图表里面
74 legend.setDrawInside(false);
75 // legend.setExtra(mLegendEntries);
76
77 // lineChart.setNoDataText(context.getResources().getString(R.string.No_data));
78 lineChart.setNoDataText(" ");
79 // 设置右下角的提示
80 Description description = new Description();
81 // description.setText("需要展示的内容");
82 description.setEnabled(false);
83 lineChart.setDescription(description);
84
85 lineChart.setExtraBottomOffset(2 * 8f);
86
87 lineChart.setXAxisRenderer(new CustomXAxisRenderer(lineChart.getViewPortHandler(), lineChart.getXAxis(), lineChart.getTransformer(YAxis.AxisDependency.LEFT)));
88 return lineChart;
89 }
90
91
92 /**
93 * 曲线初始化设置 一个LineDataSet 代表一条曲线
94 *
95 * @param lineDataSet 线条
96 * @param color 线条颜色
97 * @param mode
98 */
99 public static LineDataSet initLineDataSet(LineDataSet lineDataSet, int color, LineDataSet.Mode mode) {
100 lineDataSet.setColor(color);
101 lineDataSet.setCircleColor(color);
102 lineDataSet.setLineWidth(1f);
103 lineDataSet.setCircleRadius(2f);
104 //设置曲线值的圆点是实心还是空心
105 lineDataSet.setDrawCircleHole(true);
106 lineDataSet.setValueTextSize(10f);
107 //设置折线图填充
108 lineDataSet.setDrawFilled(true);
109 lineDataSet.setFormLineWidth(1f);
110 lineDataSet.setFormSize(15.f);
111 if (mode == null) {
112 //设置曲线展示为圆滑曲线(如果不设置则默认折线)
113 lineDataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
114 } else {
115 lineDataSet.setMode(mode);
116 }
117 // 不显示值
118 lineDataSet.setDrawValues(false);
119 return lineDataSet;
120
121 }
122
123 public static LineData showLineChart(final List<IncomeBean> dataList, String name, int color) {
124 List<Entry> entries = new ArrayList<>();
125 for (int i = 0; i < dataList.size(); i++) {
126 IncomeBean data = dataList.get(i);
127 /**
128 * 在此可查看 Entry构造方法,可发现 可传入数值 Entry(float x, float y)
129 * 也可传入Drawable, Entry(float x, float y, Drawable icon) 可在XY轴交点 设置Drawable图像展示
130 */
131 Entry entry = new Entry(i, (float) data.value);
132 entries.add(entry);
133 }
134 xAxis.setValueFormatter(new IndexAxisValueFormatter() {
135 @Override
136 public String getFormattedValue(float value) {
137 String tradeDate;
138 try {
139 tradeDate = dataList.get((int) value % dataList.size()).tradeDate;
140 } catch (Exception mE) {
141 tradeDate = "2020-01-01 00:00:00";
142 }
143
144 return StrToStr("yyyy-MM-dd HH:mm:ss", "MM-dd HH:mm", tradeDate);
145 }
146 });
147
148
149 xAxis.setLabelCount(6, false);
150
151 leftYAxis.setLabelCount(8);
152 // 每一个LineDataSet代表一条线
153 LineDataSet lineDataSet = new LineDataSet(entries, name);
154 lineDataSet = initLineDataSet(lineDataSet, color, LineDataSet.Mode.CUBIC_BEZIER);
155 LineData lineData = new LineData(lineDataSet);
156 return lineData;
157
158 }
159
160 public static void setMarkerView1(LineChart lineChart) {
161 // LineChartMarkView1 mv = new LineChartMarkView1(MApplication.getInstance(), xAxis.getValueFormatter());
162 LineChartMarkView1 mv = new LineChartMarkView1(lineChart.getContext(), xAxis.getValueFormatter());
163 mv.setChartView(lineChart);
164 lineChart.setMarker(mv);
165 lineChart.invalidate();
166 }
167
168
169 /*
170 * 设置线条填充背景颜色
171 *
172 * @param drawable
173 */
174 public static LineChart setChartFillDrawable(Drawable drawable, LineChart mLineChart) {
175 if (mLineChart.getData() != null && mLineChart.getData().getDataSetCount() > 0) {
176 LineDataSet lineDataSet = (LineDataSet) mLineChart.getData().getDataSetByIndex(0);
177 //避免在 initLineDataSet()方法中 设置了 lineDataSet.setDrawFilled(false); 而无法实现效果
178 lineDataSet.setDrawFilled(true);
179 lineDataSet.setFillDrawable(drawable);
180
181 mLineChart.invalidate();
182
183 }
184 return mLineChart;
185 }
186
187
188 // 传入某种格式的时间格式,得到特定的时间格式
189 public static String StrToStr(String SimpleDateFormat_in, String SimpleDateFormat_out, String str) {
190 SimpleDateFormat format = new SimpleDateFormat(SimpleDateFormat_in);
191 SimpleDateFormat format1 = new SimpleDateFormat(SimpleDateFormat_out);
192 Date date = null;
193 try {
194 date = format.parse(str);
195 } catch (ParseException e) {
196 e.printStackTrace();
197 }
198 return format1.format(date.getTime());
199 }
200
201
202 }

5.LineChartMarkView1

 1 **
2 * @Author: Bytezero_zhengLei
3 * @Time: 2023/3/24 10:45
4 * @Project_Name: LineChartMarkView1.java
5 * @Email: 420498246@qq.com
6 * @Description:
7 * @TODO:
8 */
9
10 public class LineChartMarkView1 extends MarkerView {
11
12 private TextView tvDate;
13 private TextView tvValue;
14 private IAxisValueFormatter xAxisValueFormatter;
15 DecimalFormat df = new DecimalFormat(".00");
16
17 public LineChartMarkView1(Context context, IAxisValueFormatter xAxisValueFormatter) {
18 super(context, R.layout.layout_markview1);
19 this.xAxisValueFormatter = xAxisValueFormatter;
20
21 tvDate = findViewById(R.id.tv_date);
22 tvValue = findViewById(R.id.tv_value);
23 }
24
25 @SuppressLint("SetTextI18n")
26 @Override
27 public void refreshContent(Entry e, Highlight highlight) {
28 Chart chart = getChartView();
29 if (chart instanceof LineChart) {
30 LineData lineData = ((LineChart) chart).getLineData();
31 //获取到图表中的所有曲线
32 List<ILineDataSet> dataSetList = lineData.getDataSets();
33 for (int i = 0; i < dataSetList.size(); i++) {
34 LineDataSet dataSet = (LineDataSet) dataSetList.get(i);
35 //获取到曲线的所有在Y轴的数据集合,根据当前X轴的位置 来获取对应的Y轴值
36 float y = dataSet.getValues().get((int) e.getX()).getY();
37 if (i == 0) {
38 tvValue.setText(dataSet.getLabel() + ":" + e.getY());
39 }
40 }
41 tvDate.setText(xAxisValueFormatter.getFormattedValue(e.getX(), null));
42 }
43
44 super.refreshContent(e, highlight);
45 }
46
47 @Override
48 public MPPointF getOffset() {
49 return new MPPointF(-(getWidth() / 2), -getHeight());
50
51 }
52 }

6.CustomXAxisRenderer

 1 /**
2 * @Author: Bytezero_zhengLei
3 * @Time: 2023/3/24 10:23
4 * @Project_Name: CustomXAxisRenderer.java
5 * @Email: 420498246@qq.com
6 * @Description:
7 * @TODO:
8 */
9
10 public class CustomXAxisRenderer extends XAxisRenderer {
11 public CustomXAxisRenderer(ViewPortHandler viewPortHandler, XAxis xAxis, Transformer trans) {
12 super(viewPortHandler, xAxis, trans);
13 }
14
15 @Override
16 protected void drawLabel(Canvas c, String formattedLabel, float x, float y, MPPointF anchor, float angleDegrees) {
17 // super.drawLabel(c, formattedLabel, x, y, anchor, angleDegrees);//注释掉这个,否则坐标标签复写两次
18 String[] lines = formattedLabel.split(" ");
19 for (int i = 0; i < lines.length; i++) {
20 float vOffset = i * mAxisLabelPaint.getTextSize();
21 Utils.drawXAxisValue(c, lines[i], x, y + vOffset, mAxisLabelPaint, anchor, angleDegrees);
22 }
23 }
24 }

5.一些 小的  layout

LineChartMarkView1的layout
 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2 android:layout_width="wrap_content"
3 android:layout_height="wrap_content"
4 android:background="@drawable/shape_square"
5 android:orientation="vertical">
6
7 <TextView
8 android:id="@+id/tv_date"
9 android:layout_width="wrap_content"
10 android:layout_height="wrap_content"
11 android:textColor="@android:color/white" />
12
13 <TextView
14 android:id="@+id/tv_value"
15 android:layout_width="wrap_content"
16 android:layout_height="wrap_content"
17 android:layout_marginTop="5dp"
18 android:textColor="@android:color/white" />
19 </LinearLayout>

6.LineChartActivity中的 layout

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2 xmlns:app="http://schemas.android.com/apk/res-auto"
3 xmlns:tools="http://schemas.android.com/tools"
4 android:layout_width="match_parent"
5 android:layout_height="match_parent"
6 tools:context=".LineChart.LineChartActivity">
7
8 <com.github.mikephil.charting.charts.LineChart
9 android:layout_gravity="center"
10 android:id="@+id/linechart"
11 android:layout_width="match_parent"
12 android:layout_height="300dp" />
13
14
15
16
17
18 </LinearLayout>

这样就ok了

Android LineChart 折线图Demo的相关教程结束。

《Android LineChart 折线图Demo.doc》

下载本文的Word格式文档,以方便收藏与打印。