Introduction
Drawing charts or graphs is a very common requirement for many projects. If you have been working as a software professional, you must have come across the situation of drawing charts. Most of the time, we tend to rely on third party controls which are costly.
Background
I am going to demonstrate .NET’s in-built function to draw some basic charts. At the end of the article, you should be able to draw basic charts in your Windows application. I am using C# here.
Using the Code
I created a Windows application and wrote the following four functions to handle four different types of charts.

DrawSliceChart
DrawPieChart
DrawBarChart
DrawLineChart
For our example, we will take input weight as (13, 23, 33, 15, 20, 10, 4, 11). We will pass this array to all of the above functions. Let us discuss all the functions one by one.
DrawSliceChart
Consider it as cutting a cake into slices based on the weight. In this chart, angle of slice is linearly proportional to weight. To understand this, we will discuss the FillPie function supported by .NET.
Signature of FillPie is as follows:
Void FillPie(Brush brush, int x,int y, int width,int height,
int startAngle, int sweepAngle)
This function is used to fill as ellipse if sweep angle is 360. To make it a circle, we make height and width both equal to diameter of circle.
height = width = 2*radius;
Let us look into the details of parameters.
Then I use another function to draw the border around the shape: DrawPie. The only difference between this and FillPie is that it takes Pen object instead of Brush.
private void DrawSliceChart(PaintEventArgs e, int[] alWeight)
{
int numberOfSections = alWeight.Length
int x0 = 100;
int y0 = 100;
int radius = 100;
int startAngle = 0;
int sweepAngle = 0;
int[] height = new int[numberOfSections];
int total = SumOfArray(alWeight);
Random rnd = new Random();
SolidBrush brush = new SolidBrush(Color.Aquamarine);
Pen pen = new Pen(Color.Black);
for (int i = 0; i < numberOfSections; i++)
{
brush.Color = Color.FromArgb(rnd.Next(200, 255),
rnd.Next(255), rnd.Next(255), rnd.Next(255));
if (i == numberOfSections - 1)
sweepAngle = 360 - startAngle;
else
sweepAngle = (360 * alWeight[i]) / total;
e.Graphics.FillPie(brush, x0 - height[i], y0 - height[i],
2*radius, 2*radius, startAngle , sweepAngle);
e.Graphics.DrawPie(pen, x0 - height[i], y0 - height[i],
2*radius, 2*radius, startAngle, sweepAngle);
startAngle += sweepAngle;
brush.Color = Color.FromKnownColor(KnownColor.Black);
}
}
DrawPieChart
This is another chart which also uses the same in built function with little modification in the previous code. In this chart, angle of slice remains the same for all slices but the radius varies based on the weight.
So here we will first find out maximum weight MaxWeight. Then MaxWeight will be equal to the radius and other slices will have radius proportionally lesser then MaxWeight.
e.g. for weight 23:
MaxWeight = 33;
width = (23*radius)/MaxWeight;
sweepAngle = 360/TotalNumberOfWeights;
startAngle will start from 0 and is incremented by sweepAngle.
startAngle += sweepAngle;
private void DrawPieChart(PaintEventArgs e, int[] alWeight)
{
int numberOfSections = alWeight.Length;
int x0 = 600;
int y0 = 500;
int radius = 200;
int startAngle = 0;
int sweepAngle = 360/numberOfSections;
int[] height = new int[numberOfSections];
int maxWeight = MaxValue(alWeight);
Random rnd = new Random(10);
SolidBrush brush = new SolidBrush(Color.Aquamarine);
Pen pen = new Pen(Color.Black);
for(int i =0;i<numberofsections;i++){
height[i] = ((Convert.ToInt32(alWeight[i])) * radius) / maxWeight;
brush.Color = Color.FromArgb(rnd.Next(200, 255), rnd.Next(255),
rnd.Next(255), rnd.Next(255));
e.Graphics.FillPie
(brush, x0 - height[i], y0 - height[i], 2 * height[i],
2 * height[i],(startAngle+i*45), sweepAngle);
e.Graphics.DrawPie(pen, x0 - height[i], y0 - height[i], 2 * height[i],
2 * height[i], (startAngle + i * 45), sweepAngle);
}
}
DrawBarChart
In this, we make use of ‘DrawRectangle’ in built function. The idea here is to first create a big rectangle defining the boundary of bar graphs. DrawRectangle takes the following parameters:
Pen – This defines the color and style of border
Rectangle – Rectangle object to be created
We will look into the rectangle object.
Rectangle(int x, int y, int width,int height)
X and y are the co-ordinates of top left corner of rectangle.
Width and height are width and height of rectangle.
So to draw a bar, we will use the same function. The only thing we have to identify is these four parameters of Rectangle. Width is constant and is equal to total length of outer rectangle divided by total number of bars. Height is calculated as follows:
Height = (weight of current array element *
height of outer rectangle )/ maximum weight.
X coordinate is incremented by width of bars everytime a new bar is created.
Y co-ordinate is calculated by the following formula:
y = y coordinate of outer rectangle + height of outer rectangle –
height of bar calculated using above formula
Like DrawPie and DrawSlice, we fill the shape with the corresponding fill function.
private void DrawBarChart(PaintEventArgs e, int[] alWeight)
{
int numberOfSections = alWeight.Length;
int lengthArea = 400;
int heightArea = 250;
int topX = 400;
int topY = 20;
int maxWeight = MaxValue(alWeight);
int[] height = new int[numberOfSections];
int total = SumOfArray(alWeight);
Random rnd = new Random();
SolidBrush brush = new SolidBrush(Color.Aquamarine);
Pen pen = new Pen(Color.Gray);
Rectangle rec = new Rectangle(topX,topY,lengthArea,heightArea);
e.Graphics.DrawRectangle(pen,rec);
pen.Color = Color.Black;
int smallX = topX;
int smallY = 0;
int smallLength = (lengthArea/alWeight.Length);
int smallHeight = 0;
for (int i = 0; i < numberOfSections; i++)
{
brush.Color = Color.FromArgb(rnd.Next(200, 255),
rnd.Next(255), rnd.Next(255), rnd.Next(255));
smallHeight = ((alWeight[i] * heightArea )/ maxWeight);
smallY = topY + heightArea - smallHeight;
Rectangle rectangle = new Rectangle
(smallX, smallY, smallLength, smallHeight);
e.Graphics.DrawRectangle(pen,rectangle);
e.Graphics.FillRectangle(brush, rectangle);
brush.Color = Color.FromKnownColor(KnownColor.Black);
e.Graphics.DrawRectangle(pen, rectangle);
smallX = smallX + smallLength;
}
}
DrawLineChart
To draw a line chart, we first create boundary with ‘DrawRectangle’ in built function. Then we decide on the points to draw the line.
X coordinate is incremented by equal distance and y co-ordinate is set based on the weight.
Here, to highlight each point, I am using function DrawDots to highlight the point by making a circle of radius 5.
private void DrawLineChart(PaintEventArgs e,int[] alWeight)
{
int numberOfSections = alWeight.Length;
int lengthArea = 400;
int heightArea = 250;
int topX = 20;
int topY = 400;
int maxWeight = MaxValue(alWeight);
int[] height = new int[numberOfSections];
int total = SumOfArray(alWeight);
Random rnd = new Random();
SolidBrush brush = new SolidBrush(Color.Aquamarine);
Pen pen = new Pen(Color.Gray);
Rectangle rec = new Rectangle(topX, topY, lengthArea, heightArea);
e.Graphics.DrawRectangle(pen, rec);
pen.Color = Color.Black;
int smallX = topX;
int smallY = 0;
int smallLength = (lengthArea / (alWeight.Length + 1));
int smallHeight = 0;
Point p1 = new Point();
Point p2 = new Point();
for (int i = 0; i < numberOfSections; i++)
{
brush.Color = Color.FromArgb(rnd.Next(200, 255),
rnd.Next(255), rnd.Next(255), rnd.Next(255));
p1 = p2;
p2.X = p2.X + smallLength;
smallHeight = ((alWeight[i] * heightArea) / maxWeight);
p2.Y = topY + heightArea - smallHeight;
if (p1.X != 0 && p1.Y != 0)
{
e.Graphics.DrawLine(pen, p1, p2);
}
DrawDots(e,p2);
smallX = smallX + smallLength;
}
}
Here is the function to highlight the point:
private void DrawDots(PaintEventArgs e, Point p1)
{
Pen pen = new Pen(Color.SeaGreen);
e.Graphics.DrawPie(pen, p1.X-5 , p1.Y-5, 10, 10, 0, 360);
e.Graphics.FillPie(new SolidBrush(Color.Purple),
p1.X - 5, p1.Y - 5, 10, 10, 0, 360);
}
Points of Interest
So these are few of the charts that we can create. We can also customize them based on our requirement. If your requirement is simply to draw one chart similar to any of these three, just copy paste the function and change the co-ordinate and color as per your requirement. In addition to that, I have used 2 more simple functions to get maximum and total of array. You can find the complete source code attached.
The important thing to note is that all the four functions are called from Paint event handler function and takes PaintEventArgs and array of weights as parameters.
History
- 7th April, 2009: Initial post