Draw The Chart
Armed with our figures, we may now draw our pie chart. The OnPaint continues with:
' Create variables to hold the changing values of Angles
Dim StartAngle As Single = 0
Dim SweepAngle As Single = 0
And we cycle through the data for each company, drawing its segment in the chosen color.
For Each gd As GraphData In Companies
SweepAngle = 360 * gd.amount / TotalCount
g.FillPie(New SolidBrush(gd.Clr), rect, StartAngle, SweepAngle)
StartAngle += SweepAngle
Next
The breakdown of the above code block goes like this:
1. Select the next company in the arraylist
2. Calculate how many of the 360 degrees it owns
3. Draw the Pie:
- Filling the segment with this company’s color,
- Containing the pie inside the Rectangle
- Starting the segment at the correct point on the ellipse
- Continuing for the number of degrees calculated for this company
4. Move the start position for the next segment by adding the number of degrees just used for the current segment.
Improve the Chart
We’ve already improved the look of the chart by setting the SmoothingMode to HighQuality, but I also quite like to finish off the display by putting edge lines round each of the segments.
This is refreshingly easy to do. Insert this additional code line just below the FillPie method in the code snippet above:
g.DrawPie(New Pen(Color.Brown), rect, StartAngle, SweepAngle)
You can alter the impact of the lines by changing the line color as you prefer.
Creating The Chart Key
The Heading
The text for the Chart’s Key is created using another Graphics method – DrawString.
We have already seen both the Pen and the Brush objects in action in the code above; the Brush to fill the segments, the Pen to draw the exterior lines. When it comes to drawing text with the DrawString method, you might expect to use a Pen object for this. By another of those quirks of the graphics class, you actually need a Brush to draw the text string, not a Pen.
You will recall that we created the Brush for the pie segments on the fly in this code line:
g.FillPie(New SolidBrush(gd.Clr), rect, StartAngle, SweepAngle)
We could do something similar with our text drawing code, but it would make it harder to read and analyze. So we will create the text brush separately. For the same reason, we will create the Font for the text separately too.
' 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)
Maybe it’s just me, but I have sometimes found setting the font arguments to be a bit tricky. Intellisense isn’t always your best friend in this particular situation, so take care to enter the arguments you really want, in the correct order.
Writing (drawing) the heading of the Key comes next:
g.DrawString("Chart Key", TextFont, TextBrsh, 310, 100)
The two values at the end of the above code line are the X and Y positions of the start of the text (i.e left and top positions on the Form).
Bullets and Company Info
Because we are now going to create several lines of text that we want to keep aligned vertically, the X position (pixel count from the left of the form) will stay the same. However, the Y position, counting from the top of the form will of course change as we move down the form displaying line after line. To keep track of this Y position we will use an Integer variable.
Dim pxFromTop As Integer = 135
I have placed the first line of company info 35 pixels below the Heading, 135 pixels below the top of the form.
Now we can again enumerate through the arraylist and use the information in there to create the detail of the chart key. You will see from the commenting included how we have achieved this.
For Each gd As GraphData In Companies
' Draw bullet
g.FillEllipse(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
Next
The only code which might need additional explanation are the values:
310 in the first two lines is the X Position of the circular bullet
15, 15 in the first two lines represent the width and height of the ellipse.
(Making their values equal will of course result in a circle)
360 in the third line is the X Position where we want the Company Name to begin.
I think we have covered variations of all the other settings in previous code snippets.
Dispose After Use
All that is left to do is the housekeeping - disposing of any disposable graphics objects that we specifically created as we were drawing.
TextBrsh.Dispose()
TextFont.Dispose()
Notice that we don’t try to dispose of any of the Brushes and Pens we created on the fly in code and also that we don’t dispose of the Graphics Object in this particular example. This is an area we will look at in more detail in future articles, as we need to.
All Done!
I have taken a lot of space to describe what is in fact not very much code. Hopefully, the extra detail and explanation will help you to see how you can create your own versions of this kind of pie chart and key.
There is a sample solution attached to this article if you would like to see it in action. However, there is no substitute for making your own mistakes as the best way to learn, so I do recommend that you try entering the code yourself in a new project and come back for the explanations if things don’t go quite as you expect.
The final version of the chart and key should look something like this:

Summary
Summary
In this first article, we have been introduced to the Graphics Object and the Rectangle. We used the DrawPie and FillPie Methods, and looked at how those methods use the Rectangle, StartAngle and SweepAngle settings to create the finished drawing we required.
We employed Brush objects to fill the coloured segments and also to draw the text; a Pen object was used to draw the enclosing lines round the pie segments and bullets.
We saw that the Font is also an object and how we can use its Constructor to create New instances based on our preferences of Font name, size and style.
The DrawString method was used to display text in the font and the various colors of our choosing. We used the FillEllipse and DrawEllipse methods to create circular Colored bullets in the Key.
We have seen that if we put our drawing code in the OnPaint event it will be redrawn whenever the form’s surface has been covered, hidden or otherwise visually affected. We learned that good housekeeping includes disposing of disposable objects when finished with.
So, although the amount of code used in this project is relatively short, it has included several key graphics techniques, including:-
• Brush objects
• DrawEllipse method
• FillEllipse
• Dispose
• DrawLine
• DrawPie
• DrawString
• FillPie
• Font object
• Persistence Using OnPaint
• Rectangle object
• SolidBrush
• StartAngle
• SweepAngle
• Using OnPaint event to Persist the drawing
What we’ve done here of course touches only the very tip of the .Net Graphics iceberg. The power, scope and potential of the graphics tools that are available to you will enable you to bring parts of your application to life in a way that would be difficult - if not impossible - in any other way.
In future articles we will continue to put some of this power to use. Along the way, I hope I will help demystify some of the difficult terms and arcane syntax that makes many developers see Graphics and GDI+ as something of a Black Art. There is so much potential in there, it would be shame not to use at least some it, and - who knows? - in time you may well succeed in graduating from Graphics Apprentice to fully qualified Wizard!