安卓图形之MPAndroidChart3.0详解三——柱状图(二)(案例篇)

1 前言

本篇文章主要描述MPAndroidChart中柱状图的一些例子,如堆叠图,重叠图,多柱图,正负柱图,这里不介绍BarChart的基本属性,因为在上一部分已经讲解,在上一篇文章基本都全部有介绍,有属性不了解的读者建议转到:安卓图形之MPAndroidChart3.0详解三——柱状图(一)(属性篇)

2 Demo
2.1 堆叠图

效果图如下:
在这里插入图片描述
完整代码如下:

xml代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.github.mikephil.charting.charts.BarChart
        android:id="@+id/bc"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

Java代码:

public class BarTest extends Fragment {

    private BarChart bc;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.bar_frag,null);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        bc = view.findViewById(R.id.bc);

        setDesc();

        setLegend();

        setXAxis();

        setYAxis();

        loadData();

    }

    //设置Title
    private void setDesc() {
        Description description = bc.getDescription();

		// 获取屏幕中间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,50);
        description.setText("年龄群体车辆违章的占比统计");
        description.setTextSize(16f);
        description.setTextColor(Color.BLACK);
        bc.setDescription(description);
    }

    //设置图例
    private void setLegend() {
        Legend legend = bc.getLegend();
        legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
        legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
        legend.setDrawInside(true);
        legend.setTextSize(14f);
        legend.setTypeface(Typeface.DEFAULT_BOLD);
        legend.setXOffset(30);
        legend.setOrientation(Legend.LegendOrientation.VERTICAL);
        legend.setTypeface(Typeface.DEFAULT_BOLD);
    }

    //设置Y轴
    private void setYAxis() {
        bc.getAxisRight().setEnabled(false);
        YAxis yAxis = bc.getAxisLeft();
        yAxis.setTextSize(14f);
        yAxis.setTextColor(Color.BLACK);
        yAxis.setXOffset(15);
        yAxis.setAxisMaximum(1200);
        yAxis.setAxisMinimum(0);
        yAxis.setGranularity(200f);
        yAxis.setLabelCount(7);
    }

    //设置X轴
    private void setXAxis() {
        XAxis xAxis = bc.getXAxis();
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setTextSize(16f);
        xAxis.setTypeface(Typeface.DEFAULT_BOLD);
        xAxis.setDrawGridLines(false);
        xAxis.setLabelCount(5);
        xAxis.setAxisMaximum(4.3f);
        xAxis.setAxisMinimum(-0.3f);
        xAxis.setGranularity(1f);
        //自定义格式
        xAxis.setValueFormatter(new IAxisValueFormatter() {
            @Override
            public String getFormattedValue(float value, AxisBase axis) {
                int tep = (int) (9 - value);
                return tep + "0后";
            }
        });
    }

    //设置数据
    private void loadData() {
        bc.setExtraOffsets(30,70,30,50);
        bc.setTouchEnabled(false);
        bc.animateXY(1000,1000);

        final float d_1[] = {230f, 480f, 480f, 480f,170f};
        final float d_2[] = { 120f,600f, 400f, 200f,80f};
        List<BarEntry> entries = new ArrayList<BarEntry>();

        for(int i = 0; i < d_1.length; i++){
            //使用BarEntry的构造方法的第三个参数来保存需要在柱块上显示的数据
            entries.add(new BarEntry(i,new float[]{d_1[i],d_2[i]},(d_2[i] / (d_1[i] + d_2[i])) * 100));
        }

        BarDataSet barDataSet = new BarDataSet(entries,"");
        barDataSet.setColors(Color.parseColor("#6D9C00"),Color.parseColor("#F07408"));
        barDataSet.setStackLabels(new String[]{"无违章","有违章"});
        barDataSet.setValueTextColor(Color.RED);

        BarData barData = new BarData(barDataSet);

        barData.setBarWidth(0.3f);
        //自定义格式
        barData.setValueFormatter(new IValueFormatter() {
            private int isY = -1;//用于判断是有违章还是无违章的柱块
            @Override
            public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
                isY ++;
                if(isY %2 ==0){//无违章,则不显示文本
                    return "";
                }else{//有违章,显示在entry中保存的数据
                    float res = (float) entry.getData();
                    return String.format("%.1f",res) + "%";
                }
            }
        });

        bc.setData(barData);

    }
}

2.2 重叠图

重叠图与堆叠图的区别:
堆叠图是在一个柱块的基础上绘制下一个柱块,即在头上绘制
重叠图是两个柱块重叠在一个,都是在同一起点绘制的,后绘制的会覆盖先绘制的
效果图:
在这里插入图片描述
完整代码如下(xml代码不变):

public class BarTest_1 extends Fragment {

    private BarChart bc;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.bar_frag,null);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        bc = view.findViewById(R.id.bc);

        setDesc();
        setLegend();
        setXAxis();
        setYAxis();
        loadData();
    }

    //设置Title
    private void setDesc() {
        Description description = bc.getDescription();

		// 获取屏幕中间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,50);
        description.setText("年龄群体车辆违章的占比统计");
        description.setTextSize(16f);
        description.setTextColor(Color.BLACK);
        bc.setDescription(description);
    }

    //设置图例
    private void setLegend() {
        Legend legend = bc.getLegend();
        legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
        legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
        legend.setDrawInside(true);
        legend.setTextSize(14f);
        legend.setTypeface(Typeface.DEFAULT_BOLD);
        legend.setXOffset(30);
        legend.setOrientation(Legend.LegendOrientation.VERTICAL);
        legend.setTypeface(Typeface.DEFAULT_BOLD);
    }

    //设置Y轴
    private void setYAxis() {
        bc.getAxisRight().setEnabled(false);
        YAxis yAxis = bc.getAxisLeft();
        yAxis.setTextSize(14f);
        yAxis.setTextColor(Color.BLACK);
        yAxis.setXOffset(15);
        yAxis.setAxisMaximum(1200);
        yAxis.setAxisMinimum(0);
        yAxis.setGranularity(200f);
        yAxis.setLabelCount(7);
    }

    //设置X轴
    private void setXAxis() {
        XAxis xAxis = bc.getXAxis();
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setTextSize(16f);
        xAxis.setTypeface(Typeface.DEFAULT_BOLD);
        xAxis.setDrawGridLines(false);
        xAxis.setLabelCount(5);
        xAxis.setAxisMaximum(4.3f);
        xAxis.setAxisMinimum(-0.3f);
        xAxis.setGranularity(1f);
        //自定义格式
        xAxis.setValueFormatter(new IAxisValueFormatter() {
            @Override
            public String getFormattedValue(float value, AxisBase axis) {
                int tep = (int) (9 - value);
                return tep + "0后";
            }
        });
    }

    //设置数据
    private void loadData() {
        bc.setExtraOffsets(30,70,30,50);
        bc.animateXY(1000,1000);

        final float d_1[] = {230f, 480f, 480f, 480f,170f};
        final float d_2[] = { 120f,600f, 400f, 200f,80f};
        List<BarEntry> entries = new ArrayList<BarEntry>();
        List<BarEntry> entries1 = new ArrayList<BarEntry>();

        for(int i = 0; i < d_1.length; i++){
            entries.add(new BarEntry(i,d_1[i]));
            //使用BarEntry的构造方法的第三个参数来保存需要在柱块上显示的数据
            entries1.add(new BarEntry(i,d_2[i] + d_1[i],(d_2[i] / (d_1[i] + d_2[i])) * 100));
        }

        BarDataSet barDataSet = new BarDataSet(entries,"无违章");
        BarDataSet barDataSet1 = new BarDataSet(entries1,"有违章");

        barDataSet.setColor(Color.parseColor("#6D9C00"));
        barDataSet.setDrawValues(false);//不绘制文本

        barDataSet1.setColor(Color.parseColor("#F07408"));
        barDataSet1.setValueTextColor(Color.RED);
        barDataSet1.setValueFormatter(new IValueFormatter() {
            @Override
            public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
                //获取entry中的数据
                float res = (float) entry.getData();
                return String.format("%.1f",res) + "%";
            }
        });

        BarData barData = new BarData(barDataSet1,barDataSet);
        barData.setBarWidth(0.3f);//设置柱块的宽度

        bc.setData(barData);

    }
}

2.3 多柱图

多柱图主要通过barChart的属性groupBars设置,使用方法见代码
在这里插入图片描述
完整代码如下(xml代码不变):

public class BarTest_2 extends Fragment {

    private BarChart bc;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.bar_frag,null);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        bc = view.findViewById(R.id.bc);

        setDesc();
        setLegend();
        setXAxis();
        setYAxis();
        loadData();
    }

    //设置Title
    private void setDesc() {
        Description description = bc.getDescription();

		// 获取屏幕中间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,50);
        description.setText("年龄群体车辆违章的占比统计");
        description.setTextSize(16f);
        description.setTextColor(Color.BLACK);
        bc.setDescription(description);
    }

    //设置图例
    private void setLegend() {
        Legend legend = bc.getLegend();
        legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
        legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
        legend.setDrawInside(true);
        legend.setTextSize(14f);
        legend.setTypeface(Typeface.DEFAULT_BOLD);
        legend.setXOffset(30);
        legend.setOrientation(Legend.LegendOrientation.VERTICAL);
        legend.setTypeface(Typeface.DEFAULT_BOLD);
    }

    //设置Y轴
    private void setYAxis() {
        bc.getAxisRight().setEnabled(false);
        YAxis yAxis = bc.getAxisLeft();
        yAxis.setTextSize(14f);
        yAxis.setTextColor(Color.BLACK);
        yAxis.setXOffset(15);
        yAxis.setAxisMaximum(800);
        yAxis.setAxisMinimum(0);
        yAxis.setGranularity(200f);
        yAxis.setLabelCount(7);
    }

    //设置X轴
    private void setXAxis() {
        XAxis xAxis = bc.getXAxis();
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setTextSize(16f);
        xAxis.setTypeface(Typeface.DEFAULT_BOLD);
        xAxis.setDrawGridLines(false);
        xAxis.setLabelCount(5);
        xAxis.setAxisMaximum(4.3f);
        xAxis.setAxisMinimum(-0.3f);
        xAxis.setGranularity(1f);
        //自定义格式
        xAxis.setValueFormatter(new IAxisValueFormatter() {
            @Override
            public String getFormattedValue(float value, AxisBase axis) {
                int tep = (int) (9 - value);
                return tep + "0后";
            }
        });
    }

    //设置数据
    private void loadData() {
        bc.setExtraOffsets(30,70,30,50);
        bc.animateXY(1000,1000);
        bc.setFitBars(true);
        final float d_1[] = {230f, 480f, 480f, 480f,170f};
        final float d_2[] = { 120f,600f, 400f, 200f,80f};
        List<BarEntry> entries = new ArrayList<BarEntry>();
        List<BarEntry> entries1 = new ArrayList<BarEntry>();

        for(int i = 0; i < d_1.length; i++){
            //使用BarEntry的构造方法的第三个参数来保存需要在柱块上显示的数据
            entries.add(new BarEntry(i,d_1[i],(d_1[i] / (d_1[i] + d_2[i])) * 100));
            entries1.add(new BarEntry(i,d_2[i],(d_2[i] / (d_1[i] + d_2[i])) * 100));
        }

        BarDataSet barDataSet = new BarDataSet(entries,"无违章");
        BarDataSet barDataSet1 = new BarDataSet(entries1,"有违章");

        barDataSet.setColor(Color.parseColor("#6D9C00"));
        barDataSet.setValueFormatter(new IValueFormatter() {
            @Override
            public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
                //获取entry中的数据
                float res = (float) entry.getData();
                return String.format("%.1f",res) + "%";
            }
        });


        barDataSet1.setColor(Color.parseColor("#F07408"));
        barDataSet1.setValueTextColor(Color.RED);
        barDataSet1.setValueFormatter(new IValueFormatter() {
            @Override
            public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
                //获取entry中的数据
                float res = (float) entry.getData();
                return String.format("%.1f",res) + "%";
            }
        });

       List<IBarDataSet> barDataSets = new ArrayList<IBarDataSet>();
       barDataSets.add(barDataSet);
       barDataSets.add(barDataSet1);

        BarData barData = new BarData(barDataSets);
        barData.setBarWidth(0.3f);//设置柱块的宽度
        //参数1:距左边的距离(开始会偏移一个组的距离)
        //参数二:组与组之间的间距
        //参数三:一组柱块之中每个之间的距离
        barData.groupBars(-0.35f,0.35f,0);

        bc.setData(barData);
    }

}

2.4 正负柱图

正负柱图其实实现起来非常简单,只要你的数据是负的,它就是向下面的,不过得你设置Y轴的最小值必须为负数,不然是看不到i下面的柱块的。
注意添加数据的方式为:entries.add(new BarEntry(i,new float[]{ 数据1 , 数据2 })),如果使用两个BarDataSet,然后把两个BarDataSet给BarData的话,出现的效果是两个BarDataSet中的数据相减后出现的柱块

效果图:
在这里插入图片描述
完整代码如下(xml代码不变):

public class BarTest_3 extends Fragment {

    private BarChart bc;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.bar_frag,null);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        bc = view.findViewById(R.id.bc);

        setDesc();
        setLegend();
        setXAxis();
        setYAxis();
        loadData();
    }

    //设置Title
    private void setDesc() {
        Description description = bc.getDescription();

		// 获取屏幕中间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,50);
        description.setText("年龄群体车辆违章的占比统计");
        description.setTextSize(16f);
        description.setTextColor(Color.BLACK);
        bc.setDescription(description);
    }

    //设置图例
    private void setLegend() {
        Legend legend = bc.getLegend();
        legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
        legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
        legend.setDrawInside(true);
        legend.setTextSize(14f);
        legend.setTypeface(Typeface.DEFAULT_BOLD);
        legend.setXOffset(30);
        legend.setOrientation(Legend.LegendOrientation.VERTICAL);
        legend.setTypeface(Typeface.DEFAULT_BOLD);
    }

    //设置Y轴
    private void setYAxis() {
        bc.getAxisRight().setEnabled(false);
        YAxis yAxis = bc.getAxisLeft();
        yAxis.setTextSize(14f);
        yAxis.setTextColor(Color.BLACK);
        yAxis.setXOffset(15);
        yAxis.setAxisMaximum(800);
        yAxis.setAxisMinimum(-800);//注意最小值为-800
    }

    //设置X轴
    private void setXAxis() {
        XAxis xAxis = bc.getXAxis();
        xAxis.setEnabled(false);
    }

    //设置数据
    private void loadData() {
        bc.setExtraOffsets(30,70,30,50);
        bc.animateXY(1000,1000);
        bc.setFitBars(true);
        final float d_1[] = {230f, 480f, 480f, 480f,170f};
        final float d_2[] = { -120f,-600f, -400f, -200f,-80f};
        List<BarEntry> entries = new ArrayList<BarEntry>();
        for(int i = 0; i < d_1.length; i++){
            entries.add(new BarEntry(i,new float[]{d_1[i],d_2[i]}));
        }

        BarDataSet barDataSet = new BarDataSet(entries,"");
//        BarDataSet barDataSet1 = new BarDataSet(entries1,"有违章");
        barDataSet.setStackLabels(new String[]{"无违章","有违章"});

        barDataSet.setColors(Color.parseColor("#6D9C00"),Color.parseColor("#F07408"));

        BarData barData = new BarData(barDataSet);
        barData.setBarWidth(0.3f);//设置柱块的宽度

        bc.setData(barData);
    }

}
  • 8
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值