文章目录
- 前言:
- 开发环境:
- 1 下载ZedGraph 控件并设置图形界面
- 2 功能实现
- 3 需求升级
- 4 小结
话不多数,先上一个效果图:
前言:
需要采集一些设备的数据以图表的形式展示出来,研究数据的走向是否平稳,波动范围等。
开发环境:
IDEA: VS2019 社区版本
框架: .NET Framework 4
绘图控件:ZedGraph
1 下载ZedGraph 控件并设置图形界面
1 使用 VS自带的NuGet包管理器下载安装ZedGraph控件。在“工具”->“NuGet包管理器”->“管理解决方案的Nuget程序包”, 搜索ZedGraph并下载即可。
打开下载好的ZedGraph所在文件夹,将其拖拽到工具箱,此时就会发现工具箱多了一个ZedGraph,这样就可以像其它控件一样使用了。建立一个Winform窗口,将ZedGraph放上去,如图
2 功能实现
这里使用随机数据来模拟设备的数据,使用定时器Timer
更新曲线。直接上代码,有注释比较容易看得懂。
2.1 先添加对ZedGraph的引用
using ZedGraph;
2.2 具体功能
public partial class TrendChart : Form
{
//定时器刷新曲线
Timer ChartTimer;
//时间
int time = 30;
//记录曲线值
PointPairList vlist = new PointPairList();
public TrendChart()
{
InitializeComponent();
//初始化ZedGraph
InitZedGraph();
ChartTimer = new Timer()
{
Interval = 300,
};
ChartTimer.Tick += ChartTimer_Tick;
ChartTimer.Start();
}
#region 初始化图表控件
private void InitZedGraph()
{
GraphPane myPane = myZedgraph.GraphPane;
myPane.IsAlignGrids = true;
myPane.Title.Text = "测试速度";
myPane.XAxis.Title.Text = "时间";
myPane.YAxis.Title.Text = "速度";
for (int i = 0; i < 30; i++)
{
double time = (double)i;
double acceleration = 2.0;
double velocity = acceleration * time;
vlist.Add(time, velocity);
}
//生成一条红色的菱形样式曲线,将曲线和值vlist绑定
//生成速度图例
LineItem myCurve = myPane.AddCurve("速度", vlist, Color.Red, SymbolType.Diamond);
//填充白色
myCurve.Symbol.Fill = new Fill(Color.White);
//显示X的网格线
myPane.XAxis.MajorGrid.IsVisible = true;
//设置Y轴刻度为红色
myPane.YAxis.Scale.FontSpec.FontColor = Color.Red;
myPane.YAxis.Title.FontSpec.FontColor = Color.Red;
//隐藏Y轴对面的刻度显示
myPane.YAxis.MajorTic.IsOpposite = false;
myPane.YAxis.MinorTic.IsOpposite = false;
// 不显示Y轴的0刻度线
myPane.YAxis.MajorGrid.IsZeroLine = false;
myPane.YAxis.MajorGrid.IsVisible = true;
myPane.YAxis.MajorGrid.Color = Color.Red;
//设置刻度范围
myPane.YAxis.Scale.Align = AlignP.Inside;
myPane.YAxis.Scale.Max = 100;
myPane.YAxis.Scale.MaxAuto = true;
//设置chart的背景颜色
myPane.Chart.Fill = new Fill(Color.White, Color.LightGoldenrodYellow, 45.0f);
//刷新轴
myZedgraph.AxisChange();
}
#endregion
/// <summary>
/// 刷新曲线
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ChartTimer_Tick(object sender, EventArgs e)
{
//随机数据模拟
Random random = new Random();
double v = random.Next(30, 60);
//添加新的数据
vlist.Add(time, v);
time += 2;
//曲线刷新
myZedgraph.AxisChange();
myZedgraph.Refresh();
}
}
2.3 效果图如下:
运行的时候可以看到全部采集的数据都绘制在曲线上了,随着时间的越长,显示的点就越密集。
3 需求升级
客户不想看到这么多数据,只想看到最新的前三十条数据怎么做呢?
方法1 判断数据是否超过30,大于30之后每添加新的数据就把最前面的一个数据移除掉
方法2 不需要移除数据,更新X轴的范围,让其只绘制前面30个数据。这个方法需要知道30个数据X轴的具体值是多少。
方法1:修改定时器刷新函数ChartTimer_Tick(object sender, EventArgs e)
private void ChartTimer_Tick(object sender, EventArgs e)
{
//随机数据模拟
Random random = new Random();
double v = random.Next(30, 60);
//添加新的数据
vlist.Add(time, v);
time += 2;
#region 方法1
if (vlist.Count > 30)
{// 保留最新的30个数据
vlist.RemoveAt(0);
}
#endregion
//曲线刷新
myZedgraph.AxisChange();
myZedgraph.Refresh();
}
效果图:可以看到数据量一直保持在30个,前面的数据会被移除掉。
方法2:
private void ChartTimer_Tick(object sender, EventArgs e)
{
//随机数据模拟
Random random = new Random();
double v = random.Next(30, 60);
//添加新的数据
vlist.Add(time, v);
//每个点的时间间隔
time += 2;
#region 方法1
//if (vlist.Count > 30)
//{// 保留最新的30个数据
// vlist.RemoveAt(0);
//}
#endregion
#region 方法2
if(vlist.Count >= 30)
{//更新X轴的显示范围
myZedgraph.GraphPane.XAxis.Scale.Max = time;
//每个点的时间间隔
myZedgraph.GraphPane.XAxis.Scale.Min = time - (30 * 2);
}
#endregion
//曲线刷新
myZedgraph.AxisChange();
myZedgraph.Refresh();
}
效果图:这个效果就看着比较连续,没有太多空旷的地方
4 小结
1 绘制动态示波器的主要是 更新实时数据,将新的数据点添加到绑定曲线的数据类型上,记得刷新曲线。这个可以使用定时器或线程来实现。
2 对于曲线上点的显示范围可以有两种方式。一个是使用固定点数,超过固定点就移除旧的数据。另外一个是调整X轴的显示范围,仅显示最近一段时间的数据。
3 固定点数:好处:很方便简易实现,绘制速度快,消耗内存小。弊端:不能保存全部数据
调整X轴范围:好处:能存储全部数据,可以整体分析。弊端:占用内存大
以上便是简单的曲线绘制了,使用何种方式绘图可以根据自己的实际需求出发。