基于Compose & Canvas的蜘蛛网雷达图呈现效果

本文介绍如何使用Android Compose和Canvas绘制蜘蛛网雷达图,详细讲解了从初始化参数、绘制多边形、绘制辅助圆到绘制数据线和标签文本的全过程,以及如何实现手指拖动旋转和fling惯性效果。最后展示了不同数据长度下的雷达图效果。
摘要由CSDN通过智能技术生成

图片

实现过程

由于我初次看文章时并没有看的太细,感觉这个效果很炫酷就上手做了,完成之后仔细对比各个细节的实现,发现是有一些不同的,不过整体的思路大致是一致的,最后还有彩蛋。

准备工作

创建Compose方法,确定参数

新建kotlin文件,输入comp,回车,AS帮我们自动生成compose方法的模板,起个名字就叫SpiderWebRadarLineDiagram(蛛网雷达折线图)。

/**

* @param modifier 修饰符

* @param dataList 需要绘制的数据列表

* @param labelList 数据列表对应的标签

* @param layerNum 绘制蛛网的层数

* @param maxData_ 最外层蛛网代表的最大值,为空则取 dataList 中的最大值

*/

@Composable

fun SpiderWebRadarLineDiagram(

modifier: Modifier,

dataList: List<Float>,

labelList: List<String>,

layerNum: Int = 5,

maxData_: Float? = null

) {

//数据长度和标签长度判断处理,若不相等或为空抛出异常

if (dataList.size != labelList.size || dataList.isEmpty()) {

throw IllegalArgumentException(“dataList.size can not be empty,and it must equals to paramList.size!“)

}

//计算数据长度,用于确定绘制几边形

val count = dataList.size

//确定最外层代表的数值上限

val maxData = maxData_ ?: dataList.max()

//TODO 绘制

}

我们绘制折线图,需要确定图的大小、数据、标签、网的层数、最大值等,这些基本信息作为参数支持调用者自由定义,后续可以把线的粗细、颜色、字体大小等都提取成参数(AS MAC上智能提取参数快捷键:option + command + P)。另外对参数的输入做合法校验和处理。

添加Canvas

在上面的蛛网图方法中的TODO 正文中添加Canvas组件,并传入modifier,Canvas内部就是我们控制绘制的地方了

@Preview(showBackground = true)

@Composable

fun SpiderWebRadarLineDiagramPreview() {

SpiderWebRadarLineDiagram(

modifier = Modifier.fillMaxSize(),

dataList = listOf(4f, 5f, 5f, 4f, 5f),

labelList = listOf(“德“, “智“, “体“, “美“, “劳“)

}

编写Preview代码,实时预览

输入prev,回车,生成Preview模版,起名 SpiderWebRadarLineDiagramPreview,调用我们刚才创建的蛛网图方法。

@Preview(showBackground = true)

@Composable

fun SpiderWebRadarLineDiagramPreview() {

SpiderWebRadarLineDiagram(

modifier = Modifier.fillMaxSize(),

dataList = listOf(4f, 5f, 5f, 4f, 5f),

labelList = listOf(“德“, “智“, “体“, “美“, “劳“)

}

这里将showBackground设为true,显示背景色可以更加接近真实的效果,传入modifier,填满整个布局,传入绘制的数据,build一下,就可以看到,一片空白,因为我们还没有绘制任何东西呢。

绘制任意多边形

绘制辅助圆

根据Canvas当前尺寸宽高的较小者,并预留5%的边距空白,确定辅助圆的半径(预留空白用于后续绘制标签文本)。

Canvas(modifier = modifier) {

//计算多边形相接圆的半径

val radius = java.lang.Float.min(size.height, size.width) * 0.45f

//画辅助圆

drawCircle(Color.Cyan, radius, center)

}

图片

计算顶点坐标

我们前面根据调用者传递进来的dataList的size,确定了需要绘制的多边形的边数 count,根据count计算出各个顶点分布的角度,结合辅助圆的半径,利用高中学过的 sin 和 cos 三角函数知识,计算出x,y的值,注意方向和正负,这里还涉及到角度转换成弧度制,使用Math.toRadians()。

/**

* 根据角度计算坐标

*

* @param rotation 角度

* @param radius 半径

*/

private fun DrawScope.calculateXY(

rotation: Float,

radius: Float

): Pair<Float, Float> {

//将角度单位转换,如180度转换成Pi

val radian = Math.toRadians(rotation.toDouble())

return calculateXYByRadian(radian, radius)

}

/**

* 根据弧度计算坐标

*

* @param radius 半径

* @param radian 弧度

*/

private fun DrawScope.calculateXYByRadian(

radian: Double,

radius: Float

): Pair<Float, Float> {

val x = (radius * cos(radian) + center.x).toFloat()

val y = (radius * sin(radian) + center.y).toFloat(&#

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

king168236

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值