Mpandroidchart: Multi Bar Chart

Created on 28 May 2017  路  9Comments  路  Source: PhilJay/MPAndroidChart

Hello,

I'm trying to create a barchart with 2 bars for each month of the year. I got some example code going and it looks great. However, there are two issues that i've struggled with.

1) The last bar is missing
2) Its grouped as "4" instead of "2" due to the xaxis grid lines and the label is centered across 4 bars.

Am i doing anything obviously wrong below?

BarChart barChart = (BarChart) rootView.findViewById(R.id.dashboardCashflowChart);

    barChart.setDrawBarShadow(false);
    barChart.setDrawValueAboveBar(true);
    //barChart.setDescription("");
    barChart.setMaxVisibleValueCount(50);
    barChart.setPinchZoom(false);
    barChart.setDrawGridBackground(false);

    XAxis xl = barChart.getXAxis();
    xl.setGranularity(1f);
    xl.setCenterAxisLabels(true);


    YAxis leftAxis = barChart.getAxisLeft();

    leftAxis.setDrawGridLines(false);
    leftAxis.setSpaceTop(30f);
    leftAxis.setAxisMinValue(0f); // this replaces setStartAtZero(true
    barChart.getAxisRight().setEnabled(false);

    //data
    float groupSpace = 0.04f;
    float barSpace = 0.02f; // x2 dataset
    float barWidth = 0.46f; // x2 dataset
    // (0.46 + 0.02) * 2 + 0.04 = 1.00 -> interval per "group"

    int startYear = 0;
    int endYear = 12;


    List<BarEntry> yVals1 = new ArrayList<BarEntry>();
    List<BarEntry> yVals2 = new ArrayList<BarEntry>();


    for (int i = startYear; i < endYear; i++) {
        yVals1.add(new BarEntry(i, 0.4f));
    }

    for (int i = startYear; i < endYear; i++) {
        yVals2.add(new BarEntry(i, 0.7f));
    }


    BarDataSet set1, set2;

    if (barChart.getData() != null && barChart.getData().getDataSetCount() > 0) {
        set1 = (BarDataSet)barChart.getData().getDataSetByIndex(0);
        set2 = (BarDataSet)barChart.getData().getDataSetByIndex(1);
        set1.setValues(yVals1);
        set2.setValues(yVals2);
        barChart.getData().notifyDataChanged();
        barChart.notifyDataSetChanged();
    } else {
        // create 2 datasets with different types
        set1 = new BarDataSet(yVals1, "Company A");
        set1.setColor(Color.rgb(104, 241, 175));
        set2 = new BarDataSet(yVals2, "Company B");
        set2.setColor(Color.rgb(164, 228, 251));

        ArrayList<IBarDataSet> dataSets = new ArrayList<IBarDataSet>();
        dataSets.add(set1);
        dataSets.add(set2);

        BarData data = new BarData(dataSets);
        barChart.setData(data);
    }

    barChart.getBarData().setBarWidth(barWidth);
    barChart.getXAxis().setAxisMinValue(startYear);
    barChart.groupBars(startYear, groupSpace, barSpace);
    barChart.invalidate();

Most helpful comment

Many thanks for helping. I'm sure i'm just missing a setting somewhere. I've been experimenting and 8 months works fine, but from 10 onwards it groups it as 4.

Screenshots of the two below. Below code was taken from some sample code which very minimal changes so not sure what i've missed!

BarChart barChart = (BarChart) rootView.findViewById(R.id.dashboardCashflowChart);

    barChart.setDrawBarShadow(false);
    barChart.setDrawValueAboveBar(true);
    barChart.setMaxVisibleValueCount(50);
    barChart.setPinchZoom(false);
    barChart.setDrawGridBackground(false);

    XAxis xl = barChart.getXAxis();
    xl.setGranularity(1f);
    xl.setCenterAxisLabels(true);

    YAxis leftAxis = barChart.getAxisLeft();

    leftAxis.setGranularity(1f);
    leftAxis.setDrawGridLines(false);
    leftAxis.setSpaceTop(30f);
    leftAxis.setAxisMinValue(0f); // this replaces setStartAtZero(true
    barChart.getAxisRight().setEnabled(false);

    //data
    float groupSpace = 0.04f;
    float barSpace = 0.02f; // x2 dataset
    float barWidth = 0.46f; // x2 dataset
    // (0.46 + 0.02) * 2 + 0.04 = 1.00 -> interval per "group"

    int startYear = 0;
    int endYear = 8;


    List<BarEntry> yVals1 = new ArrayList<BarEntry>();
    List<BarEntry> yVals2 = new ArrayList<BarEntry>();


    for (int i = startYear; i < endYear; i++) {
        yVals1.add(new BarEntry(i, 0.4f));
    }

    for (int i = startYear; i < endYear; i++) {
        yVals2.add(new BarEntry(i, 0.7f));
    }


    BarDataSet set1, set2;

    if (barChart.getData() != null && barChart.getData().getDataSetCount() > 0) {
        set1 = (BarDataSet)barChart.getData().getDataSetByIndex(0);
        set2 = (BarDataSet)barChart.getData().getDataSetByIndex(1);
        set1.setValues(yVals1);
        set2.setValues(yVals2);
        barChart.getData().notifyDataChanged();
        barChart.notifyDataSetChanged();
    } else {
        // create 2 datasets with different types
        set1 = new BarDataSet(yVals1, "Company A");
        set1.setColor(Color.rgb(104, 241, 175));
        set2 = new BarDataSet(yVals2, "Company B");
        set2.setColor(Color.rgb(164, 228, 251));

        ArrayList<IBarDataSet> dataSets = new ArrayList<IBarDataSet>();
        dataSets.add(set1);
        dataSets.add(set2);

        BarData data = new BarData(dataSets);
        barChart.setData(data);
    }

    barChart.getXAxis().setDrawLabels(true);

    String [] labels = new String[] {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};

    barChart.getXAxis().setValueFormatter(new IndexAxisValueFormatter(labels));

    barChart.getBarData().setBarWidth(barWidth);
    barChart.getXAxis().setAxisMinValue(startYear);
    barChart.getXAxis().setAxisMaximum(endYear);
    barChart.groupBars(startYear, groupSpace, barSpace);

    barChart.setFitBars(true);

    barChart.invalidate();

screenshot_1496168319
screenshot_1496168235

All 9 comments

Can u post a screen shot or plunker to help u ? I have the same chart

Thank you for your response, i've attached a screenshot.

It appears to be grouping into 4 bars and last bar is missing. If i change the "endYear" to something like 6, it groups as 2 but still the last bar is missing.

screenshot_1496139680
screenshot_1496139730

Try to add barChart.getXAxis().setAxisMaximum(endYear)

Thanks for that, it helps solved the issue with the missing last bar.

However, the bars are still grouped as 4's instead of in 2's (see first screenshot)

Are u setting Labels to ValueFormatter ?

Try this barChart.getXAxis().setValueFormatter(new IndexAxisValueFormatter(labels));

Or put ur code on a plunker so I can help u with that

Many thanks for helping. I'm sure i'm just missing a setting somewhere. I've been experimenting and 8 months works fine, but from 10 onwards it groups it as 4.

Screenshots of the two below. Below code was taken from some sample code which very minimal changes so not sure what i've missed!

BarChart barChart = (BarChart) rootView.findViewById(R.id.dashboardCashflowChart);

    barChart.setDrawBarShadow(false);
    barChart.setDrawValueAboveBar(true);
    barChart.setMaxVisibleValueCount(50);
    barChart.setPinchZoom(false);
    barChart.setDrawGridBackground(false);

    XAxis xl = barChart.getXAxis();
    xl.setGranularity(1f);
    xl.setCenterAxisLabels(true);

    YAxis leftAxis = barChart.getAxisLeft();

    leftAxis.setGranularity(1f);
    leftAxis.setDrawGridLines(false);
    leftAxis.setSpaceTop(30f);
    leftAxis.setAxisMinValue(0f); // this replaces setStartAtZero(true
    barChart.getAxisRight().setEnabled(false);

    //data
    float groupSpace = 0.04f;
    float barSpace = 0.02f; // x2 dataset
    float barWidth = 0.46f; // x2 dataset
    // (0.46 + 0.02) * 2 + 0.04 = 1.00 -> interval per "group"

    int startYear = 0;
    int endYear = 8;


    List<BarEntry> yVals1 = new ArrayList<BarEntry>();
    List<BarEntry> yVals2 = new ArrayList<BarEntry>();


    for (int i = startYear; i < endYear; i++) {
        yVals1.add(new BarEntry(i, 0.4f));
    }

    for (int i = startYear; i < endYear; i++) {
        yVals2.add(new BarEntry(i, 0.7f));
    }


    BarDataSet set1, set2;

    if (barChart.getData() != null && barChart.getData().getDataSetCount() > 0) {
        set1 = (BarDataSet)barChart.getData().getDataSetByIndex(0);
        set2 = (BarDataSet)barChart.getData().getDataSetByIndex(1);
        set1.setValues(yVals1);
        set2.setValues(yVals2);
        barChart.getData().notifyDataChanged();
        barChart.notifyDataSetChanged();
    } else {
        // create 2 datasets with different types
        set1 = new BarDataSet(yVals1, "Company A");
        set1.setColor(Color.rgb(104, 241, 175));
        set2 = new BarDataSet(yVals2, "Company B");
        set2.setColor(Color.rgb(164, 228, 251));

        ArrayList<IBarDataSet> dataSets = new ArrayList<IBarDataSet>();
        dataSets.add(set1);
        dataSets.add(set2);

        BarData data = new BarData(dataSets);
        barChart.setData(data);
    }

    barChart.getXAxis().setDrawLabels(true);

    String [] labels = new String[] {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};

    barChart.getXAxis().setValueFormatter(new IndexAxisValueFormatter(labels));

    barChart.getBarData().setBarWidth(barWidth);
    barChart.getXAxis().setAxisMinValue(startYear);
    barChart.getXAxis().setAxisMaximum(endYear);
    barChart.groupBars(startYear, groupSpace, barSpace);

    barChart.setFitBars(true);

    barChart.invalidate();

screenshot_1496168319
screenshot_1496168235

Oh great then please don't forget to close the issue

The code above works for 8, but if i change the "end year" value to 12, it doesnt work and gets grouped as 4 bars. I need it to group as 2

Got this to work by setting - barChart.getXAxis().setLabelCount(12); :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Giammaofwar picture Giammaofwar  路  3Comments

ChenZeFengHi picture ChenZeFengHi  路  3Comments

blotfi picture blotfi  路  3Comments

galex picture galex  路  3Comments

SutharRohit picture SutharRohit  路  3Comments