Android——图表库MPAndroidChart的使用
前言:将MPAndroidChart相关的方法封装成一个类,方便的使用MPAndroidChart绘制线性图。
GitHub地址:https://github.com/PhilJay/MPAndroidChart
核心功能
1、支持以下图表:
- Line Chart(线图)
- Bar Chart(条形图,又称柱状图)
- Pie Chart(饼状图)
- Stacked Bar
- Candle Stick Chart(蜡烛图)
- Cubic Line Chart(立方拟合的折线图)
- Radar Chart(雷达图)
- Realtime Chart(实时折线图)
- Sinus Bar Chart(正弦柱状图)
2、支持以下操作和设置:
- 支持x,y轴缩放
- 支持拖拽
- 支持手指滑动
- 支持高亮显示
- 支持保存图表到文件中
- 支持从文件(txt)中读取数据
- 预先定义颜色模板
- 自动生成标注
- 支持自定义x,y轴的显示标签
- 支持x,y轴动画
- 支持x,y轴设置最大值和附加信息
- 支持自定义字体,颜色,背景,手势,虚线等
使用
第一步:在build.gradle中,添加相关依赖:
repositories {
maven { url "https://jitpack.io" }
}
dependencies {
compile 'com.github.PhilJay:MPAndroidChart:v3.0.2'
}
第二步:布局文件中添加图表
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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">
<LinearLayout
android:layout_gravity="bottom"
android:layout_width="match_parent"
android:layout_height="320dp"
tools:layout_editor_absoluteY="0dp"
tools:layout_editor_absoluteX="8dp">
<com.github.mikephil.charting.charts.LineChart
android:id="@+id/data_chart"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</android.support.constraint.ConstraintLayout>
第三步:自己定义的相关图表操作的工具类。
public class DynamicLineChartManager {
private LineChart lineChart;
private YAxis leftAxis;
private YAxis rightAxis;
private XAxis xAxis;
private LineData lineData;
private LineDataSet lineDataSet;
private List<ILineDataSet> lineDataSets = new ArrayList<>();
private SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");//设置日期格式
private List<String> timeList = new ArrayList<>(); //存储x轴的时间
//一条曲线
public DynamicLineChartManager(LineChart mLineChart, String name, int color) {
this.lineChart = mLineChart;
leftAxis = lineChart.getAxisLeft();
rightAxis = lineChart.getAxisRight();
xAxis = lineChart.getXAxis();
initLineChart();
initLineDataSet(name, color);
}
//多条曲线
public DynamicLineChartManager(LineChart mLineChart, List<String> names, List<Integer> colors) {
this.lineChart = mLineChart;
leftAxis = lineChart.getAxisLeft();
rightAxis = lineChart.getAxisRight();
xAxis = lineChart.getXAxis();
initLineChart();
initLineDataSet(names, colors);
}
/**
* 初始化LineChar
*/
private void initLineChart() {
lineChart.setDrawGridBackground(false);
//显示边界
lineChart.setDrawBorders(true);
//不显示y轴右边的值
lineChart.getAxisRight().setEnabled(false);
//折线图例 标签 设置
Legend legend = lineChart.getLegend();
legend.setForm(Legend.LegendForm.LINE);
legend.setTextSize(11f);
//显示位置
legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
legend.setDrawInside(false);
xAxis.setDrawAxisLine(false);//不显示X轴
//X轴设置显示位置在底部
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setGranularity(1f);
xAxis.setLabelCount(20);
// xAxis.setValueFormatter(new IAxisValueFormatter() {
// @Override
// public String getFormattedValue(float value, AxisBase axis) {
// return timeList.get((int) value % timeList.size());
// }
// });
//保证Y轴从0开始,不然会上移一点
leftAxis.setAxisMinimum(0f);
rightAxis.setAxisMinimum(0f);
}
/**
* 初始化折线(一条线)
*
* @param name
* @param color
*/
private void initLineDataSet(String name, int color) {
lineDataSet = new LineDataSet(null, name);
lineDataSet.setLineWidth(1.5f);
lineDataSet.setCircleRadius(1.5f);
lineDataSet.setColor(color);
lineDataSet.setCircleColor(color);
lineDataSet.setHighLightColor(color);
//设置曲线填充
lineDataSet.setDrawFilled(true);
lineDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
lineDataSet.setValueTextSize(10f);
lineDataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
//添加一个空的 LineData
lineData = new LineData();
lineChart.setData(lineData);
lineChart.invalidate();
}
/**
* 初始化折线(多条线)
*
* @param names
* @param colors
*/
private void initLineDataSet(List<String> names, List<Integer> colors) {
for (int i = 0; i < names.size(); i++) {
lineDataSet = new LineDataSet(null, names.get(i));
lineDataSet.setColor(colors.get(i));
lineDataSet.setLineWidth(1.5f);
lineDataSet.setCircleRadius(1.5f);
lineDataSet.setColor(colors.get(i));
//lineDataSet.setDrawFilled(true);
lineDataSet.setCircleColor(colors.get(i));
lineDataSet.setHighLightColor(colors.get(i));
lineDataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
lineDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
lineDataSet.setValueTextSize(10f);
lineDataSets.add(lineDataSet);
}
//添加一个空的 LineData
lineData = new LineData();
lineChart.setData(lineData);
lineChart.invalidate();
}
/**
* 动态添加数据(一条折线图)
*
* @param number
*/
public void addEntry(int number) {
//最开始的时候才添加 lineDataSet(一个lineDataSet 代表一条线)
if (lineDataSet.getEntryCount() == 0) {
lineData.addDataSet(lineDataSet);
}
lineChart.setData(lineData);
//避免集合数据过多,及时清空(做这样的处理,并不知道有没有用,但还是这样做了)
// if (timeList.size() > 11) {
// timeList.clear();
// }
//
// timeList.add(df.format(System.currentTimeMillis()));
Entry entry = new Entry(lineDataSet.getEntryCount(), number);
lineData.addEntry(entry, 0);
//通知数据已经改变
lineData.notifyDataChanged();
lineChart.notifyDataSetChanged();
//设置在曲线图中显示的最大数量
lineChart.setVisibleXRangeMaximum(10);
//移到某个位置
lineChart.moveViewToX(lineData.getEntryCount() - 5);
}
/**
* 动态添加数据(多条折线图)
*
* @param numbers
*/
public void addEntry(List<Integer> numbers) {
if (lineDataSets.get(0).getEntryCount() == 0) {
lineData = new LineData(lineDataSets);
lineChart.setData(lineData);
}
//if (timeList.size() > 11) {
// timeList.clear();
//}
//timeList.add(df.format(System.currentTimeMillis()));
for (int i = 0; i < numbers.size(); i++) {
Entry entry = new Entry(lineDataSet.getEntryCount(), numbers.get(i));
lineData.addEntry(entry, i);
lineData.notifyDataChanged();
lineChart.notifyDataSetChanged();
lineChart.setVisibleXRangeMaximum(6);
lineChart.moveViewToX(lineData.getEntryCount() - 5);
}
}
/**
* 动态添加数据(多条折线图)
*
* @param numbers
*/
public void addRawEntry(float[] numbers) {
if (lineDataSets.get(0).getEntryCount() == 0) {
lineData = new LineData(lineDataSets);
lineChart.setData(lineData);
}
// if (timeList.size() > 11) {
// timeList.clear();
// }
// timeList.add(df.format(System.currentTimeMillis()));
for (int i = 0; i < numbers.length; i++) {
Entry entry = new Entry(lineDataSet.getEntryCount(), numbers[i]);
// if (lineData.getDataSetCount() > 30){
// lineData.clearValues();
// }
lineData.addEntry(entry, i);
lineData.notifyDataChanged();
lineChart.notifyDataSetChanged();
lineChart.setVisibleXRangeMaximum(10);
lineChart.moveViewToX(lineData.getEntryCount() - 5);
}
}
/**
* 设置Y轴值
*
* @param max
* @param min
* @param labelCount
*/
public void setYAxis(float max, float min, int labelCount) {
if (max < min) {
return;
}
leftAxis.setAxisMaximum(max);
leftAxis.setAxisMinimum(min);
leftAxis.setLabelCount(labelCount, false);
rightAxis.setAxisMaximum(max);
rightAxis.setAxisMinimum(min);
rightAxis.setLabelCount(labelCount, false);
lineChart.invalidate();
}
/**
* 设置高限制线
*
* @param high
* @param name
*/
public void setHightLimitLine(float high, String name, int color) {
if (name == null) {
name = "高限制线";
}
LimitLine hightLimit = new LimitLine(high, name);
hightLimit.setLineWidth(4f);
hightLimit.setTextSize(10f);
hightLimit.setLineColor(color);
hightLimit.setTextColor(color);
leftAxis.addLimitLine(hightLimit);
lineChart.invalidate();
}
/**
* 设置低限制线
*
* @param low
* @param name
*/
public void setLowLimitLine(int low, String name, int color) {
if (name == null) {
name = "低限制线";
}
LimitLine hightLimit = new LimitLine(low, name);
hightLimit.setLineWidth(4f);
hightLimit.setTextSize(10f);
hightLimit.setTextColor(color);
hightLimit.setLineColor(color);
leftAxis.addLimitLine(hightLimit);
lineChart.invalidate();
}
/**
* 设置描述信息
*
* @param str
*/
public void setDescription(String str) {
Description description = new Description();
description.setText(str);
lineChart.setDescription(description);
lineChart.invalidate();
}
}
第四步:在Activity中,设置图表的属性、添加数据。
public class DataActivity extends AppCompatActivity {
private DynamicLineChartManager dynamicLineChartManager;
private List<String> names = new ArrayList<>(); //折线名字集合
private List<Integer> colour = new ArrayList<>();//折线颜色集合
private LineChart lineChart;
private float[] force = new float[1];
private Thread thread;
private boolean stop = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_data);
lineChart = (LineChart) findViewById(R.id.data_chart);
//折线名字
names.add("ch1");
//折线颜色
colour.add(Color.BLACK);
dynamicLineChartManager = new DynamicLineChartManager(lineChart, names, colour);
dynamicLineChartManager.setYAxis(120,-10,13);
dynamicLineChartManager.setDescription("数据");
dynamicLineChartManager.setHightLimitLine(100.0f, "max", Color.RED);
dynamicLineChartManager.setLowLimitLine(0, "min", Color.GREEN);
force[0] = 0;
if (thread == null)
createThread();
}
@Override
protected void onDestroy() {
super.onDestroy();
stop = true;
}
private void createThread() {
thread = new Thread(new Runnable() {
@Override
public void run() {
while (!stop) {
try {
Thread.sleep(100);
updateChart(force);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
thread.start();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
force[0] = event.getPressure() * 100;
// runOnUiThread(update);
return true;
}
//private Runnable update = new Runnable() {
// @Override
// public void run() {
// updateChart(force);
// }
//};
//更新图表
public void updateChart(float[] data){
dynamicLineChartManager.addRawEntry(data);
}
}