MPAndroidChart Bar Chart - how to group bars with random x-axis intervals in between groups?

断了今生、忘了曾经 提交于 2019-12-10 10:08:37

问题


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

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:

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:

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

回答1:


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:

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



回答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

AFTER setting setCenterAxisLabels to true

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.




回答3:


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.



来源:https://stackoverflow.com/questions/43480358/mpandroidchart-bar-chart-how-to-group-bars-with-random-x-axis-intervals-in-bet

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!