Android 折线图表MPAndroidChart的实现

作者: MiHomes | 来源:发表于2018-06-05 18:11 被阅读381次

    昨日夜观天象,今日忽见北斗星陨落,《Android 折线图表》应运而生。


    single.png
    many.png

    一.本篇采用MPAndroidChart,大体实现步骤可分为两步:

      1.配置基本属性(包括X,Y轴)
      2.设置折线数据并添加
    

    二.
    第一步,配置基本属性。

    1.依赖:

          当前工程Build.gradle里: implementation 'com.github.PhilJay:MPAndroidChart:v3.0.3'
          项目Build.gradle里:
    
                allprojects {
                      repositories {
                      maven { url "https://jitpack.io" }
                      }
                }
    

    2.配置图表控件的基本属性:

    /**
     * 设置Chart的一些基本配置
     */
    private void initChart() {
        //配置基本信息
        lineChart.getDescription().setEnabled(false);   //设置描述
        lineChart.setTouchEnabled(true);    //设置是否可以触摸
        lineChart.setDragDecelerationFrictionCoef(0.9f);    //设置滚动时的速度快慢
        lineChart.setDragEnabled(true);     // 是否可以拖拽
        lineChart.setScaleXEnabled(false);   //设置X轴是否能够放大
        lineChart.setScaleYEnabled(false);  //设置Y轴是否能够放大
        //lineChart.setScaleEnabled(true);    // 是否可以缩放 x和y轴, 默认是true
        lineChart.setDrawGridBackground(false);//设置图表内格子背景是否显示,默认是false
        lineChart.setHighlightPerDragEnabled(true);//能否拖拽高亮线(数据点与坐标的提示线),默认是true
        lineChart.setBackgroundColor(Color.WHITE);  //设置背景颜色
    
        //配置X轴属性
        xAxis = lineChart.getXAxis();
    
        //xAxis.setLabelRotationAngle(25f);  //设置旋转偏移量
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);  //设置X轴的位置
        //设置标签文本格式
        xAxis.setTextSize(10f);
        //设置标签文本颜色
        xAxis.setTextColor(Color.rgb(255, 192, 56));
        //是否绘制轴线
        xAxis.setDrawAxisLine(true);
        //是否绘制网格线
        xAxis.setDrawGridLines(false);
        //设置是否一个格子显示一条数据,如果不设置这个属性,就会导致X轴数据重复并且错乱的问题
        xAxis.setGranularity(1f);
    
        //配置Y轴信息
        leftAxis = lineChart.getAxisLeft();
        leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);   //设置Y轴的位置
        leftAxis.setDrawGridLines(true);    //设置左边的网格线显示
        leftAxis.setGranularityEnabled(false);//启用在放大时限制y轴间隔的粒度特性。默认值:false。
        leftAxis.setTextColor(Color.rgb(255, 192, 56)); //设置Y轴文字颜色
    
        YAxis rightAxis = lineChart.getAxisRight(); //获取右边的Y轴
        rightAxis.setEnabled(false);   //设置右边的Y轴不显示
    
        //设置图例(也就是曲线的标签)
        Legend legend = lineChart.getLegend();//设置比例图
        legend.setEnabled(false);   //因为自带的图例太丑,而且操作也不方便,楼主选择自定义,设置不显示比例图
    }
    

    第二步,设置折线数据。

    首先,自定义我们的X轴适配器:

    public class MyXFormatter  implements IAxisValueFormatter {
    
    private List<String> list;
    
    public MyXFormatter(List<String> values) {
        this.list = values;
    }
    
    private static final String TAG = "MyXFormatter";
    
    @Override
    public String getFormattedValue(float value, AxisBase axis) {
        // "value" represents the position of the label on the axis (x or y)
        Log.d(TAG, "----->getFormattedValue: " + value) ;
        if (value<list.size()){
            return list.get((int) (value));
        }else {
            return null;
        }
      }
    }
    

    然后,设置折线数据。单条折线的数据方法设置如下:

    /**
     * 设置单条折线的数据
     * count 单条折线的数据量
     */
    private void setSingleDatas(int count) {
        //设置单条折线的X轴数据
        singleNameList = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            int j = i+1;
            singleNameList.add(j + "月");
        }
        //将X轴数据传入自定义的X轴ValueFormatter
        MyXFormatter formatter = new MyXFormatter(singleNameList);
        xAxis.setValueFormatter(formatter);
    
        //设置单条折现的Y轴数据
        ArrayList<Entry> yList = new ArrayList<Entry>();
        for (int i = 0; i < count; i++) {
           float value = (float) (Math.random()*100);
           yList.add(new Entry(i,value));
        }
    
        LineDataSet lineDataSet = new LineDataSet(yList, "单条折线");   //设置单条折线
        ArrayList<ILineDataSet> dataSets = new ArrayList<>();
        //设置折线的属性
        lineDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);   //设置左右两边Y轴节点描述
        lineDataSet.setValueTextColor(ColorTemplate.getHoloBlue()); //设置节点文字颜色
        lineDataSet.setDrawCircles(false);  //设置是否显示节点的小圆点
        lineDataSet.setDrawValues(false);       //设置是否显示节点的值
        lineDataSet.setHighLightColor(Color.rgb(244, 117, 117));//当点击节点时,将会出现与节点水平和垂直的两条线,可以对其进行定制.此方法为设置线条颜色
        lineDataSet.setHighlightEnabled(true);//设置是否显示十字线
        lineDataSet.setColor(Color.BLUE);    //设置线条颜色
        lineDataSet.setCircleColor(Color.WHITE);  //设置节点的圆圈颜色
        lineDataSet.setLineWidth(1f);   //设置线条宽度
        lineDataSet.setCircleRadius(4f);//设置每个坐标点的圆大小
        lineDataSet.setDrawCircleHole(false);//是否定制节点圆心的颜色,若为false,则节点为单一的同色点,若为true则可以设置节点圆心的颜色
        lineDataSet.setValueTextSize(9f);   //设置 DataSets 数据对象包含的数据的值文本的大小(单位是dp)。
        //设置折线图填充
        lineDataSet.setDrawFilled(false);    //Fill填充,可以将折线图以下部分用颜色填满
        lineDataSet.setFillAlpha(65);       ////设置填充区域透明度,默认值为85
        lineDataSet.setFillColor(ColorTemplate.getHoloBlue());//设置填充颜色
        lineDataSet.setFormLineWidth(1f);
        lineDataSet.setFormSize(15.f);
    
        dataSets.add(lineDataSet);
    
        LineData data = new LineData(dataSets);
        lineChart.setData(data);    //添加数据
    }
    

    多条折线的数据设置方法如下:

    /**
     * 设置多条折线的数据
     * @param chartData //线条x轴的个数
     * @param count     //线条的个数
     */
    private void setManyDatas(int chartData, int count) {
        singleNameList = new ArrayList<>();
        for (int i = 0; i < chartData; i++) {
            int j = i+1;
            singleNameList.add(j + "月");
        }
        MyXFormatter formatter = new MyXFormatter(singleNameList);
        xAxis.setValueFormatter(formatter);
    
        initChartColors();  //设置线条颜色集合
        initChartNames(count);   //设置不同线条名字的集合
        ArrayList<ILineDataSet> dataSets = new ArrayList<>();   //线条数据集合
    
        for (int i = 0; i < count; i++) {
            //设置单条折现的Y轴数据
            ArrayList<Entry> yList = new ArrayList<Entry>();
            for (int j = 0; j < chartData; j++) {
                float value = (float) (Math.random()*100);
                yList.add(new Entry(j,value));
            }
    
            LineDataSet lineDataSet = new LineDataSet(yList, nameList.get(i));   //设置单条折线
            //设置折线的属性
            lineDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);   //设置左右两边Y轴节点描述
            lineDataSet.setValueTextColor(ColorTemplate.getHoloBlue()); //设置节点文字颜色
            lineDataSet.setDrawCircles(false);  //设置是否显示节点的小圆点
            lineDataSet.setDrawValues(false);       //设置是否显示节点的值
            lineDataSet.setHighLightColor(Color.rgb(244, 117, 117));//当点击节点时,将会出现与节点水平和垂直的两条线,可以对其进行定制.此方法为设置线条颜色
            lineDataSet.setHighlightEnabled(true);//设置是否显示十字线
            lineDataSet.setColor(colours.get(i));    //设置线条颜色
            lineDataSet.setCircleColor(Color.WHITE);  //设置节点的圆圈颜色
            lineDataSet.setLineWidth(1f);   //设置线条宽度
            lineDataSet.setCircleRadius(4f);//设置每个坐标点的圆大小
            lineDataSet.setDrawCircleHole(false);//是否定制节点圆心的颜色,若为false,则节点为单一的同色点,若为true则可以设置节点圆心的颜色
            lineDataSet.setValueTextSize(9f);   //设置 DataSets 数据对象包含的数据的值文本的大小(单位是dp)。
            //设置折线图填充
            lineDataSet.setDrawFilled(false);    //Fill填充,可以将折线图以下部分用颜色填满
            lineDataSet.setFillAlpha(65);       ////设置填充区域透明度,默认值为85
            lineDataSet.setFillColor(ColorTemplate.getHoloBlue());//设置填充颜色
            lineDataSet.setFormLineWidth(1f);
            lineDataSet.setFormSize(15.f);
            dataSets.add(lineDataSet);
        }
        LineData data = new LineData(dataSets);
        lineChart.setData(data);    //添加数据
    
    }
    
      /**
     * 设置线条名字集合
     * @param count
     */
    private void initChartNames(int count) {
        nameList = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            int j = i+1;
            String name = "线条" + j;
            nameList.add(name);
        }
    }
    
    /**
     * 提前设置颜色集合
     */
    private void initChartColors() {
        //颜色集合
        colours = new ArrayList<>();
        colours.add(Color.GREEN);
        colours.add(Color.BLUE);
        colours.add(Color.RED);
        colours.add(Color.CYAN);
        colours.add(Color.BLACK);
        colours.add(Color.GRAY);
    }
    

    由上代码,相信看官老爷们不难看出,单条折线和多条折线的实现思路其实有异曲同工之妙。都是创建了一个ArrayList<ILineDataSet>集合,添加LineDataSet 对象并设置属性。最后将此集合通过LineData的构造方法,调用图表对象的.setData()方法进行添加的。

    补充:

    图例,也就是这玩意


    image.png

    最好自己定义,写个GirdView就可以了。还能自动换行,美滋滋。官方的不多说,丑而且自动换行有问题。

    三.踩坑之处:

    1.自定义X轴数据。
    这里有一个不得不说的要点,我们在自定义X轴数据,创建自己的IAxisValueFormatter实现类时,一定要注意提前设置 X轴的这个属性:

    //设置是否一个格子显示一条数据
    xAxis.setGranularity(1f);
    

    如果不设置这个属性,就会导致X轴数据重复并且错乱,原因是IAxisValueFormatter实现类的的方法getFormattedValue(float value, AxisBase axis)中的value返回错乱。

    2.数据刷新。

    如果你实现了自己的图表控件,并且有多种类型的数据需要重复设置,需要刷新图表控件时,若有X轴经常显示错乱的问题,不妨多调用一次lineChart.setData(data);方法。

    四.到此,就已经实现了折线图表的功能。随手分享,喜欢的朋友可以关注微信公众号MiHomes,后续会有更多更好的博客推送给您。


    MiHomes.png

    另:欢迎指出不足,会进行更正

    相关文章

      网友评论

      • Paraselenes:大佬,我自定义的X轴,当我折线图中只有一条数据的时候,X轴会有三条数据,y轴的数据居中显示,方便加个企鹅么3138856661
        MiHomes:已加
      • 小黑同学:点个赞,注释了很多属性,不错。

      本文标题:Android 折线图表MPAndroidChart的实现

      本文链接:https://www.haomeiwen.com/subject/jprmsftx.html