2LeggedSpider

Generating a dynamic bar graph using ASP.NET and C#

Posted in ASP.NET, C# by Sumit Thomas on November 21, 2004

[tweetmeme style=”compact”]Back in the days of ASP, web developers had to rely on third party components to dynamically create images on a web page. In ASP, we would use colored tables to display a bar graph. But wouldn’t it be great if we could generate a dynamic graph by ourselves instead of relying on some third-party components. Well, the .NET framework allows us to do just that and more.

Consider a scenario where we had to display a graph representing the sales of a company from say 2000-2004. We need to generate a dynamic bar graph using the data provided to us. Let me take you through the step-by-step process to accomplish the task.

I am using Notepad and .NET framework 1.0. Why notepad? Well, I believe it’s the best way to learn .NET or for that matter any programming language and also the code is very clean.

The two classes, which we need to generate images on the fly, are System.Drawing.Bitmap and System.Drawing.Graphics. The Bitmap class is used to represent an instance of an image and the Graphics class can be used to draw lines, curves and other geometric shapes.

Be sure to check about these two classes and their methods from http://msdn.microsoft.com

So lets get started. Open Notepad and type the following two lines



We will be using these two namespaces in our application.

The method we will write to generate the graph is called ‘GenerateBarGraph’

The initial structure of the code will look like this


Bar graph generated using ASP.NET and C#


protected void GenerateBarGraph(
string graphTitle,
ArrayList xValues,
ArrayList yValues,
int barWidth,
int barSpaceWidth,
int graphHeight)
{
//Our code to generate bar graph will come here
}
private void Page_Load(object sender, System.EventArgs e)
{

}


<img src="" />


The parameters passed to the GenerateBarGraph method are as follows

graphTitle : The title of the graph
xValues : The values in the x-axis
yValues : The values in the y-axis
barWidth : The width of each bar
barSpaceWidth : The space between each bars
graphHeight : The height of the graph(excluding the title and x-values)

Change the GenerateBarGraph method as follows

protected void GenerateBarGraph(
string graphTitle,
ArrayList xValues,
ArrayList yValues,
int barWidth,
int barSpaceWidth,
int graphHeight)
{
int graphTitleHeight=20; // Height in pixels utilized by the title in the graph
int itemsHeight=35; // Height in pixels utilized by the items in the x-axis

/*
The Graph’s width is calculated by adding the width of a bar and the space between
two bars multiplied by the total values in the x-axis plus the space between two bars
*/
int graphWidth= (barWidth + barSpaceWidth) * xValues.Count + barSpaceWidth;

/*
The maximum height that a bar can attain needs to be found from the y-values passed
as parameter
*/
int maxBarHeight=0;

//Total height of the image is calculated
int totalGraphHeight = graphHeight + graphTitleHeight + itemsHeight;

//Create an instance of Bitmap class with the given width and height
Bitmap barBitmap=new Bitmap(graphWidth, totalGraphHeight);

/*
Graphics class does not have a constructor and hence we call its static method
FromImage and pass the Bitmap object to it
*/
Graphics barGraphics= Graphics.FromImage(barBitmap);

/*
Using the Graphics object we fill the image of given dimensions with light gray color
*/

barGraphics.FillRectangle(
new SolidBrush(Color.WhiteSmoke),
0,
0,
graphWidth,
totalGraphHeight);

/*
We create an instance of Font class available in System.Drawing. We will be using this
to display the title of the graph.
*/
Font titleFont=new Font("Verdana",14, FontStyle.Bold);

/*
Use the Graphics object’s DrawString method to draw the title at the specified location
*/
barGraphics.DrawString(
graphTitle,
titleFont,
new SolidBrush(Color.Red),
(graphWidth / 2) - graphTitle.Length * 5,
totalGraphHeight - itemsHeight);


//////////////Code to generate bars will come here/////////////////

/*
Save the image to the web server’s D: drive. We use the PNG format to make it look
crisp.
*/
barBitmap.Save("D:\\bargraph.png",ImageFormat.Png);

//Dispose off the Graphics and Bitmap objects
barGraphics.Dispose();
barBitmap.Dispose();
}

Change the Page_Load method as follows

private void Page_Load(object sender, System.EventArgs e)
{
ArrayList _years=new ArrayList();
_years.Add("2000");
_years.Add("2001");
_years.Add("2002");
_years.Add("2003");
_years.Add("2004");

ArrayList _sales=new ArrayList();
_sales.Add(270500);
_sales.Add(211930);
_sales.Add(223300);
_sales.Add(343000);
_sales.Add(424750);

GenerateBarGraph("ABC Ltd. Sales (2000-2004)",_years, _sales, 50, 25, 400);
}

Change the source of the IMG tag used in our aspx page as follows

<img />

Now, if you run this page you will see an image displayed on the browser with the title “ABC Ltd. Sales (2000-2004)” displayed in red at the bottom

If you notice in the Page_Load method, we have passed two ArrayLists to the GenerateBarGraph method and also the other previously mentioned parameters. We will be using these two ArrayLists to display the bars.

Now replace //////////////Code to generate bars will come here///////////////// in GenerateBarGraph method with the following code.

/*
Find the highest value in the yValues ArrayList and set it as the maximum height of the bar
*/
foreach(int _value in yValues)
if(_value > maxBarHeight) maxBarHeight=_value;

//barXPos will store the x position of a bar
int barXPos = barSpaceWidth;
int barHeight;

Font itemsFont=new Font("Verdana",9, FontStyle.Bold);
Font valuesFont=new Font("Verdana", 7, FontStyle.Italic);

Random rnd=new Random();

for(int i=0;i  Gives the bar height in percentage with respect to
the maximum bar height set by us

((((int)yValues[i]* 100 / maxBarHeight) )* graphHeight)/100 will give the bar height in
pixels
*/
barHeight=((((int)yValues[i]* 100 / maxBarHeight) )* graphHeight)/100;

//Draw the bar with the set brush, x and y positions, width and height
barGraphics.FillRectangle(
barBrush,
barXPos,
graphHeight-barHeight,
barWidth,
barHeight);

//Draw the x-value along the x-axis
barGraphics.DrawString(
xValues[i].ToString(),
itemsFont,
barBrush,
barXPos,
graphHeight);

//Draw the respective y value on top of the bar
barGraphics.DrawString(
yValues[i].ToString(),
valuesFont,
barBrush,
barXPos,
(graphHeight-barHeight)-itemsHeight);

//Change the x position of the next bar
barXPos += (barWidth + barSpaceWidth);
}

If you now run the aspx page you will notice the bar graph representing the sales of a company from 2000-2004. If you refresh the page you will see that each bar will have a new color.

The Graphics API provided by the .NET framework is very extensive and what we have seen gives us a useful startup. Do take time to understand the classes and its methods used in this article.

Technorati: , ,
Advertisements
Tagged with: , ,

20 Responses

Subscribe to comments with RSS.

  1. AKR said, on August 17, 2006 at 6:12 am

    This code and explanations were very useful to us. Thank you.

  2. AKR said, on August 17, 2006 at 6:13 am

    The code and explanations were very useful to us. Thank you.

  3. Carey said, on March 4, 2008 at 7:57 pm

    Very insightful piece. We decided to get our Windows web hosting with Server Intellect – since they were one of the first to offer the new Windows Server 2008 ‘Longhorn’ on all Dedicated Servers. The new upgrade has a lot of additions – like new web, security and virtualization tech, which is very helpful to our developers.

  4. nishant said, on March 16, 2008 at 10:13 am

    great piece of code.its very good learning exp. of charts

  5. rafube said, on April 18, 2008 at 3:31 pm

    the code is handy, all these other websites have just been wasting my time. This is exactly what I’ve been looking for. Thanx a thousand times

  6. Rashid Faridi said, on April 26, 2008 at 4:55 am

    good piece of code.
    thank you

  7. Venu said, on June 26, 2008 at 8:56 am

    Good one. Precise and clear.

  8. Shanthi said, on March 12, 2009 at 6:30 pm

    Really an excellent code!!!

    Many thanks for teaching me the same.

    Great job done!!!

  9. CHANDAN said, on April 14, 2009 at 5:23 am

    This article was very helpful for me. By doing little changes in the above code, i got my desired dynamic graph.
    Thanks allot

  10. bhavanik said, on July 13, 2009 at 7:33 am

    thank u so much for yor help. Can u tell me how to draw graphs with negative values

  11. Bharat said, on November 5, 2009 at 6:06 am

    this one is really good example to solve crate chart image.

    can you give me a idea if i want to show my legend to show
    then how ? pls reply soon as possible.

    Regards
    Bharat

  12. mike said, on February 1, 2010 at 9:07 pm

    I followed your tutorial to the T. Conceptually, it may work… but practically, it does not.

    The last for loop in the last code section is either a comment or pseudo code, also the variable barBrush is undefined.

    Please correct the code.

  13. Evibiomaassox said, on May 3, 2010 at 10:45 am

    If you are a real estate professional, be really careful in dealing with KoRes Corp. in Weston Florida. Tulio Rodriguez & Monica Cataluna-Shand are shysters and look for anyway to steal ones customers. They attempt to steal your client by requesting their contact information and later contact them behind your back to get them to deal with them directly.

  14. Guest said, on September 6, 2011 at 2:37 pm

    Here is the code that I used from the example in this article with the missing code and some additional code to draw some shadows on the bar graphs.

    protected string GenerateBarGraph(string graphTitle,
    ArrayList xValues,
    ArrayList yValues,
    int barWidth,
    int barSpaceWidth,
    int graphHeight)
    {
    try
    {
    DeleteOlderImages();

    int graphTitleHeight = 20; // Height in pixels utilized by the title in the graph
    int itemsHeight = 35; // Height in pixels utilized by the items in the x-axis

    /*
    The Graph’s width is calculated by adding the width of a bar and the space between
    two bars multiplied by the total values in the x-axis plus the space between two bars
    */

    int graphWidth = 584; // (barWidth + barSpaceWidth) * xValues.Count + barSpaceWidth;

    /*
    The maximum height that a bar can attain needs to be found from the y-values passed
    as parameter
    */

    int maxBarHeight = 0;

    // Total height of the image is calculated

    int totalGraphHeight = (graphHeight + graphTitleHeight + itemsHeight);

    // Create an instance of Bitmap class with the given width and height

    Bitmap bitGraphics = new Bitmap(graphWidth, totalGraphHeight);

    /*
    Graphics class does not have a constructor and hence we call its static method
    FromImage and pass the Bitmap object to it
    */

    Graphics barGraphics = Graphics.FromImage(bitGraphics);

    /*
    Using the Graphics object we fill the image of given dimensions with light gray color
    */

    Color colGraphics = Color.FromArgb(255, 255, 238);

    barGraphics.FillRectangle(new SolidBrush(colGraphics),
    0,
    0,
    graphWidth,
    (totalGraphHeight + 40));

    /*
    We create an instance of Font class available in System.Drawing. We will be using this
    to display the title of the graph.
    */

    Font titleFont = new Font(“Verdana”, 14, FontStyle.Bold);

    /*
    Use the Graphics object’s DrawString method to draw the title at the specified location
    */

    barGraphics.DrawString(graphTitle,
    titleFont,
    new SolidBrush(Color.Red),
    (graphWidth / 2) – graphTitle.Length * 5,
    totalGraphHeight – itemsHeight);

    /*
    Find the highest value in the yValues ArrayList and set it as the maximum height of the bar
    */

    foreach (string _value in yValues)
    {
    int iValue = Int32.Parse(_value);

    if (iValue > maxBarHeight)
    {
    maxBarHeight = iValue;
    }
    }

    // barXPos will store the x position of a bar

    // barSpaceWidth;

    int iMinus = ((barSpaceWidth * 2) + 30);
    int barXPos = ((584 / 2) – iMinus);
    int barHeight;

    Font itemsFont = new Font(“Verdana”, 9, FontStyle.Bold);
    Font valuesFont = new Font(“Verdana”, 7, FontStyle.Italic);

    Random rnd = new Random();

    for (int i = 0; i 5)
    {
    barHeight = (((((Int32.Parse(yValues[i].ToString()) * 100 / maxBarHeight)) * graphHeight) / 100) – 40);
    }
    else
    {
    barHeight = ((((Int32.Parse(yValues[i].ToString()) * 100 / maxBarHeight)) * graphHeight) / 100);
    }

    // Draw the bar shadow with the set brush, x and y positions, width and height

    barGraphics.FillRectangle(barShadow,
    (barXPos + 5),
    ((graphHeight – barHeight) + 5),
    barWidth,
    barHeight);

    // Draw the bar with the set brush, x and y positions, width and height

    barGraphics.FillRectangle(barBrush,
    barXPos,
    graphHeight – barHeight,
    barWidth,
    barHeight);

    // Draw the x-value along the x-axis

    barGraphics.DrawString(xValues[i].ToString(),
    itemsFont,
    barBrush,
    barXPos,
    (graphHeight + 5));

    // Draw the respective y value on top of the bar

    barGraphics.DrawString(yValues[i].ToString(),
    valuesFont,
    barBrush,
    barXPos,
    (graphHeight – barHeight) – itemsHeight);

    // Change the x position of the next bar

    barXPos += (barWidth + barSpaceWidth);
    }

    /*
    Save the image to the web server’s D: drive. We use the PNG format to make it look
    crisp.
    */

    string strFile = String.Format(“{0}{1}{2}”,
    “/Images/Polls/BarGraph”,
    DateTime.Now.ToString(“MM_dd_yyyy_HH_mm_ss”),
    “.png”);

    if (File.Exists(strFile))
    {
    strFile = String.Format(“{0}{1}{2}”,
    “/Images/Polls/BarGraph”,
    DateTime.Now.AddSeconds(1).ToString(“MM_dd_yyyy_HH_mm_ss”),
    “.png”);
    }

    bitGraphics.Save(Server.MapPath(strFile), ImageFormat.Png);

    // Dispose off the Graphics and Bitmap objects

    barGraphics.Dispose();
    bitGraphics.Dispose();
    return (strFile);
    }

    catch (Exception exp)
    {
    string strError;

    strError = String.Format(“{0} {1} {2} : {3}”,
    “GenerateBarGraph”,
    “experience an error:”,
    exp.Message,
    exp.StackTrace);

    throw new ApplicationException(strError);
    }

    finally
    {
    }
    }

  15. kapil said, on December 28, 2011 at 4:45 pm

    what is barbrush ?? in barGraphics.FillRectangle(
    barBrush,
    barXPos,
    graphHeight – barHeight,
    barWidth,
    barHeight);

    i got error in it as :- use of unassigned local variable
    plz tell me what did i miss in code???

    thanks

  16. Kmart said, on January 6, 2012 at 8:18 pm

    I am confused with this part:
    for (int i = 0; i 5)
    {
    barHeight = (((((Int32.Parse(yValues[i].ToString()) * 100 / maxBarHeight)) * graphHeight) / 100) – 40);
    }
    else
    {
    barHeight = ((((Int32.Parse(yValues[i].ToString()) * 100 / maxBarHeight)) * graphHeight) / 100);
    }

    the for loop is incorrect, and im not sure where the initial if statement is to go with the else statement
    clarification for this part would be greatly appreciated

  17. Rey said, on July 20, 2012 at 3:43 am

    And the includes ? Why the Hell nobody write the INCLUDES in their examples ???

  18. mith said, on January 19, 2013 at 4:55 am

    what is the point of posting not working examples?

  19. Bond said, on October 17, 2013 at 2:42 am

    Create Chart bar in C#.NET


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: