Click here to Skip to main content
15,885,435 members
Articles / Web Development / ASP.NET
Article

Graph Library

Rate me:
Please Sign up or sign in to vote.
4.84/5 (43 votes)
10 Apr 2008CPOL3 min read 141.6K   7K   155   15
This article addresses the construction of a simple graph library using C#.
pic1.jpg
Pic2.jpg
Pic3.jpgPic4.JPG

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:

C#
// 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:

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

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

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

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

C#
//Initiatialize color list with dark color's 

 
private void InitColorList() 
{
 colorList = new List<color />();
 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.

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

  1. First prepare a white canvas of dimensions 200 X 200.
  2. Calculate the highest value [ x-axis values ].
  3. For each value on the x-axis...
    • Calculate the bar height using the formula: bar height=(x Value / highest value) * 190.
    • Draw the bar.
  4. Draw the axis and place the bar graph on an enlarged canvas using EmbedAxis().
  5. Draw the x-value mapping to the color using EmbedXPanel().
C#
 //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:

  1. Draw a shadow.
  2. Draw a white line at the bottom of the graph to hide the shadow.
C#
 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:

  1. First prepare a white canvas of dimensions 200 X 200.
  2. Calculate the sum of all x-values [ x-axis values ].
  3. Initialize the start angle of the pie to 0 degrees.
  4. 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.
  5. Place the pie graph on an enlarged the canvas using EmbedAxis(), with showAxis flag set to false.
  6. Draw the x-value mapping to the color using EmbedXPanel().
C#
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.

C#
 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().

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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
India India
Anoop Unnikrishnan is associated with a CMM Level 5 Company. He has done his Bachelor of Engineering in Information Science. His certifications include OCA,IBM SOA Associate, MCAD, MCTS and MCPD. Currently persuing MBA.

He is working on .NET since first Beta versions. He has also published his book "Start Programming with C#".

Grab a copy from www.pothi.com/pothi/book/anoop-unnikrishnan-start-programming-c

Anoop can be reached : anoopukrish@gmail.com

Comments and Discussions

 
QuestionFont is creepy Pin
gilbi16-Nov-15 3:08
gilbi16-Nov-15 3:08 
QuestionThanks Pin
GilbouFR29-Jul-14 1:23
GilbouFR29-Jul-14 1:23 
GeneralMy vote of 5 Pin
Manoj Kumar Choubey22-Feb-12 0:06
professionalManoj Kumar Choubey22-Feb-12 0:06 
GeneralMy vote of 1 Pin
whizMos7-Sep-10 1:01
whizMos7-Sep-10 1:01 
GeneralRe: My vote of 1 Pin
LloydA11118-Dec-10 10:09
LloydA11118-Dec-10 10:09 
You complete idiot.


See if you can crack this: fb29a481781fe9b3fb8de57cda45fbef


The unofficial awesome history of Code Project's Bob!

"People demand freedom of speech to make up for the freedom of thought which they avoid."

GeneralFix for colors Pin
avivd3-Mar-09 4:33
avivd3-Mar-09 4:33 
QuestionOHLC - Adding an extra line Pin
Alex Tostevin17-Jun-08 22:01
Alex Tostevin17-Jun-08 22:01 
AnswerRe: OHLC - Adding an extra line Pin
Alex Tostevin18-Jun-08 5:38
Alex Tostevin18-Jun-08 5:38 
GeneralGDI+ Error Pin
Member 222335920-May-08 23:22
Member 222335920-May-08 23:22 
GeneralGood Job Pin
Shibuv8-May-08 5:17
Shibuv8-May-08 5:17 
GeneralVery good Pin
jomet11-Apr-08 1:32
jomet11-Apr-08 1:32 
GeneralRe: Very good Pin
Anoop Unnikrishnan11-Apr-08 5:20
Anoop Unnikrishnan11-Apr-08 5:20 
GeneralTought is was a graph library... Pin
Axel Rietschin10-Apr-08 17:26
professionalAxel Rietschin10-Apr-08 17:26 
GeneralZedgraph Pin
zitun10-Apr-08 5:55
zitun10-Apr-08 5:55 
GeneralRe: Zedgraph [modified] Pin
Anoop Unnikrishnan10-Apr-08 7:11
Anoop Unnikrishnan10-Apr-08 7:11 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.