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

第一步:绘制蜘蛛网络

private void init() { mainPaint=new Paint(); mainPaint.setColor(Color.BLACK); mainPaint.setAntiAlias(true); mainPaint.setStrokeWidth(1); mainPaint.setStyle(Paint.Style.STROKE);}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) { radius=Math.min(w,h)/2*0.9f; centerX=w/2; centerY=h/2; //一旦size发生改变,重新绘制 postInvalidate(); super.onSizeChanged(w, h, oldw, oldh);}@Overrideprotected void onDraw(Canvas canvas) { drawPolygon(canvas);}/** * 绘制多边形 * @param canvas */private void drawPolygon(Canvas canvas){ Path path=new Path(); //1度=1*PI/180 360度=2*PI 那么我们每旋转一次的角度为2*PI/内角个数 //中心与相邻两个内角相连的夹角角度 angle= (float) (2*Math.PI/count); //每个蛛丝之间的间距 float r= radius/(count-1); for (int i = 0; i < count; i++) { //当前半径 float curR=r*i; path.reset(); for (int j = 0; j < count; j++) { if(j==0){ path.moveTo(centerX+curR,centerY); }else { //对于直角三角形sin(x)是对边比斜边,cos(x)是底边比斜边,tan(x)是对边比底边 //因此可以推导出:底边(x坐标)=斜边(半径)*cos(夹角角度) // 对边(y坐标)=斜边(半径)*sin(夹角角度) float x = (float) (centerX+curR*Math.cos(angle*j)); float y = (float) (centerY+curR*Math.sin(angle*j)); path.lineTo(x,y); } } path.close(); canvas.drawPath(path,mainPaint); }

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

多边形夹角示意图

绘制出的多边形成品如下:

多边形效果.gif

动画效果只是写了 set 方法,用 handler 实现,代码如下:

//设置数值种类public void setCount(int count) { this.count = count; postInvalidate();}//设置蜘蛛网颜色public void setMainPaint(Paint mainPaint) { this.mainPaint = mainPaint; postInvalidate();}

调用方法:

mainPaint=new Paint();mainPaint.setAntiAlias(true);mainPaint.setStrokeWidth(1);mainPaint.setStyle(Paint.Style.STROKE);Handler handler=new Handler();for (int i = 3; i < 20; i++) {final int finalI = i;handler.postDelayed(new Runnable() { @Override public void run() { mRdv.setCount(finalI); mainPaint.setStrokeWidth(finalI); mRdv.setMainPaint(mainPaint); }},i*300);}

第二步:绘制对角线

/** * 绘制直线 */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); }}

这一步比较简单,就是将中心点和各个顶点连接起来,效果如下:

多边形效果.gif

第三步:绘制标题文字

/** * 绘制标题文字 * * @param canvas */private void drawTitle(Canvas canvas) { if (count != titles.size()) { return; } //相关知识点:http://mikewang.blog.51cto.com/3826268/871765/ Paint.FontMetrics fontMetrics = textPaint.getFontMetrics(); float fontHeight = fontMetrics.descent - fontMetrics.ascent; //绘制文字时不让文字和雷达图形交叉,加大绘制半径 float textRadius = radius + fontHeight; double pi = Math.PI; for (int i = 0; i < count; i++) { float x = (float) (centerX + textRadius * Math.cos(angle * i)); float y = (float) (centerY + textRadius * Math.sin(angle * i)); //当前绘制标题所在顶点角度 float degrees = angle * i; //从右下角开始顺时针画起,与真实坐标系相反 if (degrees >= 0 && degrees < pi / 2) {//第四象限 float dis=textPaint.measureText(titles.get(i))/(titles.get(i).length()-1); canvas.drawText(titles.get(i), x+dis, y, textPaint); } else if (degrees >= pi / 2 && degrees < pi) {//第三象限 float dis=textPaint.measureText(titles.get(i))/(titles.get(i).length()-1); canvas.drawText(titles.get(i), x-dis, y, textPaint); } else if (degrees >= pi && degrees < 3 * pi / 2) {//第二象限 float dis=textPaint.measureText(titles.get(i))/(titles.get(i).length()); canvas.drawText(titles.get(i), x-dis, y, textPaint); } else if (degrees >= 3 * pi / 2 && degrees <= 2 * pi) {//第一象限 canvas.drawText(titles.get(i), x, y, textPaint); } }}

效果如下:

image.png

第四步:绘制覆盖区域

要绘制覆盖区域,首先要指定最大值和每个分类的具体数值,有了这些数值之后,就可以绘制了。

代码如下:

/** * 绘制覆盖区域 */private void drawRegion(Canvas canvas){ valuePaint.setAlpha(255); Path path=new Path(); for (int i = 0; i < count; i++) { //计算该数值与最大值比例 Double perCenter = data.get(i)/maxValue; //小圆点所在位置距离圆心的距离 double perRadius=perCenter*radius; float x = (float) (centerX + perRadius * Math.cos(angle * i)); float y = (float) (centerY + perRadius * Math.sin(angle * i)); if(i==0){ path.moveTo(x,y); }else { path.lineTo(x,y); } //绘制小圆点 canvas.drawCircle(x,y,10,valuePaint); } //闭合覆盖区域 path.close(); valuePaint.setStyle(Paint.Style.STROKE); //绘制覆盖区域外的连线 canvas.drawPath(path, valuePaint); //填充覆盖区域 valuePaint.setAlpha(128); valuePaint.setStyle(Paint.Style.FILL); canvas.drawPath(path,valuePaint);}

看一下效果:

image.png

再来看一下动态的效果吧:

多边形效果.gif

总结

终于完成了,全部代码在下面:

Android雷达图全部代码

主要是参考 crazy__chen 大神的博客,链接贴在下面,做了一遍其实还蛮简单的,这个控件还有很多不完善的,如果实际使用需要改善的地方还有很多,如果有不足希望大家可以告诉我,谢谢!!

以上就是对于安卓开发方面的知识点简介,Android Path 最佳实践之绘制雷达图,更多相关内容请继续关注拓胜科技安卓技术频道,或者需要了解拓胜安卓培训方面的问题,可以在线免费咨询拓胜教育老师。

android 雷达坐标系,Android Path之绘制雷达图的技巧相关推荐

  1. graphpad怎么修改图片大小_GraphPad Prism 绘制箱形图美化技巧

    箱形图绘制小技巧:重排位置及调整间距. 以上图为例(例图). 1. 重排位置 我们将更改例图的排列位置,将 A.B.C.D.E 列的位置,排列为 C.A.B.D.E ,方法如下: 点击 Change ...

  2. android drawable 比例,Android中的Drawable基础与自定义Drawable

    转载请注明链接:http://blog..net/feather_wch/article/details/79124608 本文要点: 1. 介绍Android中Drawable的相关知识点,并且介绍 ...

  3. Android 仿芝麻信用进度条,Android仿支付宝上芝麻信用分雷达图

    一.首先看下支付宝上芝麻信用分的效果图: 二.思路 1.确定雷达图中心点坐标 2.绘制多边形及连接线 3.根据维度值绘制覆盖区域 4.绘制分数 5.绘制每个维度的标题文字和图标 三.实现 获取布局的中 ...

  4. Qt OpenGL(三十六)——Qt OpenGL 核心模式-绘制雷达坐标系

    提示:本系列文章的索引目录在下面文章的链接里(点击下面可以跳转查看): Qt OpenGL 核心模式版本文章目录 Qt OpenGL(三十六)--Qt OpenGL 核心模式-绘制雷达坐标系 一.场景 ...

  5. android设置雷达网各层颜色,GitHub - androidTH/RadarChart: 支持自由定制外观、手势旋转的雷达图表 android radarchart...

    RadarView 一个可以自由定制.旋转交互的Android雷达图Lib 一些特性 支持手势旋转(可关闭) 支持动画的方式添加展现数据 支持对各层雷达网添加背景 支持自定义雷达网层数 支持使用圆形作 ...

  6. Android自定义视图二:如何绘制内容

    这个系列是老外写的,干货!翻译出来一起学习.如有不妥,不吝赐教! Android自定义视图一:扩展现有的视图,添加新的XML属性 Android自定义视图二:如何绘制内容 Android自定义视图三: ...

  7. r语言绘制雷达图_用r绘制雷达蜘蛛图

    r语言绘制雷达图 I've tried several different types of NBA analytical articles within my readership who are ...

  8. Android自定义系列——9.Path详细用法

    rXxx方法 rXxx方法的坐标使用的是相对位置(基于当前点的位移),而之前方法的坐标是绝对位置(基于当前坐标系的坐标). Path path = new Path();path.moveTo(100 ...

  9. Android自定义系列——7.Path之基本操作

    Path常用方法表 为了兼容性(偷懒) 本表格中去除了部分API21(即安卓版本5.0)以上才添加的方法. 作用 相关方法 备注 移动起点 moveTo 移动下一次操作的起点位置 设置终点 setLa ...

最新文章

  1. JZOJ 5637. 【NOI2018模拟4.8】一双木棋
  2. matlab 识别调试,有关matlab的人脸识别程序,但调试是不成功
  3. 线程安全的CopyOnWriteArrayList介绍
  4. 对js原型简单的理解和图解
  5. k8s查看pod的yaml文件_k8s监控系统prometheus-operator
  6. 由树的定义和递归想到的
  7. VC中用内存映射文件处理大文件
  8. CF - 472C. Design Tutorial: Make It Nondeterministic 贪心
  9. mount挂载不上,不提示任何信息
  10. 启动SparkSql,报javax.jdo.JDOFatalInternalException: Error creating transactional connection factory
  11. python编写一个汽车类_Python 类:以汽车为例
  12. eclipse越来越不稳定了
  13. 知识图到文本的生成——叁
  14. vl6180开发记录
  15. 如何清除WinME系统_restore目录下的病毒
  16. SpringBoot学习小结之Elasticsearch
  17. 物通博联·工业智能PLC物联网网关
  18. python变量和列表_自学python第一天——变量和列表
  19. 计算机网络宽带接入,【计算机网络】宽带接入技术
  20. 网络学习-1.IP基础

热门文章

  1. 电费充值api系统接口 支持国家电网
  2. JAVA SE基础笔记
  3. Kali下面装goldendict词典的安装和添加词典文件
  4. Qt开发高级进阶: WebCamera(UVC)摄像头使用QAbstractVideoSurface捕获视频帧到QImage
  5. 涉密计算机保密管理ppt,2016年保密工作计划书ppt
  6. flash下载的别人的在flash中打开显示无法打开受保护的影片怎么回事
  7. 洗衣粉等日化用品将受油价高企影响涨价
  8. oracle Blob保存方式,oracle 存储过程操作blob
  9. 免备案网站搭建,香港服务器
  10. 华为校招2016.09机试 第2题: 字符串查找