C#中的Chart控件——当数据源很多时可以显示进度条拉动观察,也可以记录到后台文本详细对照
本文源码下载地址:https://download.csdn.net/download/qq_42757964/12253382(没有积分的同学,留个邮箱,我看到后发给你们)。
因为做项目时要搜集数据量很大,不但要实时显示还要把它们每次收集到的数据留在后台里,而chart的属性又太多了,我也是扒拉了好多天才明白了一丢丢,再这就做个小Demo吧。
1.简单示例(一条线):
2.数据源随着时间不断变化,进度条变化 。多条线:
3.看在整段时期内的数据大体图(消去或出现)进度条:
4.后台将时刻记录变化记录到一个txt文本里以供详细校验:
话不多说上码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
namespace ChartDemo
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
InitChart(); //chart初始化
}
private void button1_Click(object sender, EventArgs e)
{
timer1.Start();
}
private void button2_Click(object sender, EventArgs e)
{
timer1.Stop();
}
DateTime time= DateTime.Now;
private void timer1_Tick(object sender, EventArgs e)
{
//图表的操作
Random ra = new Random();
Series series = chart1.Series[0];
Series series2 = chart1.Series[1];
series.Points.AddXY(time, ra.Next(1, 50));// ra.Next(1, 50)
series2.Points.AddXY(time, ra.Next(1, 50));
chart1.ChartAreas[0].AxisX.ScaleView.Position = series.Points.Count - 5;//让进度条跟着数据源往前走
chart1.ChartAreas[0].AxisX.ScaleView.Position = series2.Points.Count - 5;
}
//chart初始化
private void InitChart()
{
Series series = chart1.Series[0];
series.ChartType = SeriesChartType.Spline;
Series series2 = chart1.Series[1];
series2.ChartType = SeriesChartType.Spline;
//重要——进度条
chart1.ChartAreas[0].AxisX.ScaleView.Size = 5;//设置当数据超出x轴时让其自动显示滚动条,chart的双击事件中可加上此句
chart1.ChartAreas[0].AxisX.LabelStyle.Format = "HH:mm:ss";
chart1.ChartAreas[0].AxisX.ScrollBar.IsPositionedInside = true;
chart1.ChartAreas[0].AxisX.ScrollBar.Enabled = true;
}
//chart的点击事件
private void chart1_Click_1(object sender, EventArgs e)
{
chart1.ChartAreas[0].AxisX.ScaleView.Size = 5;
chart1.ChartAreas[0].AxisX.ScrollBar.IsPositionedInside = true;
chart1.ChartAreas[0].AxisX.ScrollBar.Enabled = true;
}
}
}
下面进行详细步骤说明,感兴趣的同学可以看一下:
Chart图表:
因为项目中所用到数据量很多,需要用一个动态的图标给它显示出来。当然时刻采集到数据记录到一个txt文本里也是不错的选择。
因为C#的chart控件的属性比较多这里不对属性做过多说明,我们只讲我们用到的,如果需要可以参考这个博客:https://blog.csdn.net/qq_27825451/article/details/81305387
下面就开始吧:
首先创建一个ChartDemo.
在创建好的窗体内选择chart控件:
选着两个button一个timer(button用于控制开关,timer用于对收集到数据的实时绘制):
准备步骤做完了。
下面进入正题:
首先对chart的两个属性有些许的认识
1、 ChartAreas属性
2、 Series属性
ChartAreas:可以理解为是一个图表的绘图区。——你可以把它当做是你要作图的那个图板。
Series :实际的绘图数据区域,实际呈现的图形形状。——你可以把它当做你在图板上要显示的那个图 (当然具体是折线还是柱状图还是其他什么形状就需要你自己再来设置它的细节属性了,这次我们主要拿曲线来说明)。
注意:如果不自己再添加绘图区域ChartArea,则所有的Series会画在同一个ChartArea。还有作为画板最重要的当然是XY轴坐标刻度说明之类的了。而作为一条数据线最重要的当然是上面的数据点了。
3,代码说明:
我们先只用代码让它显示最简单一条曲线,任何属性都不用设置,很简单。
首先添加chart的引用: using System.Windows.Forms.DataVisualization.Charting;
1>在写一个chart的初始化方法:
private void InitChart()
{
//用当前的chart1取你要设置数据点的那个Series设置它的样式
Series series = chart1.Series[0];//chart图表默认有一个Series
series.ChartType = SeriesChartType.Spline;
//设置X轴的样式
chart1.ChartAreas[0].AxisX.ScaleView.Size = 5;
chart1.ChartAreas[0].AxisX.LabelStyle.Format = "HH:mm:ss";
chart1.ChartAreas[0].AxisX.ScrollBar.IsPositionedInside = true;
chart1.ChartAreas[0].AxisX.ScrollBar.Enabled = true;
}
2>双击timer控件在其点击事件里进行数据的捆绑:
DateTime time= DateTime.Now;//获取系统时间
private void timer1_Tick(object sender, EventArgs e)
{
//这里我们用Random随机数来模拟数据源图表的操作
Random ra = new Random();
//在对应的线上绘制你想显示的数据集合(数据点)
Series series = chart1.Series[0];
series.Points.AddXY(time, ra.Next(1, 50));// 第一个参代表你要绑定的横坐标数据,第二个参ra.Next(1, 50) 代表你要从随机数1~50里随机取数
chart1.ChartAreas[0].AxisX.ScaleView.Position = series.Points.Count - 5; //让进度条跟着数据源往前走
}
3>双击chart控件在其点击方法事件内对进度条进行设置:
//chart的点击事件
private void chart1_Click_1(object sender, EventArgs e)
{
chart1.ChartAreas[0].AxisX.ScaleView.Size = 5;
chart1.ChartAreas[0].AxisX.ScrollBar.IsPositionedInside = true;
chart1.ChartAreas[0].AxisX.ScrollBar.Enabled = true;
}
4>功能性步骤就这么多已经写完,下面在将初始化方法写入上面Form的构造方法里,在在button点击事件里写上timer的开始与结束方法即可大功告成。如图:
我们运行一下试试:
可以看到数据源跟着在不断变化着并且点击控件也可以控制进度条的显示与否。但是XY轴没有具体的要求,Series显示的是什么我们也没设置。
稍微改进下:
下面我们演示如果我们想要显示多条数据线在同时变化的话应该在此基础上在做哪些改照
首先我们在chart的属性窗口找到我们要改动的两个属性——ChartAreas , Series :
ChartAreas:
1, 找ChartAreas属性点开:我们会发现该属性里已经默认存在一个chart1,对,每错!这就是我们一开始用的那个“画板”,我们线就是显示在它上面。说到这你应该明白了,如果我想显示多个图表或者我还想再要一个柱形图…,就可以点击添加在建一个chartarea,在在上面操作。这里不再扩展。
2, 在找到它轴Axes属性,点开我们就能看到有关XY轴(前两个)的相关属性了:
我们这里将它们对应的title设为Time Value(X轴Y轴),并将IsMarginVisible属性设为false(不设也可以,具体功能看其对应属性介绍),当然你也可以把你要显示的轴的颜色和粗细在这里一并设置好。
Series:
1, 点开series能看到已经默认存在一条series,它就是我们刚刚使用过的那条线series1(实际使用时索引的应该是series0),下面我们再来添加一个新的series2。
然后将它们(series1,2)的对应属性改为我们所需要的:
这里我们可以将IsXValueIndexed属性改为true,XValueType类型改为Time,Name命名改为我们项目中的所用名词。
属性设置完,我们在在代码里去添加对应的series对象及其对应属性(跟第一个一样):
在运行起来就是这样了:
至于用输入输出流将其记录下来就相对容易很多了,直接在绑定数据的定时器方法里写一个IO流记录文本到你指定的文件夹里就行了,这里先提一下,改天再做详细说明:
(这是我做项目中的输入输出流部分,可以先参考着看一下~)
//IO流的存储与记录
/* 拖控件上去 try
{
using (FileStream fs = File.Open(path, filem))
{
Byte[] infor = new UTF8Encoding(true).GetBytes(time + "\t空气温度" + str_air + "\tPM2.5" + str_pm25 + "\t烟雾" + str_yanwu + "\tCO2浓度" + str_co2 + "\t光照强度" + str_sun + "\r\n");
fs.Write(infor, 0, infor.Length);
}
}
catch
{
FileStream fs = File.Open(path, FileMode.CreateNew);
fs.Dispose();
}