⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 charthelper.vb

📁 使用Access数据库演示的任务分配管理程序 一个使用ADO.NET基于Microsoft Access数据库演示的任务分配管理的程序
💻 VB
字号:
Imports System.Drawing.Drawing2D

' Constants.
Friend Class ConstValues
    ' How many pixels a chart item expands.
    Public Shared ExpandSize As Integer = 10

    ' Size of 3D shadow.
    Public Shared ShadowSize As Integer = 3
End Class


' Color table that is used for chart items. User of the control 
' can override the color table with methods exposed from the main 
' control class. Colors repeat if an index is specified that is 
' larger than the color table but the color is slightly brighter. 
Friend Class ChartColors

#Region " Color Table "

    Private m_List As Color() = _
    { _
        Color.Tomato, _
        Color.LimeGreen, _
        Color.Orange, _
        Color.DarkSeaGreen, _
        Color.SteelBlue, _
        Color.MediumOrchid, _
        Color.Goldenrod, _
        Color.LightBlue, _
        Color.LightGreen, _
        Color.Coral, _
        Color.Aquamarine, _
        Color.DeepSkyBlue, _
        Color.LightSalmon, _
        Color.SkyBlue _
    }

#End Region

    ' Override a color in the color table.
    Public Sub SetColor(ByVal Index As Integer, ByVal NewColor As Color)
        ' Return right away if passed in an invalid index.
        If (Index < 0) Or (Index >= m_List.Length) Then
            Return
        End If
        m_List(Index) = NewColor
    End Sub

    ' Return color from color table. Colors repeat but are slightly brighter.
    Public Function GetColor(ByVal Index As Integer) As Color
        Dim result As Color = m_List((Index Mod m_List.Length))
        Dim x As Integer = CInt(Index / m_List.Length)
        If x > 0 Then
            ' Asked for a color larger than our internal table.
            result = Color.FromArgb( _
                Math.Min(result.R + x, 255), _
                Math.Min(result.G + x, 255), _
                Math.Min(result.B + x, 255))
        End If
        Return result
    End Function
End Class


' Base class that performs drawing functions. Shape classes 
' inherit from this class and perform shape-specific actions, 
' calculate position / size and draw shapes.
Friend Class ChartDrawing

    ' Used to access main control properties.
    Protected m_Parent As CustomChart = Nothing

    ' Constructor.
    Public Sub New(ByVal Parent As CustomChart)
        m_Parent = Parent
    End Sub

    ' Draw the chart.
    Public Overridable Sub Draw(ByVal Width As Integer, _
        ByVal Height As Integer, ByVal rc As Rectangle, _
        ByVal g As Graphics, ByVal HitTest As Graphics)

        ' Don't try drawing anything if area is too small.
        If (rc.Width <= 1) Or (rc.Height <= 1) Then
            Return
        End If

        ' First, draw the 3D shadow.
        Dim item As ChartItem
        Dim i As Integer
        For i = ConstValues.ShadowSize To 0 Step -1
            For Each item In m_Parent.List
                ' Get drawing area for this item.
                Dim rcShadow As New Rectangle(rc.Location, rc.Size)
                rcShadow.Offset(i, i)

                If item.IsExpanded Then
                    ' Draw expanded item shadow.
                    Dim rcShift As New Rectangle(rcShadow.Location, rcShadow.Size)
                    rcShift.Offset(item.ExpandOffset.X, item.ExpandOffset.Y)
                    DrawShape(g, New HatchBrush(HatchStyle.Percent50, item.Color), rcShift, item)
                Else
                    ' Draw item shadow.
                    DrawShape(g, New HatchBrush(HatchStyle.Percent50, item.Color), rcShadow, item)
                End If
            Next item
        Next i

        ' Now go through and draw chart items.
        For Each item In m_Parent.List
            ' Adjust the bounding rectangle for expanded items. If the 
            ' item is expanded, draw on a memory bitmap with non-expanded 
            ' area so the expanded area acts like it's part of the 
            ' shape (used when performing hit testing later).
            Dim rcShape As New Rectangle(rc.Location, rc.Size)
            If item.IsExpanded Then
                rcShape.Offset(item.ExpandOffset.X, item.ExpandOffset.Y)
                DrawShape(HitTest, New SolidBrush(item.Color), rc, item)
            End If

            ' Use highlight brush if mouseover, otherwise use gradient brush.
            Dim brushShape As Brush = Nothing
            If item.IsOver Then
                brushShape = New SolidBrush(item.HighlightColor)
            Else
                brushShape = New LinearGradientBrush(rcShape, item.Color, item.HighlightColor, LinearGradientMode.Horizontal)
            End If

            ' Draw the shape.
            DrawShape(g, brushShape, rcShape, item)
            DrawShape(HitTest, New SolidBrush(item.Color), rcShape, item)
        Next item

        ' Draw the shape labels. 
        ' Calculate border size used when drawing labels.
        Dim border As Integer = ConstValues.ExpandSize + ConstValues.ShadowSize + 1
        DrawLabels(g, rc, border, m_Parent.List)
    End Sub

    ' Draws labels, values and percent in each shape. All three values can be
    ' turned on / off through properties exposed by the main control class.
    Private Sub DrawLabels(ByVal g As Graphics, ByVal rc As Rectangle, _
        ByVal Border As Integer, ByVal List As ArrayList)

        ' Calculate total value of chart (sum of all items) that is 
        ' used when drawing percent. 
        Dim total As Integer = m_Parent.TotalValue

        ' Go through each item and draw label for each item in chart.
        Dim item As ChartItem
        For Each item In List
            ' Create the label string to display based on control properties.
            Dim labelStr As String = String.Empty
            If m_Parent.ShowLabel Then
                labelStr = item.Label
            End If

            ' Create the value string to display based on control properties.
            Dim valueStr As String = String.Empty
            If (m_Parent.ShowValue = True) And (m_Parent.ShowPercent = False) Then
                valueStr = item.Value.ToString()
            Else
                If (m_Parent.ShowValue = False) And (m_Parent.ShowPercent = True) Then
                    valueStr = String.Format("{0:0}%", (item.Value * 100) / total)
                Else
                    If (m_Parent.ShowValue = True) And (m_Parent.ShowPercent = True) Then
                        valueStr = String.Format("{0} ({1:0}%)", item.Value, (item.Value * 100) / total)
                    End If
                End If
            End If

            ' Calculate size of strings.
            Dim labelSize As SizeF = g.MeasureString(labelStr, m_Parent.Font)
            Dim valueSize As SizeF = g.MeasureString(valueStr, m_Parent.Font)

            ' Calculate where to draw strings.
            Dim pt As Point = item.CenterPoint
            Dim offset As New Point(Border, Border)
            If item.IsExpanded Then
                offset.X += item.ExpandOffset.X
                offset.Y += item.ExpandOffset.Y
            End If

            ' Draw strings in chart item.
            g.DrawString(labelStr, m_Parent.Font, New SolidBrush(m_Parent.ForeColor), pt.X - labelSize.Width / 2 + offset.X, pt.Y - (labelSize.Height + valueSize.Height) / 2 + offset.Y)
            g.DrawString(valueStr, m_Parent.Font, New SolidBrush(m_Parent.ForeColor), pt.X - valueSize.Width / 2 + offset.X, pt.Y - (labelSize.Height + valueSize.Height) / 2 + labelSize.Height + offset.Y)
        Next item
    End Sub

    ' Return bounding rectangle for entire chart.
    Public Overridable Function GetChartRectangle( _
        ByVal Width As Integer, ByVal Height As Integer) As Rectangle
        Return New Rectangle(0, 0, Width, Height)
    End Function

    ' Override in derived class.
    Public Overridable Sub LayoutItems(ByVal rc As Rectangle)
        System.Diagnostics.Debug.Assert(False)
    End Sub

    ' Override in derived class.
    Public Overridable Sub DrawShape(ByVal g As Graphics, ByVal b As Brush, ByVal rc As Rectangle, ByVal item As ChartItem)
        System.Diagnostics.Debug.Assert(False)
    End Sub

    ' Override in derived class.
    Public Overridable Sub DrawEmptyChart(ByVal g As Graphics, ByVal rc As Rectangle)
        System.Diagnostics.Debug.Assert(False)
    End Sub
End Class


' Pie chart class, calculates layout and draws pie shapes.
Friend Class PieDrawing
    Inherits ChartDrawing

    ' Constructor.
    Public Sub New(ByVal parent As CustomChart)
        MyBase.New(parent)
    End Sub

    ' Calculate the position of each item in the chart.
    Public Overrides Sub LayoutItems(ByVal rc As Rectangle)
        ' Return right away if area is too small.
        If (rc.Width <= 1) Or (rc.Height <= 1) Then
            Return
        End If

        Dim start As Single = 0.0F
        Dim sweep As Single = 0.0F
        Dim item As ChartItem

        ' Go through each item and calculate layout.
        For Each item In m_Parent.List
            ' Calculate the sweep angle for this item.
            sweep = CSng(item.Value * 360) / m_Parent.TotalValue

            ' Calculate the offset when this item is expanded.
            Dim shift As Point = GetPoint(start + sweep / 2, rc.Width, rc.Height)

            ' Relative to center of chart.
            shift.X -= CInt(rc.Width / 2)
            shift.Y -= CInt(rc.Height / 2)

            ' Now convert to max offset.
            Dim x As Single = CSng(ConstValues.ExpandSize) / CSng(Math.Max(Math.Abs(shift.X), Math.Abs(shift.Y)))
            shift.X = CInt(CSng(shift.X) * x)
            shift.Y = CInt(CSng(shift.Y) * x)
            item.ExpandOffset = shift

            ' Calculate center of pie slice.
            Dim center As Point = GetPoint(start + sweep / 2, rc.Width, rc.Height)
            center.X = CInt(((rc.Right - rc.Left) / 2 + center.X) / 2) + rc.Left
            center.Y = CInt(((rc.Bottom - rc.Top) / 2 + center.Y) / 2)
            item.CenterPoint = center

            ' Starting position and sweep size, both in degrees.
            item.StartPos = start
            item.SweepSize = sweep

            start += sweep
        Next item
    End Sub

    ' Draw a pie shape.
    Public Overrides Sub DrawShape(ByVal g As Graphics, ByVal br As Brush, ByVal rc As Rectangle, ByVal item As ChartItem)
        ' Make sure we have a valid area to draw on.
        If (rc.Width > 1) And (rc.Height > 1) Then
            'rc.Width = rc.Height
            g.FillPie(br, rc, item.StartPos, item.SweepSize)
        End If
    End Sub

    ' Draw what is displayed when there are no items in the chart.
    Public Overrides Sub DrawEmptyChart(ByVal g As Graphics, ByVal rc As Rectangle)
        If (rc.Width > 1) And (rc.Height > 1) Then
            g.DrawEllipse(New Pen(Color.DarkGray), rc)
        End If
    End Sub

    ' Return bounding rectangle for entire chart.
    Public Overrides Function GetChartRectangle( _
        ByVal Width As Integer, ByVal Height As Integer) As Rectangle

        ' Make chart area a square so the pie chart is a circle and not ellipse.
        ' Center the bounding rectangle in available space.
        Dim size As Integer = Math.Min(Width, Height)

        Return New Rectangle(CInt((Width - size) / 2), _
            CInt((Height - size) / 2), size, size)
    End Function


    ' Return point on circle edge given an angle.
    Private Function GetPoint(ByVal Angle As Single, ByVal Width As Integer, ByVal Height As Integer) As Point
        Dim topCenter As New Point(CInt(Width / 2), 0)
        Dim rad As Double = Math.PI * 2 * Angle / 360
        Dim pt As New Point()
        pt.X = CInt((Math.Cos(rad) * topCenter.X - Math.Sin(rad) * topCenter.Y) + Width / 2)
        pt.Y = CInt((Math.Sin(rad) * topCenter.X + Math.Cos(rad) * topCenter.Y) + Height / 2)
        Return pt
    End Function
End Class


' Stacked bar chart class, calculates layout and draws bar shapes.
Friend Class BarDrawing
    Inherits ChartDrawing

    ' Constructor.
    Public Sub New(ByVal parent As CustomChart)
        MyBase.New(parent)
    End Sub

    ' Calculate the position of each item in the chart.
    Public Overrides Sub LayoutItems(ByVal rc As Rectangle)
        ' Return right away if area is too small.
        If (rc.Width <= 1) Or (rc.Height <= 1) Then
            Return
        End If

        ' Go through each item and calculate layout.
        Dim startPos As Single = 0.0F
        Dim item As ChartItem
        For Each item In m_Parent.List
            ' The starting position (top of rectangle) and height of shape are in pixels.
            item.StartPos = startPos
            item.SweepSize = CSng(item.Value * rc.Height) / m_Parent.TotalValue

            ' Calculate the offset when this item is expanded.
            item.ExpandOffset = New Point(ConstValues.ExpandSize, 0)

            ' Center of this shape.
            item.CenterPoint = New Point(CInt(rc.Width / 2), rc.Height - CInt(item.StartPos + item.SweepSize / 2))

            startPos += item.SweepSize
        Next item
    End Sub

    ' Draw bar shape.
    Public Overrides Sub DrawShape(ByVal g As Graphics, ByVal br As Brush, ByVal rc As Rectangle, ByVal item As ChartItem)
        ' Make sure we have a valid area to draw on
        If (rc.Width > 1) And (rc.Height > 1) Then
            g.FillRectangle(br, rc.Left, rc.Bottom - CInt(item.StartPos) - CInt(item.SweepSize), rc.Width, CInt(item.SweepSize))
        End If
    End Sub

    ' Draw what is displayed when there are no items in the chart.
    Public Overrides Sub DrawEmptyChart(ByVal g As Graphics, ByVal rc As Rectangle)
        If (rc.Width > 1) And (rc.Height > 1) Then
            g.DrawRectangle(New Pen(Color.DarkGray), rc)
        End If
    End Sub
End Class

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -