Home

GDI+ Examples: 2-Column Chart

 

Introduction

 
 

In our introduction to charts, we used rectangles to draw a column chart. We will continue with the same approach here. This time, we will create a 2-column chart. This type of chart is used to analyze numbers that each represents the same category of information but from two periods.

 

Practical LearningPractical Learning: Creating a 2-Column Chart

  1. Start a new Windows Forms Application named YearlySales
  2. Set the form's Icon to Drive:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Graphics\icons\Office\GRAPH08.ICO
  3. Design the form as follows:
     
     
    Control Name Text Other Properties
    GroupBox GroupBox   Current Year's Sales  
    Label Label   1st Qtr  
    Label Label   2nd Qtr  
    Label Label   3rd Qtr  
    Label Label   4th Qtr  
    TextBox TextBox txtCurrentQtr1 1200  
    TextBox TextBox txtCurrentQtr2 14500 TextAlign: Right
    TextBox TextBox txtCurrentQtr3 8500 TextAlign: Right
    TextBox TextBox txtCurrentQtr4 16800 TextAlign: Right
    Button Button Close btnClose  
    GroupBox GroupBox   Previous Year's Sales  
    Label Label   1st Qtr  
    Label Label   2nd Qtr  
    Label Label   3rd Qtr  
    Label Label   4th Qtr  
    TextBox TextBox txtPreviousQtr1 10000  
    TextBox TextBox txtPreviousQtr2 11000 TextAlign: Right
    TextBox TextBox txtPreviousQtr3 12500 TextAlign: Right
    TextBox TextBox txtPreviousQtr4 15800 TextAlign: Right
    Button Button Generate btnGenerate  
    Label Label   _________ Legend _________  
    Label Label   This Year's Sales  
    Label Label   Last Year's Sales  
  4. Double-click an unoccupied area on the form and implement its Load event as follows:
     
    Public Class Form1
        Inherits System.Windows.Forms.Form    
        
    
        Dim graphDrawingArea As Graphics
        Dim bmpDrawingArea As Bitmap
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            bmpDrawingArea = New Bitmap(Width, Height)
            graphDrawingArea = Graphics.FromImage(bmpDrawingArea)
        End Sub
    End Class
  5. In the Class Name combo box, make sure (Form1 Events) is selected
    In the Method Name combo box, select Paint
  6. Implement the event as follows:
     
    Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
            e.Graphics.DrawImage(bmpDrawingArea, 0, 0)
    End Sub
  7. In the Class Name combo box, select btnGenerate
  8. In the Method Name combo box, select Click
  9. Implement the Click event as follows:
     
    Private Sub btnGenerate_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnGenerate.Click
            ' Retrieve the values of the current year's sales
            Dim curQtr1 As Integer = CInt(Me.txtCurrentQtr1.Text) / 100
            Dim curQtr2 As Integer = CInt(Me.txtCurrentQtr2.Text) / 100
            Dim curQtr3 As Integer = CInt(Me.txtCurrentQtr3.Text) / 100
            Dim curQtr4 As Integer = CInt(Me.txtCurrentQtr4.Text) / 100
    
            ' Create an array of Rectangle objects for the current year
            Dim rectCurrentYear As Rectangle() = {New Rectangle(Me.txtCurrentQtr1.Left + 20, 350 - curQtr1, 40, curQtr1), _
                  New Rectangle(Me.txtCurrentQtr2.Left + 20, 350 - curQtr2, 40, curQtr2), _
                     New Rectangle(Me.txtCurrentQtr3.Left + 20, 350 - curQtr3, 40, curQtr3), _
                        New Rectangle(Me.txtCurrentQtr4.Left + 20, 350 - curQtr4, 40, curQtr4)}
    
            ' Retrieve the values of last year's sales
            Dim prvQtr1 As Integer = CInt(Me.txtPreviousQtr1.Text) / 100
            Dim prvQtr2 As Integer = CInt(Me.txtPreviousQtr2.Text) / 100
            Dim prvQtr3 As Integer = CInt(Me.txtPreviousQtr3.Text) / 100
            Dim prvQtr4 As Integer = CInt(Me.txtPreviousQtr4.Text) / 100
    
            ' Create an array of Rectangle objects for the previous year
            Dim rectPreviousYear As Rectangle() = {New Rectangle(Me.txtPreviousQtr1.Left + 30, 350 - prvQtr1, 40, prvQtr1), _
                                New Rectangle(Me.txtPreviousQtr2.Left + 30, 350 - prvQtr2, 40, prvQtr2), _
                                 New Rectangle(Me.txtPreviousQtr3.Left + 30, 350 - prvQtr3, 40, prvQtr3), _
                               New Rectangle(Me.txtPreviousQtr4.Left + 30, 350 - prvQtr4, 40, prvQtr4)}
    
            ' In case the user has changed the values, erase the previous chart
            graphDrawingArea.Clear(Me.BackColor)
    
            ' Draw the chart for the previous year first to send it back
            graphDrawingArea.DrawRectangles(New Pen(Color.Blue), rectPreviousYear)
            ' Draw the chart for the current year in front
            graphDrawingArea.DrawRectangles(New Pen(Color.Red), rectCurrentYear)
    
            ' Draw the small rectangles of the legend
            graphDrawingArea.DrawRectangle(New Pen(Color.Blue), Me.lblCurYear.Left - 30, Me.lblCurYear.Top, 14, 10)
            graphDrawingArea.DrawRectangle(New Pen(Color.Red), Me.lblLastYear.Left - 30, Me.lblLastYear.Top, 14, 10)
    
            graphDrawingArea.DrawRectangle(New Pen(Color.Black), 25, 350, Width - 220, 1)
            Invalidate()
        End Sub
  10. In the Class Name combo box, select btnClose
  11. In the Method Name combo box, select Click
  12. Implement the event as follows:
     
    Private Sub btnClose_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnClose.Click
            End
    End Sub
  13. Execute the application and test the form
     
     
  14. After using it, close the form

 

The Chart's Background

 
 

One of the improvements you can bring to a chart is to provide it with a fancy background. This also can be a shape you draw. You can then paint it using one of the brushes of the GDI+ library.

 

Practical LearningPractical Learning: Painting the Chart Background

  1. Change the Click event of the Generate button as follows:
     
    Private Sub btnGenerate_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnGenerate.Click
            ' Retrieve the values of the current year's sales
            Dim curQtr1 As Integer = CInt(Me.txtCurrentQtr1.Text) / 100
            Dim curQtr2 As Integer = CInt(Me.txtCurrentQtr2.Text) / 100
            Dim curQtr3 As Integer = CInt(Me.txtCurrentQtr3.Text) / 100
            Dim curQtr4 As Integer = CInt(Me.txtCurrentQtr4.Text) / 100
    
            ' Create an array of Rectangle objects for the current year
            Dim rectCurrentYear As Rectangle() = {New Rectangle(Me.txtCurrentQtr1.Left + 20, 350 - curQtr1, 40, curQtr1), _
                                   New Rectangle(Me.txtCurrentQtr2.Left + 20, 350 - curQtr2, 40, curQtr2), _
               New Rectangle(Me.txtCurrentQtr3.Left + 20, 350 - curQtr3, 40, curQtr3), _
               New Rectangle(Me.txtCurrentQtr4.Left + 20, 350 - curQtr4, 40, curQtr4)}
    
            ' Retrieve the values of last year's sales
            Dim prvQtr1 As Integer = CInt(Me.txtPreviousQtr1.Text) / 100
            Dim prvQtr2 As Integer = CInt(Me.txtPreviousQtr2.Text) / 100
            Dim prvQtr3 As Integer = CInt(Me.txtPreviousQtr3.Text) / 100
            Dim prvQtr4 As Integer = CInt(Me.txtPreviousQtr4.Text) / 100
    
            ' Create an array of Rectangle objects for the previous year
            Dim rectPreviousYear As Rectangle() = {New Rectangle(Me.txtPreviousQtr1.Left + 30, 350 - prvQtr1, 40, prvQtr1), _
                                New Rectangle(Me.txtPreviousQtr2.Left + 30, 350 - prvQtr2, 40, prvQtr2), _
                                 New Rectangle(Me.txtPreviousQtr3.Left + 30, 350 - prvQtr3, 40, prvQtr3), _
                               New Rectangle(Me.txtPreviousQtr4.Left + 30, 350 - prvQtr4, 40, prvQtr4)}
    
            ' In case the user has changed the values, erase the previous chart
            graphDrawingArea.Clear(Me.BackColor)
    
            Dim rect As New Rectangle(20, 175, 300, 175)
            Dim linGradBrush As New LinearGradientBrush(rect, _
               Color.FromArgb(204, 102, 0), _
               Color.AntiqueWhite, _
               LinearGradientMode.Vertical)
    
            graphDrawingArea.FillRectangle(linGradBrush, rect)
            graphDrawingArea.DrawRectangle(New Pen(Color.Black), rect)
            Dim brushDiagCross As New HatchBrush(HatchStyle.DiagonalCross, Color.White, Color.Blue)
            Dim brushDotDiamond As New HatchBrush(HatchStyle.DottedDiamond, Color.Fuchsia, Color.Brown)
    
            ' Draw the chart for the previous year first to send it back
            graphDrawingArea.FillRectangles(brushDiagCross, rectPreviousYear)
            graphDrawingArea.DrawRectangles(New Pen(Color.Blue), rectPreviousYear)
            ' Draw the chart for the current year in front
            graphDrawingArea.FillRectangles(brushDotDiamond, rectCurrentYear)
            graphDrawingArea.DrawRectangles(New Pen(Color.Red), rectCurrentYear)
    
            ' Draw the small rectangles of the legend
            graphDrawingArea.FillRectangle(brushDotDiamond, Me.lblCurYear.Left - 30, Me.lblCurYear.Top, 20, 14)
            graphDrawingArea.DrawRectangle(New Pen(Color.Red), Me.lblCurYear.Left - 30, Me.lblCurYear.Top, 20, 14)
            graphDrawingArea.FillRectangle(brushDiagCross, Me.lblLastYear.Left - 30, Me.lblLastYear.Top, 20, 14)
            graphDrawingArea.DrawRectangle(New Pen(Color.Blue), Me.lblLastYear.Left - 30, Me.lblLastYear.Top, 20, 14)
    
            graphDrawingArea.DrawRectangle(New Pen(Color.Black), 25, 350, Width - 220, 1)
            Invalidate()
    End Sub
  2. Execute the application to test it:
     
  3. After using the form, close it
 

Home Copyright © 2004-2010 FunctionX, Inc.