先看效果

上代码

package com.example.hj.myapplication;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.View;

public class RadarView extends View {// 数据个数
    private int count = 8;
    //每个扇形的弧度
    private float angle = (float) (Math.PI * 2 / count);
    // 网格最大半径
    private float radius;
    // 中心X
    private int centerX;
    // 中心Y
    private int centerY;
    // 各标题
    private String[] titles = {"旅游", "吃饭", "购物", "娱乐", "会友", "转账", "红包", "看病"};
    // 各维度分值
    private double[] data = {100, 60, 65, 75, 100, 50, 30, 70};
    // 刻度值
    private String[] graduationValue = {"0", "10", "20", "30", "40", "50", "60", "70", "80", "90", "100"};
    // 数据最大值
    private float maxValue = 100;
    // 雷达区画笔
    private Paint mainPaint;
    // 数据区画笔
    private Paint valuePaint;
    // title画笔
    private Paint titlePaint;
    // 刻度值画笔
    private Paint graduationPaint;
    //判断点的所在区域的临界值,根据临界值设置点的颜色
    //100~70(包含)之间绿色,30(不包含)~70(不包含)橙色,小于等于30红色
    private float curR4;
    private float curR7;
    private float curR10;
    private int ten;

    public RadarView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);
        init();
    }public RadarView(Context context, AttributeSet attrs) {super(context, attrs);
        init();
    }public RadarView(Context context) {super(context);
        init();
    }// 初始化
    private void init() {DisplayMetrics dm = getResources().getDisplayMetrics();
        int screenWidth = dm.widthPixels;

        ten = (int) (0.0094 * screenWidth);
        int forty = (int) (0.036 * screenWidth);
        count = Math.min(data.length, titles.length);

        // 初始化雷达区画笔
        mainPaint = new Paint();
        mainPaint.setAntiAlias(true);
        mainPaint.setColor(Color.parseColor("#6BD18E"));
        mainPaint.setStyle(Paint.Style.STROKE);

        // 初始化数据区画笔
        valuePaint = new Paint();
        valuePaint.setAntiAlias(true);
        valuePaint.setColor(Color.parseColor("#00BF33"));
        valuePaint.setStyle(Paint.Style.FILL_AND_STROKE);

        // 初始化title画笔
        titlePaint = new Paint();
        titlePaint.setTextSize(forty);
        titlePaint.setStyle(Paint.Style.FILL);
        titlePaint.setColor(Color.BLACK);

        // 初始化刻度值画笔
        graduationPaint = new Paint();
        Typeface font = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD);
        graduationPaint.setTypeface(font);
        graduationPaint.setTextSize(18);
        graduationPaint.setStyle(Paint.Style.FILL);
        graduationPaint.setColor(Color.parseColor("#D0D0D0"));
    }@Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {radius = Math.min(h, w) / 2 * 0.7f;
        centerX = w / 2;
        centerY = h / 2;
        postInvalidate();
        super.onSizeChanged(w, h, oldw, oldh);
    }@Override
    protected void onDraw(Canvas canvas) {drawCircle(canvas);
        drawLines(canvas);
        drawGraduationValue(canvas);
        drawRegion(canvas);
    }/**
     * 绘制圆
     *
     * @param canvas Canvas
     */
    private void drawCircle(Canvas canvas) {Path path = new Path();
        float r = radius / 10;
        for (int i = 1; i < 11; i++) {float curR = r * i;
            curR4 = r * 4;
            curR7 = r * 7;
            curR10 = r * 10;
            for (int j = 1; j < 11; j += 2) {if (j == 0) {path.moveTo(centerX + curR, centerY);
                }}canvas.drawCircle(centerX, centerY, curR, mainPaint);
        }}/**
     * 绘制直线
     *
     * @param canvas Canvas
     */
    private void drawLines(Canvas canvas) {Path path = new Path();
        for (int i = 0; i < count; i++) {path.reset();
            path.moveTo(centerX, centerY);
            float x = (float) (centerX + radius * Math.cos(angle * i));
            float y = (float) (centerY + radius * Math.sin(angle * i));
            path.lineTo(x, y);
            canvas.drawPath(path, mainPaint);
            drawTitles(canvas, i, x, y);
        }}/**
     * 绘制title
     *
     * @param canvas Canvas
     * @param i      index
     * @param x      每条线的终点的X坐标
     * @param y      每条线的终点的Y坐标
     */
    private void drawTitles(Canvas canvas, int i, float x, float y) {Paint.FontMetrics fontMetrics = titlePaint.getFontMetrics();
        //文本高度
        float fontHeight = fontMetrics.descent - fontMetrics.ascent;
        Rect rect = new Rect();
        titlePaint.getTextBounds(titles[i], 0, titles[i].length(), rect);
        //文本的宽度
        int fontWidth = rect.width();
        //在每条线的终点基础之上去确定title的坐标
        float titleX = (float) (x + fontWidth * Math.cos(angle * i)) - (fontWidth / 2);
        float titleY = (float) (y + fontHeight * Math.sin(angle * i)) + ten;
        canvas.drawText(titles[i], titleX, titleY, titlePaint);
    }/**
     * 绘制刻度值
     *
     * @param canvas Canvas
     */
    private void drawGraduationValue(Canvas canvas) {Paint.FontMetrics fontMetrics = graduationPaint.getFontMetrics();
        //文本高度
        float fontHeight = fontMetrics.descent - fontMetrics.ascent;
        //刻度值的X轴坐标
        float graduationX = centerX - fontHeight * 6 / 5;
        //网层与网层之间的距离
        float r = radius / 10;
        for (int j = 0; j < graduationValue.length; j++) {float curR = r * j;
            float graduationY = centerY - curR;
            canvas.drawText(graduationValue[j], graduationX, graduationY, graduationPaint);
        }}/**
     * 绘制区域
     *
     * @param canvas Canvas
     */
    private void drawRegion(Canvas canvas) {Path path = new Path();
        valuePaint.setAlpha(255);
        for (int i = 0; i < count; i++) {double percent = data[i] / maxValue;
            float x = (float) (centerX + radius * Math.cos(angle * i) * percent);
            float y = (float) (centerY + radius * Math.sin(angle * i) * percent);
            if (i == 0) {path.moveTo(x, centerY);
            } else {path.lineTo(x, y);
            }double sx = Math.PI
                    * ((x - centerX) * (x - centerX) + (y - centerY)* (y - centerY));
            double s1 = Math.PI * curR4 * curR4;
            double s2 = Math.PI * curR7 * curR7;
            double s3 = Math.PI * curR10 * curR10;
            if (0 < sx && sx <= s1) {valuePaint.setColor(Color.parseColor("#FF2022"));
                canvas.drawCircle(x, y, ten, valuePaint);
            }if (s1 < sx && sx <= s2) {valuePaint.setColor(Color.parseColor("#FFA10C"));
                canvas.drawCircle(x, y, ten, valuePaint);
            }if (s2 < sx && sx <= s3) {valuePaint.setColor(Color.parseColor("#00BF33"));
                canvas.drawCircle(x, y, ten, valuePaint);
            }}path.close();
        valuePaint.setColor(Color.parseColor("#00BF33"));
        // 描边
        valuePaint.setStyle(Paint.Style.STROKE);
        canvas.drawPath(path, valuePaint);

        // 绘制填充区域的透明度(不需要填充可注释掉下边三行代码)
        valuePaint.setAlpha(127);
        // 绘制填充区域
        valuePaint.setStyle(Paint.Style.FILL_AND_STROKE);
        canvas.drawPath(path, valuePaint);
    }// 设置标题
    public void setTitles(String[] titles) {this.titles = titles;
    }// 设置数值
    public void setData(double[] data) {this.data = data;
    }public float getMaxValue() {return maxValue;
    }// 设置最大数值
    public void setMaxValue(float maxValue) {this.maxValue = maxValue;
    }// 设置蜘蛛网颜色
    public void setMainPaintColor(int color) {mainPaint.setColor(color);
    }// 设置标题颜色
    public void setTextPaintColor(int color) {titlePaint.setColor(color);
    }// 设置覆盖局域颜色
    public void setValuePaintColor(int color) {valuePaint.setColor(color);
    }
}

Android 雷达图(蜘蛛网状图)相关推荐

  1. Android 雷达图(网状图)

    有的称为雷达图,也有的说是网状图具体什么图就是这图吧,先看效果 要想实现此图其实也不是很难,由于当时刚见到图的时候有点不知所措,因为不是简单的画圆,而是需要根据数据的大小进行在交叉的地方画点,而且所要 ...

  2. Android自定义动画----蜘蛛网格图

    首先初始化函数,为了减少内存消耗,所以在onDraw外创建变量 //声明雷达和数值的画笔 private Paint radarPaint, valuePaint; //雷达网格的最大半径 priva ...

  3. android 雷达坐标系,Android Path之绘制雷达图的技巧

    Android Path之绘制雷达图的技巧,绘制蜘蛛网络其实就是绘制指定边数的正多边形,这一步比较简单,比较难的可能就是每个顶点的算法,相关注释我都写了,还有一张来自互联网的图以助于思考,如下: 第一 ...

  4. Android自定义View实现三角到八角的属性分布图-雷达图(蜘蛛网图)

    Android自定义View实现三角到八角的属性分布图-雷达图(蜘蛛网图) 前言 自定义View的关键点 绘制多边形 结尾 前言 刚开始学习自定义view,简单完成了一个属性分布器,可以实现三条到八条 ...

  5. MATLAB绘制雷达图/蜘蛛图

    雷达图/蜘蛛图 雷达图(Radar Chart) 是以从同一点开始的轴上表示的三个或更多个定量变量的二维图表的形式显示多变量数据的图形方法.轴的相对位置和角度通常是无信息的. 雷达图也称为网络图,蜘蛛 ...

  6. Matlab进阶绘图第6期—雷达图/蜘蛛图/星图

    雷达图(Radar Chart),又称星图.蜘蛛图.蜘蛛网图.网络图.Kiviat图等,是一种以从同一点开始的轴上表示的三个以上变量的二维图表的形式,来显示多变量数据的图形方法. 雷达图可以直观地对多 ...

  7. 圆形和多边形雷达图python-Matplotlib绘制雷达图和三维图的示例代码

    1.雷达图 程序示例 '''1.空白极坐标图''' import matplotlib.pyplot as plt plt.polar() plt.show() '''2.绘制一个极坐标点''' im ...

  8. 【Android 安装包优化】Android 中使用 SVG 图片 ( Android 5.0 以下的矢量图方案 | 矢量图生成为 PNG 图片 )

    文章目录 一.Android 5.0 以下的矢量图方案 二.矢量图生成为 PNG 图片 三.完整的 build.gradle 构建脚本 四.编译效果 五.参考资料 一.Android 5.0 以下的矢 ...

  9. 【Android 安装包优化】Android 中使用 SVG 图片 ( SVG 矢量图简介 | Android 中生成 Vector 矢量图资源 )

    文章目录 一.SVG 矢量图简介 二.Android 中生成 Vector 矢量图资源 三.参考资料 一.SVG 矢量图简介 Android SVG 参考文档 : https://developer. ...

最新文章

  1. html中sprite标签,Three.js模型标签
  2. [Linux] ubuntu 格式化u盘
  3. JAVA之JVM之内存分配与回收策略(二)
  4. 关于JavaScript(脚本语言)
  5. poj 3678 Katu Puzzle(2-sat)
  6. 备份数据库的expdp语句_【ORACLE语句备份】数据库表同步 ——定时任务管理器(EXPDP导出,IMPDP导入)...
  7. python 进程 线程 协程
  8. php cut截取字符串,php源码分析之DZX1.5字符串截断函数cutstr用法
  9. 西门子plm_西门子PLM组件之形状搜索(支持工业软件国产自主可控)
  10. 凸优化第四章凸优化问题 4.3线性规划问题
  11. HDU_1198 Farm Irrigation(并查集)
  12. 苹果手机屏幕镜像_微软应用上线屏幕镜像功能:可在PC端控制安卓手机
  13. 树莓派如何连接WiFi
  14. 未来,将是Captain technology新能源汽车的舞台
  15. “心脏滴血”漏洞复现
  16. Python学习资源
  17. 小程序头像和昵称填写能力用底部弹框界面实现
  18. JAVA 多用户商城系统b2b2c-Spring Cloud Stream 介绍
  19. 情不知所起,一“网”而深
  20. JavaWeb 打开的默认主页设置问题

热门文章

  1. 华为鸿蒙os适配机型曝光,手机资讯导报:华为鸿蒙OS2.0首批适配机型曝光
  2. Linux基础学习之Day7-2-LVM管理
  3. java获取下月末,java获取每月月末日期
  4. andrAndroid 权限
  5. 短链系统设计性能优化-缓存提速及CDN
  6. python课程报告模板_用Python做一次超酷的项目进度汇报,你值得拥有
  7. [转载]有经验的人对各种常用IC芯片使用感受
  8. OpenStack T版服务组件之Nova计算服务
  9. 记HP 12c的一个坑
  10. Vue3项目搭建学习笔记