首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在VB.NET上绘制采样图

在VB.NET上绘制采样图
EN

Stack Overflow用户
提问于 2014-09-23 11:39:42
回答 1查看 7.1K关注 0票数 0

我正在从Arduino收集数据,并通过串口在Visual上进行传输。现在,我想用时间和电能(单位kWh)来绘制一个图-x轴上的时间和y轴上的电能。通常我是从Arduino那里得到电流的数据。

现在我想学习如何开始绘制图表。我需要一个简单的例子来解释如何为样本绘制一个图表。我试过一些示例代码。他们似乎不起作用。

我如何绘制一个图形时间与当前从串行读取?一旦Visual开始运行,它应该保存数据w.r.t系统的时间和日期。

这里提供的例子

当前代码

代码语言:javascript
运行
复制
Imports System
Imports System.IO.Ports
Imports System.ComponentModel
Imports System.Threading

Imports System.Drawing

Public Class Form1
    Dim myPort As Array
    Dim Distance As Integer


    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        myPort = IO.Ports.SerialPort.GetPortNames()
        PortComboBox.Items.AddRange(myPort)
        BaudComboBox.Items.Add(9600)
        BaudComboBox.Items.Add(19200)
        BaudComboBox.Items.Add(38400)
        BaudComboBox.Items.Add(57600)
        BaudComboBox.Items.Add(115200)
        ConnectButton.Enabled = True
        DisconnectButton.Enabled = False
    End Sub

    Private Sub ConnectButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ConnectButton.Click
        SerialPort1.PortName = PortComboBox.Text
        SerialPort1.BaudRate = BaudComboBox.Text
        SerialPort1.Open()
        Timer1.Start()

        'lblMessage.Text = PortComboBox.Text & " Connected."
        ConnectButton.Enabled = False
        DisconnectButton.Enabled = True
    End Sub

    Private Sub DisconnectButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DisconnectButton.Click
        SerialPort1.Close()

        DisconnectButton.Enabled = False
        ConnectButton.Enabled = True
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        Try
            SerialPort1.Write("c")
            System.Threading.Thread.Sleep(250)
            Dim k As Double
            Dim distance As String = SerialPort1.ReadLine()
            k = CDbl(distance)
            ListBoxSensor.Text = k
        Catch ex As Exception

        End Try
    End Sub

    Private Sub Relay_ON_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Relay_ON.Click
        SerialPort1.Write("1")
    End Sub

    Private Sub Relay_Off_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Relay_Off.Click
        SerialPort1.Write("0")
    End Sub

End Class
EN

回答 1

Stack Overflow用户

发布于 2014-09-24 17:37:07

Add a picturebox, a timer a button and a textbox:

PictureBox1大小= 768,279

计时器间隔至500

代码语言:javascript
运行
复制
Private img As Bitmap
Private imgClone As Bitmap
Private widthInterval As Integer
'the distance from the left side of picturebox where x axis starts
Private leftPad As Integer = 50
'the distance from the down side of picturebox where x axis is
Private downPad As Integer = 30
'the distance from the up side of picturebox where y axis ends
Private upPad As Integer = 50
'the distance from the right side of picturebox where x axis ends
Private rightPad As Integer = 80
Private rn As New Random

Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    drawBack()

    Timer1.Enabled = True
End Sub

Private Sub drawBack()
    Static count As Boolean = False
    Dim g As Graphics
    'number of values in x axis e.g 1, 2, 3, ... representing time
    Dim numX As Integer = 23
    'number of values in y axis representing KW/h
    Dim numY As Integer = 5
    Dim stringFormat As New StringFormat()
    'arreys to hold the text for both axies
    Dim arrayTextX(numX), arrayTextY(numY - 1) As String
    Dim i As Integer
    'the distance from the right side of picturebox where x axis stops
    Dim rightPad As Integer = 80
    Dim brush As Brush = New SolidBrush(Color.FromArgb(245, 255, 255))
    Dim pen As Pen = New Pen(Color.FromArgb(212, 212, 212), 1)
    Dim height, x, y As Integer

    'Run once
    If count = True Then
        Return
    End If

    count = True

    stringFormat.Alignment = StringAlignment.Center

    img = New Bitmap(PictureBox1.Width, PictureBox1.Height)
    imgClone = New Bitmap(PictureBox1.Width, PictureBox1.Height)

    g = Graphics.FromImage(img)
    g.SmoothingMode = SmoothingMode.AntiAlias
    g.Clear(Color.White)

    'the distance in x axis between each value
    widthInterval = CInt((PictureBox1.Width - leftPad - rightPad) / (numX + 1))
    'the distance in y axis between each value
    height = CInt((PictureBox1.Height - upPad - downPad) / (numY + 1))

    'fill arrays with text
    For i = 0 To numX - 1
        arrayTextX(i) = (i + 1).ToString
    Next

    For i = 0 To numY - 1
        arrayTextY(i) = ((i + 1) * height).ToString
    Next

    'fill background of graph with color
    g.FillRectangle(brush, New Rectangle(leftPad, upPad, PictureBox1.Width - leftPad - rightPad + 1, _
                                         PictureBox1.Height - downPad - upPad))
    'vertical lines
    x = leftPad
    For i = 0 To numX - 1
        x += widthInterval 
        g.DrawLine(pen, x, PictureBox1.Height - downPad, x, upPad)
        g.DrawString(arrayTextX(i), New Font("Arial", 8), Brushes.Black, _
                     New Rectangle(x - 10, PictureBox1.Height - downPad + 3, 20, 20), stringFormat)
    Next

    'horizontal lines
    stringFormat.Alignment = StringAlignment.Far
    y = PictureBox1.Height - downPad
    For i = 0 To numY - 1
        y -= height
        g.DrawLine(pen, leftPad, y, PictureBox1.Width - rightPad, y)
        g.DrawString(arrayTextY(i), New Font("Arial", 8), Brushes.Black, _
                     New Rectangle(0, y - 6, leftPad - 5, 20), stringFormat)
    Next

    g.DrawString("KW/Hour", New Font("Arial", 8, FontStyle.Bold), Brushes.Black, _
                     New PointF(5, 5))
    g.DrawString("Time", New Font("Arial", 8, FontStyle.Bold), Brushes.Black, _
                     New PointF(PictureBox1.Width - 50, PictureBox1.Height - 20))

    'draws x axis
    g.DrawLine(Pens.Black, New Point(leftPad, PictureBox1.Height - downPad), _
               New Point(PictureBox1.Width - rightPad, PictureBox1.Height - downPad))
    'draws y axis
    g.DrawLine(Pens.Black, New Point(leftPad, PictureBox1.Height - downPad), _
               New Point(leftPad, upPad))

    g.Dispose()

    PictureBox1.Image = img
    imgClone = CType(img.Clone, Bitmap)
End Sub

Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
    Dim value, x As Integer
    Dim g As Graphics
    Dim pntEnd As Point
    Static pnt As Point = New Point(-1, -1)
    Static staticX As Integer = -1

    Dim hour As Integer = DateTime.Now.Hour
    Dim minute As Integer = DateTime.Now.Minute
    Dim second As Integer = DateTime.Now.Second

    second = minute * 60 + second

    x = leftPad + hour * widthInterval + CInt(CDbl(widthInterval - 1) * CDbl(second) / 3600.0R)

    If pnt.X >= 0 Then
        'checks if the new points x coordinate is the same as the previous and returns
        If x <= staticX Then
            Return
        End If
    End If

    GetValue(value)

    pntEnd = New Point(x, PictureBox1.Height - value - downPad)

    g = Graphics.FromImage(img)
    g.SmoothingMode = SmoothingMode.AntiAlias

    If pnt.X < 0 Then
        g.DrawLine(Pens.Red, pntEnd, pntEnd)
    Else
        g.DrawLine(Pens.Red, pnt, pntEnd)
    End If

    g.Dispose()

    pnt = pntEnd
    staticX = x

    PictureBox1.Invalidate()
End Sub

Private Sub GetValue(ByRef value As Integer)
    'here you can take the value from arduino.
    value = rn.Next(0, PictureBox1.Height - downPad - upPad) 'random value
End Sub

当您按Button1时,图形就开始了。

计算图的宽度(x轴)

代码语言:javascript
运行
复制
width = PictureBox1.Width - leftPad - rightPad

这个宽度等于24小时或86400秒。因此,您应该将计时器间隔设置为

代码语言:javascript
运行
复制
Timer1.Interval = CInt((86400 / width ) * 1000) 'in milliseconds

没有必要这样做,因为刻度函数检查新点是否与前一个点相同。所以把计时器间隔设置为1秒。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25994162

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档