雷达图也叫蜘蛛网,常用处就是展示出多组数据值的比较,能清晰看出变量在数据集合中的高低。
绘制一个雷达图需要借用UnityUGUI中对UI的绘制流程,以下是实现过程:
定义一个 节点数组 arr ,该数组用于确定顶点数量位置与大小。
activeSprite 为一个精灵Sprite 变量,用于后面的向雷达图添加图形,可以略过
public float[] arr;
public Sprite activeSprite;
public override Texture mainTexture
{
/*
get写入判断了三种情况
先是没有精灵变量,则返回精灵的纹理
然后判断材质是否为空以及材质上的纹理是否为空,为空则返回默认的白色纹理s_WhiteTexture
不为空就返回该材质的纹理
*/
get
{
if (activeSprite == null)
{
if (material != null && material.mainTexture != null)
{
return material.mainTexture;
}
return s_WhiteTexture;
}
return activeSprite.texture;
}
}
/*
该段就是重写 MaskableGraphic 中的 OnPopulateMesh 填充网格
最开始的if用于判断节点是否小于3 只有大于3才能构建三角形形成网格
*/
protected override void OnPopulateMesh(VertexHelper vh)
{
if (arr.Length < 3)
{
base.OnPopulateMesh(vh);
return;
}
float w = rectTransform.sizeDelta.x;
float h = rectTransform.sizeDelta.y;
vh.Clear();
float ang = 2 * Mathf.PI / arr.Length;
vh.AddVert(Vector3.zero, color, new Vector2(0.5f,0.5f));
/*该循环遍历了节点数量,并计算出节点的坐标和uv坐标分量*/
for (int i = 0; i < arr.Length; i++)
{
float x = Mathf.Sin(i * ang) * arr[i];
float y = Mathf.Cos(i * ang) * arr[i];
float uvx = (x+w/2)/w;
float uvy = (y+h/2)/h;
vh.AddVert(new Vector3(x, y, 0), color, new Vector2(uvx, uvy));
/*遍历结束后
如果 i == 0 表明该节点是第一个,则需要中心点与第一个后最后一个顶点构成三角形,
不等于0 即不是第一个顶点,就只要中心点与相邻两个顶点构成三角形
两者都是获取顶点添加三角形索引
*/
if (i == 0)
{
vh.AddTriangle(0, arr.Length, 1);
}
else
{
vh.AddTriangle(0, i, i + 1);
}
}
}
该代码会实现这样一个利用数组大小实现绘制多边形网格。当节点数够多时,也会呈现圆的特征。
–补增
也可以使用Silder,Scrollbar,或者普通的随机数来对雷达图顶点的数值进行改变,
TODO:原顶点的数值会一直保留,改变后的新值不会直接修改原值,需要将原值标记为 脏 ,脏数据会在下一帧重现渲染
//将全部Graphic 组件标记为脏
public virtual void SetAllDirty();
//将Graphic 组件上的布局标记为脏
public virtual void SetLayoutDirty();
//将Graphic 组件上关联的材质标记为脏
public virtual void SetMaterialDirty();
以上三个都是用于标记脏的不同方法,频繁将数据标记为脏造成性能影响,与对象池
相同,也有着脏标记模式
来统一管理脏数据