MPAndroidChart 图表库之快速上手BarChart(柱状图)

6,754 阅读3分钟

前一篇写了LineChart(折线图),实现了简单的平滑曲线加填充的折线图效果,现在再来记录一下怎么一步一步实现上图的堆叠柱状图的效果。

添加MPAndroidChart依赖,build.gradle(Project):

allprojects {
    repositories {
        google()
        jcenter()
        maven { url 'https://jitpack.io' }
    }
}

build.gradle(Module)下添加dependencies:

implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'

柱状图的基本创建其实与折线图差不多,BarEntry(数据类)、BarChart(柱状图本身)、BarDataSet(数据集)、BarDate(所有数据对象),其他诸如图例、描述、X、Y轴与折线图一致。

先来写一个最简单的例子看看效果:

        //设置无数据提示
        barChart.setNoDataTextColor(Color.parseColor("#003B4C"));
        barChart.setNoDataText("暂无周睡眠数据~");
        //添加数据
        List<BarEntry> entries = new ArrayList<>();
        entries.add(new BarEntry(0,2f));
        entries.add(new BarEntry(1,1.5f));
        entries.add(new BarEntry(2,3f));
        entries.add(new BarEntry(3,1f));
        entries.add(new BarEntry(4,0.8f));
        entries.add(new BarEntry(5,1.2f));
        entries.add(new BarEntry(6,2.2f));
        //数据添加到数据集
        BarDataSet dataSet = new BarDataSet(entries,"");
        //柱体颜色
        dataSet.setColor(Color.parseColor("#FF6363"));
        //不显示数值
        dataSet.setDrawValues(false);
        //数据集赋值给数据对象
        BarData data = new BarData(dataSet);
        barChart.setData(data);

最简单的效果就是这样,并不好看,对比上面效果我们需要去掉网格保留X轴和左边Y轴,以及柱体宽度太宽了,减小一点,修改X轴标签,去掉左边Y轴的标签。那么增加下面代码看看。

        //隐藏图例
        barChart.getLegend().setEnabled(false);
        //取消缩放、点击、高亮效果
        barChart.setScaleEnabled(false);
        barChart.setClickable(false);
        barChart.setHighlightPerDragEnabled(false);
        barChart.setHighlightPerTapEnabled(false);
        //设置描述位置
        Description description = barChart.getDescription();
        description.setText("小时");
        description.setPosition(60,20);
        description.setYOffset(20);
        barChart.setDescription(description);
        //获取X轴
        XAxis xAxis = barChart.getXAxis();
        //设置X轴在下方(默认X轴在上方)
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        //给X轴添加标签
        xAxis.setValueFormatter(new IndexAxisValueFormatter(new String[]{"一","二","三","四","五","六","七"}));
        //取消X轴网格线
        xAxis.setDrawGridLines(false);
        //获取左边Y轴
        YAxis leftYAxis = barChart.getAxisLeft();
        //取消Y轴网格线
        leftYAxis.setDrawGridLines(false);
        //不显示左边Y轴的标签
        leftYAxis.setDrawLabels(false);
        //获取右边Y轴
        YAxis rightYAxis = barChart.getAxisRight();
        //隐藏右边Y轴
        rightYAxis.setEnabled(false);
        //设置柱体宽带
        data.setBarWidth(0.3f);

效果接近了,那么怎么变成堆叠柱形图呢,其实就是构建BarEntry对象时里面传float数组就行了,例如:BarEntry(0,new float[]{1,4,1}),修改代码如下:

        //数据赋值
        List<BarEntry> entries = new ArrayList<>();
        entries.add(new BarEntry(0,new float[]{1,4,1}));
        entries.add(new BarEntry(1,new float[]{1,3,2}));
        entries.add(new BarEntry(2,new float[]{0.5f,5,0.5f}));
        entries.add(new BarEntry(3,new float[]{2,3,1}));
        entries.add(new BarEntry(4,new float[]{1,2,3}));
        entries.add(new BarEntry(5,new float[]{0.8f,3,1}));
        entries.add(new BarEntry(6,new float[]{2,2,2}));
        //这里一个柱体有三个堆,每个堆设置一个颜色进行区分
        List<Integer> colors = new ArrayList<>();
        colors.add(Color.parseColor("#FFA2A2"));
        colors.add(Color.parseColor("#FF8686"));
        colors.add(Color.parseColor("#FF6363"));
        设置堆颜色
        dataSet.setColors(colors);

那么怎么显示两组呢,其实再添加一组数据就行了

        //第一组数据
        List<BarEntry> entriesL = new ArrayList<>();
        entriesL.add(new BarEntry(0,new float[]{1,2,1}));
        entriesL.add(new BarEntry(1,new float[]{2,1,1}));
        entriesL.add(new BarEntry(2,new float[]{1,1,2}));
        entriesL.add(new BarEntry(3,new float[]{2,2,2}));
        entriesL.add(new BarEntry(4,new float[]{3,1,2}));
        entriesL.add(new BarEntry(5,new float[]{2,3,1}));
        entriesL.add(new BarEntry(6,new float[]{2,1,3}));
        //将第一组数据添加给数据集
        BarDataSet dataSetL = new BarDataSet(entriesL,"睡眠周报左");
        dataSetL.setDrawValues(false);
        //堆叠颜色设置
        List<Integer> colorsL = new ArrayList<>();
        colorsL.add(Color.parseColor("#FFA2A2"));
        colorsL.add(Color.parseColor("#FF8686"));
        colorsL.add(Color.parseColor("#FF6363"));
        dataSetL.setColors(colorsL);
        //第二组数据
        List<BarEntry> entriesR = new ArrayList<>();
        entriesR.add(new BarEntry(0,new float[]{2,1,1}));
        entriesR.add(new BarEntry(1,new float[]{1,1,2}));
        entriesR.add(new BarEntry(2,new float[]{1,2,1}));
        entriesR.add(new BarEntry(3,new float[]{3,1,2}));
        entriesR.add(new BarEntry(4,new float[]{2,2,2}));
        entriesR.add(new BarEntry(5,new float[]{2,1,3}));
        entriesR.add(new BarEntry(6,new float[]{2,3,1}));
         //将第二组数据添加给数据集
        BarDataSet dataSetR = new BarDataSet(entriesR,"睡眠周报右");
        dataSetR.setDrawValues(false);
        //设置颜色
        List<Integer> colorsR = new ArrayList<>();
        colorsR.add(Color.parseColor("#B4EFFF"));
        colorsR.add(Color.parseColor("#3FD6FF"));
        colorsR.add(Color.parseColor("#00BCEF"));
        dataSetR.setColors(colorsR);
        //设置X轴的最大最小值,不然柱体显示不完全
        xAxis.setAxisMinimum(0);
        xAxis.setAxisMaximum(7);
        //设置X轴标签居中显示,不然标签与柱状图不居中对应
        xAxis.setCenterAxisLabels(true);
        //将两个数据集都赋值给BarData
        BarData data = new BarData(dataSetL,dataSetR);
        //最后千万别忘了这一句,设置多组
        barChart.groupBars(0,0.4f,0);

借用一张图说明一下groupBars(float fromX, float groupSpace, float barSpace)里面各参数的意思
并且各参数的值设置应该符合公式:( barSpace + barWidth ) * 2 + groupSpace = 1.00

结语

分组加堆叠的大致写法就是这样,如果有其它需求比如自定义X轴、Y轴标签在下一篇ScatterChart(散点图)会涉及到这部分的简单用法。