2

In my Android application I have a bar chart I made using MPAndroidChart. My problem is when there are a number of bars in bar chart then the value labels above each bar are overlapping with other value labels as shown in the attached screen shot below. I know this is because there is no room for displaying the label, but I think this can be avoided if it is possible to rotate the value label by 90 degrees like in XAxis labels in my screen shot. So is that possible? If I zoomed then I can see all values clearly. I am using MPAndroidChart v3.0.1.

MPAndroid Chart

Below is my code.

        yVals1 = new ArrayList<BarEntry>();
    xVals = new ArrayList<String>();
    for (int i = 0; i < listChart.size(); i++){
        BarEntry newBEntry = new BarEntry(i,listChart.get(i).getAmount());
        xVals.add(listChart.get(i).getAltName());
        yVals1.add(newBEntry);
    }
    BarDataSet set1;
    if (bChartRepOne.getData() != null && bChartRepOne.getData().getDataSetCount() > 0) {
        set1 = (BarDataSet) bChartRepOne.getData().getDataSetByIndex(0);
        set1.setValues(yVals1);
        bChartRepOne.getData().notifyDataChanged();
        bChartRepOne.notifyDataSetChanged();
    } else {
        set1 = new BarDataSet(yVals1, chart);
        set1.setColors(ColorTemplate.MATERIAL_COLORS);
        ArrayList<IBarDataSet> dataSets = new ArrayList<IBarDataSet>();
        dataSets.add(set1);
        BarData data = new BarData(dataSets);
        data.setValueTextSize(8f);

        bChartRepOne.setData(data);
    }

    XAxis xAxis = bChartRepOne.getXAxis();
    xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
    xAxis.setDrawGridLines(false);
    xAxis.setLabelCount(xList.size()-1);
    xAxis.setGranularity(1f); // only intervals of 1 day
    xAxis.setValueFormatter(new IAxisValueFormatter() {
        @Override
        public String getFormattedValue(float value, AxisBase axis) {
            if(Math.round(value) >= xList.size()) {
                return null;
            } else {
                return xList.get(Math.round(value));
            }
        }
    });
    xAxis.setLabelRotationAngle(-90);

    YAxis leftAxis = bChartRepOne.getAxisLeft();
    leftAxis.setLabelCount(8, false);
    leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
    leftAxis.setSpaceTop(15f);
    YAxis rightAxis = bChartRepOne.getAxisRight();
    rightAxis.setEnabled(false);

    Legend l = bChartRepOne.getLegend();
    l.setEnabled(false);

    bChartRepOne.setOnChartValueSelectedListener(new OnChartValueSelectedListener() {
        @Override
        public void onValueSelected(Entry entry, Highlight highlight) {

        }

        @Override
        public void onNothingSelected() {

        }
    });
ad absurdum
  • 19,498
  • 5
  • 37
  • 60
KJEjava48
  • 1,967
  • 7
  • 40
  • 69

3 Answers3

1

As of version 3.0.1 there is no method exposed to draw the value labels for a given DataSet on an angle. This is something you can check by using the auto-complete in your IDE when you are working on a DataSet object.

If you want to attempt it yourself, you will have to write a custom renderer and call:

mChart.setRenderer(myCustomRenderer);

To make the custom renderer, you would subclass BarChartRenderer and override the following method:

drawValue(Canvas c, IValueFormatter formatter, float value, Entry entry, int dataSetIndex, float x, float y, int color) 

You would put there the code to render one label at an arbitrary rotation.

There is a method inside Utils called:

drawXAxisValue(Canvas c, String text, float x, float y,
                                  Paint paint,
                                  MPPointF anchor, float angleDegrees)

that contains the code for drawing text at an angle so you can use that as a template.

David Rawson
  • 20,912
  • 7
  • 88
  • 124
  • Can u please show me how to create myCustomRenderer.Also what are the values for c,text,x,y,paint,anchor in drawXAxisValue() ??\ – KJEjava48 Mar 17 '17 at 11:03
  • Is the same solution works for Horizontal bar chart.And also does this method of changing label angles cause any delay?? – KJEjava48 Mar 17 '17 at 11:05
  • @KJEjava48 it's exactly the same for Horizontal bar chart or anywhere else in the library where there is no public API exposed for rotation. This or _any_ method of changing label angles will cause a small (but probably unnoticeable) performance hit. – David Rawson Mar 17 '17 at 21:13
  • @KJEjava48 here's an example where the questioner wrote a custom renderer by themselves. I hope it helps you. If I have time, I'll put some more details for you later about custom renderers: https://stackoverflow.com/questions/41444573/custom-position-for-bar-values/41514885#41514885 – David Rawson Mar 17 '17 at 21:17
  • here values of each bar's are getting overlapped,what will do if the axis labels when overlapped as here "http://stackoverflow.com/questions/42731804/mpandroidchart-horizontalbarchart-labels-overlapping?noredirect=1#comment72793824_42731804" .Does the same solution work for both the case?? – KJEjava48 Mar 18 '17 at 04:22
1

I rotated the values in bar chart. It may help to someone. code is

public class MyBarChartRenderer extends BarChartRenderer {
public MyBarChartRenderer(BarDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler) {
    super(chart, animator, viewPortHandler);
}



@Override
public void drawValue(Canvas c, IValueFormatter formatter, float value, Entry entry, int dataSetIndex, float x, float y, int color) {

    // super.drawValue(c, formatter, value, entry, dataSetIndex, x, y, color);

    Paint paint=super.mDrawPaint;
    paint.setTextSize(25f);
    paint.setTextAlign(Paint.Align.CENTER);
    paint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
    Utils.drawXAxisValue(c,value,x,y,paint, MPPointF.getInstance(),270);
}}
selva_pollachi
  • 4,147
  • 4
  • 29
  • 42
1

Here is the complete code for custom renderer to rotate text at -60 degrees

public class CustomBarChartRenderer extends BarChartRenderer {

    public CustomBarChartRenderer(BarDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler) {
        super(chart, animator, viewPortHandler);
    }

    @Override
    public void drawValue(Canvas canvas, IValueFormatter formatter, float value, Entry entry, int dataSetIndex, float x, float y, int color) {
        mValuePaint.setColor(color);

        canvas.save();
        canvas.rotate(-60, x, y);

        canvas.drawText(formatter.getFormattedValue(value, entry, dataSetIndex, mViewPortHandler), x, y, mValuePaint);
        canvas.restore();

        /*
        Alternate solution
        Paint paint = super.mDrawPaint;
        paint.setTextSize(25f);

        //paint.setTextAlign(Paint.Align.CENTER);
        //paint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.NORMAL));
        Utils.drawXAxisValue(c, value + "", x, y, paint, MPPointF.getInstance(), -60);
        */
    }

}

And to set renderer use :

barChart.setRenderer(new CustomBarChartRenderer(barChart, barChart.getAnimator(), barChart.getViewPortHandler()));
Sumit Sahoo
  • 2,949
  • 1
  • 25
  • 37