此篇文章主要讲解MPAndroidChart中 折线图 的基本使用,和一些常用方法的总结。以下均为个人总结。如有错误或者不妥之处,望在评论区留言。
MPAndroidChart中的折线图主要由四部分组成
下面展示的效果图只填充数据,不添加任何样式的折线图,效果如下图:
XML布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.github.mikephil.charting.charts.LineChart
android:id="@+id/lc"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
RelativeLayout>
java代码
public class Frag_1 extends Fragment {
private LineChart lc;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.frag_1,null);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
lc = view.findViewById(R.id.lc);//获取控件
setData();//调用方法加载数据
}
public void setData(){
float datas[] = {14f,15f,16f,17f,16f,16f};
//在MPAndroidChart一般都是通过List对象来装数据的
List<Entry> entries = new ArrayList<Entry>();
//循环取出数据
for(int i = 0; i < datas.length; i++){
entries.add(new Entry(i,datas[i]));
}
//一个LineDataSet对象就是一条曲线
LineDataSet lineDataSet = new LineDataSet(entries,"第一条数据");
//LineData才是正真给LineChart的数据
LineData lineData = new LineData(lineDataSet);
lc.setData(lineData);
}
在大多数情况下,默认的样式肯定是不能满足我们的开发需求的,通过设置不同的属性或方法可以实现我们想要的效果
Description可以简单的理解为标题,但一般都是自己在布局文件中通过TextView或其他控件实现的,自带的标题很多时候都达不到很多效果。
常用属性:
属性 | 注解 |
---|---|
setText() | 设置标题的文本 |
setTextSize() | 设置文本大小 |
setTypeface() | 设置文本样式,如:加粗等 |
setTextColor() | 设置文本颜色 |
setXOffset() | 设置X轴的偏移量,float值 |
setYOffset() | 设置Y轴的偏移量,float值 |
setPosition() | 设置标题X和Y轴的偏移量 |
setEnabled() | 是否启用,bool值 |
案例:
//此方法在OnCreate中直接调用即可, 下方会给出完整代码
public void setDesc(){
Description description = new Description();
description.setText("这是折线图的标题");//设置文本
description.setTextSize(22f); //设置文本大小
description.setTypeface(Typeface.DEFAULT_BOLD);//设置文本样式加粗显示
description.setTextColor(Color.RED);//设置文本颜色
// 获取屏幕中间x 轴的像素坐标
WindowManager wm=(WindowManager)getActivity().getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics dm = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(dm);
float x = dm.widthPixels / 2;
description.setPosition(x,40);//设置文本的位置
lc.setDescription(description);//添加给LineChart
}
属性 | 注解 |
---|---|
getLegend() | 获取Legend对象 |
setFormSize() | 设置图例文字大小 |
setTextColor() | 设置文本颜色 |
setTypeface | 设置文本类型 |
setFormSize() | 设置图例的大小 |
setOrientation() | 设置多个图例的排列方式 |
setFormSize() | 设置图例的大小 |
setForm() | 设置图例的样式,如圆形、线形 |
setDrawInside() | 是否将图例绘制在内部,bool值 |
setFormToTextSpace() | 设置文本距离图例的距离,float值 |
setXOffset() | 设置X轴的偏移量,float值 |
setYOffset() | 设置Y轴的偏移量,float值 |
setVerticalAlignment() | 设置图例在垂直方向上的排列方式,LegendVerticalAlignment枚举值 |
setHorizontalAlignment() | 设置图例在水平方向上的排列方式,LegendHorizontalAlignment枚举值 |
setYEntrySpace() | 设置多个图例在Y方向上的距离,float值 |
setXEntrySpace() | 设置多个图例在X方向上的距离,float值 |
setDirection | 设置多个图例从什么方向开始绘制,如从左向右 |
setEnabled() | 是否启用,bool值 |
案例:
//该方法在onCreate中直接调用即可, 下方会给出完整代码
public void setLegend(){
//为了让大家更直观的看到效果,我这里设置了整个图形距离上下左右四个方向的边距
//在后面会讲解
lc.setExtraOffsets(30,60,30,30);
//得到Legend对象
Legend legend = lc.getLegend();
legend.setDrawInside(false);//不绘制在图形内部
legend.setTextSize(38f);//设置文字大小
legend.setTypeface(Typeface.DEFAULT_BOLD);//文字加粗
legend.setFormSize(50f);//设置图例的大小
legend.setTextColor(Color.BLUE);//设置文字颜色
legend.setFormToTextSpace(20f);//设置图例距离文字的距离
legend.setForm(Legend.LegendForm.LINE);//设置图例类型为线条
legend.setYOffset(20f);//距离底部20dp
//设置图例下、中对齐
legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
}
属性 | 注解 |
---|---|
getAxisLeft() | 获取左边的YAxis对象 |
getAxisRight() | 获取右边的YAxis对象 |
setTextSize() | 设置文本字体大小 |
setTypeface() | 设置字体类型,如加粗 |
setTextColor | 设置字体颜色 |
setDrawAxisLine() | 是否绘制靠近y轴的第一条线,设置xAxis.setDrawGridLines(false)才有效果 |
setAxisLineWidth() | 设置靠近y轴的第一条线的宽度 |
setAxisLineWidth() | 设置靠近y轴的第一条线的颜色 |
setDrawGridLines() | 是否绘制网格线(横向的线) |
setGridLineWidth() | 设置网格线的宽度 |
setGridColor() | 设置网格线的颜色 |
setPosition() | 设置Y轴的文本描述是否绘制在内侧 |
setDrawLabels() | 是否绘制左侧的描述文字 |
setAxisMaximum() | 设置y轴的最大值 |
setAxisMinimum() | 设置y轴的最小值 |
setGranularity() | 设置y轴每两个值之间的间隔 |
setGranularityEnabled() | 是否启用间隔 |
setInverted() | 设置是否倒序拍立 |
setValueFormatter() | 自定义格式,通过实现接口IAxisValueFormatter(用法在案例中) |
setXOffset() | 设置X轴的偏移量 |
setYOffset() | 设置Y轴的偏移量 |
setCenterAxisLabels() | 是否使文字在中间对齐 |
setLabelCount() | 设置展示的个数,第二个参数如果设置为true表示将强制设置标签计数,这意味着指定的标签数将沿轴绘制并均匀分布-这可能会导致标签参差不齐 |
setEnabled() | 是否启用,bool值 |
案例:
//此方法在onCreate中直接调用即可, 下方会给出完整代码
public void setYAxis(){
//不显示右侧的Y轴
lc.getAxisRight().setEnabled(false);
YAxis yAxis = lc.getAxisLeft();
yAxis.setLabelCount(7,true);//显示7个
yAxis.setAxisMaximum(19f);//设置最大值
yAxis.setAxisMinimum(9f);//设置最小值
yAxis.setTextSize(14f);//设置文本大小
yAxis.setXOffset(15);//设置15dp的距离
//自定义格式
yAxis.setValueFormatter(new IAxisValueFormatter() {
@Override
public String getFormattedValue(float value, AxisBase axis) {
if(value == 9){
return "(S)";
}
String tep = value + "";
return tep.substring(0,tep.indexOf(".")) + "℃";
}
})
}
常用属性:
XAxis的属性大部分与YAxis相同,下面只介绍XAxis中特有的几个属性
属性 | 注解 |
---|---|
setPosition() | 设置X所在的位置,可取值:TOP(默认值):位于上方,TOP_INSIDE:位于上方并绘制在图形内部,BOTTOM:位于下方,BOTTOM_INSIDE:位于下方并绘制在图形内部,BOTH_SIDED:上下两边都显示轴 |
setLabelRotationAngle() | 设置旋转的角度,float值 |
public void setXAxis() {
XAxis xAxis = lc.getXAxis();
xAxis.setTextSize(14f);//设置字体大小
xAxis.setTextColor(Color.RED);//设置字体颜色
xAxis.setLabelRotationAngle(60f);//旋转60度
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);//将x轴位于底部
xAxis.setDrawGridLines(false);//不绘制网格线
xAxis.setGranularity(1);//间隔1
//小技巧,通过设置Axis的最小值设置为负值
//可以改变距离与Y轴的距离
final String weeks[] = {"昨天","今天","明天","周五","周六","周日"};
xAxis.setAxisMaximum(5.2f);//设置最小值
xAxis.setAxisMinimum(-0.2f);//设置最大值
xAxis.setLabelCount(weeks.length);//设置数量
//自定义样式
xAxis.setValueFormatter(new IAxisValueFormatter() {
@Override
public String getFormattedValue(float value, AxisBase axis) {
return weeks[(int) value];
}
});
}
lineDataSet的设置简单的来说就是对线条的设置,如线条的颜色,线条的圆点代销大小等。
常用属性:
属性 | 注解 |
---|---|
setColor() | 设置线条颜色,有多个构造方法 |
setLineWidth() | 设置线条的宽度 |
setCircleRadius() | 设置圆点的半径大小 |
setCircleColor() | 一次性设置所有圆点的颜色 |
setDrawCircleHole() | 设置是否为空心圆 |
setCircleColorHole() | 设置空心圆心的颜色,注意该属性只有在setDrawCircleHole为true的时候才有效果 |
setDrawCircles() | 是否绘制圆点,若为false则表示只有折线 |
setFillColor() | 设置在曲线下方填充的颜色 |
setDrawFilled() | 是否在线条下方设置填充,bool类型 |
setMode() | 用于设置线条的类型,Mode枚举值,如Mode.CUBIC_BEZIER表示贝塞尔曲线 |
setCubicIntensity() | 设置线条Mode类型的强度,0-1 |
setAxisDependency() | 设置线条是参照左边的y轴还是右边的y轴,在绘制组合图的时候用到,AxisDependency枚举值 |
代码
//此方法在onCreate中直接调用即可, 下方会给出完整代码
public void setData(){
float datas[] = {16f,17f,16f,20f,22f,18f};
List<Entry> entries = new ArrayList<Entry>();
for(int i = 0; i < datas.length; i++){
entries.add(new Entry(i,datas[i]));
}
LineDataSet lineDataSet = new LineDataSet(entries,"第一条数据");
lineDataSet.setCircleRadius(5);//设置圆点半径大小
lineDataSet.setLineWidth(3);//设置折线的宽度
// lineDataSet.setCircleColor(Color.RED);//一次性设置所有圆点的颜色
lineDataSet.setDrawCircleHole(false);//设置是否空心
lineDataSet.setCircleColors(Color.RED,Color.BLACK,Color.GREEN);//依次设置每个圆点的颜色
lineDataSet.setFillColor(Color.GRAY);//设置线条下方的填充
lineDataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER); // 设置折线类型,这里设置为贝塞尔曲线
lineDataSet.setCubicIntensity(0.2f);//设置曲线的Mode强度,0-1
lineDataSet.setDrawFilled(true);//是否绘制折线下方的填充
lineDataSet.setColor(Color.RED);//设置折线的颜色,有三个构造方法
LineData lineData = new LineData(lineDataSet);
lc.setData(lineData);
}
public class Frag_1 extends Fragment {
private LineChart lc;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.frag_1,null);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
lc = view.findViewById(R.id.lc);
setData();
setDesc();
setLegend();
setYAxis();
setXAxis();
}
public void setDesc(){
Description description = new Description();
description.setText("这是折线图的标题");//设置文本
description.setTextSize(22f); //设置文本大小
description.setTypeface(Typeface.DEFAULT_BOLD);//设置文本样式加粗显示
description.setTextColor(Color.RED);//设置文本颜色
//获取屏幕的中间位置
WindowManager wm=(WindowManager)getActivity().getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics dm = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(dm);
float x = dm.widthPixels / 2;
description.setPosition(x,40);//设置文本的位置
lc.setDescription(description);//添加给LineChart
}
public void setLegend(){
//为了让大家更直观的看到效果,我这里设置了整个图形距离上下左右四个方向的边距
//在后面会讲解
lc.setExtraOffsets(30,60,30,30);
//得到Legend对象
Legend legend = lc.getLegend();
legend.setDrawInside(false);//不绘制在图形内部
legend.setTextSize(38f);//设置文字大小
legend.setTypeface(Typeface.DEFAULT_BOLD);//文字加粗
legend.setFormSize(50f);//设置图例的大小
legend.setTextColor(Color.BLUE);//设置文字颜色
legend.setFormToTextSpace(20f);//设置图例距离文字的距离
legend.setForm(Legend.LegendForm.LINE);//设置图例类型为线条
legend.setYOffset(20f);//距离底部20dp
//设置图例下、中对齐
legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
}
public void setYAxis(){
lc.getAxisRight().setEnabled(false);
YAxis yAxis = lc.getAxisLeft();
yAxis.setDrawAxisLine(false);
yAxis.setLabelCount(7,true);
yAxis.setAxisMaximum(25f);
yAxis.setAxisMinimum(13f);
yAxis.setInverted(false);
yAxis.setGridLineWidth(2);
yAxis.setTextSize(14f);
yAxis.setXOffset(15);//设置15dp的距离
yAxis.setValueFormatter(new IAxisValueFormatter() {
@Override
public String getFormattedValue(float value, AxisBase axis) {
if(value == 13){
return "(S)";
}
String tep = value + "";
return tep.substring(0,tep.indexOf(".")) + "℃";
}
});
}
public void setXAxis() {
XAxis xAxis = lc.getXAxis();
xAxis.setTextSize(14f);//设置字体大小
xAxis.setTextColor(Color.RED);//设置字体颜色
xAxis.setLabelRotationAngle(60f);//旋转60度
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);//将x轴位于底部
xAxis.setDrawGridLines(false);//不绘制网格线
xAxis.setGranularity(1);//间隔1
//小技巧,通过设置Axis的最小值设置为负值
//可以改变距离与Y轴的距离
final String weeks[] = {"昨天","今天","明天","周五","周六","周日"};
xAxis.setAxisMaximum(5.2f);//设置最小值
xAxis.setAxisMinimum(-0.2f);//设置最大值
xAxis.setLabelCount(weeks.length);//设置数量
//自定义样式
xAxis.setValueFormatter(new IAxisValueFormatter() {
@Override
public String getFormattedValue(float value, AxisBase axis) {
return weeks[(int) value];
}
});
}
public void setData(){
float datas[] = {16f,17f,16f,20f,22f,18f};
List<Entry> entries = new ArrayList<Entry>();
for(int i = 0; i < datas.length; i++){
entries.add(new Entry(i,datas[i]));
}
LineDataSet lineDataSet = new LineDataSet(entries,"第一条数据");
lineDataSet.setCircleRadius(5);//设置圆点半径大小
lineDataSet.setLineWidth(3);//设置折线的宽度
// lineDataSet.setCircleColor(Color.RED);//一次性设置所有圆点的颜色
lineDataSet.setDrawCircleHole(false);//设置是否空心
lineDataSet.setCircleColors(Color.RED,Color.BLACK,Color.GREEN);//依次设置每个圆点的颜色
lineDataSet.setFillColor(Color.GRAY);
lineDataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER); // 设置折线类型,这里设置为贝塞尔曲线
lineDataSet.setCubicIntensity(0.2f);//设置曲线的Mode强度,0-1
lineDataSet.setDrawFilled(true);//是否绘制折线下方的填充
// lineDataSet.setAxisDependency(YAxis.AxisDependency.RIGHT);设置依附左边还是右边,
lineDataSet.setColor(Color.RED);//设置折线的颜色,有三个构造方法
LineData lineData = new LineData(lineDataSet);
lc.setData(lineData);
}
}
public class Frag_2 extends Fragment {
private LineChart lc;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.frag_1,null);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
lc = view.findViewById(R.id.lc);
setXAxis();
setYAxis();
loadData();
}
/**
* 设置Y轴
*/
private void setYAxis() {
//得到YAxis对象
YAxis yAxis = lc.getAxisLeft();
lc.getAxisRight().setEnabled(false);//不显示右侧的y轴
//设置字体颜色白色
yAxis.setTextColor(Color.WHITE);
//设置最大值和最小值
yAxis.setAxisMaximum(120);
yAxis.setAxisMinimum(0);
//设置字体大小
yAxis.setTextSize(14f);
//字体加粗
yAxis.setTypeface(Typeface.DEFAULT_BOLD);
yAxis.setDrawAxisLine(false);//不绘制第一条横线
yAxis.setGridColor(Color.WHITE);//网格颜色
//强制只绘制5个Label
yAxis.setLabelCount(5,true);
}
public void setXAxis(){
//得到XAxis对象
XAxis xAxis = lc.getXAxis();
xAxis.setTextColor(Color.WHITE);//字体颜色
//设置最大最小值
xAxis.setAxisMaximum(63);
xAxis.setAxisMinimum(3);
xAxis.setGranularity(3);//设置间隔
//将x显示在下方
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setTextSize(14f);//字体大小
//自定义格式
xAxis.setValueFormatter(new IAxisValueFormatter() {
@Override
public String getFormattedValue(float value, AxisBase axis) {
if(value < 10){
String tep = "0" + value;
return tep.substring(0,tep.indexOf("."));
}
if(value == 63){
return "(S)";
}
String tep1 = value + "";
return tep1.substring(0,tep1.indexOf("."));
}
});
xAxis.setLabelCount(20);
xAxis.setDrawGridLines(false);
}
private void loadData() {
//设置边距
lc.setExtraTopOffset(100);
lc.setExtraBottomOffset(100);
lc.setExtraLeftOffset(10);
lc.setExtraRightOffset(50);
//不绘制图例和标题
lc.getLegend().setEnabled(false);
lc.getDescription().setEnabled(false);
//设置背景颜色
lc.setBackgroundColor(getResources().getColor(R.color.map_1_bule));
float datas[] = {92,103,29,45,40,70,10,15,20,30,55,90,60,2,27,70,64,91,10,72};
List<Entry> yData = new ArrayList<Entry>();
for(int i = 0; i < datas.length; i++){
yData.add(new Entry(i*3 + 3,datas[i]));
}
LineDataSet lineDataSet = new LineDataSet(yData,"");
lineDataSet.setLineWidth(4);//设置线条宽度
lineDataSet.setColor(Color.WHITE);//设置线条颜色
lineDataSet.setCircleColor(Color.WHITE);//设置圆点颜色
lineDataSet.setCircleRadius(8);//设置圆的大小
lineDataSet.setDrawValues(false);//不绘制文本
lineDataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);//设置为贝塞尔曲线
lineDataSet.setCubicIntensity(0.1f);//曲线强度0.1
lineDataSet.setDrawCircleHole(false);//设置为实心圆
LineData lineData = new LineData(lineDataSet);
lc.setData(lineData);
}
}
这里补充两个线条的折线图,两个线条的折线图和一个线条的折线图其实没有本质的区别,只不过是多了一个LineDataSet,然后将这两个LineDataSet通过LineData的构造方法传递就行啦,下面有一个小小的Demo,供大家参考
public class Frag_3 extends Fragment {
private LineChart lc;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.frag_1,null);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
lc = view.findViewById(R.id.lc);
setXAxis();
setYAxis();
loadData();
}
private void setXAxis() {
XAxis xAxis = lc.getXAxis();
xAxis.setTextColor(Color.BLUE);
xAxis.setTextSize(18f);
xAxis.setYOffset(20);
xAxis.setAxisMaximum(5.2f);
xAxis.setAxisMinimum(-0.2f);
xAxis.setGranularity(1);
final String weeks[] = {"昨天","今天","明天","周五","周六","周日"};
xAxis.setValueFormatter(new IAxisValueFormatter() {
@Override
public String getFormattedValue(float value, AxisBase axis) {
return weeks[(int) value];
}
});
xAxis.setDrawGridLines(false);
}
public void setYAxis(){
YAxis yAxis = lc.getAxisLeft();
lc.getAxisRight().setEnabled(false);
yAxis.setLabelCount(4,true);
yAxis.setAxisMaximum(25.5f);
yAxis.setAxisMinimum(12);
yAxis.setDrawLabels(false);
yAxis.setDrawAxisLine(false);
}
public void loadData(){
lc.getLegend().setEnabled(false);
lc.getDescription().setEnabled(false);
lc.setExtraTopOffset(100f);
lc.setExtraBottomOffset(100f);
float d1[] = {22f,24f,25f,25f,25f,22f};
float d2[] = {14f,15f,16f,17f,16f,16f};
List<Entry> entries1 = new ArrayList<Entry>();
List<Entry> entries2 = new ArrayList<Entry>();
for(int i = 0; i< d1.length; i++){
entries1.add(new Entry(i,d1[i]));
entries2.add(new Entry(i,d2[i]));
}
LineDataSet lineDataSet1 = new LineDataSet(entries1,"");
LineDataSet lineDataSet2 = new LineDataSet(entries2,"");
分别为两个LineDataSet设置
lineDataSet1.setLineWidth(2f);
lineDataSet2.setLineWidth(2f);
lineDataSet1.setColor(Color.RED);
lineDataSet2.setColor(Color.BLUE);
lineDataSet1.setDrawCircleHole(false);
lineDataSet2.setDrawCircleHole(false);
lineDataSet1.setCircleHoleRadius(4f);
lineDataSet2.setCircleHoleRadius(4f);
lineDataSet1.setCircleColor(Color.RED);
lineDataSet2.setCircleColor(Color.BLUE);
lineDataSet1.setMode(LineDataSet.Mode.CUBIC_BEZIER);
lineDataSet1.setCubicIntensity(0.2f);
lineDataSet2.setMode(LineDataSet.Mode.CUBIC_BEZIER);
lineDataSet2.setCubicIntensity(0.2f);
//两个LineDataSet通过LineData的构造方法传递即可
LineData lineData = new LineData(lineDataSet1,lineDataSet2);
lc.setData(lineData);
}
}