9

I'm using the MPAndroidChart library to create bar charts.

We can use the following to show the bar values on top of the bar.

mChart.setDrawValueAboveBar(false);

or we can use this :

barDataSet.setDrawValues(true);

to show the bar values inside the bar itself. I want to know if we can set a custom position for the values. For example below the y-axis.

enter image description here

Solution

public class TextBarChartRenderer extends BarChartRenderer {

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

    @Override
    public void drawValues(Canvas c) {
        List<IBarDataSet> dataSets = mChart.getBarData().getDataSets();

        final float valueOffsetPlus = Utils.convertDpToPixel(22f)
        float negOffset;

        for (int i = 0; i < mChart.getBarData().getDataSetCount(); i++) {

            IBarDataSet dataSet = dataSets.get(i);
            applyValueTextStyle(dataSet);
            float valueTextHeight = Utils.calcTextHeight(mValuePaint, "8");
            negOffset = valueTextHeight + valueOffsetPlus;

            BarBuffer buffer = mBarBuffers[i];

            float left;
            float right;
            float top;
            float bottom;

            for (int j = 0; j < buffer.buffer.length * mAnimator.getPhaseX(); j += 4) {

                left = buffer.buffer[j];
                right = buffer.buffer[j + 2];
                top = buffer.buffer[j + 1];
                bottom = buffer.buffer[j + 3];

                float x = (left + right) / 2f;

                if (!mViewPortHandler.isInBoundsRight(x))
                    break;

                if (!mViewPortHandler.isInBoundsY(top) || !mViewPortHandler.isInBoundsLeft(x))
                    continue;

                BarEntry entry = dataSet.getEntryForIndex(j / 4);
                float val = entry.getY();

                if(val > 0) {
                    drawValue(c, dataSet.getValueFormatter(), val, entry, i, x,
                            (bottom + negOffset),
                            dataSet.getValueTextColor(j / 4));
                }
            }
        }

    }
}

Also had to add this so that the values are visible

mChart.setExtraOffsets(0, 0, 0, 20);
sauvik
  • 2,224
  • 1
  • 17
  • 25

2 Answers2

4

There is no method in the API exposed for changing the position of the value labels to below the YAxis. You will probably have to extend and modify the library to meet your uncommon requirement.

One option to try would be to implement an IAxisValueFormatter on the XAxis to render y-values instead of x-values. A simple example could re-use the existing IndexAxisValueFormatter. Let's say you have the labels for the y-values in a String [] called yLabels. You can now do this:

mChart.getXAxis().setValueFormatter(new IndexAxisValueFormatter(yLabels));

If that doesn't work, you will have to look at the source for BarChartRenderer. There is a method called drawValues() which you can override to achieve the effect you want.

So you would have something like:

public class MyBarChartRenderer extends BarChartRenderer {

    //TODO: a constructor matching the superclass

    @Override
    public void drawValues(Canvas c) {
        //TODO: copy and paste the code from the superclass and simply
        //change the offset for drawing the labels
    }
}
David Rawson
  • 20,912
  • 7
  • 88
  • 124
  • 1
    I tried the IAxisValueFormatter and I could display the yValues on the x-axis but they were adjacent to the actual xValues label. I couldn't display the values one below the other. I'll try to overrided the drawValues() method next. Thanks. – sauvik Jan 15 '17 at 20:22
  • @amarok that's great! there are examples of overriding the rendering functions [here](https://stackoverflow.com/questions/41340819/mpandroidchart-add-custom-image-inside-bars/41373250#41373250) and [here](https://stackoverflow.com/questions/31201874/mpandroidchart-linechart-custom-highlight-drawable/41312738#41312738) – David Rawson Jan 15 '17 at 20:26
  • It worked. I have posted my code. Thanks for all your help :) – sauvik Jan 28 '17 at 21:53
  • @amarok That's great. Well done! You can post it as an answer if you want. Then accept your answer – David Rawson Jan 28 '17 at 21:55
  • This question for how to write a custom renderer: http://stackoverflow.com/q/43443787 – David Rawson May 01 '17 at 05:46
0

In version 3.1.0 of the MPAndroidCharts setting mChart.setDrawValueAboveBar(false); will draw the values below the top of the bar.

The Berga
  • 3,744
  • 2
  • 31
  • 34
  • @AnirbanDas, maybe you have another setting overriding the `setDrawValueAboveBar`. Check their examples and create a very basic chart and test it out. Also check if you are using the latest version. – The Berga Mar 04 '20 at 10:02