一年前写过一篇折线图的制作,当时显示效果还可以,只不过因为之前刚接触写博客,所以写的内容不是很完善,加上比较忙,都是草率记录的,代码结构也不是很好。昨天我又把这个项目的代码熟悉了一遍,然后把代码更改精炼了下。应该比以前更容易读懂了。

代码如下,上面都有注释:

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;//折线图public class LineChart : MaskableGraphic, ICanvasRaycastFilter{[SerializeField]//曲线个数private int lineCount = 1;[SerializeField]//颜色private List<Color> lineColors = new List<Color>() { };[SerializeField]private int xwidth = 20;//数据间隔[SerializeField]private float pointWidth = 4;//线的宽度[SerializeField]private float linewidth = 6;//线的宽度private List<float> pointList = new List<float>();private Vector3 pos;//数据点的坐标private RectTransform rectTransform;private Text numText;//两个数据之间的间隔private float xLength;//最多显示的数据数量private const int RemainCount = 50;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));//所以我们就先设置小一单位 在设置加一单位  保证大小变化 //此函数改变RectTransform的大小  可以触发OnPopulateMesh调用SetVerticesDirty();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 = 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 = Color.white;quadverts[0].uv0 = Vector2.zero;quadverts[1].position = new Vector3((i / lineCount) * xwidth - pointWidth, pointList[i] + pointWidth);quadverts[1].color = Color.white;quadverts[1].uv0 = Vector2.zero;quadverts[2].position = new Vector3((i / lineCount) * xwidth + pointWidth, pointList[i] + pointWidth);quadverts[2].color = Color.white;quadverts[2].uv0 = Vector2.zero;quadverts[3].position = new Vector3((i / lineCount) * xwidth + pointWidth, pointList[i] - pointWidth);quadverts[3].color = Color.white;quadverts[3].uv0 = Vector2.zero;vh.AddUIVertexQuad(quadverts);}}//如果鼠标在数据点上 就会返回truepublic 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;}void Update(){//鼠标是否放在白点处if (IsRaycastLocationValid(Input.mousePosition, null)){numText.gameObject.SetActive(true);numText.text = (pos.y).ToString();numText.transform.localPosition = pos;}else{numText.gameObject.SetActive(false);}}}

然后我们在面板上创建一个Scroll View更改名字为LineChart(命名随意),因为我们不需要显示滑动条,所以将Scroll View下的两个滑动条都给删除掉。然后将我们上面的脚本加到子目录Content上。如下图:

因为我们设置的以左下角为原点,向右为X轴,向上为Y轴,所以我们设置Content的Anchors和Pivot都为0,如下图:

设置已经完成,这时候我们只需在外部调用往里添加数据就可以了。

public class Test : MonoBehaviour {public LineChart lineChart;// Use this for initializationIEnumerator Start (){while(true){lineChart.AddPoint(Random.Range(10.0f,50.0f));yield return new WaitForSeconds(2f);}}
}

还有就是我们要实现鼠标移动到数据上显示数据的值,这时候我们需要在Content下创建一个Text,命名为NumText,设置他的Pivot为(0.5,-0.2)。这样可以让文本显示在数上0.2单位处。偏移量你可以自己设定。

以上就是对折线图制作的更新。对于绘制曲线以及原理,可以观看第一篇折线图博客。点击打开链接。希望本博客对你有帮助!

2019.4.10更

有很多人加我qq说不能显示出来折线。这里我们需要设置下面板:color的Alpha值设置为1,默认是0.

2019.6.4更

最近找到一个问题,就是调用OnPopulateMesh函数并不是SetSizeWithCurrentAnchors,而是SetVerticesDirty();我们在操作完更改后的位置处调用一下SetVerticesDirty()变可以让OnPopulateMesh重新绘制一次了。

Unity3D开发之折线图的制作(二)相关推荐

  1. Unity3D开发之折线图的制作(三)折线图终结篇之抗锯齿

    至于怎么挂载脚本怎么能够运行请参考折线图制作(二)的文章. 之前写的折线图一直被锯齿烦恼着,一直无法使用.一开始一直以为要自己写边际模糊算法来模糊编辑的锯齿部分,这可太难了.后来我的美术搭档告诉我可以 ...

  2. Unity3D开发之折线图制作

    因为之前有人问我有没有源码,看这篇博客没看懂.所以最近博主又把这个实现的代码精简了下放到这里.有兴趣的可以来看下.点击打开链接 . 柱状图.折线图这个在数据可视化中会经常用到,可是unity自身并不带 ...

  3. 如何用计算机做出折线图,Numbers怎么做折线图 Numbers制作折线图教程

    Numbers中有丰富的图表可供用户们选择,有的人想要了解下 Numbers怎么做折线图 .Numbers如何做折线图?小编带来了Numbers制作折线图教程,看完就知道Numbers怎么画折线图啦~ ...

  4. 动态折线图,制作原来是这么简单

    动态折线图,依据动态资料所绘制成的多角曲线图.通常用横轴代表时间,纵轴代表指标数值,每个时间与指标值形成坐标点,将各相邻两坐标点用直线相连,即构成动态折线图. 从上图得知,近一年汽油与柴油的价格总体呈 ...

  5. Unity3D开发之扇形图

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

  6. iOS开发中识别图中的二维码

    上一篇博客中给出了生成二维码和条形码的代码,本篇博客将会给出识别图片中二维码的代码. 代码: //1. 初始化扫描仪,设置设别类型和识别质量 CIDetector*detector = [CIDete ...

  7. unity3d开发 打飞机小游戏(二)(飞机动画设置)

    紧接着上一期的场景继续啊~ 首先要介绍一个unity3d里面的概念叫层次layer,其实并不难理解嘛,就是越高层的东西就越不容易被覆盖嘛,最底层的一般就是背景嘛,点击你的场景里面的资源,然后右边Ins ...

  8. 中绘制折线_统计图之折线图的结构和制作过程

    统计图(statisticalgraph)是用点.线.面等各种几何图形来形象化表达统计数据.它将研究对象的特征.内部构成.相互关系.对比情况.频数分布等情况形象而生动地表达出来,更直观地反映出事物间的 ...

  9. 【GraphMaker】Unity3D图表——柱状图、折线图、饼图

    http://blog.csdn.net/yongh701/article/details/71637090?utm_source=itdadao&utm_medium=referral 版权 ...

最新文章

  1. java中记忆深刻的问题_工作中碰到比较印象深刻的问题(面试必问)
  2. pythorch创建简单的神经网络源码
  3. shell脚本--使用for循环逐行访问txt文件
  4. asp.net中RegularExpressionValidator控件中正则表达式用法
  5. mysql抖动可能的原因,12 | 为什么我的MySQL会“抖”一下?
  6. 如何使用Node.js和CloudFormation在AWS Lambda中构建和部署GraphQL服务器
  7. Wamp修改httpd.conf中的DocumentRoot不生效解决办法
  8. 终于!华为Mate 9已获安卓9.0正式版更新
  9. 佛罗里达大学计算机专业世界排名,2020年佛罗里达大学排名TFE Times美国最佳计算机科学硕士专业排名第55...
  10. Ionic开发App中重要的部分
  11. modal 可拖拽 elementui antd
  12. R语言ggplot2可视化时间序列柱形图:通过双色渐变配色颜色主题可视化时间序列柱形图
  13. Office小技巧|Excel表格输入身份证数字就变了乱码怎么办?
  14. Windows Server安装 IIS 时报错:刷新服务器管理器时出现意外错 误:无法打开匿名级安全令牌。(异常来自 HRESULT:0x80070543)
  15. Eclipse没有Dynamic Web Project选项解决
  16. 嵌入式学习(二)之SoC芯片的开发流程
  17. Sa-Token中接口的限流
  18. Go安装、配置和vsCode配置Go
  19. 百度和360的关键词提交
  20. AI Security3-通用漏洞披露(CVE: Common Vulnerabilities and Exposures)

热门文章

  1. 扫地机器人哪个牌子好?合格的扫地机器人推荐
  2. ThreadLocal不好用?那是你没用对!
  3. C语言编程工具Dev C++的安装教程
  4. CDH6中的各种目录
  5. Docker+Ovs构建SDN网络
  6. 【blob】blob视频的一种下载办法 m3u8
  7. Windows 安装appium环境
  8. C语言中的静态变量和静态函数
  9. python---引用其他py文件中的函数
  10. 无盘服务器chkdsk *: /f)修复命令,使用CHKDSK命令修复U盘文件或目录损坏无法读取问题...