【问题标题】:MPAndroidChart Bar Chart - how to group bars with random x-axis intervals in between groups?MPAndroidChart 条形图 - 如何在组之间对具有随机 x 轴间隔的条进行分组?
【发布时间】:2017-09-14 18:37:14
【问题描述】:

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

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

例如,如果我生成一个包含条目 x 值 {0、5、13、17...50} 的数据集并调用“groupBars”,则我的所有条目都以 1 个 x 值分开,如下所示:

我想要的是每个条都被分组并且每个条都在它们指定的 x 值处可见。如果我简单地删除 groupBars 调用,我会得到与我想要的类似的东西,但由于条形图都是重叠的,所以并不完全像这样:

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

        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);

【问题讨论】:

  • 我有同样的问题,我正在尝试从一周内解决它。此外,我看到如果我使用“groupBars”方法并且我有很多数据,这些条不会调整大小,但我只看到第一个条(我没有概述)如果你找到解决方案,你能分享一下好吗?如果我找到了,我也会这样做
  • @GracePii 查看我发布的解决方案

标签: java android bar-chart android-view mpandroidchart


【解决方案1】:

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

我用三个数据集创建了一个新的 BarData 类,并将条形宽度(我们称之为BAR_WIDTH)设置为 0.2(即三个条形加起来将占用 0.6 个单位的空间,而将有 0.4 个单位的数据集后的间距)。

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

所以在我上面的代码中,修改bar-entry创建代码如下:

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);

【讨论】:

  • 但是如何对齐 x 轴标签?他们不是有点左对齐吗?
【解决方案2】:

我认为解决方案是使用

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

随着

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

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

请参阅this 的 GroupedBarChart 部分了解更多详情。

【讨论】:

    【解决方案3】:

    你错过的两件事是:

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

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

    在使用 setCenterAxisLabels 之前

    将 setCenterAxisLabels 设置为 true 之后

    这是我用来将标签对齐到每组组的中心的代码 sn-p

    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) * 条数 + groupspace = 1

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

    【讨论】: