Thread Graph : Chart « GUI Applications « VB.Net Tutorial






Thread Graph
'Visual Basic 2005 Programmer's Reference
'by Rod Stephens (Author) 

'# Publisher: Wrox (October 21, 2005)
'# Language: English
'# ISBN-10: 0764571982
'# ISBN-13: 978-0764571985


Imports System.Drawing
Imports System.Windows.Forms
Imports System.Math
Imports System.Threading

public class ThreadGraph
   public Shared Sub Main
        Application.Run(New Form1)
   End Sub
End class


Public Class Form1

    Private m_Ymid As Integer
    Private m_Y As Integer
    Private Const GRID_STEP As Integer = 40

    Private m_GraphThread As Thread

    ' Get ready.
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        m_Ymid = picGraph.ClientSize.Height \ 2
        m_Y = m_Ymid

        ' Make the Bitmap and Graphics objects.
        Dim wid As Integer = picGraph.ClientSize.Width
        Dim hgt As Integer = picGraph.ClientSize.Height
        Dim bm As New Bitmap(wid, hgt)
        Dim gr As Graphics = Graphics.FromImage(bm)

        ' Draw guide lines.
        gr.Clear(Color.Blue)
        For i As Integer = m_Ymid To picGraph.ClientSize.Height Step GRID_STEP
            gr.DrawLine(Pens.LightBlue, 0, i, wid - 1, i)
        Next i
        For i As Integer = m_Ymid To 0 Step -GRID_STEP
            gr.DrawLine(Pens.LightBlue, 0, i, wid - 1, i)
        Next i

        picGraph.Image = bm
    End Sub

    ' Start drawing the graph.
    Private Sub btnGraph_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGraph.Click
        If m_GraphThread Is Nothing Then
            ' The thread isn't running. Start it.
            AddStatus("Starting thread")

            m_GraphThread = New Thread(AddressOf DrawGraph)
            m_GraphThread.Priority = ThreadPriority.BelowNormal
            m_GraphThread.IsBackground = True
            m_GraphThread.Start()

            AddStatus("Thread started")

            btnGraph.Text = "Stop"
        Else
            ' The thread is running. Stop it.
            AddStatus("Stopping thread")

            m_GraphThread.Abort()
            ' m_GraphThread.Join()
            m_GraphThread = Nothing

            AddStatus("Thread stopped")

            btnGraph.Text = "Start"
        End If
    End Sub

    ' Draw a graph until stopped.
    Private Sub DrawGraph()
        Try
            ' Generate pseudo-random values.
            Dim y As Integer = m_Y
            Do
                ' Generate the next value.
                NewValue()

                ' Plot the new value.
                PlotValue(y, m_Y)
                y = m_Y
            Loop
        Catch ex As Exception
            AddStatus("[Thread] " & ex.Message)
        End Try
    End Sub

    ' Generate the next value.
    Private Sub NewValue()
        ' Delay a bit before calculating the value.
        Dim stop_time As Date = Now.AddMilliseconds(20)
        Do While Now < stop_time
        Loop

        ' Calculate the next value.
        Static rnd As New Random
        m_Y += rnd.Next(-4, 5)
        If m_Y < 0 Then m_Y = 0
        If m_Y >= picGraph.ClientSize.Height - 1 Then m_Y = picGraph.ClientSize.Height - 1
    End Sub

    ' Plot a new value.
    Private Delegate Sub PlotValueDelegate(ByVal old_y As Integer, ByVal new_y As Integer)
    Private Sub PlotValue(ByVal old_y As Integer, ByVal new_y As Integer)
        ' See if we're on the worker thread and thus
        ' need to invoke the main UI thread.
        If Me.InvokeRequired Then
            ' Make arguments for the delegate.
            Dim args As Object() = {old_y, new_y}

            ' Make the delegate.
            Dim plot_value_delegate As PlotValueDelegate
            plot_value_delegate = AddressOf PlotValue

            ' Invoke the delegate on the main UI thread.
            Me.Invoke(plot_value_delegate, args)

            ' We're done.
            Exit Sub
        End If

        ' Make the Bitmap and Graphics objects.
        Dim wid As Integer = picGraph.ClientSize.Width
        Dim hgt As Integer = picGraph.ClientSize.Height
        Dim bm As New Bitmap(wid, hgt)
        Dim gr As Graphics = Graphics.FromImage(bm)

        ' Move the old data one pixel to the left.
        gr.DrawImage(picGraph.Image, -1, 0)

        ' Erase the right edge and draw guide lines.
        gr.DrawLine(Pens.Blue, wid - 1, 0, wid - 1, hgt - 1)
        For i As Integer = m_Ymid To picGraph.ClientSize.Height Step GRID_STEP
            gr.DrawLine(Pens.LightBlue, wid - 2, i, wid - 1, i)
        Next i
        For i As Integer = m_Ymid To 0 Step -GRID_STEP
            gr.DrawLine(Pens.LightBlue, wid - 2, i, wid - 1, i)
        Next i

        ' Plot a new pixel.
        gr.DrawLine(Pens.White, wid - 2, old_y, wid - 1, new_y)

        ' Display the result.
        picGraph.Image = bm
        picGraph.Refresh()

        gr.Dispose()
    End Sub

    ' Add a status string to txtStatus.
    Private Delegate Sub AddStatusDelegate(ByVal txt As String)
    Private Sub AddStatus(ByVal txt As String)
        ' See if we're on the worker thread and thus
        ' need to invoke the main UI thread.
        If Me.InvokeRequired Then
            ' Make arguments for the delegate.
            Dim args As Object() = {txt}

            ' Make the delegate.
            Dim add_status_delegate As AddStatusDelegate
            add_status_delegate = AddressOf AddStatus

            ' Invoke the delegate on the main UI thread.
            Me.Invoke(add_status_delegate, args)

            ' We're done.
            Exit Sub
        End If

        txtStatus.Text &= vbCrLf & txt
        txtStatus.Select(txtStatus.Text.Length, 0)
        txtStatus.ScrollToCaret()
    End Sub

    ' Display the current time.
    Private Sub tmrUpdateClock_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrUpdateClock.Tick
        lblTime.Text = Now.ToString("T")
    End Sub
End Class
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Public Class Form1
    Inherits System.Windows.Forms.Form

    'Form overrides dispose to clean up the component list.
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing AndAlso components IsNot Nothing Then
            components.Dispose()
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
        Me.components = New System.ComponentModel.Container
        Me.lblTime = New System.Windows.Forms.Label
        Me.txtStatus = New System.Windows.Forms.TextBox
        Me.picGraph = New System.Windows.Forms.PictureBox
        Me.btnGraph = New System.Windows.Forms.Button
        Me.tmrUpdateClock = New System.Windows.Forms.Timer(Me.components)
        CType(Me.picGraph, System.ComponentModel.ISupportInitialize).BeginInit()
        Me.SuspendLayout()
        '
        'lblTime
        '
        Me.lblTime.Location = New System.Drawing.Point(208, 4)
        Me.lblTime.Name = "lblTime"
        Me.lblTime.Size = New System.Drawing.Size(80, 16)
        Me.lblTime.TabIndex = 7
        Me.lblTime.Text = "Label1"
        Me.lblTime.TextAlign = System.Drawing.ContentAlignment.MiddleRight
        '
        'txtStatus
        '
        Me.txtStatus.Dock = System.Windows.Forms.DockStyle.Bottom
        Me.txtStatus.Location = New System.Drawing.Point(0, 38)
        Me.txtStatus.Multiline = True
        Me.txtStatus.Name = "txtStatus"
        Me.txtStatus.ReadOnly = True
        Me.txtStatus.ScrollBars = System.Windows.Forms.ScrollBars.Vertical
        Me.txtStatus.Size = New System.Drawing.Size(292, 85)
        Me.txtStatus.TabIndex = 6
        Me.txtStatus.Text = "Ready"
        '
        'picGraph
        '
        Me.picGraph.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D
        Me.picGraph.Dock = System.Windows.Forms.DockStyle.Bottom
        Me.picGraph.Location = New System.Drawing.Point(0, 123)
        Me.picGraph.Name = "picGraph"
        Me.picGraph.Size = New System.Drawing.Size(292, 150)
        Me.picGraph.TabIndex = 5
        Me.picGraph.TabStop = False
        '
        'btnGraph
        '
        Me.btnGraph.Location = New System.Drawing.Point(8, 4)
        Me.btnGraph.Name = "btnGraph"
        Me.btnGraph.Size = New System.Drawing.Size(48, 24)
        Me.btnGraph.TabIndex = 4
        Me.btnGraph.Text = "Graph"
        '
        'tmrUpdateClock
        '
        Me.tmrUpdateClock.Enabled = True
        Me.tmrUpdateClock.Interval = 250
        '
        'Form1
        '
        Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.ClientSize = New System.Drawing.Size(292, 273)
        Me.Controls.Add(Me.lblTime)
        Me.Controls.Add(Me.txtStatus)
        Me.Controls.Add(Me.picGraph)
        Me.Controls.Add(Me.btnGraph)
        Me.Name = "Form1"
        Me.Text = "ThreadGraph"
        CType(Me.picGraph, System.ComponentModel.ISupportInitialize).EndInit()
        Me.ResumeLayout(False)
        Me.PerformLayout()

    End Sub
    Friend WithEvents lblTime As System.Windows.Forms.Label
    Friend WithEvents txtStatus As System.Windows.Forms.TextBox
    Friend WithEvents picGraph As System.Windows.Forms.PictureBox
    Friend WithEvents btnGraph As System.Windows.Forms.Button
    Friend WithEvents tmrUpdateClock As System.Windows.Forms.Timer

End Class








15.4.Chart
15.4.1.Custom ChartCustom Chart
15.4.2.Char CPU and MemoryChar CPU and Memory
15.4.3.Performance Monitor
15.4.4.GDI+ Line ChartGDI+ Line Chart
15.4.5.Thread GraphThread Graph