MPAndroidChart - 圆边条形图

时间:2015-06-10 15:40:57

标签: android mpandroidchart

我正在尝试创建如下图表,对于我的Android应用程序使用MPAndroidChart。我无法弄清楚,如何使条形图的边缘呈圆形边缘。它始终是方形边缘。

enter image description here

那么请你建议我应该做些什么?

提前感谢您的帮助。

8 个答案:

答案 0 :(得分:8)

我已经实现了一个解决方案来直接实现库本身。

首先创建一个attrs.xml,添加一个要在图表视图中使用的新属性。像这样:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="BarChart">
        <attr name="radius" format="integer" />
    </declare-styleable>
</resources>

然后在BarChartRenderer上编辑名为drawDataSet的方法:

protected void drawDataSet(Canvas c, BarDataSet dataSet, int index) {

    Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());

    mShadowPaint.setColor(dataSet.getBarShadowColor());

    float phaseX = mAnimator.getPhaseX();
    float phaseY = mAnimator.getPhaseY();

    List<BarEntry> entries = dataSet.getYVals();

    // initialize the buffer
    BarBuffer buffer = mBarBuffers[index];
    buffer.setPhases(phaseX, phaseY);
    buffer.setBarSpace(dataSet.getBarSpace());
    buffer.setDataSet(index);
    buffer.setInverted(mChart.isInverted(dataSet.getAxisDependency()));

    buffer.feed(entries);

    trans.pointValuesToPixel(buffer.buffer);

    // if multiple colors
    if (dataSet.getColors().size() > 1) {

        for (int j = 0; j < buffer.size(); j += 4) {

            if (!mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2]))
                continue;

            if (!mViewPortHandler.isInBoundsRight(buffer.buffer[j]))
                break;

            if (mChart.isDrawBarShadowEnabled()) {
                if (mRadius > 0)
                    c.drawRoundRect(new RectF(buffer.buffer[j], mViewPortHandler.contentTop(),
                            buffer.buffer[j + 2],
                            mViewPortHandler.contentBottom()), mRadius, mRadius, mShadowPaint);
                else
                    c.drawRect(buffer.buffer[j], mViewPortHandler.contentTop(),
                            buffer.buffer[j + 2],
                            mViewPortHandler.contentBottom(), mShadowPaint);
            }

            // Set the color for the currently drawn value. If the index
            // is
            // out of bounds, reuse colors.
            mRenderPaint.setColor(dataSet.getColor(j / 4));
            if (mRadius > 0)
                c.drawRoundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
                        buffer.buffer[j + 3]), mRadius, mRadius, mRenderPaint);
            else
                c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
                        buffer.buffer[j + 3], mRenderPaint);
        }
    } else {

        mRenderPaint.setColor(dataSet.getColor());

        for (int j = 0; j < buffer.size(); j += 4) {

            if (!mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2]))
                continue;

            if (!mViewPortHandler.isInBoundsRight(buffer.buffer[j]))
                break;

            if (mChart.isDrawBarShadowEnabled()) {
                if (mRadius > 0)
                    c.drawRoundRect(new RectF(buffer.buffer[j], mViewPortHandler.contentTop(),
                            buffer.buffer[j + 2],
                            mViewPortHandler.contentBottom()), mRadius, mRadius, mShadowPaint);
                else
                    c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
                            buffer.buffer[j + 3], mRenderPaint);
            }

            if (mRadius > 0)
                c.drawRoundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
                        buffer.buffer[j + 3]), mRadius, mRadius, mRenderPaint);
            else
                c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
                        buffer.buffer[j + 3], mRenderPaint);
        }
    }
}

通过执行此操作,您将更改矩形但不更改其高亮显示,因此请在drawHighlighted方法上更改此代码:

if (mRadius > 0)
      c.drawRoundRect(mBarRect, mRadius, mRadius, mHighlightPaint);
else
      c.drawRect(mBarRect, mHighlightPaint);

要将xml文件中的属性添加到此渲染中,您还需要添加set方法:

public void setRadius (int radius) {
        mRadius = radius;
}

最后在BarChart对象上创建一个新的构造函数来获取radius属性:

public BarChart(Context context, AttributeSet attrs) {
        super(context, attrs);
        mRadius = attrs.getAttributeIntValue("http://schemas.android.com/apk/res-auto", "radius", 0);
        ((BarChartRenderer)mRenderer).setRadius(mRadius);
    }

瞧!快乐的编码:)

答案 1 :(得分:3)

我尝试将@mallaudin和@Janusz Hain代码组合在一起。现在正在工作,谢谢!!! 这是我的代码

public class CustomBarChartRender extends BarChartRenderer {

private RectF mBarShadowRectBuffer = new RectF();

private int mRadius;

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

public void setRadius(int mRadius) {
    this.mRadius = mRadius;
}

protected void drawDataSet(Canvas c, IBarDataSet dataSet, int index) {

    Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());
    mBarBorderPaint.setColor(dataSet.getBarBorderColor());
    mBarBorderPaint.setStrokeWidth(Utils.convertDpToPixel(dataSet.getBarBorderWidth()));
    mShadowPaint.setColor(dataSet.getBarShadowColor());
    boolean drawBorder = dataSet.getBarBorderWidth() > 0f;

    float phaseX = mAnimator.getPhaseX();
    float phaseY = mAnimator.getPhaseY();

    if (mChart.isDrawBarShadowEnabled()) {
        mShadowPaint.setColor(dataSet.getBarShadowColor());

        BarData barData = mChart.getBarData();

        float barWidth = barData.getBarWidth();
        float barWidthHalf = barWidth / 2.0f;
        float x;

        int i = 0;
        double count = Math.min(Math.ceil((int) (double) ((float) dataSet.getEntryCount() * phaseX)), dataSet.getEntryCount());
        while (i < count) {

            BarEntry e = dataSet.getEntryForIndex(i);

            x = e.getX();

            mBarShadowRectBuffer.left = x - barWidthHalf;
            mBarShadowRectBuffer.right = x + barWidthHalf;

            trans.rectValueToPixel(mBarShadowRectBuffer);

            if (!mViewPortHandler.isInBoundsLeft(mBarShadowRectBuffer.right)) {
                i++;
                continue;
            }

            if (!mViewPortHandler.isInBoundsRight(mBarShadowRectBuffer.left))
                break;

            mBarShadowRectBuffer.top = mViewPortHandler.contentTop();
            mBarShadowRectBuffer.bottom = mViewPortHandler.contentBottom();

            c.drawRoundRect(mBarRect, mRadius, mRadius, mShadowPaint);
            i++;
        }
    }

    // initialize the buffer
    BarBuffer buffer = mBarBuffers[index];
    buffer.setPhases(phaseX, phaseY);
    buffer.setDataSet(index);
    buffer.setInverted(mChart.isInverted(dataSet.getAxisDependency()));
    buffer.setBarWidth(mChart.getBarData().getBarWidth());

    buffer.feed(dataSet);

    trans.pointValuesToPixel(buffer.buffer);

    boolean isSingleColor = dataSet.getColors().size() == 1;

    if (isSingleColor) {
        mRenderPaint.setColor(dataSet.getColor());
    }

    int j = 0;
    while (j < buffer.size()) {

        if (!mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2])) {
            j += 4;
            continue;
        }

        if (!mViewPortHandler.isInBoundsRight(buffer.buffer[j]))
            break;

        if (!isSingleColor) {
            // Set the color for the currently drawn value. If the index
            // is out of bounds, reuse colors.
            mRenderPaint.setColor(dataSet.getColor(j / 4));
        }

        if (dataSet.getGradientColor() != null) {
            GradientColor gradientColor = dataSet.getGradientColor();
            mRenderPaint.setShader(new LinearGradient(
                    buffer.buffer[j],
                    buffer.buffer[j + 3],
                    buffer.buffer[j],
                    buffer.buffer[j + 1],
                    gradientColor.getStartColor(),
                    gradientColor.getEndColor(),
                    android.graphics.Shader.TileMode.MIRROR));
        }

        if (dataSet.getGradientColors() != null) {
            mRenderPaint.setShader(new LinearGradient(
                    buffer.buffer[j],
                    buffer.buffer[j + 3],
                    buffer.buffer[j],
                    buffer.buffer[j + 1],
                    dataSet.getGradientColor(j / 4).getStartColor(),
                    dataSet.getGradientColor(j / 4).getEndColor(),
                    Shader.TileMode.MIRROR));
        }
        Path path2 = roundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
                buffer.buffer[j + 3]), mRadius, mRadius, true, true, false, false);
        c.drawPath(path2, mRenderPaint);
        if (drawBorder) {
            Path path = roundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
                    buffer.buffer[j + 3]), mRadius, mRadius, true, true, false, false);
            c.drawPath(path, mBarBorderPaint);
        }
        j += 4;
    }

}

private Path roundRect(RectF rect, float rx, float ry, boolean tl, boolean tr, boolean br, boolean bl) {
    float top = rect.top;
    float left = rect.left;
    float right = rect.right;
    float bottom = rect.bottom;
    Path path = new Path();
    if (rx < 0) rx = 0;
    if (ry < 0) ry = 0;
    float width = right - left;
    float height = bottom - top;
    if (rx > width / 2) rx = width / 2;
    if (ry > height / 2) ry = height / 2;
    float widthMinusCorners = (width - (2 * rx));
    float heightMinusCorners = (height - (2 * ry));

    path.moveTo(right, top + ry);
    if (tr)
        path.rQuadTo(0, -ry, -rx, -ry);//top-right corner
    else {
        path.rLineTo(0, -ry);
        path.rLineTo(-rx, 0);
    }
    path.rLineTo(-widthMinusCorners, 0);
    if (tl)
        path.rQuadTo(-rx, 0, -rx, ry); //top-left corner
    else {
        path.rLineTo(-rx, 0);
        path.rLineTo(0, ry);
    }
    path.rLineTo(0, heightMinusCorners);

    if (bl)
        path.rQuadTo(0, ry, rx, ry);//bottom-left corner
    else {
        path.rLineTo(0, ry);
        path.rLineTo(rx, 0);
    }

    path.rLineTo(widthMinusCorners, 0);
    if (br)
        path.rQuadTo(rx, 0, rx, -ry); //bottom-right corner
    else {
        path.rLineTo(rx, 0);
        path.rLineTo(0, -ry);
    }

    path.rLineTo(0, -heightMinusCorners);

    path.close();//Given close, last lineto can be removed.

    return path;
}}

在其他班级:

CustomBarChartRender barChartRender = new CustomBarChartRender(barChart,barChart.getAnimator(), barChart.getViewPortHandler());
    barChartRender.setRadius(20);
    barChart.setRenderer(barChartRender);

答案 2 :(得分:2)

为此,您需要对BarchartRenderer类进行custimze ....

第1步

创建一个自定义类(如果你没有将mpchart作为模块添加)复制将BarchartRenderer类中的所有代码粘贴到你的自定义类中。 现在用我的自定义类.....替换你的drawDataSet方法.....

第2步

将setRender转换为刚刚创建的自定义类。

用于设置渲染Java代码的Kotlin代码将有点相同。

最后享受

BarChartCustomRenderer customRenderer = BarChartCustomRenderer(mDashBoardBinding.topperChart, mDashBoardBinding.topperChart.getAnimator(), mDashBoardBinding.topperChart.getViewPortHandler());

topperChart.setRenderer(customRenderer);

drawDataSet

protected void drawDataSet(Canvas c, IBarDataSet dataSet, int index) {

            Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());

            mShadowPaint.setColor(dataSet.getBarShadowColor());

            float phaseX = mAnimator.getPhaseX();
            float phaseY = mAnimator.getPhaseY();


            // initialize the buffer
            BarBuffer buffer = mBarBuffers[index];
            buffer.setPhases(phaseX, phaseY);
            buffer.setDataSet(index);
            buffer.setBarWidth(mChart.getBarData().getBarWidth());
            buffer.setInverted(mChart.isInverted(dataSet.getAxisDependency()));

            buffer.feed(dataSet);

            trans.pointValuesToPixel(buffer.buffer);

            // if multiple colors
            if (dataSet.getColors().size() > 1) {

                for (int j = 0; j < buffer.size(); j += 4) {

                    if (!mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2]))
                        continue;

                    if (!mViewPortHandler.isInBoundsRight(buffer.buffer[j]))
                        break;

                    if (mChart.isDrawBarShadowEnabled()) {
                        if (mRadius > 0)
                            c.drawRoundRect(new RectF(buffer.buffer[j], mViewPortHandler.contentTop(),
                                    buffer.buffer[j + 2],
                                    mViewPortHandler.contentBottom()), mRadius, mRadius, mShadowPaint);
                        else
                            c.drawRect(buffer.buffer[j], mViewPortHandler.contentTop(),
                                    buffer.buffer[j + 2],
                                    mViewPortHandler.contentBottom(), mShadowPaint);
                    }

                    // Set the color for the currently drawn value. If the index
                    // is
                    // out of bounds, reuse colors.
                    mRenderPaint.setColor(dataSet.getColor(j / 4));
                    if (mRadius > 0)
                        c.drawRoundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
                                buffer.buffer[j + 3]), mRadius, mRadius, mRenderPaint);
                    else
                        c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
                                buffer.buffer[j + 3], mRenderPaint);
                }
            } else {

                mRenderPaint.setColor(dataSet.getColor());

                for (int j = 0; j < buffer.size(); j += 4) {

                    if (!mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2]))
                        continue;

                    if (!mViewPortHandler.isInBoundsRight(buffer.buffer[j]))
                        break;

                    if (mChart.isDrawBarShadowEnabled()) {
                        if (mRadius > 0)
                            c.drawRoundRect(new RectF(buffer.buffer[j], mViewPortHandler.contentTop(),
                                    buffer.buffer[j + 2],
                                    mViewPortHandler.contentBottom()), mRadius, mRadius, mShadowPaint);
                        else
                            c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
                                    buffer.buffer[j + 3], mRenderPaint);
                    }

                    if (mRadius > 0)
                        c.drawRoundRect(new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
                                buffer.buffer[j + 3]), mRadius, mRadius, mRenderPaint);
                    else
                        c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
                                buffer.buffer[j + 3], mRenderPaint);
                }
            }
        }

答案 3 :(得分:1)

上述答案是正确的,但如果图表具有负值则不起作用。

我选择了this答案的圆角矩形代码。

<强>步骤

  1. 将以下方法添加到BarChartRenderer

    /**
     * @param rect rectangle to be rounded
     * @param rx   radius x
    * @param ry   radius y
    * @param tl   true - for rounding top-left corner
    * @param tr   true - for rounding top-right corner
    * @param br   true - for rounding bottom-right corner
    * @param bl   true - for rounding bottom-left corner
    * @return path
    */
    private Path roundRect(RectF rect, float rx, float ry, boolean tl, boolean tr, boolean br, boolean bl) {
    float top = rect.top;
    float left = rect.left;
    float right = rect.right;
    float bottom = rect.bottom;
    Path path = new Path();
    if (rx < 0) rx = 0;
    if (ry < 0) ry = 0;
    float width = right - left;
    float height = bottom - top;
    if (rx > width / 2) rx = width / 2;
    if (ry > height / 2) ry = height / 2;
    float widthMinusCorners = (width - (2 * rx));
    float heightMinusCorners = (height - (2 * ry));
    
    path.moveTo(right, top + ry);
    if (tr)
        path.rQuadTo(0, -ry, -rx, -ry);//top-right corner
    else {
        path.rLineTo(0, -ry);
        path.rLineTo(-rx, 0);
    }
    path.rLineTo(-widthMinusCorners, 0);
    if (tl)
        path.rQuadTo(-rx, 0, -rx, ry); //top-left corner
    else {
        path.rLineTo(-rx, 0);
        path.rLineTo(0, ry);
    }
    path.rLineTo(0, heightMinusCorners);
    
    if (bl)
        path.rQuadTo(0, ry, rx, ry);//bottom-left corner
    else {
        path.rLineTo(0, ry);
        path.rLineTo(rx, 0);
    }
    
    path.rLineTo(widthMinusCorners, 0);
    if (br)
        path.rQuadTo(rx, 0, rx, -ry); //bottom-right corner
    else {
        path.rLineTo(rx, 0);
        path.rLineTo(0, -ry);
    }
    
    path.rLineTo(0, -heightMinusCorners);
    
    path.close();//Given close, last lineto can be removed.
    
    return path;
    }
    
  2. drawDataSet(Canvas c, IBarDataSet dataSet, int index)方法中,使用以下代码替换所有 drawRoundRect方法

     Path path = roundRect(yourRect, yourRadius, yourRadius, true, true, false, false);
                    canvas.drawPath(path, yourPaint);
    

答案 4 :(得分:1)

我已经基于上述内容为实际库创建了类(具有用于绘制的不同代码)-v3.1.0-alpha

class RoundedBarChartRenderer(chart: BarDataProvider,
                          animator: ChartAnimator,
                          viewPortHandler: ViewPortHandler,
                          private val mRadius: Float) :
    BarChartRenderer(chart, animator, viewPortHandler) {

private val mBarShadowRectBuffer = RectF()

override fun drawDataSet(c: Canvas?, dataSet: IBarDataSet?, index: Int) {

    if (c == null || dataSet == null) return

    val trans = mChart.getTransformer(dataSet.axisDependency)

    mBarBorderPaint.color = dataSet.barBorderColor
    mBarBorderPaint.strokeWidth = Utils.convertDpToPixel(dataSet.barBorderWidth)

    val drawBorder = dataSet.barBorderWidth > 0f

    val phaseX = mAnimator.phaseX
    val phaseY = mAnimator.phaseY

    // draw the bar shadow before the values
    if (mChart.isDrawBarShadowEnabled) {
        mShadowPaint.color = dataSet.barShadowColor

        val barData = mChart.barData

        val barWidth = barData.barWidth
        val barWidthHalf = barWidth / 2.0f
        var x: Float

        var i = 0
        val count = Math.min(Math.ceil((dataSet.entryCount.toFloat() * phaseX).toDouble()).toInt(), dataSet.entryCount)
        while (i < count) {

            val e = dataSet.getEntryForIndex(i)

            x = e.x

            mBarShadowRectBuffer.left = x - barWidthHalf
            mBarShadowRectBuffer.right = x + barWidthHalf

            trans.rectValueToPixel(mBarShadowRectBuffer)

            if (!mViewPortHandler.isInBoundsLeft(mBarShadowRectBuffer.right)) {
                i++
                continue
            }

            if (!mViewPortHandler.isInBoundsRight(mBarShadowRectBuffer.left))
                break

            mBarShadowRectBuffer.top = mViewPortHandler.contentTop()
            mBarShadowRectBuffer.bottom = mViewPortHandler.contentBottom()

            c.drawRoundRect(mBarRect, mRadius, mRadius, mShadowPaint)
            i++
        }
    }

    // initialize the buffer
    val buffer = mBarBuffers[index]
    buffer.setPhases(phaseX, phaseY)
    buffer.setDataSet(index)
    buffer.setInverted(mChart.isInverted(dataSet.axisDependency))
    buffer.setBarWidth(mChart.barData.barWidth)

    buffer.feed(dataSet)

    trans.pointValuesToPixel(buffer.buffer)

    val isSingleColor = dataSet.colors.size == 1

    if (isSingleColor) {
        mRenderPaint.color = dataSet.color
    }

    var j = 0
    while (j < buffer.size()) {

        if (!mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2])) {
            j += 4
            continue
        }

        if (!mViewPortHandler.isInBoundsRight(buffer.buffer[j]))
            break

        if (!isSingleColor) {
            // Set the color for the currently drawn value. If the index
            // is out of bounds, reuse colors.
            mRenderPaint.color = dataSet.getColor(j / 4)
        }

        if (dataSet.gradientColor != null) {
            val gradientColor = dataSet.gradientColor
            mRenderPaint.shader = LinearGradient(
                    buffer.buffer[j],
                    buffer.buffer[j + 3],
                    buffer.buffer[j],
                    buffer.buffer[j + 1],
                    gradientColor.startColor,
                    gradientColor.endColor,
                    android.graphics.Shader.TileMode.MIRROR)
        }

        if (dataSet.gradientColors != null) {
            mRenderPaint.shader = LinearGradient(
                    buffer.buffer[j],
                    buffer.buffer[j + 3],
                    buffer.buffer[j],
                    buffer.buffer[j + 1],
                    dataSet.getGradientColor(j / 4).startColor,
                    dataSet.getGradientColor(j / 4).endColor,
                    Shader.TileMode.MIRROR)
        }


        c.drawRoundRect(RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
                buffer.buffer[j + 3]), mRadius, mRadius, mRenderPaint)

        if (drawBorder) {
            c.drawRoundRect(RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
                    buffer.buffer[j + 3]), mRadius, mRadius, mBarBorderPaint)
        }
        j += 4
    }
}

}

答案 5 :(得分:1)

您可以使用@Xan 提供的要点,如果您希望两边都是圆边,您可以实现要点并为条形图视图提供以下属性

barChartView.axisLeft.axisMinimum = 0f;

这将使两边变圆。

答案 6 :(得分:0)

从MPAndroidChart的最后一个代码创建了一个完整的要点

https://gist.github.com/xanscale/e971cc4f2f0712a8a3bcc35e85325c27

答案 7 :(得分:0)

1)添加以下类:

public class RoundedBarChart extends BarChartRenderer {


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

    private float mRadius=5f;

    public void setmRadius(float mRadius) {
        this.mRadius = mRadius;
    }

    @Override
    protected void drawDataSet(Canvas c, IBarDataSet dataSet, int index) {

     
            Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());

            mShadowPaint.setColor(dataSet.getBarShadowColor());

            float phaseX = mAnimator.getPhaseX();
            float phaseY = mAnimator.getPhaseY();



            if(mBarBuffers!=null){
                // initialize the buffer
                BarBuffer buffer = mBarBuffers[index];
                buffer.setPhases(phaseX, phaseY);
                buffer.setDataSet(index);
                buffer.setBarWidth(mChart.getBarData().getBarWidth());
                buffer.setInverted(mChart.isInverted(dataSet.getAxisDependency()));

                buffer.feed(dataSet);

                trans.pointValuesToPixel(buffer.buffer);

                // if multiple colors
                if (dataSet.getColors().size() > 1) {

                    for (int j = 0; j < buffer.size(); j += 4) {

                        if (!mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2]))
                            continue;

                        if (!mViewPortHandler.isInBoundsRight(buffer.buffer[j]))
                            break;

                        if (mChart.isDrawBarShadowEnabled()) {
                            if (mRadius > 0)
                                c.drawRoundRect(new RectF(buffer.buffer[j], mViewPortHandler.contentTop(), buffer.buffer[j + 2], mViewPortHandler.contentBottom()), mRadius, mRadius, mShadowPaint);
                            else
                                c.drawRect(buffer.buffer[j], mViewPortHandler.contentTop(), buffer.buffer[j + 2], mViewPortHandler.contentBottom(), mShadowPaint);
                        }

                        // Set the color for the currently drawn value. If the index
                        // is
                        // out of bounds, reuse colors.
                        mRenderPaint.setColor(dataSet.getColor(j / 4));
                        if (mRadius > 0){

                            Path path = RoundedRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2] , buffer.buffer[j + 3] , 15,15, true, true, false, false);
                            c.drawPath(path,mRenderPaint);
                        }
                        else
                            c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], buffer.buffer[j + 3], mRenderPaint);


                    }
                } else {

                    mRenderPaint.setColor(dataSet.getColor());

                    for (int j = 0; j < buffer.size(); j += 4) {

                        if (!mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2]))
                            continue;

                        if (!mViewPortHandler.isInBoundsRight(buffer.buffer[j]))
                            break;

                        if (mChart.isDrawBarShadowEnabled()) {
                            if (mRadius > 0)
                                c.drawRoundRect(new RectF(buffer.buffer[j], mViewPortHandler.contentTop(),
                                        buffer.buffer[j + 2],
                                        mViewPortHandler.contentBottom()), mRadius, mRadius, mShadowPaint);
                            else
                                c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
                                        buffer.buffer[j + 3], mRenderPaint);
                        }

                        if (mRadius > 0){
                            Path path = RoundedRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2] , buffer.buffer[j + 3] , 15,15, true, true, false, false);
                            c.drawPath(path,mRenderPaint);
                        }
                        else
                            c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
                                    buffer.buffer[j + 3], mRenderPaint);
                    }
                }
            }
        
    }
    public static Path RoundedRect(
            float left, float top, float right, float bottom, float rx, float ry,
            boolean tl, boolean tr, boolean br, boolean bl
    ){
        Path path = new Path();
        if (rx < 0) rx = 0;
        if (ry < 0) ry = 0;
        float width = right - left;
        float height = bottom - top;
        if (rx > width / 2) rx = width / 2;
        if (ry > height / 2) ry = height / 2;
        float widthMinusCorners = (width - (2 * rx));
        float heightMinusCorners = (height - (2 * ry));

        path.moveTo(right, top + ry);
        if (tr)
            path.rQuadTo(0, -ry, -rx, -ry);//top-right corner
        else{
            path.rLineTo(0, -ry);
            path.rLineTo(-rx,0);
        }
        path.rLineTo(-widthMinusCorners, 0);
        if (tl)
            path.rQuadTo(-rx, 0, -rx, ry); //top-left corner
        else{
            path.rLineTo(-rx, 0);
            path.rLineTo(0,ry);
        }
        path.rLineTo(0, heightMinusCorners);

        if (bl)
            path.rQuadTo(0, ry, rx, ry);//bottom-left corner
        else{
            path.rLineTo(0, ry);
            path.rLineTo(rx,0);
        }

        path.rLineTo(widthMinusCorners, 0);
        if (br)
            path.rQuadTo(rx, 0, rx, -ry); //bottom-right corner
        else{
            path.rLineTo(rx,0);
            path.rLineTo(0, -ry);
        }

        path.rLineTo(0, -heightMinusCorners);

        path.close();//Given close, last lineto can be removed.

        return path;
    }
}

2)使用barChart.renderer = RoundedBarChart(barChart, barChart.animator, barChart.viewPortHandler)