android MPDroidChart-圆边条形图

bpzcxfmw  于 2023-01-03  发布在  Android
关注(0)|答案(9)|浏览(153)

我正试图创建一个图表如下,为我的Android应用程序使用MPEandroidChart.我无法弄清楚,如何使条形图的边缘为圆边.它总是来作为方边.

所以你能建议我该怎么做吗?
先谢谢你的帮助。

kx1ctssn

kx1ctssn1#

我尝试组合@mallaudin和@Janusz海恩代码。它的工作现在,谢谢!!!这是我的代码

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

j1dl9f462#

我已经实现了一个解决方案来直接在库本身上实现这一点。
首先创建一个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);
    }

瞧!快乐的编码:)

k2arahey

k2arahey3#

从MPEandroidChart的最后代码创建了一个完整的要点
https://gist.github.com/xanscale/e971cc4f2f0712a8a3bcc35e85325c27

eivgtgni

eivgtgni4#

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

iq3niunx

iq3niunx5#

为此,您需要自定义BarchartRenderer类....

    • 步骤1**

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

    • 第二步**

之后,将setRender设置为您刚刚创建的自定义类。
Kotlin代码设置渲染Java代码将有点相同。
最后享受

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

topperChart.setRenderer(customRenderer);
    • 绘制数据集**:
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);
                }
            }
        }
0sgqnhkj

0sgqnhkj6#

我已经创建了基于上述实际库(其中有不同的代码绘图)- v3.1.0-阿尔法类

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
    }
}

}

rqcrx0a6

rqcrx0a67#

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

barChartView.axisLeft.axisMinimum = 0f;

这将使两侧都变圆。

pkbketx9

pkbketx98#

上面的答案是正确的,但是如果图形有负值,它就不起作用
我已经选择了圆角矩形代码形式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;
}

1.在drawDataSet(Canvas c, IBarDataSet dataSet, int index)方法中,将alldrawRoundRect方法替换为以下代码

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

gpfsuwkq9#

用@duc tan的答案,我解决了这个问题,但是他的代码没有处理高亮。2我添加下面的代码来解决高亮角。

public void drawHighlighted(Canvas c, Highlight[] indices) {
        BarData barData = mChart.getBarData();

        for (Highlight high : indices) {

            IBarDataSet set = barData.getDataSetByIndex(high.getDataSetIndex());

            if (set == null || !set.isHighlightEnabled()) {
                continue;
            }

            BarEntry e = set.getEntryForXValue(high.getX(), high.getY());

            if (!isInBoundsX(e, set)) {
                continue;
            }

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

            mHighlightPaint.setColor(set.getHighLightColor());
            mHighlightPaint.setAlpha(set.getHighLightAlpha());

            boolean isStack = high.getStackIndex() >= 0 && e.isStacked();

            final float y1;
            final float y2;

            if (isStack) {

                if (mChart.isHighlightFullBarEnabled()) {

                    y1 = e.getPositiveSum();
                    y2 = -e.getNegativeSum();

                } else {

                    Range range = e.getRanges()[high.getStackIndex()];

                    y1 = range.from;
                    y2 = range.to;
                }

            } else {
                y1 = e.getY();
                y2 = 0.f;
            }

            prepareBarHighlight(e.getX(), y1, y2, barData.getBarWidth() / 2f, trans);

            setHighlightDrawPos(high, mBarRect);

            Path path2 = roundRect(new RectF(mBarRect.left, mBarRect.top, mBarRect.right,
                    mBarRect.bottom), mRadius, mRadius, true, true, false, false);

            c.drawPath(path2, mHighlightPaint);
        }
    }

相关问题