iadcialim24
iadcialim24

Reputation: 4015

MPAndroidChart: Barchart xAxis label not centered

I have this grouped bar chart that can set to any number of bars in a group. It will first start with 2 bars in a group. Then if user clicks the button. it will add a new bar in the group. and click again. new bar again. and so on. my goal is to redraw the chart with new bar but the x-axis label must always be in the center of the grouped bar.

I always have a problem on the time when there are 5 bars. enter image description here

Above, Feb is not centered on the 2nd grouped bar anymore. Sample code in here: https://github.com/PhilJay/MPAndroidChart/issues/3505

(I posted the question here too bec it seems that github is not maintained anymore)

In the code, the function resize is core of it that wants to reduce the width of the bars when new bars are added and at the same time increase the scale minima. But to no avail. Need help

Upvotes: 6

Views: 13147

Answers (4)

Waqas ali
Waqas ali

Reputation: 61

To align x axis at center of groupBarChart you need to fulfill the below formula

Formula :: (barWidth + barSpace)*count + groupSpace = 1    :-count= no of bars/groups

here:
barWdith = ??
barSpace = 0.05f
grouSpace = 0.44f

You can find the barWidth using below formula:

barWidth = (1 - groupSpace) /`enter code here` count - barSpace;

Upvotes: 0

Extremis II
Extremis II

Reputation: 5583

first you have to dynamically set the min and max value for x-axis

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

and then set it to center:

mChart.getXAxis().setCenterAxisLabels(true);

I have provided a detailed answer here: set interval between x-axis labels: stackoverflow

Upvotes: 6

sauvik
sauvik

Reputation: 2254

Check this sample grouped bar chart code.

public class MpAndroidGroupedBarChart extends AppCompatActivity {

    BarChart mChart;

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

        mChart = (BarChart) findViewById(R.id.bar_chart);
        mChart.setDrawBarShadow(false);
        mChart.getDescription().setEnabled(false);
        mChart.setPinchZoom(false);
        mChart.setDrawGridBackground(false);

        // empty labels so that the names are spread evenly
        String[] labels = {"", "Name1", "Name2", "Name3", "Name4", "Name5", ""};
        IAxisValueFormatter xAxisFormatter = new LabelFormatter(mChart, labels);
        XAxis xAxis = mChart.getXAxis();
        xAxis.setCenterAxisLabels(true);
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setDrawGridLines(false);
        xAxis.setGranularity(1f); // only intervals of 1 day
        xAxis.setTextColor(Color.BLACK);
        xAxis.setTextSize(12);
        xAxis.setAxisLineColor(Color.WHITE);
        xAxis.setAxisMinimum(1f);
        xAxis.setValueFormatter(xAxisFormatter);

        YAxis leftAxis = mChart.getAxisLeft();
        leftAxis.setTextColor(Color.BLACK);
        leftAxis.setTextSize(12);
        leftAxis.setAxisLineColor(Color.WHITE);
        leftAxis.setDrawGridLines(false);
        leftAxis.setGranularity(2);
        leftAxis.setLabelCount(8, true);
        leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);

        mChart.getAxisRight().setEnabled(false);
        mChart.getLegend().setEnabled(false);

        float[] valOne = {10, 20, 30, 40, 50};
        float[] valTwo = {60, 50, 40, 30, 20};
        float[] valThree = {20, 10, 30, 60, 40};
        float[] valFour = {40, 10, 60, 30, 10};
        float[] valFive = {60, 50, 40, 30, 50};

        ArrayList<BarEntry> barOne = new ArrayList<>();
        ArrayList<BarEntry> barTwo = new ArrayList<>();
        ArrayList<BarEntry> barThree = new ArrayList<>();
        ArrayList<BarEntry> barFour = new ArrayList<>();
        ArrayList<BarEntry> barFive = new ArrayList<>();
        for (int i = 0; i < valOne.length; i++) {
            barOne.add(new BarEntry(i, valOne[i]));
            barTwo.add(new BarEntry(i, valTwo[i]));
            barThree.add(new BarEntry(i, valThree[i]));
            barFour.add(new BarEntry(i, valFour[i]));
            barFive.add(new BarEntry(i, valFive[i]));
        }

        BarDataSet set1 = new BarDataSet(barOne, "barOne");
        set1.setColor(Color.BLUE);
        BarDataSet set2 = new BarDataSet(barTwo, "barTwo");
        set2.setColor(Color.MAGENTA);
        BarDataSet set3 = new BarDataSet(barThree, "barTwo");
        set3.setColor(Color.RED);
        BarDataSet set4 = new BarDataSet(barFour, "barTwo");
        set4.setColor(Color.GREEN);
        BarDataSet set5 = new BarDataSet(barFive, "barTwo");
        set5.setColor(Color.LTGRAY);

        set1.setHighlightEnabled(false);
        set1.setDrawValues(false);
        set2.setHighlightEnabled(false);
        set2.setDrawValues(false);
        set3.setHighlightEnabled(false);
        set3.setDrawValues(false);
        set4.setHighlightEnabled(false);
        set4.setDrawValues(false);
        set5.setHighlightEnabled(false);
        set5.setDrawValues(false);

        ArrayList<IBarDataSet> dataSets = new ArrayList<IBarDataSet>();
        dataSets.add(set1);
        dataSets.add(set2);
        dataSets.add(set3);
        dataSets.add(set4);
        dataSets.add(set5);
        BarData data = new BarData(dataSets);
        float groupSpace = 0.2f;
        float barSpace = 0f;
        float barWidth = 0.16f;
        // (barSpace + barWidth) * 5 + groupSpace = 1
        // multiplied by 5 because there are 5 five bars
        // labels will be centered as long as the equation is satisfied
        data.setBarWidth(barWidth);
        // so that the entire chart is shown when scrolled from right to left
        xAxis.setAxisMaximum(labels.length - 1.1f);
        mChart.setData(data);
        mChart.setScaleEnabled(false);
        mChart.setVisibleXRangeMaximum(2f);
        mChart.groupBars(1f, groupSpace, barSpace);
        mChart.invalidate();

    }


    private class LabelFormatter implements IAxisValueFormatter {

        String[] labels;
        BarLineChartBase<?> chart;

        LabelFormatter(BarLineChartBase<?> chart, String[] labels) {
            this.chart = chart;
            this.labels = labels;
        }

        @Override
        public String getFormattedValue(float value, AxisBase axis) {
            return labels[(int) value];
        }
    }
}

labels will be centered as long as this equation is satisfied

(barSpace + barWidth) * 5 + groupSpace = 1

multiplied by 5 because there are 5 five bars

RESULT

enter image description here

Upvotes: 14

Don Chakkappan
Don Chakkappan

Reputation: 7560

I think the Label position is correct & the problem is with Bar position & Spacing.Please try the following method.

    /**
     * Group charts by specifying width & other properties externally
     *
     * @param dataSets  Entire DataSet made
     * @param data      Bar Data created from datasets
     * @see <a href="https://github.com/PhilJay/MPAndroidChart/wiki/Setting-Data#grouped-barchart">http://google.com</a>
     */
    private void setupChartGrouping(ArrayList<IBarDataSet> dataSets,
                                    BarData data) {
        if (dataSets.size() > 1) {
            barChart.getXAxis().setCenterAxisLabels(true);
            barChart.getBarData().setBarWidth(getBarWidth(dataSets.size()));
            barChart.getXAxis().setAxisMinimum(-data.getBarWidth() / 2);
            barChart.getXAxis().setAxisMaximum(dataSets.size());
            barChart.groupBars(0, GROUPED_CHART_GROUP_SPACING, GROUPED_CHART_BAR_SPACING);

        } else {

            barChart.getXAxis().setCenterAxisLabels(false);
            barChart.getXAxis().resetAxisMaximum();
            barChart.getXAxis().resetAxisMinimum();

            barChart.getAxisLeft().setDrawGridLines(false);
            barChart.getXAxis().setDrawGridLines(false);
        }
    }

    private static final float GROUPED_CHART_MAGICAL_NUMBER = 1.00f;
    public static final float GROUPED_CHART_BAR_SPACING = 0.05f;
    public static final float GROUPED_CHART_GROUP_SPACING = 0.20f;

    /**
     * Size would be ==> ((barSpace + barWidth) * no: of bars in a group) + groupSpace = 1.00
     *
     * @param barEntryCount No: of bars in a Group
     * @return Width of a Single Bar in Chart
     */
    public static float getBarWidth(int barEntryCount) {
        return ((GROUPED_CHART_MAGICAL_NUMBER - GROUPED_CHART_GROUP_SPACING) / barEntryCount) - GROUPED_CHART_BAR_SPACING;
    }

Upvotes: 4

Related Questions