Unity3D开发之扇形图

扇形图原理和折线图差不多,都是在UI的OnPopulateMesh函数下绘制的。由于做的是半径不均匀的扇形图,所以去贴图抗锯齿没有实现。大家有啥想法(怎么取uv以及边界模糊的贴图怎么画)欢迎留言。

下面是OnPopulateMesh下的代码块。

protected override void OnPopulateMesh(VertexHelper toFill)
    {
        toFill.Clear();

        //ITEMS表示这个圆形被多少个三角形均分  数量越多 圆越精细
        offset = 360 / ITEMS;
        List<UIVertex> vertices = new List<UIVertex>();
        radiusOffset = 0.5f / count;//count 数据个数

        for (int i = 0; i < count; i++)
        {
            //if(i==0) continue;
            float value = Values[i];
            int c = (int)(value * ITEMS);
            float offsetAngle = 360 * value / c;

            float angle = 0;
            for (int j = 0; j < i; j++)
            {
                angle += Values[j];
            }

            angle *= 360;

            Vector2 originDir = Quaternion.Euler(0, 0, angle) * Vector2.up;

            for (int j = 0; j < c - 1; j++)
            {
                Vector2 startDir = Quaternion.Euler(0, 0, offsetAngle * j) * originDir;
                Vector2 endDir = (j == c - 2) ? Quaternion.Euler(0, 0, (360 * value)) * originDir: Quaternion.Euler(0, 0, offsetAngle * (j + 1)) * originDir;
                vertices.Add(new UIVertex() { position = Vector2.zero, color = Colors[i],uv0 = new Vector2(0f,0)});
                vertices.Add(new UIVertex() { position = endDir * GetRadius(i), color = Colors[i],uv0 = new Vector2(0,0.9f)});
                vertices.Add(new UIVertex() { position = startDir * GetRadius(i), color = Colors[i] ,uv0=new Vector2(1,0.9f)});
            }
            
        }
        toFill.AddUIVertexTriangleStream(vertices);
    }

 //这里设置每个扇形的半径
    float GetRadius(int index)
    {
        //return length; //选用此处代码则扇形图是半径均匀的
        return length* (0.5f + index * radiusOffset);//不同区域数据半径不同
    }

还加入了扇形区域选择提示数据值的功能。判断鼠标是否点击到了扇形图内还是折线图里相同的计算方法:

 public BoolAndFloat IsRaycastLocationValid(UnityEngine.Vector2 sp, UnityEngine.Camera eventCamera)
    {
        Vector2 local;
        //求出屏幕坐标在canvas下的2D坐标
        RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, sp, eventCamera, out local);
        

        Vector3 crossDir = Vector3.Cross(Vector3.up, new Vector3(local.x, local.y, 0));
        float angle = Vector2.Angle(Vector2.up, local);
        float dis = local.magnitude;
        if (Vector3.Dot(crossDir, Vector3.forward) <= 0)
            angle = 360 - angle;

        float value = angle / 360;
        int index = GetIndex(value);

        float radius = GetRadius(index);
        if (dis <= radius)
            return new BoolAndFloat(true,Values[index], radius, GetToTal(index));
        else return new BoolAndFloat(false,0, radius,0);
    }

    float GetToTal(int index)
    {
        float angle = 0;
        for (int i = 0; i < index+1; i++)
        {
            angle += Values[i];
        }

        return angle * 360;
    }
    int GetIndex(float value)
    {
        float temp = 0;
        for (int i = 0; i < Values.Count; i++)
        {
            temp += Values[i];
            if (value <= temp)
                return i;
        }

        return 0;
    }

public struct BoolAndFloat
{
    public bool Value1;
    public float Value2;
    public float Dis;
    public float Angle;

    public BoolAndFloat(bool value1, float value2, float dis,float angle)
    {
        Value1 = value1;
        Value2 = value2;
        Dis = dis;
        Angle = angle;
    }
}

运行结果如下:

项目地址如下:扇形图项目下载地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值