Click here to Skip to main content
Click here to Skip to main content

Graph Library

, 10 Apr 2008 CPOL
Rate this:
Please Sign up or sign in to vote.
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:

// 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<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.

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().
 //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.
 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().
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

License

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

Share

About the Author

Anoop Unnikrishnan
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

 
QuestionThanks PinmemberMember 1052568829-Jul-14 1:23 
GeneralMy vote of 5 Pinmembermanoj kumar choubey22-Feb-12 0:06 
GeneralMy vote of 1 PinmemberwhizMos7-Sep-10 1:01 
GeneralRe: My vote of 1 PinmemberLloyd Atkinson18-Dec-10 10:09 
GeneralFix for colors Pinmemberavivd3-Mar-09 4:33 
QuestionOHLC - Adding an extra line PinmemberAlex Tostevin17-Jun-08 22:01 
AnswerRe: OHLC - Adding an extra line PinmemberAlex Tostevin18-Jun-08 5:38 
GeneralGDI+ Error PinmemberMember 222335920-May-08 23:22 
GeneralGood Job PinmemberShibuv8-May-08 5:17 
GeneralVery good Pinmemberjomet11-Apr-08 1:32 
GeneralRe: Very good PinmemberAnoop Unnikrishnan11-Apr-08 5:20 
GeneralTought is was a graph library... Pinmemberaxelriet10-Apr-08 17:26 
GeneralZedgraph Pinmemberzitun10-Apr-08 5:55 
GeneralRe: Zedgraph [modified] PinmemberAnoop Unnikrishnan10-Apr-08 7:11 

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

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

| Advertise | Privacy | Mobile
Web04 | 2.8.141029.1 | Last Updated 10 Apr 2008
Article Copyright 2008 by Anoop Unnikrishnan
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid