C#中Chart控件的一些由浅至深的理解
最近在做这样一个桌面应用程序,从公司后台服务器查询后,获取到设备上报的数据(每条都是字符串+JSON的形式),其中字符串里包含了设备名称、上报时间这两条信息,JSON中则包含了数据上报类型、重点关注的设备CPU温度及其他次要信息。需求呢,则是需要将这些数据中的时间、温度筛选出来制成折线图,并达到最终的一个显示效果(算是简单的数据可视化吧)。
其中参考几篇帮助较大的博文:
1.C# Chart控件,chart、Series、ChartArea曲线图绘制的重要属性
http://blog.sina.com.cn/s/blog_621e24e20101cp64.html
2.C# Chart各个属性详细解析、应用
https://blog.csdn.net/Andrewniu/article/details/78770227
3.c#改变坐标轴的标注
https://blog.csdn.net/u014683488/article/details/52106424
4.当然还有微软的官方文档
https://docs.microsoft.com/zh-cn/dotnet/api/system.web.ui.datavisualization.charting.customlabel?view=netframework-4.7.2
实际上工具使用者的需求是这样的:
①如图中所示,x轴能准确看出时间,且只显示整点的网格线,y轴则显示某个区间内的CPU温度,并且在重点关注范围能够明显区分;
②曲线上前后两点之间,若上报时间大于30分钟,则曲线不连续;
③显示温度最大值的时间及数值,并有y轴网格线穿过该点(未实现)
下面进入正文,在满足各个需求在实现过程中遇到的问题。
在此之前,需要大概了解的chart属性有ChartAreas、Series,想要画出目标图形,需要对两者的众多属性进行设置,上面参考博文中有详细解释,在我的理解中,按照结构来讲大概是如下图这样,Chart控件内可以添加多个ChartAreas,可以理解为作图区域,默认有一个为ChartAreas[0];而在各个ChartAreas中都可以有多个Series,Series是一些列点(Points)的集合,而这些点组成的集合与X轴(X axis)以及Y轴(Y axis)则构成了我们眼中的图表,即存在这样的结构:
----Chart ......一级
--------ChartAreas ......二级
------------Series ......三级
----------------Points ......四级
------------X axis ......三级
------------Y axis ......三级
在心中有个大致的认识后,还是需要动手才能创造出目标物,毕竟写代码这种事情读万卷书不如行万里路。那么就根据各个需求各个击破。
一、需求一
该需求中设计操作有,①改变x轴标签(label)②设置x轴y轴最大最小值及间隔③区分不同区间的y值。
此处主要是对ChartAreas中的Axes(轴)进行操作,先看一下Axes集合中包含的内容,进行操作“选择chart——点击‘ChartAreas’后的‘集合’——点击‘Axes’后的‘集合’”,如图:
直接贴代码
①给x轴添加标签
CustomLabel label = new CustomLabel();
label.FromPosition = i - 0.5;
label.ToPosition = i + 0.5;
//标签序号,在同一个标签中
label.RowIndex = 0;
chart1.ChartAreas[0].AxisX.CustomLabels.Add(label);
②设置x、y轴最大最小值及间隔
chart1.ChartAreas[0].AxisX.Maximum = EndHour;
chart1.ChartAreas[0].AxisX.Minimum = BeginHour;
chart1.ChartAreas[0].AxisX.Interval = 1;
chart1.ChartAreas[0].AxisY.Maximum = 120;
chart1.ChartAreas[0].AxisX.Minimum = 60;
chart1.ChartAreas[0].AxisY.Interval = 5;
③之前想的是创建两个ChartAres进行叠加,新的ares作为“背景”置于折线图后,尝试过之后发现并不容易(水平有限-.-),就退而求其次自己在excel表格中对等高的单元格填充颜色后获得所需比例的图像,按照温度的关注区间,制作了两张颜色所占高度不同比例的图,最后根据y轴数据最小值来设置不同背景;
if (Min_Y < 80)
{chart1.ChartAreas[0].AxisY.Minimum = 60;chart1.ChartAreas[0].BackImage = Application.StartupPath + "\\2.png";
}
else
{chart1.ChartAreas[0].AxisY.Minimum = 80;chart1.ChartAreas[0].BackImage = Application.StartupPath + "\\1.png";
}
至此需求一的关键实现已满足。
二、需求二
两点之间不连续的话,之前并没听说过折线图的点之间还可以不连线,则考虑到两个series之间并不存在绝对联系,则可通过添加一个新的series来实现。
if (time - lastTime > (decimal)0.5) //大于30分钟,不跟上一条点集连续,再加一条
{Series NewSeries = new Series();//NewSeries.ChartType = SeriesChartType.Line;onSeries = onSeries + 1;NewSeries.Name = "CPU温度" + onSeries;chart1.Series.Add(NewSeries.Name);chart1.Series[NewSeries.Name].MarkerBorderColor = Color.Honeydew;chart1.Series[NewSeries.Name].MarkerBorderWidth = 2;chart1.Series[NewSeries.Name].MarkerSize = 8;chart1.Series[NewSeries.Name].MarkerColor = Color.Red;chart1.Series[NewSeries.Name].MarkerStyle = MarkerStyle.Circle;chart1.Series[NewSeries.Name].ChartType = SeriesChartType.Line;
}
那么需求二关键实现也满足了。
三、需求三
可能对于整个需求来说,需求三才是一个难点,之前的想法并没有把标签Label和工具提示ToolTip的作用区分开来,在尝试后认为:
①Label作为Series上点Points的一个属性,在设置后会显示在图表上表示该点的附近的一个合适位置,设置后则显示在所在ChartAres上(未找到可以隐藏该属性的方法,如Label.Visible=false这样的);
②作为ToolTip的话,设置完成后可以通过获得该点的该属性值获取设置到的文本,故在此设置此属性来显示最大值上文字。
故对每个点的ToolTip都进行设置,在轮询找到Y值最大值时,进行设置:
chart1.Series[onSeries].Points[now].ToolTip = "时间:" + X_Value[i] + "\r\n" + "值:" + Y_Value[i];
在上述代码段中,X_Value为从数据中筛选到的数据上报时间的集合,将其值设置为该点的工具提示文本,后面要做的就是只将最大值的Label设置为与ToolTip文本相关的值(要注意,ToolTip后面也是有用的,就是在鼠标移动到该点时,将ToolTip的内容显示出来),下面先设置最大值的显示:
chart1.Series[Max_Index].Points[Max_Y_Index].Label = "时间:" + chart1.Series[Max_Index].Points[Max_Y_Index].ToolTip + "\r\n" + "值:" + Max_Y;
在上述代码段中,Max_Index为最大值所在Series的序号,Max_Y_Index为最大值的点在其所在Series的序号,即最大值所在点的标签文本=最大值所在点的工具提示文本+其他描述。
接下来看似已经实现了所有需求,但在需求中漏掉了较为重要的一点,作为数据可视化来讲,怎么能只是显示一个数据呢(虽然用户需求是这样,但作为初级程序员来说,不能对自己降低要求),要做的就是上面说的,移动鼠标到一个Point,显示该点的ToolTip,直接贴代码:
private void chart1_GetToolTipText(object sender, ToolTipEventArgs e)
{try{HitTestResult myTestResult = chart1.HitTest(e.X, e.Y, ChartElementType.DataPoint);//获取命中测试的结果if (myTestResult.ChartElementType == ChartElementType.DataPoint){//第几个点int i = myTestResult.PointIndex;DataPoint dp = myTestResult.Series.Points[i];double XValue = chart1.Series[0].Points[i].XValue;//获取数据点的X值//string YValue = dp.YValues[0].ToString();//获取数据点的Y值JSONObject j;e.Text = "序列:" + myTestResult.Series.Name + "\r\n时间:" + dp.ToolTip + "\r\n值:" + dp.YValues[0] + "\r\n";//ChartResult.Series[i].ToolTip;}}catch (Exception exc){}
}
显示效果的话如下:
四、总结
引用一句话来总结吧,实践是检验真理的唯一标准。古人也说,纸上谈来终觉浅,绝知此事要躬行。看的再多不如动手一试,当然也不是说在无任何基础的情况下去试,之前看到一位大牛博客中说的,当学习理论知识感到饱和或者厌倦的时候,就去动手做一些东西;当动手到毫无头绪如何进行下一步的时候,尝试去查阅理论知识来丰富自己的思维,这句话在我看来是非常赞同并在贯彻落实的。
当然,学习的过程缺少不了总结,在这个桌面应用中,主要是用于将本地磁盘中的视频与上报数据中的温度进行对比,以分析各个时间段视频的各项参数是否符合标准,其中当然不仅上述的些许操作,整个流程如下:
①操作access数据库存储配置文件
②向后台发送http请求获取上报数据
③上述的显示原始数据初步处理的结果
④获取本地视频的各项参数(帧率、大小、时长等)
⑤以时间为x轴数值,以各项参数为y轴参数,画出多条曲线加上文字分析,对比配置文件内的标准,检测在某个时间点的温度下视频的某个参数是否符合。
贴上一张最终结果的设计界面,有想法的同学私信交流。
C#中Chart控件的一些由浅至深的理解相关推荐
- 在 ASP.NET MVC 中使用 Chart 控件
在 .NET 3.5 的时候,微软就提供了一个 Chart 控件,网络上有大量的关于在 VS2008 中使用这个控件的文章,在 VS2010 中,这个控件已经被集成到 ASP.NET 4.0 中,可以 ...
- C# chart控件中游标随着鼠标移动
chart控件中游标如何随着移动? 思路很简单,只需要在鼠标进入chart控件时,获取鼠标的位置,然后将数值赋给游标的position属性. 具体实现方法如下: 选中chart控件.F4进入属性窗口, ...
- C# 中添加chart 控件
C# 中的chart 控件并不是VC编译器自带的控件,但是它拥有画图的能力,例如柱形图.饼状图.折线图,等等: 1.在网上下载mschart 的安装包:并执行安装文件: https://downloa ...
- C#中的Chart控件——当数据源很多时可以显示进度条拉动观察,也可以记录到后台文本详细对照
C#中的Chart控件--当数据源很多时可以显示进度条拉动观察,也可以记录到后台文本详细对照 本文源码下载地址:https://download.csdn.net/download/qq_427579 ...
- C#在chart控件中实现图上内插数据点功能
C#的chart控件可以轻松实现数据的查看,但是我们却没法轻易地对数据进行交互式编辑,所以前期我开发了chart控件数据点的框选.删除.平移功能,后来又开发了chart控件漫游功能.在我自己进行数据处 ...
- 基于Winform的Chart控件的简单使用(Chart控件中的条形统计图、折线统计图、扇形统计图的简单使用)
Chart控件集成了颇多的统计图模型,拿来即用的理念大大节省了开发的时间.下面演示最常见的三种统计图模型的使用. 效果展示: C#代码: using System; using System.Coll ...
- C# chart控件基础使用
基本介绍:chart(图表) 功能:主要用来绘制折线图,柱状图与饼状图,也可达到动态效果(例如作示波器): 需要说明 一个chart可以包含多个chartArea. chartArea是具体的坐标区域 ...
- C#chart控件绘制折线图、柱状图、饼图、雷达图
转载来源:https://blog.csdn.net/u011854789/article/details/82946553 参考链接: http://www.cnblogs.com/winshe/a ...
- C# Chart控件,chart、Series、ChartArea曲线图绘制的重要属性
原文有备份,如有错误和需要改进的地方,请不吝指正会继续修改的 8个月没写博客了- -,一来是有不想继续干开发的想法,二来是赖的写,三来还是不想总结.所以为了继续坚持自己的开发和总结的信念,总结一下C# ...
最新文章
- 三年级计算机课教案文档,小学三年级信息技术第十三课文件和文件夹教学设计...
- 如何确定python开发环境已经配置好_python学习第一天:window安装python开发环境完整篇...
- iPad如何越狱?4.2.1完美越狱教程 一 (DFU 绿霸越狱)
- PrimeFaces Mobile入门
- 转!最适合新手小白的8个python开发环境(内附python IDE最新下载地址+软件激活码+长期有效)
- JSP开发环境配置问题解答
- 面试题29. 顺时针打印矩阵/54. 螺旋矩阵
- VIM查看空格,换行,TAB键
- 1.图像显示图像腐蚀图像模糊canny边缘检测视频操作调用摄像头
- 隐秘攻击:恶意病毒可使智能手机加速老化
- 对第三组博客的检查情况
- HR别掉坑里了,送你最精确的计薪算法!
- 项目管理中如何应对用户频繁的需求变更?
- 常用的坐标系及其EPSG编码
- 千兆宽带网接入电脑电脑却只有百兆
- 京东历史价格查询的方法是?
- 计算机的声音图标打不开怎么回事,win10电脑音量图标打不开怎么办
- Android Studio模拟器的创建和SDK的安装
- 如何寻找省级软件产业主管部门认可的软件检测机构出具报告
- Linux【搭建环境与基本指令】