3

I want to make a bar chart with 3 different datasets grouped together at each data point like so:

enter image description here

However, I am unable to group the bars together using the library's provided groupBars method because no matter what x-value I set for an entry, it groups the bars according to the interval I specify in its parameters.

For example, if I generate a dataset with entry x-values {0, 5, 13, 17...50} and call `groupBars', all of my entries are gathered 1 x-value apart like so:

enter image description here

What I want is the bars to each be grouped and each be visible at their specified x-value. If I simply remove the groupBars call, I get something similar to what I want but not quite since the bars are all overlapping, like so:

enter image description here

How do I achieve a result similar to the above image but with the bar of each dataset completely visible? Here is my code for generating the dataset and grouping the bars:

        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);
damememan
  • 592
  • 7
  • 14
  • I have the same problem and I am trying to solve it from a week. Moreover, i saw that If I use the "groupBars" method and I have a lot of data, the bars don't resize, but I see only the first bars (I haven't an overview) If you find a solution could you share it, please? I will do the same, if i find one – Grancein Apr 27 '17 at 09:05
  • @GracePii see my posted solution – damememan Apr 27 '17 at 15:14

3 Answers3

2

I have solved the problem by modifying the x-values of each bar-entry and the bar width.

I create a new BarData class with the three datasets and set the bar width (let's call it BAR_WIDTH) to be 0.2 (i.e. the three bars together will take up 0.6 units in space, and there will be 0.4 unit of spacing after the dataset).

For any given bar entry, I place my first bar at the x-value I want (lets call it i), my second bar at x-value i+BAR_WIDTH, and third bar at i+2*BAR_WIDTH. The result is a group of 3 bar entries centered at any x-value I want, like so:

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

So in my above code, modify the bar-entry creation code to be as follows:

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);
damememan
  • 592
  • 7
  • 14
2

Two things that you have missed out is:

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

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

BEFORE using setCenterAxisLabels

enter image description here

AFTER setting setCenterAxisLabels to true

enter image description here

this is the code snippet I am using to align labels to center of each set of group

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

If you are not sure about the number of grouped bar graph (here it's 4) then

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

Here the barwidth is calculated as follows

(barwidth + barspace) * no of bars + groupspace = 1

the sum of all this spaces should be equal to 1 for label to be aligned to center of grouped bar graph.

Extremis II
  • 5,185
  • 2
  • 19
  • 29
  • Hi @sudesh , can you please answer my Bounty question regarding XAxis labels issue , here is question https://stackoverflow.com/questions/55325511/mpandroid-chart-not-displaying-any-labels-for-xaxis-what-is-missing – Deep Shah Mar 27 '19 at 10:35
  • Hi Sudesh, Can you please help me with this bar graph issue: https://stackoverflow.com/questions/59477589/how-to-enable-scroll-in-a-bar-chart-and-align-xaxis-labels-with-the-bar-groups – sak Dec 25 '19 at 15:10
0

I think the solution is to use

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

along with

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

in order to set X-Axis label into the centre of the bar group.

Please refer to GroupedBarChart section of this for further details.

Amit
  • 3,422
  • 3
  • 28
  • 39