Custom position for bar values

2019-02-19 05:24发布

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

1条回答
【Aperson】
2楼-- · 2019-02-19 05:38

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
    }
}
查看更多
登录 后发表回答