Article Options
Premium Sponsor
Premium Sponsor

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

Ged Mead (XTab) is a Microsoft Visual Basic MVP who has been working on computer software and design for more than 25 years. His journey has taken him through many different facets of IT. These include training as a Systems Analyst, working in a mainframe software development environment, creating financial management systems and a short time spent on military laptop systems in the days when it took two strong men to carry a 'mobile' system.

Based in an idyllic lochside location in the West of Scotland, he is currently involved in an ever-widening range of VB.NET, WPF and Silverlight development projects. Now working in a consultancy environment, his passion however still remains helping students and professional developers to take advantage of the ever increasing range of sophisticated tools available to them.

Ged is a regular contributor to forums on vbCity and authors articles for DevCity. He is a moderator on VBCity and the MSDN Tech Forums and spends a lot of time answering technical questions there and in several other VB forum sites. Senior Editor for DevCity.NET, vbCity Developer Community Leader and Admin, and DevCity.NET Newsletter Editor. He has written and continues to tutor a number of free online courses for VB.NET developers.


View all articles by Ged Mead...
Pie Chart


  In the first article of the series we created a very basic pie chart using the GDI+ methods available to us in the .NET Framework.   So for the first example in this article we will recreate this chart and then print it.

  The Pie Chart in that first article is drawn directly on to the surface of the Windows Form.  This highlights a useful and interesting fact relating to how drawing and printing works: you can often use exactly the same code to draw (i.e. print) to a printer as you use to draw on to a form.

   As it happens, in our first example this will result in unnecessary duplication of code.  This  is because in Part 1 of the series we didn't put the drawing code in a procedure that we could call multiple times from various parts of the application.  We put it all in the OnPaint event of the form.

   At the price of writing ugly code I'm going to stick with this approach because it will make it much easier to compare directly what we did in Part 1 to draw the chart with what we want to do here to print out the result.   In other words, I don't want to fall into the trap of tidying up the original code just to make it look better when the original idea was to write code that a beginner could understand and use.

   So here is the code we used originally.   You can copy and paste it into a new form in a project of your own or check out the demo solution at the end of the article.   It consisted of the setting up of variables....

Structure GraphData
  Dim Amount As Single
  Dim Clr As Color
  Dim Description As String

' Create a constructor for the Structure
  Sub New(ByVal amt As Integer, ByVal col As Color, ByVal desc As String)
   Me.Amount = amt
   Me.Clr = col
   Me.Description = desc
  End Sub
End Structure

Dim Companies As New System.Collections.ArrayList

Creating some dummy data for display purposes....

Private Sub frmPrintPie_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
  Companies.Add(New GraphData(50, Color.Blue, "Muir Inc."))
  Companies.Add(New GraphData(75, Color.Yellow, "Philmas Co."))
  Companies.Add(New GraphData(62, Color.Red, "Xamco"))
  Companies.Add(New GraphData(27, Color.LightGreen, "Wright plc"))
End Sub

And this block of code in the form's OnPaint event to draw the pie chart and the key:

Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
  Dim g As Graphics = e.Graphics
  g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
  Dim rect As Rectangle = New Rectangle(100, 105, 150, 150)
  Dim TotalCount As Single
   For Each gd As GraphData In Companies
    TotalCount += gd.Amount
' Create variables to hold the changing values of Angles
  Dim StartAngle As Single = 0
  Dim SweepAngle As Single = 0
   For Each gd As GraphData In Companies
    SweepAngle = 360 * gd.amount / TotalCount
New SolidBrush(gd.Clr), rect, StartAngle, SweepAngle) 

    g.DrawPie(New Pen(Color.Brown), rect, StartAngle, SweepAngle) 
    StartAngle += SweepAngle

' Create a Brush to draw the text
 Dim TextBrsh As Brush = New SolidBrush(Color.Black)
' Create a Font object instance for text display
 Dim TextFont As New Font("Arial", 12, FontStyle.Bold)
 g.DrawString("Chart Key", TextFont, TextBrsh, 310, 100)
 Dim pxFromTop As Integer = 135
  For Each gd As GraphData In Companies
   ' Draw bullet
   New SolidBrush(gd.Clr), 310, pxFromTop, 15, 15)
  ' Draw line round bullet.
   g.DrawEllipse(New Pen(Color.Black), 310, pxFromTop, 15, 15)
  ' Draw the text - color coded
  g.DrawString(gd.Description & " (" & gd.Amount & ")", _
   TextFont, TextBrsh, 360, pxFromTop)
  ' Increase gap from Top for next line
  pxFromTop += 30
End Sub 

   If you want a complete breakdown of how the above code works, you will find it explained step by step in the Part 1 article.


   Build the project and run it.  On the form you will see:


   In order to print what the user sees we will use a PrintDocument control.   While many people find some of the printing processes in VB.NET hard to fathom, this control at least is easy to understand and use.  Most times you will only want to use its Print method in order to fire the PrintPage event.  

    It sometimes takes a bit of a mindset shift to move ourselves away from thinking of "printing" being some kind of mechanical device that magically happens when you hit a print button.  If you stop and think about it for a moment it makes absolute sense to realise that all that really happens when the printer prints is that a series of dots are transferred to the printer paper.  We recognise those patterns as words and images; and this is exactly the same logic that we are perfectly happy to accept when we write code to draw strings, shapes or images on a form.  It really is literally a "Back to Basics" kind of approach.

   As I explained above, all we are going to do for this first pass at printing is to copy and paste the OnPaint code and use it again.    The first thing you need to do is to add a PrintDocument control to the form.  As you'll see when you drag it on to the form, it will automatically drop into the component tray below the actual form area itself; this being because it's a non-visual control.   You can leave the control's name as the default of PrintDocument1.

   Now go into the code window and select the PrintDocument1 from the left hand combobox and the PrintPage event from the combo on the right.    Copy and paste the OnPaint code above into this procedure.   The exact same drawing code will now be actioned as soon as the PrintPage event is fired.

   Therefore that just leaves us with the task of firing that PrintPage event.   Drag a button on to the form and in the button's click event add this code:


   Save the project, make sure your printer is turned on, run the project and click the print button that you just created.   All other things being equal, you should be rewarded with a hard copy printed version of the pie chart and its key.

Sponsored Links