MPAndroidChart3使用详解9:RadarChart(雷达图)顶角显示圆点——重写RadarChart控件添加顶角圆点绘制方案

本文介绍在Android中使用MPAndroidChart的RadarChart控件绘制顶角圆点的方法。先查看控件源码,从绘制网线的公开方法入手,逐步查找相关变量和方法以获取顶点坐标,再重写RadarChart和RadarChartRenderer类进行圆点绘制,最后给出实现步骤和效果。
ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

目录

 

1 思路:

2 实现:

3 效果:


1 思路:

查看RadarChart控件源码,找到绘制网线的相关源码,获取到各个顶点的坐标后,便可以在各个顶点绘制圆。

Step 1:既然圆点是在网线各个顶点,那便跟绘制网线相关联,我们可以从绘制网线的公开方法入手去查找,最先想到就是setDrawWeb方法,直接影响网线的绘制,这个方法也很简单只设置了mDrawWeb的值。

Step 2:接下来我们要查找变量mDrawWeb在绘制中的实际已应用,绘制便跟onDraw方法有关。可以看出绘制网线时,调用了mRenderer变量的drawExtras(canvas)

Step 3:查找mRenderer变量的具体对象

Step 4:查找RadarChartRenderer对象中drawExtras(canvas)方法到底做了什么事情。

Step 5:drawExtras(canvas)方法中如下这段代码是绘制每段网线的,从中可以获取到各个顶点的坐标。

Step 6:通过该坐标在里面进行圆点的绘制,由于我们无法直接编辑源码,我们还需要重写RadarChart和RadarChartRenderer这两个类。

2 实现:

Step 1:新建我们自己的RadarChartRenderer类继承RadarChartRenderer,重写drawWeb(Canvas c)方法,里面内容直接拷贝原方法代码后在指定加上如下这段代码。

for (int j = 0; j < labelCount; j++) {
    for (int i = 0; i < mChart.getData().getEntryCount(); i++) {
        float r = (mChart.getYAxis().mEntries[j] - mChart.getYChartMin()) * factor;
        Utils.getPosition(center, r, sliceangle * i + rotationangle, p1out);
        Utils.getPosition(center, r, sliceangle * (i + 1) + rotationangle, p2out);
        c.drawLine(p1out.x, p1out.y, p2out.x, p2out.y, mWebPaint);
        // start(加上下面这几行代码,用于绘制每个顶角上的圆)
        if (mDrawAngleCircle && j == labelCount - 1) {
            mAngleCirclePaint.setColor(mAngleCircleColors == null || mAngleCircleColors.length == 0 ? Color.BLACK : this.mAngleCircleColors[i % mAngleCircleColors.length]);
            c.drawCircle(p2out.x, p2out.y, mAngleCircleRadius, mAngleCirclePaint);
        }
        // end
    }
}

完整代码:

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;

import com.github.mikephil.charting.animation.ChartAnimator;
import com.github.mikephil.charting.charts.RadarChart;
import com.github.mikephil.charting.utils.MPPointF;
import com.github.mikephil.charting.utils.Utils;
import com.github.mikephil.charting.utils.ViewPortHandler;

public class RadarChartRenderer extends com.github.mikephil.charting.renderer.RadarChartRenderer {

    private Paint mAngleCirclePaint;
    private float mAngleCircleRadius = Utils.convertDpToPixel(5f);
    private int[] mAngleCircleColors;
    private boolean mDrawAngleCircle = false;

    public RadarChartRenderer(RadarChart chart, ChartAnimator animator, ViewPortHandler viewPortHandler) {
        super(chart, animator, viewPortHandler);
        mAngleCirclePaint = new Paint();
    }

    @Override
    protected void drawWeb(Canvas c) {
        float sliceangle = mChart.getSliceAngle();

        // calculate the factor that is needed for transforming the value to
        // pixels
        float factor = mChart.getFactor();
        float rotationangle = mChart.getRotationAngle();

        MPPointF center = mChart.getCenterOffsets();

        // draw the web lines that come from the center
        mWebPaint.setStrokeWidth(mChart.getWebLineWidth());
        mWebPaint.setColor(mChart.getWebColor());
        mWebPaint.setAlpha(mChart.getWebAlpha());

        final int xIncrements = 1 + mChart.getSkipWebLineCount();
        int maxEntryCount = mChart.getData().getMaxEntryCountSet().getEntryCount();

        MPPointF p = MPPointF.getInstance(0,0);
        for (int i = 0; i < maxEntryCount; i += xIncrements) {

            Utils.getPosition(
                    center,
                    mChart.getYRange() * factor,
                    sliceangle * i + rotationangle,
                    p);

            c.drawLine(center.x, center.y, p.x, p.y, mWebPaint);
        }
        MPPointF.recycleInstance(p);

        // draw the inner-web
        mWebPaint.setStrokeWidth(mChart.getWebLineWidthInner());
        mWebPaint.setColor(mChart.getWebColorInner());
        mWebPaint.setAlpha(mChart.getWebAlpha());

        int labelCount = mChart.getYAxis().mEntryCount;

        MPPointF p1out = MPPointF.getInstance(0,0);
        MPPointF p2out = MPPointF.getInstance(0,0);
        for (int j = 0; j < labelCount; j++) {

            for (int i = 0; i < mChart.getData().getEntryCount(); i++) {

                float r = (mChart.getYAxis().mEntries[j] - mChart.getYChartMin()) * factor;

                Utils.getPosition(center, r, sliceangle * i + rotationangle, p1out);
                Utils.getPosition(center, r, sliceangle * (i + 1) + rotationangle, p2out);

                c.drawLine(p1out.x, p1out.y, p2out.x, p2out.y, mWebPaint);
                // start(加上下面这几行代码,用于绘制每个顶角上的圆)
                if (mDrawAngleCircle && j == labelCount - 1) {
                    mAngleCirclePaint.setColor(mAngleCircleColors == null || mAngleCircleColors.length == 0 ? Color.BLACK : this.mAngleCircleColors[i % mAngleCircleColors.length]);
                    c.drawCircle(p2out.x, p2out.y, mAngleCircleRadius, mAngleCirclePaint);
                }
                // end
            }
        }
        MPPointF.recycleInstance(p1out);
        MPPointF.recycleInstance(p2out);
    }

    /**
     * 顶角圆点颜色
     * @param colors 颜色
     */
    public void setAngleCircleColor(int[] colors) {
        this.mAngleCircleColors = colors;
    }

    /**
     * 顶角圆点半径
     * @param radius 半径
     */
    public void setAngleCircleRadius(float radius) {
        this.mAngleCircleRadius = Utils.convertDpToPixel(radius);
    }

    /**
     * 是否绘制顶角圆点
     * @param draw
     */
    public void setDrawAngleCircle(boolean draw) {
        this.mDrawAngleCircle = draw;
    }

}

 Step 2:新建我们自己的RadarChart类继承RadarChart,重写init()方法。

@Override
protected void init() {
    super.init();
    this.mRenderer = new RadarChartRenderer(this, mAnimator, mViewPortHandler);
}

完整代码:

import android.content.Context;
import android.util.AttributeSet;

public class RadarChart extends com.github.mikephil.charting.charts.RadarChart {

    public RadarChart(Context context) {
        super(context);
    }

    public RadarChart(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public RadarChart(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void init() {
        super.init();
        this.mRenderer = new RadarChartRenderer(this, mAnimator, mViewPortHandler);
    }

    /**
     * 是否绘制顶角圆点
     * @param draw
     */
    public void setDrawAngleCircle(boolean draw) {
        ((RadarChartRenderer) this.mRenderer).setDrawAngleCircle(draw);
    }

    /**
     * 顶角圆点颜色
     * @param colors 颜色
     */
    public void setAngleCircleColor(int[] colors) {
        ((RadarChartRenderer) this.mRenderer).setAngleCircleColor(colors);
    }

    /**
     * 顶角圆点半径
     * @param radius 半径
     */
    public void setAngleCircleRadius(float radius) {
        ((RadarChartRenderer) this.mRenderer).setAngleCircleRadius(radius);
    }

}

  Step 3:在界面中,使用我们自己RadarChart,再开启绘制顶点圆点,设置颜色。

rc.setDrawAngleCircle(true);
rc.setAngleCircleColor(new int[] {
    Color.parseColor("#36a9ce"),
    Color.parseColor("#33ff66"),
    Color.parseColor("#ef5aa1"),
    Color.parseColor("#ff0000"),
    Color.parseColor("#6600ff")
});

 

3 效果:

雷达图的使用教程:https://blog.youkuaiyun.com/Honiler/article/details/90407390 

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Homilier

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值