dcsimg
 

Creating Simple Charts and Graphs

Wednesday Dec 3rd 2003 by Mark Strawmyer

Learn to create simple charts and graphs using the Microsoft .NET Framework's System.Drawing namespace.

Mark Strawmyer Presents: .NET Nuts & Bolts


Welcome to the next installment of the .NET Nuts & Bolts. In this column, we'll focus on creating simple charts and graphs using the Microsoft .NET Framework. This will involve using classes in the System.Drawing namespace.

Why Create Dynamic Charts and Graphs?

Charts and/or graphs can be very useful in both Windows-based and Web-based applications for pictorially displaying information and statistics. There are tools such as Crystal Reports that can be used to generate reports. There also area number of charting tools such as Chart FX, Dundas Chart, and TeeChart that will allow you to create robust charts and graphs for display within your applications. However, it isn't always feasible to purchase licenses for these tools, especially if the application is relatively simple or is constrained by a low budget. Lucky for those with a shoe string budget, the Microsoft .NET Framework includes the classes in the System.Drawing namespace.

How Do I Dynamically Create a Chart or Graph?

Creating a chart or graph using the Microsoft .NET Framework is easier than one might expect. The degree of difficulty of the chart is based on the complexity of the information you are trying to display and the shape you are trying to use to display it. The basic steps of creating a chart or graph are as follows:

  1. Create a new image in the desired format.
  2. Draw the desired shape using the drawing classes in the System.Drawing namespace.
  3. Save the image to a stream (memory, file, and so forth) so that it can be used.

Creating a Pie Chart Sample Code

The following sample class demonstrates how to create a dynamic image that contains a pie chart. It takes the background color, width, height, and an array of decimal values as the input. The PieChart object sums up the values and draws the pie chart for each value as a percent of the total. Each section of the chart will be drawn in one of the ten colors that have been set up.

using

 System;

using

 System.Drawing;

using

 System.Drawing.Imaging;

namespace

 CodeGuru.SampleCode
{
  

/// <summary> ///Draw a pie chart using the given information./// </summary>public class

 PieChart
  {
    

public

 Bitmap Draw(Color bgColor, 

int

 width, 

int

 height,
           

decimal

[] vals)
  {
    

// Create a new image and erase the background

    Bitmap bitmap = 

new

 Bitmap(width,height,
                               PixelFormat.Format32bppArgb);
    Graphics graphics = Graphics.FromImage(bitmap);
    SolidBrush brush = 

new

 SolidBrush(bgColor);
    graphics.FillRectangle(brush, 0, 0, width, height);
    brush.Dispose();

    

// Create brushes for coloring the pie chart

    SolidBrush[] brushes = 

new

 SolidBrush[10];
    brushes[0] = 

new

 SolidBrush(Color.Yellow);
    brushes[1] = 

new

 SolidBrush(Color.Green);
    brushes[2] = 

new

 SolidBrush(Color.Blue);
    brushes[3] = 

new

 SolidBrush(Color.Cyan);
    brushes[4] = 

new

 SolidBrush(Color.Magenta);
    brushes[5] = 

new

 SolidBrush(Color.Red);
    brushes[6] = 

new

 SolidBrush(Color.Black);
    brushes[7] = 

new

 SolidBrush(Color.Gray);
    brushes[8] = 

new

 SolidBrush(Color.Maroon);
    brushes[9] = 

new

 SolidBrush(Color.LightBlue);

    

// Sum the inputs to get the totaldecimal

 total = 0.0m;
    

foreach

( 

decimal

 val 

in

 vals )
      total += val;

    

// Draw the pie chartfloat

 start = 0.0f;
    

float

 end = 0.0f;
    

decimal

 current = 0.0m;
    

for

( 

int

 i = 0; i < vals.Length; i++ )
    {
      current += vals[i];
      start = end;
      end = (

float

) (current / total) * 360.0f;
      graphics.FillPie(brushes[i % 10], 0.0f, 0.0f, width, 
                       height, start, end - start);
    }

    

// Clean up the brush resourcesforeach

( SolidBrush cleanBrush 

in

 brushes )
      cleanBrush.Dispose();

    

return

 bitmap;
    }
  }
}

Using Charts in a Web Application

In the example above, we saw how to dynamically create an image that contains a pie chart based on our data. It is nice to have a chart as long as you can actually use it in an application.

Chart Generator Sample Web Page

The following sample code contains a Web page that can be used to generate dynamic charts or graphs. The page uses query string values to indicate what type of chart is to be constructed and contain data points for rendering the chart. The page sets the content type to image to ensure the result is treated as an image.

using

 System;

using

 System.Collections;

using

 System.ComponentModel;

using

 System.Data;

using

 System.Drawing;

using

 System.Drawing.Imaging;

using

 System.IO;

using

 System.Web;

using

 System.Web.SessionState;

using

 System.Web.UI;

using

 System.Web.UI.WebControls;

using

 System.Web.UI.HtmlControls;

namespace

 CodeGuru.SampleCode
{
  

/// <summary> ///Web page to control drawing of desired charts./// </summary>public class

 DrawChart : System.Web.UI.Page
  {
    

private

 void Page_Load(

object

 sender, System.EventArgs e)
    {
      Response.ContentType = "image/png";

      

// Read chart setup informationstring

 chartType = Request.QueryString["chartType"];
      

int

 height = Convert.ToInt32(Request.QueryString["height"]);
      

int

 width = Convert.ToInt32(Request.QueryString["width"]);
      Bitmap StockBitMap;
      Color bgColor = Color.FromArgb(255,253,244);
      MemoryStream memStream = 

new

 MemoryStream();

      

switch

( chartType )
      {
        

default

:
          

// Determine the number of points given and read // the valuesint

 numPoints = 1;
          

while

(Request.QueryString["P"+numPoints.ToString()]!=

null

)
                numPoints++;
          

decimal

[] vals = 

new

 Decimal[numPoints];
          

for

( int i = 0; i < numPoints; i++ )
              vals[i] = Convert.ToInt32(
           Request.QueryString["P"+i.ToString()]);

          PieChart pie = 

new

 PieChart();
          StockBitMap = pie.Draw(bgColor, width, height, vals);
          

break

;
      }

      

// Render BitMap Stream Back To Client

      StockBitMap.Save(memStream, ImageFormat.Png);
      memStream.WriteTo(Response.OutputStream);
    }

    

#region

 Web Form Designer generated code
    

override protected void

 OnInit(EventArgs e)
    {
      

// // CODEGEN: This call is required by the ASP.NET Web Form // Designer. //

      InitializeComponent();
      

base

.OnInit(e);
    }

    

/// <summary> ///Required method for Designer support - do not modify///the contents of this method with the code editor./// </summary>private void

 InitializeComponent()
    {
      

this

.Load += new System.EventHandler(

this

.Page_Load);
    }
    

#endregion

  }
}

Chart Generator Sample Web Page

Using the Web page in the above example, we now have a Web page that will return an image when accessed. We will use this within a Web application to display the chart. The following code contains the code behind of a sample page that has an image control. We set the ImageUrl of the image to the URL of our Web page, including the appropriate query string values. This will cause the chart image to display in our application.

using

 System;

using

 System.Collections;

using

 System.ComponentModel;

using

 System.Data;

using

 System.Drawing;

using

 System.Web;

using

 System.Web.SessionState;

using

 System.Web.UI;

using

 System.Web.UI.WebControls;

using

 System.Web.UI.HtmlControls;

namespace

 CodeGuru.SampleCode
{
  

/// <summary> ///Test page to display the pie chart./// </summary>public class

 TestCharts : System.Web.UI.Page
  {
    

protected

 System.Web.UI.WebControls.Image PieChartImage;

    

private

 void Page_Load(

object

 sender, System.EventArgs e)
    {
      

this

.PieChartImage.ImageUrl = 
        "./DrawChart.aspx?chartType=pie&width=200&height=200&" + 
        "P1=20&P2=15&P3=55&P4=82&P5=102&P6=6";
    }

    

#region

 Web Form Designer generated code
    

override protected void

 OnInit(EventArgs e)
    {
      

// // CODEGEN: This call is required by the ASP.NET Web Form // Designer. //

      InitializeComponent();
      

base

.OnInit(e);
    }

    

/// <summary> ///Required method for Designer support - do not modify///the contents of this method with the code editor./// </summary>private void

 InitializeComponent()
    {
      

this

.Load += 

new

 System.EventHandler(

this

.Page_Load);
    }
    

#endregion

  }
}

Possible Enhancements

Now we have built a chart generation tool that will allow us to return images that contain various custom charts. There are all sorts of enhancements that could make this even more valuable. Here are some ideas for you to consider.

  • The pie chart we built supports 10 different data points until the colors start repeating themselves. The chart could be changed to not be limited to just 10 colors, but rather select from any of the available colors.
  • The pie chart we built does not contain any text labels indicating the values on which the chart is based. A text legend can be drawn using the DrawString method of the graphics class. The values could be drawn within their respective portions of the pie chart, or within a separate legend.
  • Our test page has several values hard coded for the data points to display. You would want to change this to retrieve the desired data and pass them as parameters to the charting page.
  • The DrawChart web page currently only supports drawing the pie chart. More charts can be added by including them in the switch statement that determines the chart to be rendered. Other types of charts that could be built with relative ease include a bar graph and a line point graph.

Future Columns

The next column has yet to be determined. If you have something in particular that you would like to see explained, please e-mail me at mstrawmyer@crowechizek.com.

About the Author

Mark Strawmyer, MCSD, MCSE, MCDBA is a Senior Architect of .NET applications for large and mid-size organizations. Mark is a technology leader with Crowe Chizek in Indianapolis, Indiana. He specializes in the architecture, design, and development of Microsoft-based solutions. You can reach Mark at mstrawmyer@crowechizek.com.

# # #

Home
Mobile Site | Full Site