Click here to Skip to main content
Click here to Skip to main content
Articles » Languages » VB.NET » Utilities » Downloads
 
Add your own
alternative version

Application dashboard for tracking .NET application performance

, 26 Jul 2006 CPOL
Provides graphical feedback on the performance (memory usage, garbage collection, threads, exceptions, loaded classes) of a .NET application.
Imports System.ComponentModel

Public Class WhiteDial

#Region "Private members"
    Private _MinimumValue As Long
    Private _MaximumValue As Long
    Private _PriorHigh As Long
    Private _CurrentValue As Long

    Private _AutoGrowMaximum As Boolean = True

    Private _ArcPenColor As Color = Color.Red
    Private _ArcPenHighlightColor As Color = Color.LightCoral
    Private _ArcPen As New Pen(Color.Red, 4)
    Private _ArcPenHighlight As New Pen(Color.LightCoral, 2)

    Private _DialCentrePoint As New Point(45, 45)

    ' Fit the dial into the background graphic
    Private Const _TopRatio As Double = 15 / 94
    Private Const _BottomRatio As Double = 60 / 94

    Private Const _StartAngle As Integer = 135
    Private Const _MaxAngle As Integer = 270
    Private _CurrentAngle As Integer = 30
    Private _CurrentPriorHigh As Integer = 45

    Private _DialClipRectangle As New Rectangle(22, 22, 68, 68)

    'TODO: Resize the dial value indicator when the control is resized...
    Private _DialValueRectangle As New Rectangle(32, 54, 27, 10)
    Private _DialFont As New Font(FontFamily.GenericSansSerif, 7, FontStyle.Regular)
    Private _dialTextAlignment As New System.Drawing.StringFormat(StringFormatFlags.NoWrap)
#End Region

#Region "Public interface"

    ''' <summary>
    ''' The minimum level on the dial
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks>This value must be less than the maximum value</remarks>
    <Category("Values")> _
    <Description("The minimum level on the dial")> _
    Public Property MinimumValue() As Long
        Get
            Return _MinimumValue
        End Get
        Set(ByVal value As Long)
            If value > _MaximumValue Then
                Throw New ArgumentOutOfRangeException("MinimumValue", "Minimum value cannot exceed maximum value")
            Else
                _MinimumValue = value
            End If
        End Set
    End Property

    ''' <summary>
    ''' The maximum level on the dial
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks>If <see cref="AutoGrowMaximum">AutoGrowMaximum</see> is set this value will grow
    ''' will increase if a value greater than the maximum is set 
    ''' </remarks>
    <Category("Values")> _
    <Description("The maximum level on the dial")> _
    Public Property MaximumValue() As Long
        Get
            Return _MaximumValue
        End Get
        Set(ByVal value As Long)
            If value < MinimumValue Then
                Throw New ArgumentOutOfRangeException("MaximumValue", "Maximum value cannot be less than the minimum value")
            Else
                _MaximumValue = value
            End If
        End Set
    End Property

    ''' <summary>
    ''' The current level on the dial
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks>
    ''' 
    ''' </remarks>
    <Category("Values")> _
    <Description("The current level on the dial")> _
    Public Property CurrentValue() As Long
        Get
            Return _CurrentValue
        End Get
        Set(ByVal value As Long)
            If value > _PriorHigh And MaximumValue > 0 Then
                _PriorHigh = value
                _CurrentPriorHigh = (_PriorHigh / MaximumValue) * _MaxAngle
            End If

            If value < _MinimumValue Then
                _CurrentValue = _MinimumValue
            ElseIf value > _MaximumValue Then
                If _AutoGrowMaximum Then
                    _MaximumValue = value
                    _CurrentValue = value
                Else
                    _CurrentValue = _MaximumValue
                End If
            Else
                _CurrentValue = value
            End If

            If value > 0 And MaximumValue > 0 Then
                _CurrentAngle = (_CurrentValue / MaximumValue) * _MaxAngle
            Else
                _CurrentAngle = 0
            End If
            Me.Refresh()
        End Set
    End Property

    ''' <summary>
    ''' The prior high water level on the dial
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks>
    ''' This indicates the highest value that has been reached by this 
    ''' dial
    ''' </remarks>
    <Category("Values")> _
    <Description("The prior high water level on the dial")> _
    Public ReadOnly Property PriorHigh() As Integer
        Get
            Return _PriorHigh
        End Get
    End Property

    ''' <summary>
    ''' The colour used to draw the fat line on the dial
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <Category("Appearance")> _
    Public Property ArcPenColor() As Color
        Get
            Return _ArcPenColor
        End Get
        Set(ByVal value As Color)
            _ArcPenColor = value
            _ArcPen = New Pen(_ArcPenColor, 4)
            Me.Refresh()
        End Set
    End Property

    ''' <summary>
    ''' The colour used to draw the thinner inner line of the dial
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks>
    ''' </remarks>
    <Category("Appearance")> _
    Public Property ArcPenHighlightColor() As Color
        Get
            Return _ArcPenHighlightColor
        End Get
        Set(ByVal value As Color)
            _ArcPenHighlightColor = value
            _ArcPenHighlight = New Pen(_ArcPenHighlightColor, 2)
            Me.Refresh()
        End Set
    End Property

    ''' <summary>
    ''' Whether a value higher than the current <see cref="MaximumValue">maximum</see> causes 
    ''' the maximum to be increased
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property AutoGrowMaximum() As Boolean
        Get
            Return _AutoGrowMaximum
        End Get
        Set(ByVal value As Boolean)
            _AutoGrowMaximum = value
        End Set
    End Property
#End Region

#Region "Custom drawing code"
    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaint(e)

        e.Graphics.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAliasGridFit

        e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
        e.Graphics.DrawArc(_ArcPen, _DialClipRectangle, _StartAngle, _CurrentAngle)
        If _CurrentAngle > 10 Then
            e.Graphics.DrawArc(_ArcPenHighlight, _DialClipRectangle, _StartAngle + 2, _CurrentAngle - 5)
        End If

        If _CurrentPriorHigh > _CurrentAngle Then
            e.Graphics.DrawArc(_ArcPen, _DialClipRectangle, _StartAngle + _CurrentPriorHigh - 4, 4)
            e.Graphics.DrawArc(_ArcPenHighlight, _DialClipRectangle, _StartAngle + _CurrentPriorHigh - 2, 2)
        End If

        e.Graphics.FillRectangle(Brushes.DarkGreen, _DialValueRectangle)
        e.Graphics.DrawString(_CurrentValue.ToString, _DialFont, Brushes.Yellow, _DialValueRectangle, _dialTextAlignment)
    End Sub
#End Region

#Region "Resizing code"
    Protected Overrides Sub OnResize(ByVal e As System.EventArgs)
        MyBase.OnResize(e)

        '\\ Recalculate the offset centre point
        _DialCentrePoint = New Point(CInt((Me.Width / 96) * 45), CInt((Me.Height / 96) * 45))

        '\\ Recalculate the dial rectangle
        _DialClipRectangle = New Rectangle(CInt(_TopRatio * Me.Width), CInt(_TopRatio * Me.Height), CInt(_BottomRatio * Me.Width), CInt(_BottomRatio * Me.Height))

        '\\ Recalculate the text rectangle

    End Sub
#End Region

    Public Sub New()
        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Set the pen styles to have rounded ends
        _ArcPen.EndCap = Drawing2D.LineCap.Round
        _ArcPenHighlight.EndCap = Drawing2D.LineCap.Round

    End Sub
End Class

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Duncan Edwards Jones
Software Developer (Senior)
Ireland Ireland
C# / SQL Server developer
Microsoft MVP 2006, 2007
Visual Basic .NET
Follow on   Twitter   LinkedIn

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.141223.1 | Last Updated 27 Jul 2006
Article Copyright 2006 by Duncan Edwards Jones
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid