Android雷达图(蜘蛛网图)绘制
龙旋
共 1978字,需浏览 4分钟
· 2022-03-23
最近因为项目需求,要实现一款雷达图来表示用户的各种成就值。
雷达图的绘制很简单,只要思路清晰按部就班的绘制就可以了,其中使用得最多,是路径path类的使用,使用这个类可以让我们更加方便地绘制出正多边形等效果。
效果图如下:
使用方式
使用方式很简单,只要在布局文件里面,直接使用这个控件就好了,记得给它设置一个合适的具体的大小。
另外可以控制绘制的是多少边形,通过提供的一些public方法,可以设置画笔颜色等,当然大家也可以按照自己的需求去修改啦。
//设置标题
public void setTitles(String[] titles) {
this.titles = titles;
}
//设置数值
public void setData(double[] data) {
this.data = data;
}
//设置最大数值
public void setMaxValue(float maxValue) {
this.maxValue = maxValue;
}
//设置蜘蛛网颜色
public void setMainPaintColor(int color){
mainPaint.setColor(color);
}
//设置标题颜色
public void setTextPaintColor(int color){
textPaint.setColor(color);
}
//设置覆盖局域颜色
public void setValuePaintColor(int color){
valuePaint.setColor(color);
}
具体实现
1、获得布局中心
我们在onSizeChanged(int w, int h, int oldw, int oldh)方法里面,根据View的长宽,获取整个布局的中心坐标,因为整个雷达都是以整个中心开始绘制的。
public class RadarView extends View {
private int count = 6; //数据个数
private float angle = (float) (Math.PI*2/count);
private float radius; //网格最大半径
private int centerX; //中心X
private int centerY; //中心Y
private String[] titles = {"a","b","c","d","e","f"};
private double[] data = {100,60,60,60,100,50,10,20}; //各维度分值
private float maxValue = 100; //数据最大值
private Paint mainPaint; //雷达区画笔
private Paint valuePaint; //数据区画笔
private Paint textPaint; //文本画笔
...
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
radius = Math.min(h, w)/2*0.9f;
//中心坐标
centerX = w/2;
centerY = h/2;
postInvalidate();
super.onSizeChanged(w, h, oldw, oldh);
}
...
}
2、绘制蜘蛛网络
/**
* 绘制正多边形
*/
private void drawPolygon(Canvas canvas){
Path path = new Path();
float r = radius/(count-1);//r是蜘蛛丝之间的间距
for(int i=1;i
float curR = r*i;//当前半径
path.reset();
for(int j=0;j
if(j==0){
path.moveTo(centerX+curR,centerY);
}else{
//根据半径,计算出蜘蛛丝上每个点的坐标
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);
}
}
3、绘制从中心到末端的直线
同样根据半径,计算出每个末端坐标
/**
* 绘制直线
*/
private void drawLines(Canvas canvas){
Path path = new Path();
for(int i=0;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);
}
}
4、绘制文本
对于文本的绘制,首先要找到末端的坐标,由于末端和文本有一定距离,给每个末端加上这个距离以后,再绘制文本。
另外,当文本在左边时,由于不希望文本和蜘蛛网交叉,我们可以先计算出文本的长度,然后使起始绘制坐标向左偏移这个长度。
/**
* 绘制文字
* @param canvas
*/
private void drawText(Canvas canvas){
Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
float fontHeight = fontMetrics.descent - fontMetrics.ascent;
for(int i=0;i
float x = (float) (centerX+(radius+fontHeight/2)*Math.cos(angle*i));
float y = (float) (centerY+(radius+fontHeight/2)*Math.sin(angle*i));
if(angle*i>=0&&angle*i<=Math.PI/2){//第4象限
canvas.drawText(titles[i], x,y,textPaint);
}else if(angle*i>=3*Math.PI/2&&angle*i<=Math.PI*2){//第3象限
canvas.drawText(titles[i], x,y,textPaint);
}else if(angle*i>Math.PI/2&&angle*i<=Math.PI){//第2象限
float dis = textPaint.measureText(titles[i]);//文本长度
canvas.drawText(titles[i], x-dis,y,textPaint);
}else if(angle*i>=Math.PI&&angle*i<3*Math.PI/2){//第1象限
float dis = textPaint.measureText(titles[i]);//文本长度
canvas.drawText(titles[i], x-dis,y,textPaint);
}
}
}
5、绘制覆盖区域
覆盖区域,只要使用path记录下坐标点,然后设
valuePaint.setStyle(Paint.Style.FILL_AND_STROKE);
使path包围区域被填充
/**
* 绘制区域
* @param canvas
*/
private void drawRegion(Canvas canvas){
Path path = new Path();
valuePaint.setAlpha(255);
for(int i=0;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);
}
//绘制小圆点
canvas.drawCircle(x,y,10,valuePaint);
}
valuePaint.setStyle(Paint.Style.STROKE);
canvas.drawPath(path, valuePaint);
valuePaint.setAlpha(127);
//绘制填充区域
valuePaint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawPath(path, valuePaint);
}
本篇文章主要是path类的使用,另外这个控件没有做较好的屏幕适配,大家可以根据自己的需要修改。
到这里就结束啦。
评论
智慧城市一张图,空天信息企业两条路
图源:《未来城市》纪录片撰文 | 朱君编辑 | 神璐璐审核 | 刘玉琳封面 | 《未来城市》纪录片4月2日,国家数据局就《深化智慧城市发展 推进城市全域数字化转型的指导意见》(以下简称《意见》)向社会公开征求意见,智慧城市建设方向再次明确。图源:国家数据局《意见》明确指出,鼓励有
泰伯网
5
日语五十音图学习难吗?
学习日语的初学者们都知道,我们学习日语最初就必须要接触日语五十音图,虽然相对其他语言来说,五十音图挺不是很难学,但是很多初学者可能会记不住,别担心,老师为大家带来了学习经验分享,一起来看看吧!五十音图就是日语最基础的基础,也就是地基。由于日语的元音比较单调,只有a/i/u/e/o这五种,再和各种辅音
python教程
0
超越原生,散点图实现华夫饼图
之前我们介绍过了如何使用新卡片图实现华夫饼图。参考:超越原生,PowerBI 华夫饼图实现但是利用卡片图实现的华夫饼图有一些缺点,形状之间的大小跟间距不太好把握,而且有时形状大一点的话显示就会不正常,需要做出二次调整。今天给大家介绍一种原生视觉对象生成华夫饼图的更佳方案,既简单又美观。上图是利用散点
PowerBI战友联盟
2
一张图看工业互联网标识六年发展
采写:王改静编辑:改静指导:新文延伸阅读:工业互联网标识建设六年系列做大做深,工业互联网标识解析还需突破几个难题?激活工业互联网标识数据要素价值,还要几步走?释放数据要素X效应,工业互联网标识体系能做什么?释放工业数据最大潜能:如何跨越标识规模化应用三重障碍?专家谈 I 标识“爬坡”:提档加力与未来
工业互联网世界
0
永久激活GPT4.0 + 多模态(文生图+图片解析)!终身使用!我上车了
GPT 4.0,太牛了🔥!!用GPT4.0生成个代码,轻轻松松就能帮你搞定如果你有想拍视频的想法,或者从事相关新媒体职业,那这个视频脚本生成就很适合你GPT4.0好用是好用,但它的价格也是真贵啊!一个月要 20 美元,折合大概 150 块人民币,一年就是 1800。MJ 绘画更是高攀不起的
Python客栈
0
Llama 3恐怖如斯,400B+版本即将到来!还有文生图Imagine Flash三步成图!
点蓝色字关注“机器学习算法工程师”设为星标,干货直达!简单总结一下:Llama 3包含8B和70B两个版本(包含预训练模型和Instruction tuning模型),性能相比Llama 2有明显提升,其中最大的模型Llama 3 70B人工评测超过GPT-3.5,未来还会推出参数量更大(400B+
机器学习算法工程师
10
全网最全网络基础思维导图(38张)
来源:架构师技术联盟计算机网络基础知识点多且杂,想要系统地学习,思维导图肯定是必不可少的。今天整理了38张思维导图,帮助你轻松理清思路,快速掌握关键内容。建议你收藏起来慢慢看,在看过之后最好能重新动手画一画,让计算机网络知识在你的大脑中连接起来。 01 TCP/IP网
良许Linux
0
iMeta | 最全可视化韦恩图和集合图工具EVenn使用手册
通讯点击蓝字 关注我们最全可视化集合工具EVenn使用手册iMeta主页:http://www.imeta.science研究论文● 原文链接DOI: https://doi.org/10.1002/imt2.184● 2024年4月11日,中国中医科学院陈同、黄璐琦和中国农科院
生信宝典
0