## 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

- 7
^{th} April, 2009: Initial post