unity3d折线图

看到一位大佬做的,花了一点时间才复现出来。
请添加图片描述


public class LineChart : MaskableGraphic,ICanvasRaycastFilter
{ 
    [SerializeField] private int lineCount = 1;
    [SerializeField] private List<UnityEngine.Color> lineColors = new List<UnityEngine.Color>() { };
    [SerializeField] private int xwidth = 10;//数据间隔
    [SerializeField] private float pointWidth = 1;//点的宽度
    [SerializeField] private float linewidth = 3;//线的宽度
    private List<float> pointList = new List<float>();

    private Vector3 pos;//点的坐标
    private RectTransform rectTransform;
    private Text numText;
    //两个数据之间的间隔
    private float xLength=200f;
    //最多显示的数据数量
    private const int RemainCount = 10;

    public Vector3 Pos
    {
        get
        {
            return pos;
        }
    }
    protected override void Awake()
    {
        base.Awake();
        rectTransform = GetComponent<RectTransform>();
        //xLength = transform.parent.parent.GetComponent<RectTransform>().sizeDelta.x;
        //numText = transform.Find("NumText").GetComponent<Text>();
    }
    private bool IsReachLength = false;

    public void AddPoint(float point)
    {
        pointList.Add(point);
        int count = pointList.Count;

        if (count > lineCount)//如果只有一条曲线,则至少有两个点才可以开始绘制曲线
        {
            Vector2 size = rectTransform.sizeDelta;

            rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, xwidth * (count)); //当数据量达到我们设定的显示上限  数据个数保持不变  这个时候设置他的大小是不发生变化的 
            rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, xwidth * (count + 1));//所以我们就先设置小一单位 在设置加一单位  保证大小变化 
            SetVerticesDirty();                                                                                             //此函数改变RectTransform的大小  可以触发OnPopulateMesh调用
            //SetAllDirty();
            if (size.x > xLength)//显示区域的大小
            {
                if (count > RemainCount)//当数据个数大于我们规定的显示个数  就需要移除前面的数据 
                {
                    pointList.RemoveAt(0);
                    Vector3 pos = transform.localPosition;
                    transform.localPosition = pos + new Vector3(xwidth, 0, 0);//把显示往前移动一个单位 然后做移动动画
                }
                transform.DOLocalMoveX(transform.localPosition.x - xwidth, 0.3f);
            }
        }
    }
    protected override void OnPopulateMesh(VertexHelper vh)
    {
        int _count = pointList.Count;

        //画线
        if (_count > lineCount)
        {
            vh.Clear();
            for (int i = 0; i < _count - lineCount; i++)
            {
                //让曲线宽度在各种斜率下宽度一致
                float k = (pointList[i + lineCount] - pointList[i]) / (xwidth);

                //float _y = Mathf.Sqrt(Mathf.Pow(k, 2) + 4);
                float _y = Mathf.Sqrt(Mathf.Pow(Mathf.Abs(k) + 1, 2)) * linewidth / 2;
                _y = Mathf.Abs(_y);
                UIVertex[] verts = new UIVertex[4];
                verts[0].position = new Vector3(xwidth * (i / lineCount), pointList[i] - _y / 2);
                verts[1].position = new Vector3(xwidth * (i / lineCount), _y / 2 + pointList[i]);
                verts[2].position = new Vector3(xwidth * ((i + lineCount) / lineCount), pointList[i + lineCount] + _y / 2);
                verts[3].position = new Vector3(xwidth * ((i + lineCount) / lineCount), pointList[i + lineCount] - _y / 2);
                for (int j = 0; j < 4; j++)
                {
                    verts[j].color = UnityEngine.Color.yellow;
                    //verts[j].color = lineColors[(i % lineCount)];
                    verts[j].uv0 = Vector2.zero;
                }
                vh.AddUIVertexQuad(verts);
            }
        }
        //draw quad  显示数据大小的方块点
        for (int i = 0; i < _count; i++)
        {
            UIVertex[] quadverts = new UIVertex[4];
            quadverts[0].position = new Vector3((i / lineCount) * xwidth - pointWidth, pointList[i] - pointWidth);
            quadverts[0].color = UnityEngine.Color.white;
            quadverts[0].uv0 = Vector2.zero;

            quadverts[1].position = new Vector3((i / lineCount) * xwidth - pointWidth, pointList[i] + pointWidth);
            quadverts[1].color = UnityEngine.Color.white;
            quadverts[1].uv0 = Vector2.zero;

            quadverts[2].position = new Vector3((i / lineCount) * xwidth + pointWidth, pointList[i] + pointWidth);
            quadverts[2].color = UnityEngine.Color.white;
            quadverts[2].uv0 = Vector2.zero;

            quadverts[3].position = new Vector3((i / lineCount) * xwidth + pointWidth, pointList[i] - pointWidth);
            quadverts[3].color = UnityEngine.Color.white;
            quadverts[3].uv0 = Vector2.zero;

            vh.AddUIVertexQuad(quadverts);
        }
    }
    
    //鼠标在数据点
    public bool IsRaycastLocationValid(UnityEngine.Vector2 sp, UnityEngine.Camera eventCamera)
    {
        Vector2 local;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, sp, eventCamera, out local);
        Rect rect = GetPixelAdjustedRect();

        local.x += rectTransform.pivot.x * rect.width;
        local.y += rectTransform.pivot.y * rect.height;
        int _count = pointList.Count;
        for (int i = 0; i < _count; i++)
        {
            if (local.x > (i / lineCount) * xwidth - 3f && local.x < ((i / lineCount) * xwidth + 3f) && local.y > (pointList[i] - 3f)
                && local.y < (pointList[i] + 3f))
            {
                pos = new Vector3((i / lineCount) * xwidth, pointList[i], 0);
                return true;
            }
        }
        return false;
    }
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
    }

原文在这:https://blog.csdn.net/qq_33994566/article/details/72730325

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值