目录
前言
在使用这个功能的时候在网上找了不少资料,有的弄起来很麻烦,也有的很不好看。所以我写了一个小模块封装,减少重复性的开发。(或许是懒人模块?)不过这个自定义X轴显示也太麻烦了吧! (╯‵□′)╯︵┻━┻ 所以直接索性,不弄自定义x轴了。
项目导入
在build.gradle 里将项目导入
dependencies {
...
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
...
}
由于这里引用的是github的 所以还需要 在工程中的 build.gradle 增加这一行
allprojects {
repositories {
google()
jcenter()
maven { url 'https://jitpack.io' }
}
}
导入后有时会导致项目编译不了,报错
More than one file was found with OS independent path 'META-INF/proguard/androidx-annotations.pro'
解决方法是在 build.gradle (Module:app) 这里 也就是你导入这个项目包的文件内增加这一段就解决了。
android {
...
packagingOptions {
exclude 'META-INF/proguard/androidx-annotations.pro'
}
...
}
使用MPAndroidChart
使用到的类
创建一个新的类为 BaseLinerView
这个主要实现的功能就是 画一个限制长度的折线图,我这里限制只显示30个点,这个数据可以自己随意更改,超过30个点就从0开始重新画。这个是支持实时更新的增加步进点的。
public abstract class BaseLinerView {
public View mView;
// 最多显示30 条X轴数据 超过重新开始
public static final int MAX_VALUES = 30;
private LineChart line_chart;
private LineDataSet dataSet;
private List<Entry> entries;
//线条颜色
public String lineColor;
//填充颜色
public String lineColor2;
//零线
public int zeroLine = 30;
public List<String> xValue = new ArrayList<>();
//折线图最大值
public int maxValue = 45;
//折线图最小值
public int minValue = 30;
//折线图步进
public float step = 0.5f;
public boolean init = false;
private int i = 2;
private LineData lineData;
public void initView() {
line_chart = mView.findViewById(R.id.liner);
initData();
setAxis();
setLegend();
// 设置图表控件是否可以进行触控操作
line_chart.setEnabled(false);
// 调用图表控件「描述方法」并直接禁用
line_chart.getDescription().setEnabled(false);
}
private void setLegend() {
// 获得图例的实例
Legend legend = line_chart.getLegend();
// 设置图例是否在图表控件内部显示
legend.setDrawInside(true);
// 设置图例的排列方向
legend.setOrientation(Legend.LegendOrientation.VERTICAL);
// 设置图例在图表控件中的水平对齐方向
legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
// 设置图例在图表控件中的垂直对齐方向
legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
// 设置图例的色块大小
legend.setFormSize(15);
// 设置图例的色块形状
legend.setForm(Legend.LegendForm.CIRCLE);
// 设置图例的文字大小
legend.setTextSize(15);
// 设置图例的文字颜色
legend.setTextColor(Color.BLACK);
}
abstract public String getLineName();
private void setAxis() {
// 获得X轴实例
XAxis xl = line_chart.getXAxis();
// X轴显示当前时间 小时与分钟
xl.setValueFormatter(new IndexAxisValueFormatter(xValue));
// 设置X轴显示位置
xl.setPosition(XAxis.XAxisPosition.BOTTOM);
xl.setDrawAxisLine(false);
// 设置X轴步长
xl.setGranularity(1);
// 设置是否显示X轴的延伸线
xl.setDrawGridLines(false);
// 获得左边Y轴实例
YAxis yl = line_chart.getAxisLeft();
// 不画网格
yl.setDrawGridLines(false);
// 设置左边Y轴最小单位为0
yl.setAxisMinimum(minValue);
// 设置Y轴步进
yl.setGranularity(step);
yl.setAxisMaximum(maxValue); // 设置Y轴最大值为100
yl.setLabelCount(20, false); // 强制设置标签个数
// 获得右边Y轴的实例
YAxis yl_right = line_chart.getAxisRight();
// 设置右边Y轴是否可用
yl_right.setEnabled(false);
}
private void initData() {
entries = new ArrayList<>();
for(int i = 0;i < MAX_VALUES;i++){
entries.add(new Entry(i,zeroLine));
xValue.add(getNowTime());
}
setDataStyle();
}
//获取当前时间的字符串
public String getNowTime(){
@SuppressLint("SimpleDateFormat")
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
return sdf.format(new Date());
}
/**
* 设置折线的样式
*
*/
private void setDataStyle() {
// List<ILineDataSet> dataSets = new ArrayList<>();
dataSet = new LineDataSet(entries, getLineName());
// 折线的颜色
dataSet.setFillColor(Color.parseColor(lineColor));
// 填充色的颜色
dataSet.setDrawFilled(lineColor2 != null);
if(lineColor2 !=null) {
dataSet.setColor(Color.parseColor(lineColor2));
}
// 折线的宽度
dataSet.setLineWidth(2);
// 是否设置圆点空洞
dataSet.setDrawCircleHole(false);
// 设置圆点的半径
dataSet.setCircleRadius(1);
// 设置圆的背景颜色
dataSet.setCircleColor(Color.parseColor("#78C256"));
// 设置数值字体大小
dataSet.setValueTextSize(13);
// 设置数值字体颜色
dataSet.setValueTextColor(Color.parseColor("#78C256"));
// 设置折线的显示模式
dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
dataSet.setDrawValues(false);
dataSet.setDrawCircles(false);
lineData = new LineData(dataSet);
line_chart.setData(lineData);
init = true;
}
/**
* 实时更新折线图中坐标点数据
*/
public void onUdata(float v) {
if(!init){
return;
}
if(i > MAX_VALUES - 1){
i = 0;
}
entries.set(i,new Entry(i,(int)v));
xValue.set(i,getNowTime());
line_chart.setData(lineData);
line_chart.invalidate();
i++;
}
}
使用方法
在初始化里将这个折线图初始化,在初始化前,先在layout放置控件
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginEnd="30dp"
android:layout_marginStart="30dp"
android:layout_marginTop="40dp"
android:layout_marginBottom="70dp"
android:orientation="vertical"
android:padding="25dp">
<com.github.mikephil.charting.charts.LineChart
android:id="@+id/liner"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="5"
android:background="#eef0f2" />
</LinearLayout>
之后在Activity中引用
private BaseLinerView baseLinerView;
private void initLine() {
baseLinerView = new BaseLinerView() {
@Override
public String getLineName() {
return "曲线名称";
}
};
baseLinerView.mView = findViewById(R.id.liner);
baseLinerView.lineColor = "#FF6655";
baseLinerView.lineColor2 = "#FF9593";
baseLinerView.zeroLine = 0;
baseLinerView.minValue = 0;
baseLinerView.maxValue = 100;
baseLinerView.initView();
}
如果想要更新数据执行即可
baseLinerView.onUdata(你要增加的数据);