使用MpAndroidChart

时间:2019-12-19 07:33:01

标签: android mpandroidchart

我正在尝试使水平条形图的角变圆,这是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)

    }
}

但是结果如下:

enter image description here

但是我想要这样:

enter image description here

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

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

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

1 个答案:

答案 0 :(得分:1)

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

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

        <mat-table [dataSource]="dataSource">

          <ng-container *ngFor="let item of headerRow; let i = index" matColumnDef={{headerRow[i]}}>
            <mat-header-cell *matHeaderCellDef> {{headerRow[i]}} </mat-header-cell>
            <mat-cell *matCellDef="let row">

              <mat-form-field floatLabel="never">
                <input matInput placeholder="Name" [value]="row[i]" [(ngModel)]="row[i]">

              </mat-form-field>
            </mat-cell>
          </ng-container>
          <mat-header-row *matHeaderRowDef="headerRow"></mat-header-row>
          <mat-row *matRowDef="let row; columns: headerRow;">
          </mat-row>
        </mat-table>
        <mat-paginator [pageSizeOptions]="[5, 10, 25, 100]"></mat-paginator>

现在,在您的活动中

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

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