使用MpAndroidChart的水平条形图的负条和正条的圆角 [英] Round Corners for both Negative and Positive bars of horizontal bar chart using MpAndroidChart

查看:865
本文介绍了使用MpAndroidChart的水平条形图的负条和正条的圆角的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to make the corners of horizontal bar chart rounded, here's the CustomChartRenderer code:

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)

    }
}

但是结果如下:

但是我想要这样:

那么我在这里做错了什么?我也已经在寻找其他线程,但是它们都没有要求对负条和正条都使用水平条形图,因此请帮助我解决此问题.

So what i am doing wrong here? I have looked for other threads too but none of them claims for horizontal bar chart for both negative and positive bars so please help me to solve this issue.

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

Update: Here's the settings for horizontal bar chart:

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

推荐答案

在这里回答问题并不迟,但可能会对其他人有所帮助.我们 可以通过很少的自定义编码来实现.

It is little late to answer here but may be helpful for others. We can achieve it by little custom coding.

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

first of all we need to create a custom class

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

现在,在您的活动中

now, in your Activity

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

希望这会有所帮助,如果发现有帮助,请接受答案.

Hope this is helpful, please accept the answer if found helpful.

这篇关于使用MpAndroidChart的水平条形图的负条和正条的圆角的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆