用数学思维实现雷达分析图

前言

前段时间回看里约奥运会的国球比赛,岛国媒体给我龙队一个响亮的称号—— 六边形战士

马龙是我的偶像,看到这样的称号当然很骄傲。

分析图片可以知道:六个定点分别标识个技术点名称,对应 半径 所填充长度表示分值,龙队在各方面的分数都是满分,所以在雷达分析图上覆盖区全部填充。

作为程序员的我,不免要从技术实现的角度思考问题,接下来我们一起造轮子:

先上效果图:

设计思路

回顾两个知识点:

  • 在一平面中,确定一坐标原点(0,0),水平向右为x轴正方向,竖直向上为y轴正方向,从右上方开始顺时针依次为第一象限、第二象限、第三象限和第四象限。
  • 平面中的任一点的坐标应该是:其与原点所在直线的倾斜角的余弦为x,正弦值为y。

从效果图来看,我们应该把view区域按照数学中的平面坐标来区分,雷达图中心点(外接圆圆心)为坐标原点,水平向右的半径为x轴正方向,竖直向上的半径为y轴正方向,从右上方开始顺时针依次为第一象限、第二象限、第三象限和第四象限。

大致的思路是这样的,我们需要自定义属性,自定义view:重写构造、onDraw方法,这些都是必须的。我们可以在onSizeChanged方法中进行计算和确认各组成内容的位置与大小。在计算好大小和位置后,在onDraw中进行绘制。

关键的是:我们的目标是将各数据绘制在各半径上,最后链接起来构成完整区域,那就需要将各半径上所有点计算出,找到对应数据对应的点的坐标,然后绘制。

01

自定义View

A、定义属性:

主要就是一些线条颜色、字体颜色、大小等属性。

B、继承View,声明各属性

C、定义画笔和数据集合

注意:覆盖物区域我们使用Path实现。

其中,创建了两个类:RadarEntry是数据实体类,RadarPoints 是每条半径上的所有点,其中用List存放各店,index表识哪条半径。

D、重写构造方法

显而易见得:在构造方法中获取来自xml文件中的各属性值。

E、初始化

将各画笔根据设置的属性进行初始化。

02

onSizeChanged中计算各位置和大小

A、中心点位置、每部分对应圆形角

B、计算文字所占大小,进而得出半径大小

因为文字和各半径处在同一条线上,而view创建后,每条线的长度就已经确定,那我们就需要将文字计算出大小,去除就是雷达半径的最佳长度。

在计算文字大小时,应该使用Rect和Paint结合计算得出。

循环各文字大小,找到最大的值,用图形半径减去最大值,就是雷达半径的最佳长度。

C、创建根据百分比计算位置的工具方法

因为直角三角形一个角的邻边,等于直角边*该角的余弦值。

所以,横坐标x的值,应该是对应半径*角度的余弦值乘以百分比,当然,此图中的原点实际为外接圆的圆心,并不在屏幕的原点上,所以需要在+圆心的横坐标。

计算y值也是如此。

D、计算每条边上的结点位置,计算各数据对应点

以上就用到了刚刚创建的根据百分比获取坐标的方法。

注意:x轴正方向为第一条轴线,顺时针旋转。

其实我们只是将每条半径上的所有节点的坐标进行了计算。

E、计算文字的位置

此步骤是将文字大小计算并设置到对应List中。

我们将文字位置分了四类:类似于数学中的四各象限,不同象限的位置应该分别处理。

到这里,我们的所有计算相关的操作就做完了,接下来开始绘制。

03

各组成部分绘制

以下步骤都在onDraw方法中执行。

A、绘制中心点、根据各节点绘制环形网

因为各节点我们已经计算得出,并且全部设置在对应List中,所以直接循环进行绘制各点,并将各点进行连接,就可以得到环形网。

B、当然还有半径

也是将各点连接起来就可以。

C、将覆盖物绘出

将各半径上的数据对应的点全部循环连接,但要注意,循环结束后,并没有将最后一个点和第一个点连接起来,所以需要在特意将它俩连接。完成后填充闭合图形。

到此覆盖物便画好了。

D、绘制文字

根据计算得出的文字位置进行绘制,不再累赘。

到此,所以的绘制全部结束!

04

暴露设置数据源方法

注意要调用postInvalidate方法进行刷新。

总结

怎么样,有木有很简单,有木有感觉把中学的数学再一次拾起。哈哈。

大家的支持就是我前进的动力!

原文发布于微信公众号 - Android机动车(JsAndroidClub)

原文发表时间:2017-10-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Android知识点总结

开源计划之--Android绘图库--LogicCanvas

Painter采用单例模式 优化原型模式,各Shape采用深拷贝来解决构造较长、繁琐的情况 比较new 对象和拷贝的效率问题,拷贝一点。具体见文:来谈谈Ja...

16430
来自专栏Coco的专栏

谈谈一些有趣的CSS题目(三)-- 层叠顺序与堆栈上下文知多少

16750
来自专栏Thinks

带你轻松打开svg滤镜的大门

上次和大家一起,用最简单直白,轻松粗暴的方式学习了一遍SVG动画,这次我们再一起来搞点不一样的东西,SVG滤镜的实现。

18620
来自专栏HTML5学堂

原生JS | 导航底部横线跟随鼠标缓动

HTML5学堂(码匠):在上周当中,我们用jQuery实现了 - 在导航底部存在一条横线,跟随着鼠标缓动到相应导航项 - 的特效,今天我们来讲讲原生JS的实现方...

71380
来自专栏知晓程序

开发 | 「小游戏」开发难?不妨先从 2048 入手试试看

最近流行微信「跳一跳」小游戏,我也心血来潮写了一个微信小程序版 2048,本篇文章主要分享实现 2048 的算法以及注意的点,一起来学习吧!

14540
来自专栏编程之旅

iOS开发——Core Graphics绘图

我们在搭建UI界面时,有很多时候,我们会用到iOS自带的绘图功能来完成一些界面的效果,很常用也很方便。今天我们在这里就一起讨论一下iOS的绘图功能。

26620
来自专栏我有一个梦想

Python 项目实践二(生成数据)第一篇

上面那个小游戏教程写不下去了,以后再写吧,今天学点新东西,了解的越多,发现python越强大啊! 数据可视化指的是通过可视化表示来探索数据,它与数据挖掘紧密相关...

30990
来自专栏葡萄城控件技术团队

Spread for Windows Forms快速入门(9)---使用公式

Spread的公式计算引擎支持300多种内置函数,并支持通过内置函数和运算符来自定义公式。支持的函数包括日期、时间函数、工程计算函数、财务计算函数、逻辑函数、数...

23250
来自专栏欧阳大哥的轮子

路径布局-基于数学函数的视图布局方法

路径布局MyPathLayout是MyLayout布局体系中的第7种布局体系,在这种布局体系中您只需要提供一个坐标轴、一个曲线函数、以及视图之间的距离这三个要素...

8020
来自专栏听雨堂

从MapX到MapXtreme2004[11]-坐标概论

        坐标的问题是Mapxtreme中最郁闷的问题,前几天在这上面耗了很多时间,没有搞定,今天又是不得不钻研,还好,小有心得。         1、...

22370

扫码关注云+社区

领取腾讯云代金券