本文介绍MpAndroidChart对曲线图绘制的用法,包括引用库的配置及语法使用,帮你从零做一款曲线图或者折线图。
MPandroidChart
是一款稳定实用的绘图库,可以绘制折线图、曲线图、柱状图、饼图、雷达图等,功能十分强大。对比了HelloChart
和WilliamChart
图标库以后,觉得后两款的动画效果不错,但是功能和稳定性没有MPandroidChart
好,所以最终还是选择用这款图表库。附上上述图表库的GitHub
地址,大家根据自己喜好,可以自由选择使用。
图表库 | GitHub地址 |
---|---|
MPandroidChart | 点击进入 |
HelloChart | 点击进入 |
WilliamChart | 点击进入 |
本文所用MPandroidChart
的jar包,版本号:v2.16: 点击下载
注:Android studio用户可直接去GitHub添加依赖即可,截止2017年8月,最新版为3.0.2。
在项目中,将jar
包拷贝到项目的lib
文件夹下,右键单击,选择Build Path..
,在选择Add to Build Path
。
LineChart
可以当做折线图或曲线图使用,如果用饼图,改为com.github.mikephil.charting.charts.PieChart
即可。
<com.github.mikephil.charting.charts.LineChart
android:id="@+id/lineChart"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.8" />
Activity
代码中声明绑定控件:private LineChart lineChart;// 声明图表控件
lineChart = (LineChart) findViewById(R.id.lineChart);//绑定控件
MPandroidChart
关键类名解释:LineChart
表示整个图表类XAxis
表示X轴类YAxis
表示Y轴类LineDataSet
表示一条曲线数据集(曲线类)LineData
表示LineChart
的数据源类Legend
曲线图例类MarkerView
点击坐标点弹出提示框(CustomMarkerView
为自定义的提示框)Entry
表示Y轴的数据值对象,如new Entry(123f, i)
,其中123f
是该坐标点的Y轴value
值,i
是一个指针,代表给第i个点赋值123f
。①.获取坐标数据源,X轴数据源List
, Y轴数据源List
。
②.配置ArrayList
,设置一条曲线数据源。
③.设置LineData
,将LineDataSet
添加到LineData
。
④.设置图表数据lineChart.setData(LineData)
⑤.其他设置:
- 设置图例Legend
(如需要可设置,亦可省略)。
- 设置坐标点弹出框CustomMarkerView
(如需要可设置,亦可省略)。
①.封装工具类原因:
为了代码的复用,不在每个用到图表的类中,都引用一堆图表的设置属性代码,故此将图表的属性,封装在ChartUtil
图表工具类中,随处调用即可。大家可将下面的类整个复制到自己的项目中,即可使用。
②坐标点击弹出框: 在该工具类中,有个内部类CustomMarkerView
,此类继承MarkerView
类,实现的是一个自定义的点击坐标点弹出提示框(看上图动画展示),用来显示当前坐标点的y轴数据。
③曲线的坐标数据隐藏: 曲线的坐标数据,在工具类中设置为隐藏了,因为在手机屏幕上显示多个点的时候,数字会重叠,用户体验比较差,通过点击弹出提示框的方式,可以有好的展示数据,增强交互体验。
④重要的方法使用介绍:
设置曲线图或折线图显示:true为曲线图,false为折线图
lineDataSet.setDrawCubic(true);
而在MPandroidChart
最新版V3.0中,要使用这种方式设置曲线图:
lineDataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
设置为面图(显示曲线和X轴围成的区域阴影面):true
为显示,false
只显示一条曲线,曲线和X轴围成的阴影不显示。(上图动画中为显示阴影效果)。
lineDataSet.setDrawFilled(true);
图例设置:
每条线都有一个图例,说明这是条什么曲线,图例的颜色和样式(方块、圆形、线段),都可以设置:
Legend mLegend = lineChart.getLegend();
mLegend.setEnabled(true);
// 图例样式 (CIRCLE圆形;LINE线性;SQUARE是方块)
mLegend.setForm(LegendForm.SQUARE);
显示坐标点的值:true
为显示,false
为不显示。
当数值长度,图表会自动四舍五入,保留一位小数。
lineDataSet.setDrawValues(false);
绘制动画设置:
// 执行的动画,x轴(动画持续时间2500毫秒)
lineChart.animateX(2500)
注: 其他设置,在下面工具类代码里都给出示例,每行都给出了注释,大家可以自行设置。
⑤该工具类用到颜色bg_blue
,需要在项目 res/value/color.xml
中增加颜色,颜色值可以设置为你需要的颜色.
<color name="bg_blue">#58ACED
⑥点击弹出框的使用:
弹出框的布局需要自定义,将下面代码保存在chart_marker_view.xml
中,放入代码路径res/layout
下,并为弹出框background
属性配上一个底图,名为img_message
,或者设置一个深色的颜色均可。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:background="@drawable/img_message">
<TextView
android:id="@+id/txt_tips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="5dp"
android:text="123.4567899"
android:textSize="10dp"
android:textColor="@android:color/white"
android:focusable="true"
android:focusableInTouchMode="true"
android:ellipsize="marquee"
android:singleLine="true"
/>
RelativeLayout>
⑦.在工具类代码中,通过下面方式使用“提示弹出框”。
//声明点击提示框
CustomMarkerView mv = new CustomMarkerView(context, R.layout.chart_marker_view,unitName);
//设置曲线的点击提示框
lineChart.setMarkerView(mv);
⑧.完整的曲线图工具类代码,可复制项目中直接使用:
package com.today.util;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.widget.TextView;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.Legend.LegendForm;
import com.github.mikephil.charting.components.MarkerView;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.XAxis.XAxisPosition;
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.highlight.Highlight;
import com.today.main.R;
public class ChartUtil {
/**
* 显示图表
* @param context
* 上下文
* @param lineChart
* 图表对象
* @param xDataList
* X轴数据
* @param yDataList
* Y轴数据
* @param title
* 图表标题(如:XXX趋势图)
* @param curveLable
* 曲线图例名称(如:--用电量/时间)
* @param unitName
* 坐标点击弹出提示框中数字单位(如:KWH)
*/
public static void showChart(Context context, LineChart lineChart, List xDataList,
List yDataList, String title, String curveLable,String unitName) {
// 设置数据
lineChart.setData(setLineData(context, xDataList, yDataList, curveLable));
CustomMarkerView mv = new CustomMarkerView(context, R.layout.chart_marker_view,unitName);
// set the marker to the chart
lineChart.setMarkerView(mv);
// 是否在折线图上添加边框
lineChart.setDrawBorders(true);
// 曲线描述 -标题
lineChart.setDescription(title);
// 标题字体大小
lineChart.setDescriptionTextSize(16f);
// 标题字体颜色
lineChart.setDescriptionColor(context.getApplicationContext().getResources()
.getColor(R.color.txt_black));
// 如果没有数据的时候,会显示这个,类似文本框的placeholder
lineChart.setNoDataTextDescription("暂无数据");
// 是否显示表格颜色
lineChart.setDrawGridBackground(false);
// 禁止绘制图表边框的线
lineChart.setDrawBorders(false);
// 表格的的颜色,在这里是是给颜色设置一个透明度
// lineChart.setGridBackgroundColor(Color.WHITE & 0x70FFFFFF);
// 设置是否启动触摸响应
lineChart.setTouchEnabled(true);
// 是否可以拖拽
lineChart.setDragEnabled(true);
// 是否可以缩放
lineChart.setScaleEnabled(true);
// 如果禁用,可以在x和y轴上分别进行缩放
lineChart.setPinchZoom(false);
// lineChart.setMarkerView(mv);
// 设置背景色
// lineChart.setBackgroundColor(getResources().getColor(R.color.bg_white));
// 图例对象
Legend mLegend = lineChart.getLegend();
// mLegend.setPosition(LegendPosition.BELOW_CHART_CENTER);
// 图例样式 (CIRCLE圆形;LINE线性;SQUARE是方块)
mLegend.setForm(LegendForm.SQUARE);
// 图例大小
mLegend.setFormSize(8f);
// 图例上的字体颜色
mLegend.setTextColor(context.getApplicationContext().getResources().getColor(R.color.bg_blue));
mLegend.setTextSize(12f);
// 图例字体
// mLegend.setTypeface(mTf);
// 图例的显示和隐藏
mLegend.setEnabled(true);
// 隐藏右侧Y轴(只在左侧的Y轴显示刻度)
lineChart.getAxisRight().setEnabled(false);
XAxis xAxis = lineChart.getXAxis();
// 显示X轴上的刻度值
xAxis.setDrawLabels(true);
// 设置X轴的数据显示在报表的下方
xAxis.setPosition(XAxisPosition.BOTTOM);
// 轴线
// xAxis.setDrawAxisLine(false);
// 设置不从X轴发出纵向直线
xAxis.setDrawGridLines(false);
// 执行的动画,x轴(动画持续时间)
lineChart.animateX(2500);
// lineChart.notifyDataSetChanged();
}
/**
* 曲线赋值与设置
*
* @param context
* 上下文
* @param xDataList
* x轴数据
* @param yDataList
* y轴数据
* @return LineData
*/
private static LineData setLineData(Context context, List xDataList, List yDataList,
String curveLable) {
// LineDataSet表示一条曲线数据对象
ArrayList lineDataSets = new ArrayList();
// y轴的数据集合
LineDataSet lineDataSet = new LineDataSet(yDataList, curveLable);
// mLineDataSet.setFillAlpha(110);
// mLineDataSet.setFillColor(Color.RED);
// 用y轴的集合来设置参数
// 不显示坐标点的数据
lineDataSet.setDrawValues(false);
// 显示坐标点的小圆点
lineDataSet.setDrawCircles(true);
// 定位线
lineDataSet.setHighlightEnabled(true);
// 线宽
lineDataSet.setLineWidth(2.0f);
// 显示的圆形大小
lineDataSet.setCircleSize(4f);
// 显示颜色
lineDataSet.setColor(context.getApplicationContext().getResources().getColor(R.color.bg_blue));
// 圆形的颜色
lineDataSet.setCircleColor(context.getApplicationContext().getResources().getColor(R.color.bg_blue));
// 高亮的线的颜色
lineDataSet.setHighLightColor(context.getApplicationContext().getResources()
.getColor(R.color.text_yellow));
// 设置坐标点的颜色
lineDataSet.setFillColor(context.getApplicationContext().getResources().getColor(R.color.bg_blue));
// 设置坐标点为空心环状
lineDataSet.setDrawCircleHole(false);
// lineDataSet.setValueTextSize(9f);
lineDataSet.setFillAlpha(65);
// 设置显示曲线和X轴围成的区域阴影
lineDataSet.setDrawFilled(true);
// 坐标轴在左侧
lineDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
// 设置每条曲线图例标签名
// lineDataSet.setLabel("标签");
lineDataSet.setValueTextSize(14f);
// 曲线弧度(区间0.05f-1f,默认0.2f)
lineDataSet.setCubicIntensity(0.2f);
// 设置为曲线显示,false为折线
lineDataSet.setDrawCubic(true);
lineDataSets.add(lineDataSet);
// y轴的数据
LineData lineData = new LineData(xDataList, lineDataSets);
return lineData;
}
}
/**
* 自定义图表的MarkerView(点击坐标点,弹出提示框)
*/
class CustomMarkerView extends MarkerView {
private TextView tvContent;
private String unitName;
/**
*
* @param context
* 上下文
* @param layoutResource
* 资源文件
* @param unitName
* Y轴数值计量单位名称
*/
public CustomMarkerView(Context context, int layoutResource,final String unitName) {
super(context, layoutResource);
// 显示布局中的文本框
tvContent = (TextView) findViewById(R.id.txt_tips);
this.unitName = unitName;
}
// 每次markerview回调重绘,可以用来更新内容
@Override
public void refreshContent(Entry e, Highlight highlight) {
// 设置Y周数据源对象Entry的value值为显示的文本内容
tvContent.setText("" + e.getVal()+unitName);
}
@Override
public int getXOffset(float xpos) {
// 水平居中
return -(getWidth() / 2);
}
@Override
public int getYOffset(float ypos) {
// 提示框在坐标点上方显示
return -getHeight();
}
}
<resources>
<color name="txt_black_light">#333333color>
<color name="bg_white">#FFFFFFcolor>
<color name="bg_blue">#58ACEDcolor>
<color name="text_yellow">#FFC800color>
resources>
在需要引用图表的类中,只需给X和Y轴数据源赋值,然后调用ChartUtil.showChart()
方法,就可完成一条曲线的绘制了,非常方便快捷。示例如下:
List xDataList = new ArrayList<>();// x轴数据源
List yDataList = new ArrayList<>();// y轴数据数据源
//给上面的X、Y轴数据源做假数据测试
for (int i = 0; i < 24; i++) {
// x轴显示的数据
xDataList.add(i + ":00");
//y轴生成float类型的随机数
float value = (float) (Math.random() * range) + 3;
yDataList.add(new Entry(value, i));
}
//显示图表,参数( 上下文,图表对象, X轴数据,Y轴数据,图表标题,曲线图例名称,坐标点击弹出提示框中数字单位)
ChartUtil.showChart(this, lineChart, xDataList, yDataList, "供热趋势图", "供热量/时间","kw/h");
通过本文,可以快速的完成绘制一条曲线图,步骤总结:
MPandroidChart.jar
包。LineChart
布局,绑定控件。xDataList
和yDataList
。ChartUtil
类,调用showChart()
方法。