Graph Library






4.84/5 (41 votes)
This article addresses the construction of a simple graph library using C#.
- Download source - 3.24 KB
- Download demo project - 27.83 KB
- Download Version2 Library + Demo - 20.04 KB



Introduction
Graphics within the .NET Framework is a powerful feature that can be adapted to a wide range of purposes. Here I have developed a class to demonstrate the use of graphics to create graphs like:
- Bar graph
- Pie graph
- Line graph
Using the Code
The attached project contains a file named DrawGraph.cs, which is the generic library to generate graphs. The methods in this library generate graphs like the Single dimension Bar graph, 3D Bar graph, Single dimension Pie graph, 3D Pie graph and Line graph. All the graphs are generated in bitmap format. The code below demonstrates the use of this library in a Windows application:
// Values used to create graph
string [] keyValue=new string[ui_lbx_DataKey.Items.Count];
float[] values = new float[ui_lbx_DataKey.Items.Count];
for (int i = 0; i < ui_lbx_DataKey.Items.Count; i++)
{
keyValue[i] = ui_lbx_DataKey.Items[i].ToString();
values[i] = float.Parse(ui_lbx_DataValue.Items[i].ToString());
}
//Include namespace System.Anoop.Graph and initiaze the
//bargraph object with values,label on x & y axis, font format and alpha
DrawGraph bargraph = new DrawGraph(keyValue, values,
ui_txt_xlabel.Text, ui_txt_ylabel.Text,
"Courier", 255);
//Generating graph and assigning it to respective picture box
p1.Image = bargraph.DrawBarGraph();
p2.Image = bargraph.Draw3dBarGraph();
p3.Image = bargraph.DrawPieGraph();
p4.Image = bargraph.Draw3DPieGraph();
//Generating Line graph
DrawGraph bargraph1 = new DrawGraph(keyValue, values,
ui_txt_xlabel.Text, ui_txt_ylabel.Text,
"Courier", 255);
p5.Image = bargraph1.DrawLineGraph();
The code below demonstrates the use of this library in an ASP.NET application:
DrawGraph bargraph = new DrawGraph(keyValue, values,
"Financial Year","Profit", "Courier", 255);
//Generating graph and assigning it to respective imagebox
System.Drawing.Bitmap b = new System.Drawing.Bitmap(400, 400);
b = bargraph.DrawLineGraph();
b.Save(Server.MapPath("Graph")+"\\LineGraph.bmp");
Image1.ImageUrl =".\\Graph\\LineGraph.bmp";
System.Drawing.Bitmap b1 = new System.Drawing.Bitmap(400, 400);
b1 = bargraph.DrawPieGraph();
b1.Save(Server.MapPath("Graph") + "\\PieGraph.bmp");
Image2.ImageUrl = ".\\Graph\\PieGraph.bmp";
System.Drawing.Bitmap b2 = new System.Drawing.Bitmap(400, 400);
b2 = bargraph.Draw3DPieGraph();
b2.Save(Server.MapPath("Graph") + "\\3DPieGraph.bmp");
Image3.ImageUrl = ".\\Graph\\3DPieGraph.bmp";
System.Drawing.Bitmap b3 = new System.Drawing.Bitmap(400, 400);
b3 = bargraph.Draw3dBarGraph();
b3.Save(Server.MapPath("Graph") + "\\3dBarGraph.bmp");
Image4.ImageUrl = ".\\Graph\\3dBarGraph.bmp";
Code
There are a few imports made at the start of the class. Those imports are included to work with image files.
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Drawing;
Now come the global variables:
string[] valueLabels; float[] values;
string xLabel;
//Label displayed on x axis
string yLabel;
//Label displayed on y axis
string fontFormat;
//format for labels
int alpha;
//alpha for graph
List <color> colorList;
//Dark colors only
These global variables are being initialized using the constructor:
public DrawGraph(string[] valueLabels,float[] values,string xLabel,string
yLabel,string fontFormat,int alpha)
{
this.valueLabels = valueLabels;
this.values = values;
this.xLabel = xLabel;
this.yLabel = yLabel;
this.alpha = alpha;
this.fontFormat=fontFormat;
InitColorList();
}
Here InitColorList()
is a method to initialize colorList
with dark colors.
//Initiatialize color list with dark color's
private void InitColorList()
{
colorList = new List ();
foreach (string colorName in Enum.GetNames(typeof(System.Drawing.KnownColor)))
{
//Check if color is dark
if (colorName.StartsWith("D") == true)
{
colorList.Add(System.Drawing.Color.FromName(colorName));
}
}
}
//Embed axis for bar graphs
In this class we have some more private methods like EmbedAxis()
, EmbedXPanel()
and EmbedXLinePanel()
. These are used to create axes, create x-axis value mapping with color and create x-axis value mapping to line color respectively.
Bitmap EmbedAxis(Bitmap graph,bool showAxis)
{
Bitmap backgroundCanvas = new Bitmap(400, 300);
Bitmap yLabelImage = new Bitmap(15,200);
Graphics graphicsBackImage = Graphics.FromImage(backgroundCanvas);
Graphics objGraphic2 = Graphics.FromImage(graph);
Graphics objGraphicY = Graphics.FromImage(yLabelImage);
Pen blackPen = new Pen(Color.Black, 2);
//Paint the graph canvas white SolidBrush
whiteBrush = new SolidBrush(Color.White);
graphicsBackImage.FillRectangle(whiteBrush,0, 0, 400, 300);
if (showAxis == true)
{
//draw lable for y axis
StringFormat sf = new StringFormat(StringFormatFlags.DirectionVertical);
Font f = new Font(fontFormat,8);
SizeF sizef = objGraphicY.MeasureString("<- " + yLabel, f, Int32.MaxValue,sf);
RectangleF rf = new RectangleF(0, 0, sizef.Width, sizef.Height);
objGraphicY.DrawRectangle(Pens.Transparent,rf.Left, rf.Top, rf.Width, rf.Height);
objGraphicY.DrawString((yLabel.Length>0?"<-":"") + yLabel,
f, Brushes.Black, rf, sf);
graphicsBackImage.DrawString(xLabel +(xLabel.Length>0?" ->":""),
f, Brushes.Black, 30, 235);
graphicsBackImage.DrawLine(blackPen,new Point(0, 230), new Point(230, 230));
graphicsBackImage.DrawLine(blackPen, new Point(20, 20), new Point(20, 250));
}
graphicsBackImage.DrawImage(graph, 25, 25);
if (showAxis == true)
{
graphicsBackImage.DrawImage(yLabelImage, 0, 90);
}
return (backgroundCanvas);
}
//Embed x Panel
Bitmap EmbedXPanel(Bitmap graph)
{
Bitmap xPanel = new Bitmap(100, 200);
Graphics objGraphicPanel = Graphics.FromImage(xPanel);
Graphics graphicGraph = Graphics.FromImage(graph);
for (int i = 0, x = 10; i <values.Length; i++)
{
//Draw the bar
SolidBrush brush = new SolidBrush(Color.FromArgb(alpha,colorList[i]));
objGraphicPanel.FillRectangle(brush, 10, 190 - x, 10, 10);
string drawString = valueLabels[i] + " = " + values[i].ToString();
Font drawFont = new Font(fontFormat, 8);
SolidBrush drawBrush = new SolidBrush(Color.Black);
objGraphicPanel.DrawString(drawString,drawFont, drawBrush, 20, 190 - x);
//x axis spacing by 20
x += 20;
}
graphicGraph.DrawImage(xPanel,300, 25); return (graph);
}
//Embed x Panel[Line graph style]
Bitmap EmbedXLinePanel(Bitmap graph)
{
Bitmap xPanel = new Bitmap(100, 200);
Graphics objGraphicPanel = Graphics.FromImage(xPanel);
Graphics graphicGraph = Graphics.FromImage(graph);
for (int i = 1, x = 10; i < values.Length; i++)
{
//Draw the bar
SolidBrush brush = new SolidBrush(Color.FromArgb(alpha,colorList[i]));
Pen colorPen = new Pen(brush,2);
objGraphicPanel.DrawLine(colorPen,10, 190 - x, 20, 190 - x);
string drawString = valueLabels[i - 1].ToString() + " - " + valueLabels[i].ToString();
Font drawFont = new Font(fontFormat, 8);
SolidBrush drawBrush = new SolidBrush(Color.Black);
objGraphicPanel.DrawString(drawString, drawFont, drawBrush, 20, 190 - x);
//x axis spacing by 20
x += 20;
}
graphicGraph.DrawImage(xPanel,300, 25);
return (graph);
}
Let's check out the method to create a Bar graph. Here this method follows a simple algorithm:
- First prepare a white canvas of dimensions 200 X 200.
- Calculate the highest value [ x-axis values ].
- For each value on the x-axis...
- Calculate the bar height using the formula: bar height=(x Value / highest value) * 190.
- Draw the bar.
- Draw the axis and place the bar graph on an enlarged canvas using
EmbedAxis()
. - Draw the x-value mapping to the color using
EmbedXPanel()
.
//Generate Bar graph
public Bitmap DrawBarGraph()
{
Bitmap objgraph = new Bitmap(200, 200);
// Canvas for graph
Graphics graphicGraph = Graphics.FromImage(objgraph);
//Paint the graph canvas white
SolidBrush whiteBrush = new SolidBrush(Color.White);
graphicGraph.FillRectangle(whiteBrush,0, 0, 200, 200);
float highestValue;
//Highest value in the values array
//Get the highest value
float[] tempValue = new float[values.Length];
for (int j = 0; j < values.Length; j++)
{
tempValue[j] = values[j]; } Array.Sort<float>(tempValue);
highestValue = tempValue[values.Length - 1];
//Generate bar for each value
for (int i = 0, x = 10; i < values.Length; i++)
{
float barHeight;
//hight of the bar
barHeight = (values[i] / highestValue) * 190;
//Draw the bar
SolidBrush brush = new SolidBrush(Color.FromArgb(alpha, colorList[i]));
graphicGraph.FillRectangle(brush,x, 194 - barHeight, 10, barHeight);
//x axis spacing by 20
x += 20;
}
//
Increase the size of the canvas and draw axis
objgraph = EmbedAxis(objgraph, true);
//Draw the key-value pair with repective color code
objgraph = EmbedXPanel(objgraph);
return (objgraph);
}
Drawing a 3D Bar Graph is similar to the above code of bar graphs except that we need to perform some additional tasks like:
- Draw a shadow.
- Draw a white line at the bottom of the graph to hide the shadow.
public Bitmap Draw3dBarGraph()
{
Bitmap objgraph = new Bitmap(200, 200);
//Canvas for graph
Bitmap objXValuePanel = new Bitmap(100,200);
//Canvas to display x-axis values
Graphics graphicGraph = Graphics.FromImage(objgraph);
Graphics graphicXValuePanel = Graphics.FromImage(objXValuePanel);
//Paint the graph canvas white
SolidBrush whiteBrush = new SolidBrush(Color.White);
graphicGraph.FillRectangle(whiteBrush,0, 0, 200, 200);
float highestValue;
//Highest value in the values array
//Get the highest value
float[] tempValue = new float[values.Length];
for (int j = 0; j < values.Length; j++)
{
tempValue[j] = values[j];
}
Array.Sort<float>(tempValue);
highestValue = tempValue[values.Length - 1];
//Generate bar for each value
for (int i = 0, x = 10; i < values.Length; i++)
{
SolidBrush brush = new SolidBrush(Color.FromArgb(alpha,colorList[i]));
float barHeight;
//hight of the bar
barHeight = (values[i] / highestValue)* 190;
//Draw continuous shade for 3D effect
float shadex = x + 10; float shadey = 194 - ((int)barHeight) + 10;
for (int iLoop2 = 0; iLoop2 < 10; iLoop2++)
{
graphicGraph.FillRectangle(brush, shadex - iLoop2, shadey - iLoop2, 10, barHeight);
}
//Draw bar
graphicGraph.FillRectangle(new HatchBrush(HatchStyle.Percent50, brush.Color),
x, 194 - barHeight, 10, barHeight);
//Increment the x position
x += 20;
}
//Mask bottom with a white line
Pen whitePen = new Pen(Color.White, 10);
graphicGraph.DrawLine(whitePen,new Point(10, 200), new Point(230, 200));
//Increase the size of the canvas and draw axis
objgraph = EmbedAxis(objgraph, true);
//Draw the key-value pair with repective color code
objgraph = EmbedXPanel(objgraph);
return (objgraph);
}
To draw a Pie graph following the below algorithm:
- First prepare a white canvas of dimensions 200 X 200.
- Calculate the sum of all x-values [ x-axis values ].
- Initialize the start angle of the pie to 0 degrees.
- For each value...
- Calculate
sweepAngle
using the formula: sweep angle= (x value * 360) / sum of all x values. - Draw the pie.
- Increase the start angle with the sweep angle.
- Calculate
- Place the pie graph on an enlarged the canvas using
EmbedAxis()
, withshowAxis
flag set tofalse
. - Draw the x-value mapping to the color using
EmbedXPanel()
.
public Bitmap DrawPieGraph()
{
Bitmap objgraph = new Bitmap(200, 200);
Graphics graphicGraph = Graphics.FromImage(objgraph);
//Create location and size of ellipse.
int x = 0;
int y = 0;
int width = 200;
int height = 100;
//Create start and sweep
angles. float sweepAngle = 0;
float startAngle = 0;
float total = 0;
for (int i = 0; i < values.Length; i++)
{
total += values[i];
}
for (int i = 0; i < values.Length; i++)
{
SolidBrush objBrush = new SolidBrush(colorList[i]);
sweepAngle = (values[i] * 360) / total;
graphicGraph.SmoothingMode = SmoothingMode.AntiAlias;
graphicGraph.FillPie(objBrush, x, y, width, height, startAngle, sweepAngle);
startAngle += sweepAngle; }
//Increase the size of the canvas in which the graph resides
objgraph = EmbedAxis(objgraph, false);
//Draw the key-value pair with repective color code
objgraph = EmbedXPanel(objgraph); return (objgraph);
}
Drawing a 3D Pie is similar to a Pie graph with an additional task: drawing shadows.
Bitmap Draw3DPieGraph()
{
Bitmap objgraph = new Bitmap(200, 200);
Graphics graphicGraph = Graphics.FromImage(objgraph);
//Create location and size of ellipse.
int x =0;
int y = 0;
int width = 200;
int height = 100;
//Find the sum of all values float
total = 0; for (int i = 0; i < values.Length; i++)
{
total += values[i];
}
//When loop=0: Draw shadow
//loop=1: Draw graph
for (int loop = 0; loop < 2; loop++)
{
//Create start and sweep angles
float sweepAngle = 0;
float startAngle = 0;
//Draw pie for each value
for (int i = 0; i < values.Length; i++)
{
SolidBrush objBrush = new SolidBrush(colorList[i]);
sweepAngle = (values[i] * 360) / total;
graphicGraph.SmoothingMode = SmoothingMode.AntiAlias;
if (loop == 0)
{
for (int iLoop2 = 0; iLoop2 < 10; iLoop2++)
graphicGraph.FillPie(new HatchBrush(HatchStyle.Percent50,objBrush.Color),
x, y + iLoop2, width, height, startAngle, sweepAngle);
}
else
{
graphicGraph.FillPie(objBrush, x, y, width, height, startAngle, sweepAngle);
}
startAngle += sweepAngle;
}
}
//Increase the size of the canvas in which the graph resides
objgraph = EmbedAxis(objgraph, false);
//Draw the key-value pair with repective
color code objgraph = EmbedXPanel(objgraph);
return (objgraph);
}
To draw a Line graph, we use the same formula of bar graph to calculate the height. Once the points are marked, just join them using lines with different colors. x-Panel has to be drawn using EmbedXLinePanel()
.
//Generate Line graph
public Bitmap DrawLineGraph()
{
Bitmap objgraph = new Bitmap(200, 200);
//Canvas for graph
Graphics graphicGraph = Graphics.FromImage(objgraph);
//Paint the graph canvas white
SolidBrush whiteBrush = new SolidBrush(Color.White);
graphicGraph.FillRectangle(whiteBrush,0, 0, 200, 200);
int highestValue;
//Highest value in the values array
//Get the highest value
int[] tempValue = new int[values.Length];
for (int j = 0; j < values.Length;j++)
{
tempValue[j] = (int)values[j];
}
Array.Sort<int>(tempValue);
highestValue = tempValue[values.Length - 1];
int[,] points = new int[values.Length, 2];
//Generate bar for each value
for (int i = 0, x = 10; i < values.Length; i++)
{
decimal barHeight;
//height of the bar
barHeight = (decimal)(values[i] / highestValue * 190);
points[i, 0] = x; barHeight = 194 - barHeight;
points[i, 1] = (int)Decimal.Round(barHeight,0);
Font f = new Font(fontFormat, 8);
graphicGraph.FillEllipse(Brushes.Black, points[i,0]-2, points[i, 1]-2, 5, 5);
graphicGraph.DrawString(values[i].ToString(), f,
Brushes.Black,new Point(points[i, 0]-14, points[i, 1]-5));
x += 20;
}
for (int i = 1; i < values.Length; i++)
{
Point startPoint = new Point(points[i - 1, 0], points[i - 1, 1]);
Point endPoint = new Point(points[i, 0], points[i, 1]);
SolidBrush brush = new SolidBrush(colorList[i]); Pen colorPen = new Pen(brush, 2);
graphicGraph.DrawLine(colorPen, startPoint, endPoint);
}
objgraph = EmbedAxis(objgraph,true);
objgraph = EmbedXLinePanel(objgraph);
return (objgraph);
}
History
- 27 February, 2008 -- Original version posted
- 27 March, 2008 -- Introduced Bar Line Graph