Article Options
Premium Sponsor
Premium Sponsor

 »  Home  »  .NET Newbie  »  GDI+ Chart Success Part 7: Printing Charts  »  Bar Chart - Drawing
 »  Home  »  Windows Development  »  Graphics  »  GDI+ Chart Success Part 7: Printing Charts  »  Bar Chart - Drawing
GDI+ Chart Success Part 7: Printing Charts
by Ged Mead | Published  10/16/2006 | .NET Newbie Graphics | Rating:
Bar Chart - Drawing


   In Part 2 and Part 4 of this series we created bar charts using two different approaches.  For the purposes of this article on Printing I will simply copy and paste the code we used in the second of those articles and then print out the resulting image.   As both versions use a PictureBox control to house the chart there is in fact very little difference between them anyway.

Creating the Chart

   As I did on the previous page, I will just lump below all the code you need to draw the bar chart.  A step by step explanation of how it all works can be found beginning here in the original article.  

   Add a new form to your project, drag a PictureBox control on to it and name it PBBarChart.   Copy and paste in the following code to set up the variables and create some demonstration data.

Option Strict On
Imports System.Drawing.Drawing2D
Imports System.Collections 

Structure GraphData
 Dim Country As String
 Dim Sales As Integer
 Dim BarColor As Color

 Sub New(ByVal country As String, ByVal sales As Short, ByVal barcol As Color)
   Me.Country = country
   Me.Sales = sales
   Me.BarColor = barcol
 End Sub
End Structure

' Create Variables
Dim LeftMargin As Integer = 35
Dim RightMargin As Integer = 15
Dim BaseMargin As Integer = 35
Dim TopMargin As Integer = 10
Dim BarGap As Integer = 12
Dim SalesData As New ArrayList
Dim HighSale As Double ' Maximum sales figure
Dim VertScale As Double ' Scaling used for bar heights
Dim g As Graphics
Dim bmap As Bitmap
Dim VertLineLength As Integer
Dim BarWidth As Integer ' width of bars
Dim BaseLineLength As Integer ' X Axis length
Private Sub GetData()

SalesData.Add(New GraphData("Belgium", 934, Color.Blue))
SalesData.Add(New GraphData("Greece", 385, Color.DarkOrange))
SalesData.Add(New GraphData("Portugal", 1029, Color.Green))
SalesData.Add(New GraphData("Spain", 729, Color.IndianRed))
SalesData.Add(New GraphData("Turkey", 1472, Color.Tomato))
SalesData.Add(New GraphData("UK", 1142, Color.Aquamarine))
End Sub

  Now, the procedures used to draw the bar chart:

Private Function GetGraphics() As Graphics
 ' Make bmap the same size and resolution as the PictureBox
 bmap = New Bitmap(PBBarChart.Width, PBBarChart.Height, PBBarChart.CreateGraphics)
 ' Assign the Bitmap object to the Graphics object and Return it
 Return Graphics.FromImage(bmap)
End Function

Private Sub DrawVerticalAxis(ByVal g As Graphics)
  Dim StartPoint As New Point(LeftMargin, PBBarChart.Height - BaseMargin)
  Dim EndPoint As New Point(LeftMargin, TopMargin)
  Dim LinePen As New Pen(Color.Black, 2)
  g.DrawLine(LinePen, StartPoint, EndPoint)

  VertLineLength = PBBarChart.Height - (BaseMargin + TopMargin)

    For Each gd As GraphData In SalesData
     If gd.Sales > HighSale Then HighSale = gd.Sales

  Dim NextCent As Integer = CInt(HighSale)
  Do While NextCent Mod 100 <> 0
   NextCent += 1

 Dim TotalTicks As Integer = CInt(NextCent / 100)
 Dim YPos As Integer = CInt(VertLineLength / TotalTicks)
 Dim TickSP As New Point(LeftMargin - 5, StartPoint.Y - YPos)
 Dim TickEP As New Point(LeftMargin, StartPoint.Y - YPos)
 Dim ValueFont As New Font("Arial", 8, FontStyle.Regular)
  For i As Integer = 1 To TotalTicks
   g.DrawLine(New Pen(Color.Black), TickSP, TickEP) ' Tick mark
   CStr(i * 100), ValueFont, Brushes.Black, 2, TickSP.Y - 5)
   TickSP.Y = CInt(TickSP.Y - (VertLineLength / TotalTicks))
   TickEP.Y -= CInt(VertLineLength / TotalTicks)
End Sub

Draw the bars:

Private Sub Draw3DBars()
 g.DrawLine(New Pen(Color.Black), LeftMargin, PBBarChart.Height - BaseMargin, _
   PBBarChart.Width - RightMargin, PBBarChart.Height - BaseMargin)
 BaseLineLength = PBBarChart.Width - (LeftMargin + RightMargin)
 BarWidth = CInt((BaseLineLength / SalesData.Count) - BarGap)
 Dim BarStartX As Integer = LeftMargin + BarGap
 Dim BaseLine As Integer = PBBarChart.Height - BaseMargin
 VertScale = VertLineLength / HighSale
  For Each gd As GraphData In SalesData
   Dim Corners(3) As Point
   Corners(0) = New Point(BarStartX, BaseLine - 10)
   Corners(1) = New Point(BarStartX + BarWidth - 5, BaseLine - 10)
   Corners(2) = New Point(BarStartX + BarWidth, BaseLine)
   Corners(3) = New Point(BarStartX + 5, BaseLine)
   Dim BarHeight As Integer = CInt(gd.Sales * VertScale)

  Dim barmainBrush As New HatchBrush(HatchStyle.Percent50, gd.BarColor)
  Dim bartopBrush As New SolidBrush(gd.BarColor)
  ' Draw one complete bar
   For i As Integer = 0 To BarHeight - 11
    g.FillPolygon(barmainBrush, Corners)
Corners(0).Y -= 1
    Corners(1).Y -= 1
    Corners(2).Y -= 1
    Corners(3).Y -= 1
  g.FillPolygon(bartopBrush, Corners)
 ' Move the startpoint for the next bar
  BarStartX += CInt(BarWidth + BarGap)
 ' Dispose of brushes
End Sub 

Finally, the procedure that adds the legend:

Private Sub WriteTheNames()
   Dim TextStartX As Integer = LeftMargin + BarGap + 5
   ' Create a Brush to draw the text
   Dim TextBrsh As Brush = New SolidBrush(Color.Black)
   ' Create a Font object instance for text display
   ' dynamically adjusted font size would be useful:
   Dim fntSize As Integer = CInt(BarWidth / 7)
   Dim TextFont As New Font("Verdana", fntSize, FontStyle.Bold)
   ' Write them:
    For Each gd As GraphData In SalesData
     g.DrawString(gd.Country, TextFont, TextBrsh, TextStartX,
     CInt(PBBarChart.Height - (BaseMargin - 4)))
     TextStartX += CInt(BarWidth + BarGap)
End Sub


Sponsored Links