Home Articles

MPAndroidChart条形图 - 如何在组之间对随机x轴间隔的条形图进行分组?

Asked
Viewed 1019 times
2

我想制作一个条形图,其中3个不同的数据集在每个数据点组合在一起,如下所示:

enter image description here

但是,我无法使用库提供的 groupBars 方法将条形组合在一起,因为无论我为条目设置了什么x值,它都会根据我在参数中指定的间隔对条形图进行分组 .

例如,如果我生成一个带有条目x值{0,5,13,17 ... 50}并调用`groupBars'的数据集,那么我的所有条目都会被收集1 x值,如下所示:

enter image description here

我想要的是每个被分组的条形图,每个条形图在其指定的x值处可见 . 如果我只是删除 groupBars 调用,我会得到类似于我想要的东西但不完全,因为条形图都是重叠的,如下所示:

enter image description here

如何获得与上述图像类似的结果,但每个数据集的条形图是否完全可见?这是我生成数据集和分组条形码的代码:

ArrayList<BarEntry> happinessValues = new ArrayList<>();
        ArrayList<BarEntry> stressValues = new ArrayList<>();
        ArrayList<BarEntry> painValues = new ArrayList<>();

        for (int i = 0; i < 50; ++i) {
            happinessValues.add(new BarEntry(
                    i,
                    datapoint.getHappiness()));
            stressValues.add(new BarEntry(
                    i,
                    datapoint.getStress()));
            painValues.add(new BarEntry(
                    i,
                    datapoint.getPain()));
        }

        HappinessDataset happyDataset;

        BarDataSet stressDataset, painDataset;

            happyDataset = new HappinessDataset(happinessValues, "Happiness");

            stressDataset = new BarDataSet(stressValues, "Stress");

            painDataset = new BarDataSet(painValues, "Pain");

            BarData data = new BarData(happyDataset, stressDataset, painDataset);

            mChart.setData(data);

        mChart.getXAxis().setAxisMinimum(0);
        mChart.getXAxis().setAxisMaximum(50);


      float groupSpace = 0.4f;
        float barSpace = 0f; // x3 DataSet
        float barWidth = 0.2f; // x3 DataSet
        // (0.2 + 0) * 3 + 0.4 = 1.00 -> interval per "group"
        mChart.groupBars(startTime, groupSpace, barSpace);

3 Answers

  • 2

    你错过的两件事是:

    • mChart.getXAxis().setAxisMaximum(0 + barChart.getBarData().getGroupWidth(groupSpace, barSpace) * groupCount);

    • mChart.getXAxis().setCenterAxisLabels(true);

    在使用setCenterAxisLabels之前

    enter image description here

    将setCenterAxisLabels设置为true后

    enter image description here

    这是我用来将标签与每组组的中心对齐的代码片段

    float barSpace = 0.02f;
        float groupSpace = 0.3f;
        int groupCount = 4;
    
        data.setBarWidth(0.15f);
        barChart.getXAxis().setAxisMinimum(0);
        barChart.getXAxis().setAxisMaximum(0 + barChart.getBarData().getGroupWidth(groupSpace, barSpace) * groupCount);
        barChart.groupBars(0, groupSpace, barSpace); // perform the "explicit" grouping
    

    如果你不确定分组条形图的数量(这里是4)那么

    float defaultBarWidth = -1;
        int groupCount = xAxisValues.size();
    
        defaultBarWidth = (1 - groupSpace)/barDataSets.size()  - barSpace;
            if(defaultBarWidth >=0) {
                barData.setBarWidth(defaultBarWidth);
            }
       if(groupCount != -1) {
                mChart.getXAxis().setAxisMinimum(0);
                mChart.getXAxis().setAxisMaximum(0 + mChart.getBarData().getGroupWidth(groupSpace, barSpace) * groupCount);
                mChart.getXAxis().setCenterAxisLabels(true);
            }
    

    这里的条宽计算如下

    (barwidth barspace)* no groups groupspace = 1

    所有这些空格的总和应该等于1,以使标签与分组条形图的中心对齐 .

  • 1

    我认为解决方案是使用

    barChart.groupBars(fromX, groupSpace, barSpace);
    barChart.notifyDataSetChanged()
    

    随着

    XAxis xAxis = chart.getXAxis();
    xAxis.setCenterAxisLabels(true);
    

    为了将X轴标签设置为条形组的中心 .

    有关详细信息,请参阅this的GroupedBarChart部分 .

  • 0

    我通过修改每个条形条的x值和条宽来解决了这个问题 .

    我用三个数据集创建一个新的BarData类,并设置条宽(让我们称之为 BAR_WIDTH )为0.2(即三个条在一起将占用空间中的0.6个单位,并且在数据集之后将有0.4个单位的间距) .

    对于任何给定的条形图,我将第一个条形图放在我想要的x值(让我们称之为 i ),我的第二个条形图位于x值 i+BAR_WIDTH ,第三个条形图位于 i+2*BAR_WIDTH . 结果是一组以我想要的任何x值为中心的3个条形条目,如下所示:

    http://i.imgur.com/KrKTE45l.jpg

    所以在上面的代码中,修改条形码创建代码如下:

    final float BAR_WIDTH = 0.2f;
    
         happinessValues.add(new BarEntry(
                            i,
                            datapoint.getHappiness()));
                    stressValues.add(new BarEntry(
                            i + BAR_WIDTH,
                            datapoint.getStress()));
                    painValues.add(new BarEntry(
                            i + 2 * BAR_WIDTH,
                            datapoint.getPain()));
    
    mChart.getBarData().setBarWidth(BAR_WIDTH);
    

Related