Android图表控件MPAndroidChart——柱状图BarChart实现多列堆积柱形图

发现最新的MPAndroidChart和以前版本的使用有一些差距,就写下了现在新版的使用方法

相关文章:

Android图表控件MPAndroidChart的简单介绍(MPAndroidChart3.0)

Android图表控件MPAndroidChart——曲线图LineChart的使用(多条曲线)

Android图表控件MPAndroidChart——曲线图LineChart(多条曲线)动态添加数据

Android图表控件MPAndroidChart——柱状图BarChart的使用(多条柱状图)

Android图表控件MPAndroidChart——曲线图+柱状图 CombinedChart的使用 

Android图表控件MPAndroidChart——源码修改实现曲线图X轴直尺刻度样式

本文相关代码

MPAndroidChart在github上地址:https://github.com/PhilJay/MPAndroidChart

一.效果图

1.一条柱状图

2.多条柱状图

二.具体使用

柱状图的使用和线性图的使用差不多

1.得到BarChart对象 并初始化

2.得到BarEntry对象,此处添加(X,Y)值

3.得到BarDataSet对象,添加BarEntry对象

4.得到BarData对象,添加BarDaraSet对象

5.显示柱状图 BarChart.setData(BarData)

java代码 一个BarChart管理类

public class BarChartManager {
    private BarChart mBarChart;
    private YAxis leftAxis;
    private YAxis rightAxis;
    private XAxis xAxis;

    public BarChartManager(BarChart barChart) {
        this.mBarChart = barChart;
        leftAxis = mBarChart.getAxisLeft();
        rightAxis = mBarChart.getAxisRight();
        xAxis = mBarChart.getXAxis();
    }

    /**
     * 初始化LineChart
     */
    private void initLineChart() {
        //背景颜色
        mBarChart.setBackgroundColor(Color.WHITE);
        //网格
        mBarChart.setDrawGridBackground(false);
        //背景阴影
        mBarChart.setDrawBarShadow(false);
        mBarChart.setHighlightFullBarEnabled(false);

        //显示边界
        mBarChart.setDrawBorders(true);
        //设置动画效果
        mBarChart.animateY(1000, Easing.EasingOption.Linear);
        mBarChart.animateX(1000, Easing.EasingOption.Linear);

        //折线图例 标签 设置
        Legend legend = mBarChart.getLegend();
        legend.setForm(Legend.LegendForm.LINE);
        legend.setTextSize(11f);
        //显示位置
        legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
        legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
        legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
        legend.setDrawInside(false);

        //XY轴的设置
        //X轴设置显示位置在底部
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setGranularity(1f);
        //保证Y轴从0开始,不然会上移一点
        leftAxis.setAxisMinimum(0f);
        rightAxis.setAxisMinimum(0f);
    }

    /**
     * 展示柱状图(一条)
     *
     * @param xAxisValues
     * @param yAxisValues
     * @param label
     * @param color
     */
    public void showBarChart(List<Float> xAxisValues, List<Float> yAxisValues, String label, int color) {
        initLineChart();
        ArrayList<BarEntry> entries = new ArrayList<>();
        for (int i = 0; i < xAxisValues.size(); i++) {
            entries.add(new BarEntry(xAxisValues.get(i), yAxisValues.get(i)));
        }
        // 每一个BarDataSet代表一类柱状图
        BarDataSet barDataSet = new BarDataSet(entries, label);

        barDataSet.setColor(color);
        barDataSet.setValueTextSize(9f);
        barDataSet.setFormLineWidth(1f);
        barDataSet.setFormSize(15.f);

        ArrayList<IBarDataSet> dataSets = new ArrayList<>();
        dataSets.add(barDataSet);
        BarData data = new BarData(dataSets);
        //设置X轴的刻度数
        xAxis.setLabelCount(xAxisValues.size() - 1, false);
        mBarChart.setData(data);
    }

    /**
     * 展示柱状图(多条)
     *
     * @param xAxisValues
     * @param yAxisValues
     * @param labels
     * @param colours
     */
    public void showBarChart(List<Float> xAxisValues, List<List<Float>> yAxisValues, List<String> labels, List<Integer> colours) {
        initLineChart();
        BarData data = new BarData();
        for (int i = 0; i < yAxisValues.size(); i++) {
            ArrayList<BarEntry> entries = new ArrayList<>();
            for (int j = 0; j < yAxisValues.get(i).size(); j++) {

                entries.add(new BarEntry(xAxisValues.get(j), yAxisValues.get(i).get(j)));
            }
            BarDataSet barDataSet = new BarDataSet(entries, labels.get(i));

            barDataSet.setColor(colours.get(i));
            barDataSet.setValueTextColor(colours.get(i));
            barDataSet.setValueTextSize(10f);
            barDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
            data.addDataSet(barDataSet);
        }
        int amount = yAxisValues.size();

        float groupSpace = 0.12f; //柱状图组之间的间距
        float barSpace = (float) ((1 - 0.12) / amount / 10); // x4 DataSet
        float barWidth = (float) ((1 - 0.12) / amount / 10 * 9); // x4 DataSet

        // (0.2 + 0.02) * 4 + 0.08 = 1.00 -> interval per "group"
        xAxis.setLabelCount(xAxisValues.size() - 1, false);
        data.setBarWidth(barWidth);


        data.groupBars(0, groupSpace, barSpace);
        mBarChart.setData(data);
    }


    /**
     * 设置Y轴值
     *
     * @param max
     * @param min
     * @param labelCount
     */
    public void setYAxis(float max, float min, int labelCount) {
        if (max < min) {
            return;
        }
        leftAxis.setAxisMaximum(max);
        leftAxis.setAxisMinimum(min);
        leftAxis.setLabelCount(labelCount, false);

        rightAxis.setAxisMaximum(max);
        rightAxis.setAxisMinimum(min);
        rightAxis.setLabelCount(labelCount, false);
        mBarChart.invalidate();
    }

    /**
     * 设置X轴的值
     *
     * @param max
     * @param min
     * @param labelCount
     */
    public void setXAxis(float max, float min, int labelCount) {
        xAxis.setAxisMaximum(max);
        xAxis.setAxisMinimum(min);
        xAxis.setLabelCount(labelCount, false);

        mBarChart.invalidate();
    }

    /**
     * 设置高限制线
     *
     * @param high
     * @param name
     */
    public void setHightLimitLine(float high, String name, int color) {
        if (name == null) {
            name = "高限制线";
        }
        LimitLine hightLimit = new LimitLine(high, name);
        hightLimit.setLineWidth(4f);
        hightLimit.setTextSize(10f);
        hightLimit.setLineColor(color);
        hightLimit.setTextColor(color);
        leftAxis.addLimitLine(hightLimit);
        mBarChart.invalidate();
    }

    /**
     * 设置低限制线
     *
     * @param low
     * @param name
     */
    public void setLowLimitLine(int low, String name) {
        if (name == null) {
            name = "低限制线";
        }
        LimitLine hightLimit = new LimitLine(low, name);
        hightLimit.setLineWidth(4f);
        hightLimit.setTextSize(10f);
        leftAxis.addLimitLine(hightLimit);
        mBarChart.invalidate();
    }

    /**
     * 设置描述信息
     *
     * @param str
     */
    public void setDescription(String str) {
        Description description = new Description();
        description.setText(str);
        mBarChart.setDescription(description);
        mBarChart.invalidate();
    }
}

使用

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

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

        <com.github.mikephil.charting.charts.BarChart
            android:id="@+id/bar_chart2"
            android:layout_width="match_parent"
            android:layout_height="380dp"/>
    </LinearLayout>
</ScrollView>

Activity中

public class BarChartActivity extends AppCompatActivity {


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bar_chart);

        BarChart barChart1 = (BarChart) findViewById(R.id.bar_chart1);
        BarChart barChart2 = (BarChart) findViewById(R.id.bar_chart2);

        BarChartManager barChartManager1 = new BarChartManager(barChart1);
        BarChartManager barChartManager2 = new BarChartManager(barChart2);

        //设置x轴的数据
        ArrayList<Float> xValues = new ArrayList<>();
        for (int i = 0; i <= 10; i++) {
            xValues.add((float) i);
        }

        //设置y轴的数据()
        List<List<Float>> yValues = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            List<Float> yValue = new ArrayList<>();
            for (int j = 0; j <= 10; j++) {
                yValue.add((float) (Math.random() * 80));
            }
            yValues.add(yValue);
        }

        //颜色集合
        List<Integer> colours = new ArrayList<>();
        colours.add(Color.GREEN);
        colours.add(Color.BLUE);
        colours.add(Color.RED);
        colours.add(Color.CYAN);

        //线的名字集合
        List<String> names = new ArrayList<>();
        names.add("折线一");
        names.add("折线二");
        names.add("折线三");
        names.add("折线四");

        //创建多条折线的图表
        barChartManager1.showBarChart(xValues, yValues.get(0), names.get(1), colours.get(3));
        barChartManager2.showBarChart(xValues, yValues, names, colours);
        barChartManager2.setXAxis(11f, 0f, 11);
    }
}

三.使用中遇见的一些问题

1.多条柱状图无法显示并排显示,如下所示

猜测显示多条柱状图默认模式是上述的效果,想要显示多条柱状图并排显示需要进行相应的设置

//柱状图宽度
data.setBarWidth(barWidth);
//(起始点、柱状图组间距、柱状图之间间距)
data.groupBars(0, groupSpace, barSpace);

例:如图标题一中图2,显示了4条不同类别的柱状图

其中:

float groupSpace = 0.12f; //柱状图组之间的间距
float barSpace =  0.02f; // x4 DataSet
float barWidth = 0.2f; // x4 DataSet
// (0.2 + 0.02) * 4 + 0.12 = 1.00 即100% 按照百分百布局

值是按照 一个组(即X轴一个刻度范围类) 需要显示的柱状图数量以及间距之和为 1

在上述管理类中计算的方式中使用以下方法 (可自由适配柱状图类别数量)

int amount = yAxisValues.size(); //需要显示柱状图的类别 数量
float groupSpace = 0.12f; //柱状图组之间的间距
float barSpace = (float) ((1 - 0.12) / amount / 10); // x4 DataSet
float barWidth = (float) ((1 - 0.12) / amount / 10 * 9); // x4 DataSet

2.显示的柱状图左边或者右边只显示了一半,具体效果如下

解决办法

再次设置X轴的最小值和最大值即可

即最后一个方法

public void setXAxis(float max, float min, int labelCount) {
    xAxis.setAxisMaximum(max);
    xAxis.setAxisMinimum(min);
    xAxis.setLabelCount(labelCount, false);

    mBarChart.invalidate();
}
barChartManager2.setXAxis(11f, 0f, 11);

猜你喜欢

转载自blog.csdn.net/ww897532167/article/details/74171294