809
社区成员
发帖
与我相关
我的任务
分享
Option Explicit
Const Margin As Integer = 10 '字体与边界处距离
Const intLeftMargin As Integer = 30 '左连界
Const intRightMargin As Integer = 35 '右连界
Const intBottomMargin As Integer = 20 '下连界
Const intTopMargin As Integer = 30 '上连界
Const intXSpan As Integer = 5 'X轴分段数
Const intYSpan As Integer = 10 'Y轴分段数
Dim intXAddSpan As Integer '数据点到达图右边界时,应左移的时间数(秒)
Dim intXMin As Long 'X轴显示坐标的最小值,由于时间可以突破65535秒,所以将变量设为长整型
Dim intXMax As Long 'X轴显示坐标的最大值,由于时间可以突破65535秒,所以将变量设为长整型
Dim intYMin As Integer 'Y轴显示坐标的最小值
Dim intYMax As Integer 'Y轴显示坐标的最大值
Dim intDisplayWidth As Integer '定义动态曲线显示窗口的图像宽度,以pixel为单位
Dim intDisplayHeight As Integer '定义动态曲线显示窗口的图像高度,以pixel为单位
Dim intPixelsPerStepInX As Integer 'X轴两点间的像素数,pixel,以每秒几个像素为步长,这样可以保持X轴坐标的一致,不会因小数问题而出现误差
Dim sinPixelsPerStepInY As Single 'Y轴两点间的像素数,pixel,此处为单精度数,目的是为了保证计算精度
Dim N As Integer '时间计数器
Dim NWindow As Integer '窗口计数器
Dim WindowSpan As Integer '窗口显示范围
Dim intTimeStep As Integer '定义时间步长
Dim cx As Integer '当前点X坐标
Dim cy As Integer '当前点Y坐标
Dim lx As Integer '上一点X坐标
Dim ly As Integer '上一点Y坐标
Dim llx As Integer '切割点处X坐标
Dim lly As Integer '切割点处Y坐标
Private Sub CmdStart_Click()
If TmrTriger.Enabled = False Then '如果时钟未启动,打开时钟
TmrTriger.Enabled = True
End If
End Sub
Private Sub CmdStop_Click()
If TmrTriger.Enabled = True Then '如果时钟已启动,关闭时钟
TmrTriger.Enabled = False
End If
End Sub
Private Sub Form_Load()
intXMin = 0 'X轴坐标显示最小值
intXMax = 50 'X轴坐标显示最大值
intYMin = 0 'Y轴坐标显示最小值
intYMax = 20 'Y轴坐标显示最大值
N = 0 '计数器置初始值
intTimeStep = 3 '时间步长为3秒
WindowSpan = intXMax - intXMin '窗体的大小
intXAddSpan = WindowSpan / intXSpan '当时间超过窗体显示最大值时,定义需延长的显示长度
InitialGraph PicFrame, intXMin, intXMax, intYMin, intYMax '初始化数据显示窗口宽度
DrawGraph PicFrame, "二氧化碳浓度曲线", intXMin, intXMax, intXSpan, "秒", 0, 100, intYSpan, "%" '画网格
PicDisplay.Left = PicFrame.ScaleLeft + intLeftMargin '计算动态显示曲线窗口的左边界
PicDisplay.Top = PicFrame.ScaleTop + intTopMargin '计算动态显示曲线窗口的右边界
PicDisplay.Width = intDisplayWidth '计算动态显示曲线窗口的宽度
PicDisplay.Height = intDisplayHeight '计算动态显示曲线窗口的高度
BitBlt PicDisplay.hDC, 0, 0, PicDisplay.Width, PicDisplay.Height, PicFrame.hDC, PicFrame.ScaleLeft + intLeftMargin, PicFrame.ScaleTop + intTopMargin, vbSrcCopy '将图1中的显示内容拷至图2中
PicDisplay.Refresh '刷新显示
End Sub
'数据显示窗口宽度初始化
Private Sub InitialGraph(ByVal Pic As PictureBox, ByVal XMin As Long, ByVal XMax As Long, ByVal YMin As Integer, ByVal YMax As Integer)
intDisplayWidth = Pic.ScaleWidth - Pic.ScaleLeft - intLeftMargin - intRightMargin '计算动态曲线显示窗口的宽度
intDisplayHeight = Pic.ScaleHeight - Pic.ScaleTop - intTopMargin - intBottomMargin '计算动态曲线显示窗口的宽度
intPixelsPerStepInX = intDisplayWidth / (XMax - XMin) '计算每两相邻点间像素数
intDisplayWidth = intPixelsPerStepInX * (XMax - XMin) '重新计算动态曲线显示窗口的宽度
PicFrame.Width = intLeftMargin + intRightMargin + intDisplayWidth '将曲线显示窗口的宽度设为像素的整数倍
End Sub
'画窗体函数
Private Sub DrawGraph(ByVal Pic As PictureBox, ByVal Title As String, _
ByVal XMin As Long, ByVal XMax As Long, ByVal XSpan As Integer, ByVal XUnit As String, _
ByVal YMin As Integer, ByVal YMax As Integer, ByVal YSpan As Integer, ByVal YUnit As String)
Dim i As Integer '定义循环变量
Dim YWidth As Integer 'X轴每一段对应的像素数
Dim XWidth As Integer 'Y轴每一段对应的像素数
Dim temp As Long '定义临时变量
'输出标题
Pic.BackColor = vbBlack '设定背景色为黑色
Pic.ForeColor = vbWhite '设定背景色为白色
Pic.CurrentX = Pic.ScaleLeft + (Pic.ScaleWidth - Pic.ScaleLeft) / 2 - TextWidth(Title) / 2 '设定标题输出坐标X值
Pic.CurrentY = Pic.ScaleTop + Margin '设定标题输出坐标Y值
Pic.Print Title '输出标题
'输出横轴与纵轴
XWidth = intDisplayWidth / XSpan '计算横轴每一段的像素间距
YWidth = intDisplayHeight / YSpan '计算纵轴每一段的像素间距
Pic.Line (intLeftMargin, intTopMargin)-(intLeftMargin + intDisplayWidth, intTopMargin + intDisplayHeight), , B '画方框
For i = 1 To XSpan - 1 '画纵轴
Pic.Line (Pic.ScaleLeft + intLeftMargin + i * XWidth, Pic.ScaleTop + intTopMargin)-(Pic.ScaleLeft + intLeftMargin + i * XWidth, Pic.ScaleHeight - intBottomMargin)
Next i
For i = 1 To YSpan - 1 '画横轴
Pic.Line (Pic.ScaleLeft + intLeftMargin, Pic.ScaleTop + intTopMargin + i * YWidth)-(Pic.ScaleWidth - intRightMargin, Pic.ScaleTop + intTopMargin + i * YWidth)
Next i
'输出Y轴坐标
For i = 0 To YSpan
'temp = YMin + i * YSpan '计算Y轴坐标值
temp = YMin + i * ((intYMax - intYMin) / YSpan) '计算Y轴坐标值
Pic.CurrentX = Pic.ScaleLeft + intLeftMargin - TextWidth(Trim(temp)) - 5 '计算Y轴坐标输出X值
Pic.CurrentY = Pic.ScaleHeight - intBottomMargin - YWidth * i - TextHeight(Trim(temp)) / 2 '计算Y轴坐标输出Y值
Pic.Print Trim(temp) '输出Y轴坐标
Next i
Pic.CurrentX = Pic.ScaleLeft + intLeftMargin - TextWidth(Trim(YUnit)) - 5 '计算Y轴输出单位X值
Pic.CurrentY = Pic.ScaleTop + intTopMargin - TextHeight(Trim(YUnit)) * (3 / 2) '计算Y轴输出单位Y值
Pic.Print Trim(YUnit) '输出Y轴单位
'输出X轴坐标
For i = 0 To XSpan
'temp = XMin + i * intXAddSpan '计算X轴坐标值
temp = XMin + i * ((intXMax - intXMin) / XSpan) '计算X轴坐标值
Pic.CurrentX = Pic.ScaleLeft + intLeftMargin - TextWidth(Trim(temp)) / 2 + i * XWidth '计算X轴输出单位X值
Pic.CurrentY = Pic.ScaleHeight - intBottomMargin + 5 '计算X轴输出单位Y值
Pic.Print Trim(temp) '输出X轴单位
Next i
Pic.CurrentX = Pic.ScaleWidth - TextWidth(Trim(XUnit)) - 2 '计算X轴输出单位X值
Pic.CurrentY = Pic.ScaleHeight - intBottomMargin + 5 '计算X轴输出单位Y值
Pic.Print Trim(XUnit) '输出X轴单位
'刷新显示
Pic.Refresh '刷新图像
End Sub
Private Sub TmrTriger_Timer()
NWindow = N - intXMin '计算当前点位置
cx = PicDisplay.ScaleLeft + NWindow * intPixelsPerStepInX '根据当前点位置计算其在图中对应的X值
cy = PicDisplay.ScaleTop + 0.1 * intDisplayHeight + Rnd * 0.9 * intDisplayHeight '随机产生当前点的Y值,其值在0.1-0.9之间
'If NWindow >= 0 And NWindow <= WindowSpan Then '如果当前点没有超出窗口
If NWindow >= 0 And NWindow < WindowSpan Then '如果当前点没有超出窗口
If NWindow = 0 Then '如果当前点为第一个点
PicDisplay.PSet (cx, cy), PicDisplay.ForeColor '输出一点
PicDisplay.Refresh
End If
If NWindow > 0 And NWindow < WindowSpan Then '如果当前点即不为第一个点,也不是最后一个点
PicDisplay.Line (lx, ly)-(cx, cy), PicDisplay.ForeColor '用线将当前点与上一点连接起来
PicDisplay.Refresh
End If
'If NWindow = WindowSpan Then '如果当前点为最后一个点
' PicDisplay.Line (lx, ly)-(cx, cy), PicDisplay.ForeColor '用线将当前点与上一点连接起来
' llx = PicDisplay.ScaleLeft + (NWindow - intXAddSpan) * intPixelsPerStep '将当前点的X值左移intXAddSpan个单位
' lly = cy '记下当前点的Y值
' PicDisplay.Refresh '刷新画面
' End If
If NWindow + intTimeStep >= WindowSpan Then
llx = PicDisplay.ScaleLeft + (NWindow - intXAddSpan) * intPixelsPerStepInX '将当前点的X值左移intXAddSpan个单位
lly = cy '记下当前点的Y值
End If
Else
BitBlt PicDisplay.hDC, 0, 0, (WindowSpan - intXAddSpan) * intPixelsPerStepInX, PicDisplay.ScaleHeight, PicDisplay.hDC, PicDisplay.ScaleLeft + intXAddSpan * intPixelsPerStepInX, PicDisplay.ScaleTop, vbSrcCopy '将图2中的后半部分拷至前面
PicDisplay.Refresh '刷新画面
'将图1中的空白图拷至图2后面
BitBlt PicDisplay.hDC, (WindowSpan - intXAddSpan) * intPixelsPerStepInX, PicDisplay.ScaleTop, intXAddSpan * intPixelsPerStepInX, PicDisplay.ScaleHeight, PicFrame.hDC, PicFrame.ScaleLeft + intLeftMargin + (WindowSpan - intXAddSpan) * intPixelsPerStepInX, PicFrame.ScaleTop + intTopMargin, vbSrcCopy
PicDisplay.Refresh '刷新画面
NWindow = NWindow - intXAddSpan '窗口记数器左移
cx = PicDisplay.ScaleLeft + NWindow * intPixelsPerStepInX ' 计算当前点的X值
PicDisplay.Line (llx, lly)-(cx, cy), PicDisplay.ForeColor '接着左移后的画面继续输出曲线
intXMin = intXMin + intXAddSpan '延长横轴最小值
intXMax = intXMax + intXAddSpan '延长横轴最大值
PicFrame.Cls ' 清除显示
DrawGraph PicFrame, "二氧化碳浓度曲线", intXMin, intXMax, intXSpan, "秒", intYMin, intYMax, intYSpan, "%" '按新X轴坐标重画显示画面
PicFrame.Refresh '刷新显示
End If
N = N + intTimeStep '计数器加2,模拟每2秒一个点
lx = cx '将当前点X值赋给上一点X值
ly = cy '将当前点Y值赋给上一点Y值
End Sub