MPAndroidChart_并列柱状图,及如何实现点击隐藏掉不需要的条目。

版权声明:https://blog.csdn.net/petterp https://blog.csdn.net/petterp/article/details/88924778

MPAndroidChart攻略第一步——LineChart的点点滴滴。

带你入门折线图的基本使用,各种属性的设置,自定义轴上的标签,及去除边框线与轴线,和MarkView提示的使用。

MPAndroidChart_折线图的那些事

MPAndroidChart_饼图的那些事

MPAndroidChart_动态柱状图

MPAndroidChart_水平条形图的那些事

MPAndroidChart_并列柱状图,及如何实现点击隐藏掉不需要的条目。

昨天在比赛中遇到了MP的并列柱状图,看网上对这方面记录并不是很多,所以今天就做一个教程吧。

先看简单的需求草图吧

好了,现在开始上代码,需要特别注意的地方,会重点标出来提醒。

public class Main2Activity extends AppCompatActivity {
    private BarChart chart;
    private CountDownTimer count;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        chart=findViewById(R.id.chart);
        info();
        count=new CountDownTimer(Integer.MAX_VALUE,2000) {
            @Override
            public void onTick(long millisUntilFinished) {
                setData();
            }

            @Override
            public void onFinish() {

            }
        }.start();
    }
  
    private void info(){
        XAxis xAxis=chart.getXAxis();
        xAxis.setDrawGridLines(false);
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setLabelCount(5);
        //设置x轴最小值
        xAxis.setAxisMinimum(0f);
        //设置x轴最大值
        xAxis.setAxisMaximum(5f);
        final String[] data={"周一","周二","周三","周四","周五"};
        //标签居中
        xAxis.setTextSize(25f);
        xAxis.setCenterAxisLabels(true);
        //自定义x轴
        xAxis.setValueFormatter(new IAxisValueFormatter() {
            @Override
            public String getFormattedValue(float v, AxisBase axisBase) {
                return data[(int) Math.abs(v%5)];
            }
        });

        YAxis left=chart.getAxisLeft();
        left.setAxisMinimum(0f);
        left.setAxisMaximum(6f);
        left.setLabelCount(6);
        //设置字体大小
        left.setTextSize(25f);
        //设置y轴左侧竖线宽度 不设置在自定义标签时会出现不显示竖线的情况
        left.setAxisLineWidth(1f);
        //隐藏Y轴左侧网格线
        left.setDrawGridLines(false);
        final String[] setY={"","畅通","缓行","拥堵","一般拥堵","严重拥堵"};
        left.setValueFormatter(new IAxisValueFormatter() {
            @Override
            public String getFormattedValue(float v, AxisBase axisBase) {
                return v>=6?"":setY[(int) v];
            }
        });

        YAxis right=chart.getAxisRight();
        right.setDrawGridLines(false);
        right.setAxisMinimum(0f);
        right.setTextSize(25f);
        right.setAxisMaximum(5f);

        //设置图表编译,避免x轴标签显示不全
        chart.setExtraBottomOffset(10);
        //禁用图例
        chart.getLegend().setEnabled(false);
        //禁用描述
        chart.getDescription().setEnabled(false);
    }

    private void setData(){
        List<BarEntry> list1=new ArrayList<>();
        List<BarEntry> list2=new ArrayList<>();
        List<BarEntry> list3=new ArrayList<>();
        for (int i=0;i<5;i++){
            list1.add(new BarEntry(i, (float) (Math.random()*5)));
            list2.add(new BarEntry(i, (float) (Math.random()*5)));
            list3.add(new BarEntry(i, (float) (Math.random()*5)));
        }
        BarDataSet set1=new BarDataSet(list1,"");
        BarDataSet set2=new BarDataSet(list2,"");
        BarDataSet set3=new BarDataSet(list3,"");
        set1.setColor(Color.RED);
        set2.setColor(Color.BLUE);
        set3.setColor(Color.GREEN);

        BarData data=new BarData(set1,set2,set3);
        //组内柱状图之间的空间
        float barspace=0.05f;
        //每组之间的空间
        float groupspcae=0.3f;
        //柱状图的宽度
        float barWidth=(1-0.3f-0.05f*3)/3;
        //设置柱状图的宽度
        data.setBarWidth(barWidth);
        //(起始点,组间隔,组内间隔)
        data.groupBars(0f,groupspcae,barspace);

        //上面的计算公式为  图组间隔+(柱状图间隔*柱状图个数)+子柱状图宽度*每组柱状图个数=1f
        //简单计算为  子柱状图宽度=(1f-图组间隔-(柱状图间隔*柱状图个数))/每组柱状图个数

        //设置
        chart.setData(data);
        //刷新布局
        chart.invalidate();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (count != null) {
            count.cancel();
            count=null;
        }
    }
}

看看实际效果图

现在,我们来实现如何点击隐藏相应的条目。

思路是这样的,这里感谢我的工作室同学,简单又粗暴:

点击相应的按钮,设置相应的柱状图颜色为白色。算一种比较投巧的办法吧。

我当时的想法是,对数据进行保留,然后加上标记位,每次点击,将相应位置的数据改为0,然后刷新布局即可。但是总是List数据改了 ,图表刷新却直接将一组数据全删了,很是纳闷,试了一个上午,都没有找到原因。

如果你们谁有更好的想法,也欢迎说一下

以下细节需要注意:

背景色一定要改为白色,默认的那个背景色并不是纯白,网格线需要禁用,否则效果很是尴尬。

需要隐藏掉标签显示,否则柱状图颜色没了,标签还在,当然也可以通过自定义 标签的显示,将相对应的标签自定义为“”,也可以实现禁用。

 下面开始上代码

public class Main2Activity extends AppCompatActivity implements View.OnClickListener {
    private BarChart chart;
    private CountDownTimer count;
    private BarDataSet set1;
    private BarDataSet set2;
    private BarDataSet set3;
    //标记位
    private boolean mode1 = false, mode2 = false, mode3 = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        chart = findViewById(R.id.chart);
        info();
        //定时器
        count = new CountDownTimer(Integer.MAX_VALUE, 2000) {
            @Override
            public void onTick(long millisUntilFinished) {
                setData();
            }

            @Override
            public void onFinish() {

            }
        }.start();
    }


    private void info() {
        XAxis xAxis = chart.getXAxis();
        xAxis.setDrawGridLines(false);
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setLabelCount(5);
        //设置x轴最小值
        xAxis.setAxisMinimum(0f);
        //设置x轴最大值
        xAxis.setAxisMaximum(5f);
        final String[] data = {"周一", "周二", "周三", "周四", "周五"};
        //标签居中
        xAxis.setTextSize(25f);
        xAxis.setCenterAxisLabels(true);
        //自定义x轴
        xAxis.setValueFormatter(new IAxisValueFormatter() {
            @Override
            public String getFormattedValue(float v, AxisBase axisBase) {
                return data[(int) Math.abs(v % 5)];
            }
        });

        YAxis left = chart.getAxisLeft();
        left.setAxisMinimum(0f);
        left.setAxisMaximum(6f);
        left.setLabelCount(6);
        //设置字体大小
        left.setTextSize(25f);
        //设置y轴左侧竖线宽度 不设置在自定义标签时会出现不显示竖线的情况
        left.setAxisLineWidth(1f);
        //隐藏Y轴左侧网格线
        left.setDrawGridLines(false);
        final String[] setY = {"", "畅通", "缓行", "拥堵", "一般拥堵", "严重拥堵"};
        left.setValueFormatter(new IAxisValueFormatter() {
            @Override
            public String getFormattedValue(float v, AxisBase axisBase) {
                return v >= 6 ? "" : setY[(int) v];
            }
        });

        YAxis right = chart.getAxisRight();
        right.setDrawGridLines(false);
        right.setAxisMinimum(0f);
        right.setTextSize(25f);
        right.setAxisMaximum(5f);

        //设置图表编译,避免x轴标签显示不全
        chart.setExtraBottomOffset(10);
        //禁用图例
        chart.getLegend().setEnabled(false);
        //禁用描述
        chart.getDescription().setEnabled(false);
        chart.setBackgroundColor(Color.WHITE);

        findViewById(R.id.hide_red).setOnClickListener(this);
        findViewById(R.id.hide_blue).setOnClickListener(this);
        findViewById(R.id.hide_gre).setOnClickListener(this);
    }

     private void setData() {
        List<BarEntry> list1 = new ArrayList<>();
        List<BarEntry> list2 = new ArrayList<>();
        List<BarEntry> list3 = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            list1.add(new BarEntry(i, (float) (Math.random() * 5)));
            list2.add(new BarEntry(i, (float) (Math.random() * 5)));
            list3.add(new BarEntry(i, (float) (Math.random() * 5)));
        }
        set1 = new BarDataSet(list1, "");
        set2 = new BarDataSet(list2, "");
        set3 = new BarDataSet(list3, "");
        setHide(mode1, set1, Color.RED);
        setHide(mode2, set2, Color.BLUE);
        setHide(mode3, set3, Color.GREEN);
        BarData data = new BarData(set1, set2, set3);
        //组内柱状图之间的空间
        float barspace = 0.05f;
        //每组之间的空间
        float groupspcae = 0.3f;
        //柱状图的宽度
        float barWidth = (1 - 0.3f - 0.05f * 3) / 3;
        //设置柱状图的宽度
        data.setBarWidth(barWidth);
        //(起始点,组间隔,组内间隔)
        data.groupBars(0f, groupspcae, barspace);

        //上面的计算公式为  图组间隔+(柱状图间隔*柱状图个数)+子柱状图宽度*每组柱状图个数=1f
        //简单计算为  子柱状图宽度=(1f-图组间隔-(柱状图间隔*柱状图个数))/每组柱状图个数

        //设置
        chart.setData(data);
        //刷新布局
        chart.invalidate();
    }


    //设置柱状图颜色为白色
    private void setHide(boolean mode, BarDataSet set, int color) {
        if (mode) {
            set.setColor(Color.WHITE);
        } else {
            set.setColor(color);
        }
        set.setDrawValues(false);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.hide_red:
                mode1 = true;
                set1.setColor(Color.WHITE);
                chart.invalidate();
                break;
            case R.id.hide_blue:
                mode2 = true;
                set2.setColor(Color.WHITE);
                chart.invalidate();
                break;
            case R.id.hide_gre:
                mode3 = true;
                set3.setColor(Color.WHITE);
                chart.invalidate();
                break;
        }
    }

  @Override
    protected void onDestroy() {
        super.onDestroy();
        if (count != null) {
            count.cancel();
            count = null;
        }
    }

}

效果就是这样。如果有更好的解决方案,也欢迎大家告诉我。 

猜你喜欢

转载自blog.csdn.net/petterp/article/details/88924778