目录
一、常用方法及相关属性
折线图中的属性所在位置:
常用方法:
二、动态曲线例子:
基本概念:
1、添加依赖
2、LineChartUtil :
3、MainActivity:
4、CustomMarkerView:
5、activity_main:
6、markview:
7、效果图:
三、多条折线图
1、MainActivity:
2、LineChartHelper:
3、activity_main:
4、CustomMarkerView:(同上)
5、效果图:
一、常用方法及相关属性
MPAndroidChart是一个非常流行的开源库,可以帮助你实现折线图、柱状图、饼图等多种图形。
折线图中的属性所在位置:
常用方法:
- setTouchEnabled(boolean enabled) :设置图表是否可以触摸。
- setDragEnabled(boolean enabled):设置图表是否可以拖动。
- setScaleEnabled(boolean enabled):设置图表是否可以缩放。
- setDrawGridBackground(boolean enabled):设置是否在图表中绘制背景网格。
- setPinchZoom(boolean enabled):设置图表是否可以通过两个手指捏合进行缩放。
- getDescription():获取图表的描述对象。
- setDescription(String desc):设置图表的描述文本。
- setDescriptionEnabled(boolean enabled):设置图表描述是否可见。
- getXAxis():获取X轴对象。
- getAxisRight():获取右侧Y轴对象。
- getAxisLeft():获取左侧Y轴对象。
- setData(LineData data):设置图表的数据。
- getData():获取图表的数据。
- invalidate():使图表视图失效。
- setVisibleXRangeMaximum(float maxXRange):设置图表在X轴上可见的范围的最大值。
- moveViewToX(float xValue):将图表视图移动到指定的X轴数值。
- setMarker(IMarker marker):设置图表上用于标记选中项的Marker对象。
- setHighlightPerTapEnabled(boolean enabled):设置是否显示单击选中项的高亮。
- setHighlightPerDragEnabled(boolean enabled):设置是否显示拖动选中项的高亮。
- setOnChartValueSelectedListener(OnChartValueSelectedListener listener):设置当值被选中时调用的监听器。
- animateX(int durationMillis):在指定的时间内动画显示图表的X轴。
- animateY(int durationMillis):在指定的时间内动画显示图表的Y轴。
- animateXY(int xDurationMillis, int yDurationMillis):在指定的时间内动画显示图表的X轴和Y轴。
- setNoDataText(String text):设置没有数据时显示的文本。
二、例子:
基本概念:
LineChart // 折线表,存线集合,与xml中的控件绑定实力化
LineData // 线集合,所有折线以数组的形式存到此集合中
LineDataSet // 点集合,即一条折线
Entry // 某条折线上的一个点
XAxis // X轴
YAxis // Y轴,Y轴分左右,通过lineChart的getAxisLeft()、getAxisRight()得到
Legend // 图例,即标识哪一条曲线,如用红色标识电流折线,蓝色标识电压折线
LimitLine // 限制线
Description // 描述
1、添加依赖
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
2、LineChartUtil :
package com.example.linechart;
import android.graphics.Color;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Description;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.LimitLine;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
public class LineChartUtil {
private LineChart mLineChart;
// 设置最多显示20个点
int maxVisibleCount = 20;
private float lastX = 0;
public LineChartUtil(LineChart lineChart){
mLineChart = lineChart;
}
/**
* 初始化X轴
*/
public void initXAxis() {
XAxis xAxis = mLineChart.getXAxis();
// 2.设置X轴的位置(默认在上方):
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);//值:BOTTOM,BOTH_SIDED,BOTTOM_INSIDE,TOP,TOP_INSIDE
// 3.设置X轴坐标之间的最小间隔(因为此图有缩放功能,X轴,Y轴可设置可缩放)
xAxis.setGranularity(1f);
// 4.设置X轴的刻度数量
xAxis.setLabelCount(40, false);
// 5.设置X轴的值(最小值、最大值、然后会根据设置的刻度数量自动分配刻度显示)
xAxis.setAxisMinimum(0f);
xAxis.setAxisMaximum(20f);
// 6.设置当前图表中最多在x轴坐标线上显示刻度线的总量
mLineChart.setVisibleXRangeMaximum(5);// 设置当前图表中最多在x轴坐标线上显示的刻度线总量为6
}
/**
* 初始化折线图数据集合
*/
public void initLineChartData() {
// 创建一个空数据集合并将其设置到图表中
LineDataSet dataSet = new LineDataSet(null, "动态折线图");
dataSet.setLineWidth(2.0f);
// 设置折线的颜色
dataSet.setColor(Color.RED);
// 设置曲线为圆滑曲线
dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
// 设置折线图填充
dataSet.setDrawFilled(true);
// 设置每个点是否以圆圈来显示
dataSet.setDrawCircles(true);
// 是否显示每个点的y值
dataSet.setDrawValues(true);
// 创建LineData对象并设置其为图表的数据
LineData data = new LineData(dataSet);
mLineChart.setData(data);
}
/**
* 初始化折线图
*/
public void initLineChart() {
// 折线图是否可以触摸
mLineChart.setTouchEnabled(true);
// 折线图是否可以拖动
mLineChart.setDragEnabled(true);
// 折线图是否可以放大
mLineChart.setScaleEnabled(true);
// 折线图是否显示网格
mLineChart.setDrawGridBackground(true);
// 如果设置为true, x和y轴可以用2个手指同时缩放,如果设置为false, x和y轴可以分别缩放。默认值:假
mLineChart.setPinchZoom(true);
// 返回图表的Description对象,该对象负责保存与显示在图表右下角的描述文本相关的所有信息(默认情况下)
mLineChart.getDescription().setEnabled(false);
mLineChart.animateX(1500);
// 设置x轴的属性
initXAxis();
// 设置y轴的属性
initYAxis();
initLegend();
}
/**
* 初始化折线图的图标
*/
public void initLegend() {
Legend legend = mLineChart.getLegend();
// 设置图例位置为底部居中
legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
// 显示图例文本
legend.setEnabled(true);
// 设置图例文本颜色
legend.setTextColor(Color.BLACK);
// 设置图例样式为水平
legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
// 设置描述内容
Description description = new Description();
description.setText("时间/min");
description.setTextColor(Color.RED);
mLineChart.setDescription(description);
}
/**
* 初始化折线图的y轴
*/
public void initYAxis() {
// 1.得到Y轴
YAxis leftYAxis = mLineChart.getAxisLeft();
YAxis rightYAxis = mLineChart.getAxisRight();
// 2.设置某一个Y轴是否显示
rightYAxis.setEnabled(false); //右侧Y轴不显示
//3.限制线LimitLine(如上右图)
LimitLine limitLine = new LimitLine(50,"警戒线"); //得到限制线
limitLine.setLineWidth(2f); //宽度
limitLine.setTextSize(10f);
limitLine.setTextColor(Color.BLACK); //颜色
limitLine.setLineColor(Color.GREEN);
leftYAxis.addLimitLine(limitLine); //Y轴添加限制线
//4.X轴和Y轴类似,都具有相同的属性方法
rightYAxis.setAxisMinimum(0f);
rightYAxis.setAxisMaximum(100f);
rightYAxis.setGranularity(1f);
// rightYAxis.setLabelCount(11,false);
rightYAxis.setTextColor(Color.BLUE); //文字颜色
rightYAxis.setGridColor(Color.RED); //网格线颜色
rightYAxis.setAxisLineColor(Color.GREEN); //Y轴颜色
}
public boolean addEntry() {
LineData data = mLineChart.getData();
if (data != null) {
LineDataSet set = (LineDataSet) data.getDataSetByIndex(0);
if (set == null) {
set = createSet();
data.addDataSet(set);
}
// 添加新点到数据集中
data.addEntry(new Entry(lastX++, (float) (Math.random() * 80) + 10f), 0);
// 更新数据
data.notifyDataChanged();
mLineChart.notifyDataSetChanged();
// 平移x轴,确保新添加的点显示在最右侧
float maxX = data.getXMax();
if (maxX > maxVisibleCount) {
// mLineChart.getXAxis().setAxisMinimum(data.getXMin() + 1);
// mLineChart.getXAxis().setAxisMaximum(data.getXMax() + maxVisibleCount);
// maxVisibleCount+=20;
return false;
}
// 将图表滚动到最新的点处
mLineChart.moveViewToX(data.getEntryCount()-4);
}
return true;
}
/**
* 创建数据集
*/
public LineDataSet createSet() {
LineDataSet set = new LineDataSet(null, "动态折线图");
set.setLineWidth(2.5f);
set.setColor(Color.RED);
set.setDrawCircles(false);
set.setDrawValues(false);
return set;
}
}
3、MainActivity:
package com.example.linechart;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.graphics.Color;
import android.view.View;
import android.widget.Button;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Description;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.LimitLine;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private LineChart mLineChart;
private Timer timer;
boolean isStart = false;
private Button pauseBtn,startBtn;
private LineChartUtil mLineChartUtil;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pauseBtn = findViewById(R.id.pause);
startBtn = findViewById(R.id.start);
startBtn.setOnClickListener(this);
pauseBtn.setOnClickListener(this);
// 获取LineChart视图
mLineChart = findViewById(R.id.chart);
mLineChartUtil = new LineChartUtil(mLineChart);
// 设置LineChart的属性
mLineChartUtil.initLineChart();
// 初始化折线图的数据
mLineChartUtil.initLineChartData();
}
@Override
public void onResume() {
super.onResume();
// 定义并启动定时器
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
// 在数据集中添加新点
runOnUiThread(new Runnable() {
@Override
public void run() {
if (isStart){
isStart = mLineChartUtil.addEntry();
}
}
});
}
}, 0, 500);
}
@Override
public void onPause() {
super.onPause();
timer.cancel();
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.pause:
isStart = false;
break;
case R.id.start:
isStart = true;
break;
}
}
}
4、CustomMarkerView:
package com.example.linechart;
import android.content.Context;
import android.widget.TextView;
import com.github.mikephil.charting.components.MarkerView;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.utils.MPPointF;
import java.util.Locale;
public class CustomMarkerView extends MarkerView {
private TextView mValueTextView;
public CustomMarkerView(Context context, int layoutResource) {
super(context, layoutResource);
// 实例化 TextView 控件
mValueTextView = findViewById(R.id.tv_value);
}
@Override
public void refreshContent(Entry e, Highlight highlight) {
// 格式化数值并设置到 TextView 中
String valueText = String.format(Locale.getDefault(), "%.2f °C", e.getY());
mValueTextView.setText(valueText);
super.refreshContent(e, highlight);
}
/**
* 设置 MarkerView 的偏移量,使其显示在当前点的上方
*/
@Override
public MPPointF getOffset() {
return new MPPointF(-(getWidth() / 2f), -getHeight());
}
}
5、activity_main:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<com.github.mikephil.charting.charts.LineChart
android:id="@+id/chart"
android:layout_width="match_parent"
android:layout_height="300dp" />
<Button
android:id="@+id/start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="开始"/>
<Button
android:id="@+id/pause"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="暂停"/>
</LinearLayout>
6、markview:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tv_value"
android:background="#DA2B7C"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/white"
android:textSize="12sp"/>
</LinearLayout>
效果图:
三、多条折线图
1、MainActivity:
package com.example.linedemo3;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.data.Entry;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
LineChartHelper mLineChartHelper;
LineChart mLineChart;
List<Entry> entries1,entries2,entries3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLineChart = findViewById(R.id.lineChart);
mLineChartHelper = new LineChartHelper(mLineChart,MainActivity.this);
initData();
mLineChartHelper.setChartData(entries1,entries2,entries3);
}
private void initData() {
// 创建三条折线的数据集合
entries1 = new ArrayList<>();
entries2 = new ArrayList<>();
entries3 = new ArrayList<>();
for (int i = 0; i < 20; i++) {
entries1.add(new Entry(i, (float) Math.random()+10));
entries2.add(new Entry(i, (float) Math.random()+10));
entries3.add(new Entry(i, (float) Math.random()+10));
}
}
}
2、LineChartHelper:
package com.example.linedemo3;
import android.content.Context;
import android.graphics.Color;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Description;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.LimitLine;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
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.interfaces.datasets.ILineDataSet;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.List;
public class LineChartHelper {
private LineChart mLineChart;
private Context mContext;
public LineChartHelper(LineChart lineChart,Context context) {
mLineChart = lineChart;
mContext = context;
initLineChart();
}
/**
* 初始化折线图
*/
public void initLineChart() {
// 创建 CustomMarkerView 对象,并设置 MarkerView
CustomMarkerView markerView = new CustomMarkerView(mContext, R.layout.markview);
mLineChart.setMarker(markerView);
// 折线图是否可以触摸
mLineChart.setTouchEnabled(true);
// 折线图是否可以拖动
mLineChart.setDragEnabled(true);
// 折线图是否可以放大
mLineChart.setScaleEnabled(true);
// 折线图是否显示网格
mLineChart.setDrawGridBackground(true);
// 如果设置为true, x和y轴可以用2个手指同时缩放,如果设置为false, x和y轴可以分别缩放。默认值:假
mLineChart.setPinchZoom(true);
// 返回图表的Description对象,该对象负责保存与显示在图表右下角的描述文本相关的所有信息(默认情况下)
mLineChart.getDescription().setEnabled(false);
mLineChart.animateX(1500);
// 设置x轴的属性
initXAxis();
// 设置y轴的属性
initYAxis();
initLegend();
}
/**
* 初始化X轴
*/
public void initXAxis() {
XAxis xAxis = mLineChart.getXAxis();
// 2.设置X轴的位置(默认在上方):
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);//值:BOTTOM,BOTH_SIDED,BOTTOM_INSIDE,TOP,TOP_INSIDE
// 3.设置X轴坐标之间的最小间隔(因为此图有缩放功能,X轴,Y轴可设置可缩放)
xAxis.setGranularity(1f);
// 4.设置X轴的刻度数量
xAxis.setLabelCount(40, false);
// 5.设置X轴的值(最小值、最大值、然后会根据设置的刻度数量自动分配刻度显示)
xAxis.setAxisMinimum(0f);
xAxis.setAxisMaximum(20f);
// 6.设置当前图表中最多在x轴坐标线上显示刻度线的总量
mLineChart.setVisibleXRangeMaximum(5);// 设置当前图表中最多在x轴坐标线上显示的刻度线总量为6
}
/**
* 初始化折线图的图标
*/
public void initLegend() {
Legend legend = mLineChart.getLegend();
// 设置图例位置为底部居中
legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
// 显示图例文本
legend.setEnabled(true);
// 设置图例文本颜色
legend.setTextColor(Color.BLACK);
// 设置图例样式为水平
legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
// 设置描述内容
Description description = new Description();
description.setText("时间/min");
description.setTextColor(Color.RED);
mLineChart.setDescription(description);
}
/**
* 初始化折线图的y轴
*/
public void initYAxis() {
// 1.得到Y轴
YAxis leftYAxis = mLineChart.getAxisLeft();
YAxis rightYAxis = mLineChart.getAxisRight();
// 2.设置某一个Y轴是否显示
rightYAxis.setEnabled(false); //右侧Y轴不显示
//3.限制线LimitLine(如上右图)
LimitLine limitLine = new LimitLine(50,"警戒线"); //得到限制线
limitLine.setLineWidth(2f); //宽度
limitLine.setTextSize(10f);
limitLine.setTextColor(Color.BLACK); //颜色
limitLine.setLineColor(Color.GREEN);
leftYAxis.addLimitLine(limitLine); //Y轴添加限制线
//4.X轴和Y轴类似,都具有相同的属性方法
rightYAxis.setAxisMinimum(0f);
rightYAxis.setAxisMaximum(100f);
rightYAxis.setGranularity(1f);
// rightYAxis.setLabelCount(11,false);
rightYAxis.setTextColor(Color.BLUE); //文字颜色
rightYAxis.setGridColor(Color.RED); //网格线颜色
rightYAxis.setAxisLineColor(Color.GREEN); //Y轴颜色
}
public void setChartData(List<Entry> entries1, List<Entry> entries2, List<Entry> entries3) {
// 将数据集合封装成 LineDataSet 对象,并设置各种绘制属性
LineDataSet dataSet1 = new LineDataSet(entries1, "室温/°C");
dataSet1.setColor(Color.RED);
dataSet1.setValueTextColor(Color.RED);
dataSet1.setLineWidth(2f);
LineDataSet dataSet2 = new LineDataSet(entries2, "箱内温度/°C");
dataSet2.setColor(Color.GREEN);
dataSet2.setValueTextColor(Color.GREEN);
dataSet2.setLineWidth(2f);
LineDataSet dataSet3 = new LineDataSet(entries3, "外面温度/°C");
dataSet3.setColor(Color.BLUE);
dataSet3.setValueTextColor(Color.BLUE);
dataSet3.setLineWidth(2f);
// 将三条折线的 LineDataSet 对象放入 LineData 中
List<ILineDataSet> dataSets = new ArrayList<>();
dataSets.add(dataSet1);
dataSets.add(dataSet2);
dataSets.add(dataSet3);
LineData lineData = new LineData(dataSets);
// 设置绘制样式以及其他属性
mLineChart.setData(lineData);
mLineChart.animateXY(1000, 1000);
}
}
3、activity_main:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.github.mikephil.charting.charts.LineChart
android:id="@+id/lineChart"
android:layout_width="match_parent"
android:layout_height="300dp"
/>
</LinearLayout>
4、CustomMarkerView:(同上)
5、效果图: