【问题标题】:Round Corners for both Negative and Positive bars of horizontal bar chart using MpAndroidChart使用 MpAndroidChart 的水平条形图的负条和正条的圆角
【发布时间】:2023-04-07 13:58:02
【问题描述】:

我正在尝试使水平条形图的角变圆,这是 CustomChartRenderer 代码:

package com.almaraiquest.Utils

import android.graphics.*
import com.github.mikephil.charting.animation.ChartAnimator
import com.github.mikephil.charting.interfaces.dataprovider.BarDataProvider
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet
import com.github.mikephil.charting.renderer.HorizontalBarChartRenderer
import com.github.mikephil.charting.utils.ViewPortHandler


class MyCustomChartRender(chart: BarDataProvider, animator: ChartAnimator, viewPortHandler: ViewPortHandler) : HorizontalBarChartRenderer(chart, animator, viewPortHandler) {

    override fun drawDataSet(c: Canvas?, dataSet: IBarDataSet?, index: Int) {
        super.drawDataSet(c, dataSet, index)
        val trans = mChart.getTransformer(dataSet!!.axisDependency)

        mShadowPaint.color = dataSet.barShadowColor

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

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

        buffer.feed(dataSet)

        trans.pointValuesToPixel(buffer.buffer)

        val length = buffer.buffer.size
        var left = 0f
        var right = 0f
        val top = buffer.buffer[length - 3]
        val bot = buffer.buffer[length - 1]
        var leftSaved = false


            var j = 0
            while (j < buffer.size()) {
                if (!mViewPortHandler.isInBoundsTop(buffer.buffer[j + 3])) break
                if (!mViewPortHandler.isInBoundsBottom(buffer.buffer[j + 1])) {
                    j += 4
                    continue
                }
                // Set the color for the currently drawn value.
// If the index is
// out of bounds, reuse colors.
                val color = dataSet.getColor(j / 4)
                mRenderPaint.color = color
                if (color != 0 && !leftSaved) {
                    leftSaved = true
                    left = buffer.buffer[j]
                }
                if (j > 4) { // it works but its ugly
                    right = buffer.buffer[j - 2]
                }
                c!!.drawRect(buffer.buffer[j], buffer.buffer[j + 1] + 10, buffer.buffer[j + 2],
                        buffer.buffer[j + 3] - 10, mRenderPaint)
                j += 4
            }


        val erasePaint = Paint()
        erasePaint.setAntiAlias(true)
        erasePaint.setStyle(Paint.Style.STROKE)
        val paintWidth = 20f
        erasePaint.setStrokeWidth(paintWidth)
        erasePaint.setXfermode(PorterDuffXfermode(PorterDuff.Mode.CLEAR))
        c!!.drawRoundRect(RectF(left - paintWidth / 2, top, right + paintWidth / 2, bot), 30f, 30f, erasePaint)

    }
}

但结果如下:

但我想要这样:

那么我在这里做错了什么?我也在寻找其他线程,但没有一个线程声称负条和正条的水平条形图,所以请帮我解决这个问题。

更新: 以下是水平条形图的设置:

private fun setHorizontalChart(data : BarData, brand: ArrayList<String>){

        horizonatal_chart.setDrawBarShadow(false)
        val description = Description()
        description.text = ""
        horizonatal_chart.description = description

        horizonatal_chart.legend.setEnabled(false)
        horizonatal_chart.setPinchZoom(false)
        horizonatal_chart.setDrawValueAboveBar(false)
        horizonatal_chart.setScaleEnabled(false)
        horizonatal_chart.setDrawValueAboveBar(true)

        //Display the axis on the left (contains the labels 1*, 2* and so on)
        val xAxis = horizonatal_chart.getXAxis()
        xAxis.setDrawGridLines(false)
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM)
        xAxis.setEnabled(true)
        xAxis.setDrawAxisLine(false)
        xAxis.textColor = Color.parseColor("#a1a1a1")

        val yLeft = horizonatal_chart.axisLeft

        //Set the minimum and maximum bar lengths as per the values that they represent
        yLeft.axisMaximum = 100f
        yLeft.axisMinimum = 0f
        yLeft.isEnabled = false

        //Now add the labels to be added on the vertical axis
        xAxis.valueFormatter = IAxisValueFormatter { value, axis -> brand[value.toInt()] }

        val yRight = horizonatal_chart.axisRight
        yRight.setDrawAxisLine(true)
        yRight.setDrawGridLines(false)
        yRight.isEnabled = false

        //Set bar entries and add necessary formatting
        horizonatal_chart.axisLeft.setAxisMinimum(data.yMin)

        data.barWidth = 0.9f
        val myCustomChartRender = MyCustomChartRender(horizonatal_chart, horizonatal_chart.animator, horizonatal_chart.viewPortHandler)
        //Add animation to the graph
        horizonatal_chart.renderer = myCustomChartRender
        horizonatal_chart.animateY(2000)
        horizonatal_chart.data = data
        horizonatal_chart.setTouchEnabled(false)
        horizonatal_chart.invalidate()
    }

【问题讨论】:

  • 你的公开完整码可以吗,我可以查一下
  • @CườngNguyễn 请检查并告诉您是否需要其他任何东西。
  • @CườngNguyễn 你检查了吗?

标签: android mpandroidchart


【解决方案1】:

在这里回答有点晚,但可能对其他人有帮助。我们 可以通过少量自定义编码来实现。

首先我们需要创建一个自定义类

 public class RoundedHorizontalBarChartRenderer extends HorizontalBarChartRenderer {
    public RoundedHorizontalBarChartRenderer(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();


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

现在,在您的活动中

BarChart barchart = (BarChart) findViewById( R.id.barchart );
        RoundedHorizontalBarChartRenderer roundedBarChartRenderer= new RoundedHorizontalBarChartRenderer(barchart , barchart.getAnimator(), barchart.getViewPortHandler());
        roundedBarChartRenderer.setmRadius(20f);
        barchart.setRenderer(roundedBarChartRenderer);

希望对你有帮助,如果有帮助请采纳。

【讨论】:

  • @MuhammedHaris 你想用 RadarChart 做什么?想做圆角吗?您能否提供任何参考资料,以便我可以看到您到底想要什么。
猜你喜欢
  • 1970-01-01
  • 2020-04-19
  • 2020-09-11
  • 2017-05-24
  • 1970-01-01
  • 1970-01-01
  • 2018-05-04
  • 2015-01-13
  • 1970-01-01
相关资源
最近更新 更多