自定义Android View组件——实现雷达图效果

今天有一个任务,在学生教育系统的客户端打开的页面实现一个雷达图,将雷达图的数据分成语文、数学、外语、文科、理科和其他。
效果图是这样
这里写图片描述
于是我就开始了思考,为了这个自定义的view组件可以在以后进行复用,所以我增加了可变的成员变量count,代表要表示的项的总数。
根据雷达图的样式,可以获得大概的绘制步骤

  1. 雷达图的形状实质是一个正n边形,确定正n边形的顶点坐标,需要确定这个正n边形的外接圆。如图所示
    这里写图片描述
  2. 如图分析,设多边形为n边形,顺时针算起每个顶点的角度为 360 / n * i,外接圆的半径为r,则根据左上角坐标(0,0)可得圆心坐标为(r,r),由此可算出各个顶点的坐标。

    根据分析则可以进行如下步骤的编码:
    定义类RadoView.java
    代码如下;

public class RadoView extends View {
   

    private int count = 6;   //多边形的变数

    private int[] radius = new int[]{
  100, 200, 300, 400, 500};  //各个外接圆的变数

    private int maxRadius = radius[radius.length - 1];

    private int[] marks = new int[count];
    private String[] keys = new String[count];

    LinkedHashMap<String, Integer> map = new LinkedHashMap<>();

    private Paint paintLine;   //画线

    private Paint paintMarkLine;  //分值连线
    private Paint paintMarkPoint;  //分值画点

    private Paint paintText;  //绘制文字

    private double x;   //当前点的横坐标
    private double y;    //当前点的纵坐标
    private double lastX;  //上一次的坐标
    private double lastY;

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

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

    public RadoView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
}

根据分析图可以发现,根据三角函数计算坐标的角度并非是360 / n,而是构造直角三角形根据三角函数计算
写一个方法计算这个角度

/**
     * 得到需要计算的角度
     *
     * @param angle 角度,例:30.60.90
     * @return res
     */
    private double getNewAngle(double angle) {
        double res = angle;
        if (angle >= 0 && angle <= 90) {
            res = 90 - angle;
        } else if (angle > 90 && angle <= 180) {
            res = angle - 90;
        } else if (angle > 180 && angle <= 270) {
            res = 270 - angle;
        } else if (angle > 270 && angle <= 360) {
            res = angle - 270;
        }
        return res;
    }

算出角度后,应该计算出每个角度的所在象限
注意,这个角度的所在象限是根据外接圆的圆心来判断的,以6边形为例子,每个角的度数分别是30,60,90,120….,30和60度的顶点所在的象限为第一象限,120度所在为第二象限,以此类推
编写函数int getQr(double),计算所在象限

private int getQr(double angle) {
        int res = 0;
        if (angle >= 0 && angle <= 90) {
            res = 1;
        } else if (angle > 90 && angle <= 180) {
            res = 2;
        } else if (angle > 180 && angle <= 270) {
            res = 3;
        } else if (angle > 270 && angle <= 360) {
            res = 4;
        }
        return res;
    }

此时根据点的象限和角度,便可以计算出顶点的x坐标和y坐标
角度在1,2象限的时候,横坐标为一个半径加上这个顶点在第二象限部分的横坐标,这个横坐标可以根据构造直角三角形,使用三角函数计算得出

private double getPointX(double angle, double radius) {
        double newAngle = getNewAngle(angle);
        double res = 0;
        double width = radius * Math.cos(newAngle / 180 * Math.PI);
        int qr = getQr(angle);
        switch (qr) {
            case 1:
            case 2:
                res = maxRadius + width;
                break;
            case 3:
            case 4:
                res =
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值