本人学习MPAndroidChart的经历可以说十分坎坷,对于没有什么经验的小白来说,真的不好入手,但总的来说其实也不是很难。
让我们来略微了解一下LineChart(折线图)的基本方法吧!
首先
第一步要使用MPAndroidChart这个Android图标库需要导入:
两种方式:1.导入架包2.添加依赖
官网地址:https://github.com/PhilJay/MPAndroidChart
依赖导入
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
}
然后我们就开始创建UI布局啦!
第二步先创建一个lineChart.xml的布局文件
具体代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<com.github.mikephil.charting.charts.LineChart
android:id="@+id/linechart_with"
android:layout_width="match_parent"
android:layout_height="400dp"/>
</LinearLayout>
是不是十分简单
我们就只需要对这一个控件进行操作,我的理解就是这个控件就是一张画布,可以对画布进行自由发挥
但是也有一定的约束,要发挥它的作用 实现图表库的作用实现数据可视化,方便用户直观的获取数据。
第三步 创建一个LineChartActivity.java文件
public class LineChartActiviy extends AppCompatActivity {
public LineChart lineChart;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.linechartdemo);
lineChart = (LineChart)findViewById(R.id.linechart_with);
}
}
初始化代码
初始化一个LineChart对象
找到布局文件,找到对应的id,就可以很快乐的对他进行操作啦!
第四步我们来思考一下一个折线图有啥 ? 数据 ,折线,座标轴,描述差不过了我们先说单条折线。
第五步我们存数据
数据我们用List来存储折线图的数据
我们来说一下这个折线图的数据 Entry类型的 作用就是来存储折线图数据
public Entry(float x, float y) {
super(y);
this.x = x;
}
第一个参数 float x,是折线图中数据值的位置索引
第二个参数float y,是具体数据值
我们主要传入数据的用法
创建一个List<Entry> mList = new ArrayList<>();存储数据
有存数据的容器了就得把数据存进去
数据来源可以自己写,网络请求获取,json文件解析数据等等。
一般来说初学者的话就是两种手写代码,或者使用Random函数自动生成
各有各的好处,手写代码就是很直观 ,每次的图都一样,用于测试展示都ok,
Random生成的数据每次都不一样,出来的图也不一样,可以用来动态生成数据。如果需要特别一定范围内的数据,一点更给生成的范围
一般来说,初学者就用手写的就练习
private float[] lineFloat = {1,2,3,4,5,6,2,2};
随机给都是可以的
mList.add(new Entry(1f,lineFloat[1]));
创建新的Entry对象接收两个float类型的参数,添加到List中
如果一条数据一条数据的写真的很麻烦,但是我们可以使用for循环来简化这个过程
for(int i,i<lineFloat.length,i++){
mList.add(new Entry(i,lineFloat[i]));
}
数据存到列表中了
第六步设置这条折线
初始化这条折线 这条折线是一个LineDataSet对象
看源码
private List<Integer> mCircleColors = null;
public LineDataSet(List<Entry> yVals, String label) {
super(yVals, label);
// mCircleRadius = Utils.convertDpToPixel(4f);
// mLineWidth = Utils.convertDpToPixel(1f);
if (mCircleColors == null) {
mCircleColors = new ArrayList<Integer>();
}
mCircleColors.clear();
// default colors
// mColors.add(Color.rgb(192, 255, 140));
// mColors.add(Color.rgb(255, 247, 140));
mCircleColors.add(Color.rgb(140, 234, 255));
}
先看我们需要传入两个参数 一个列表,一个String 的Label,
列表我们已经创建好了,就是mList,
Label我们可以理解为这条折线的名字
再看定义的一个List<Integer> 对象的mCircleColors
就是给了每个数据点的的颜色,默认的一个颜色
LineDataSet set = new LineDataSet(mList,"等级分布");//初始化这条折线
设置折线的宽度,颜色,是否有圆心,很多很多,就举例代码样式
set.setLineWidth(3f);//折线的宽度
set.setCircleRadius(3.5f);//数据点的半径
set.setMode();//折线的样式 默认为折线,曲线也则改为LineDataSet.Mode.CUBIC_BEZIER
set.setCircleColor(Color.RED);//数据点的颜色
set.setDrawFilled(false);//是否对数据点圆心进行填充
set.setDrawCircleHole(false);//是否数据点圆是否为空心圆
set.setColor(Color.RED);//设置折线颜色
set.setValueTextSize(10f);//设置显示数据的值
用到的都在这里啦!其他的可以自己去拓展
第七步管理数据集
初始化一个LineData对象,
LineData data = new LineData(set);
然后我们呢看源码
public class LineData extends BarLineScatterCandleBubbleData<ILineDataSet> {
public LineData() {
super();
}
public LineData(ILineDataSet... dataSets) {
super(dataSets);
}
public LineData(List<ILineDataSet> dataSets) {
super(dataSets);
}
}
就这么一点没得看哦!
但是都是精华哦!
首先我们看有三个构造方法分别传无参构造,ILineDataSet对象和List<ILineDataSet>
很显然就是把我们设置好的LineDataSet对象给传进去,但是List<ILineDataSet>
说明了折线图不止一条数据线,所以我们可以再创建数据折线线都当作参数给LineDataSet,以实现折线图中的多条数据
接着我们开始设置这个LineData对象
data.setDrawValues(false);//折线上是否绘制数据
data.setValueTextColor(Color.RED);//数据的字体颜色
data.setValueTextSize(15f);//数据的字体大小
我们初级一般用到的就这三个就够了
其实我们不去设置默认都ok,有需要的再去设置自己需要的效果
第八步 XY轴
一个坐标轴可是图表的框架
但是这个框架根据需求,美观性可以选择性的调用和设置
我们知道一般是两个轴X轴和Y轴
但是再MPAndroidChart中可不止,Y轴就有两个
在左边的Y轴我们给他起名(leftYAxis),右边的就是(rightYAxis)
X轴就一个但是位置可以设置 ,上下都可以
定义
XAxis xAxis = lineChart.getXAxis();//初始化X轴
YAxis leftyAxis =lineChart.getAxisLeft();//初始化左边Y轴
YAxis rightyAxis = lineChart.getAxisRight();//初始化右边Y轴
xAxis.setEnabled(true);//是否调用x轴
xAxis.setPosition(XAxis.XAxisPosition.TOP);//设置X轴的位置
xAxis.setLabelCount(5);//设置x轴标签的数目
xAxis.setTextSize(20f);//设置标签的字体大小
xAxis.setTextColor(Color.BLUE);//设置标签字体的颜色
xAxis.setDrawAxisLine(false);//是否绘制x轴的直线
xAxis.setDrawGridLines(false);//是否画网格线
xAxis.setLabelCount(7);//设置X轴的标签数量
//xAxis.setAxisMaximum(10f);//设置X轴标签最大值
//xAxis.setAxisMinimum(0f);//设置X轴标签最小值
XY轴设置都是互通的,当然方法也不止折线,目前用到的就是这些,
重点来了
自定义坐标轴标签
为什么要自定义坐标轴标签?
目的是为了满足需求,默认的是0,1,2...
很low
我们定义为星期吧七天
public static final String[] week = {"周一","周二","周三","周五","周六","周日"};
7个标签
怎么操作呢??
有个方法自定义X轴的标签显示
xAxis.setValueFormatter(valueFormatter);
看源码
public void setValueFormatter(ValueFormatter f) {
if (f == null)
mAxisValueFormatter = new DefaultAxisValueFormatter(mDecimals);
else
mAxisValueFormatter = f;
}
简单说就是你给的参数是ValueFormatter类型的,为null的时候就给你新建一个自带的,
不为null就是传的参数
那我们就创建这个CalueFormatter类型
ValueFormatter valueFormatter = new ValueFormatter() {
@Override
public String getFormattedValue(float value) {
return ""+week[(int)value];
}
};
根据参数value来取出List中对应的数据
value一定要强转成(int)类型,我们取得是索引;
返回值是String,我们就用""+来实现String
到这里我们的任务只差最后一步
实现图表
lineChart.setData(data);//在UI中绘制图表
看源码
public void setData(T data) {
mData = data;
mOffsetsCalculated = false;
if (data == null) {
return;
}
}
就是绘制图表
如果传入的值为null就什么都没有
简简单单一行,却需要我们给他准备这么多,你的成功可能在旁人只能看到最后一步,可对你来说却大量的准备最后水到成水渠的成功。
第一次写博客,分享学习的坎坷。
最后附上源码(两条折线图和运行效果)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<com.github.mikephil.charting.charts.LineChart
android:id="@+id/linechart_with"
android:layout_width="match_parent"
android:layout_height="400dp"/>
</LinearLayout>
public class LineChartActiviy extends AppCompatActivity {
public LineChart lineChart;
public static int[] moreline = {22,24,25,25,25,22};
public static int[] lessline = {14,15,16,17,16,16};
public static final String[] week = {"昨天","今天","明天","周五","周六","周日"};
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.linechartdemo);
lineChart = (LineChart)findViewById(R.id.linechart_with);
setData(lineChart);
}
public static void setData(LineChart lineChart) {
List<Entry> list = new ArrayList<>();
List<Entry> list2 = new ArrayList<>();
for (int i = 0; i < moreline.length; i++) {
list.add(new Entry((float)i,moreline[i]));
list2.add(new Entry((float)i,lessline[i]));
}
LineDataSet set = new LineDataSet(list,"");
LineDataSet set2 = new LineDataSet(list2,"");
Description description = lineChart.getDescription();
description.setEnabled(false);
lineChart.setDescription(description);
set.setLineWidth(3f);
set.setCircleRadius(3.5f);
set.setMode(LineDataSet.Mode.CUBIC_BEZIER);
set.setCircleColor(Color.RED);
set.setDrawFilled(false);
set.setDrawCircleHole(false);
set.setColor(Color.RED);
set.setValueTextSize(10f);
//set2.setDrawCircleHole(true);
set2.setLineWidth(3f);
set2.setCircleRadius(3.5f);
set2.setMode(LineDataSet.Mode.CUBIC_BEZIER);
set2.setCircleColor(Color.BLUE);
set2.setDrawFilled(false);
set2.setDrawCircleHole(false);
set2.setColor(Color.BLUE);
set2.setValueTextSize(10f);
LineData data = new LineData(set,set2);
data.setDrawValues(false);
data.setValueTextColor(Color.RED);
data.setValueTextSize(15f);
XAxis xAxis = lineChart.getXAxis();
xAxis.setEnabled(true);
xAxis.setPosition(XAxis.XAxisPosition.TOP);
xAxis.setLabelCount(5);
xAxis.setTextSize(20f);
xAxis.setTextColor(Color.BLUE);
xAxis.setDrawAxisLine(false);
xAxis.setDrawGridLines(false);
xAxis.setAxisMaximum(10f);
xAxis.setAxisMinimum(0f);
xAxis.setLabelCount(7);
ValueFormatter valueFormatter = new ValueFormatter() {
@Override
public String getFormattedValue(float value) {
return ""+week[(int)value];
}
};
xAxis.setValueFormatter(valueFormatter);
YAxis leftyAxis =lineChart.getAxisLeft();
leftyAxis.setDrawAxisLine(false);
leftyAxis.setLabelCount(4);
leftyAxis.setDrawLabels(false);
YAxis rightyAxis = lineChart.getAxisRight();
rightyAxis.setEnabled(false);
lineChart.setData(data);
}
}