Creating Simple Charts and Graphs

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 total
    decimal total = 0.0m;
    foreach( decimal val in vals )
      total += val;

    // Draw the pie chart
    float 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 resources
    foreach( 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 information
      string 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 values
          int 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.

# # #



About the Author

Mark Strawmyer

Mark Strawmyer is a Senior Architect of .NET applications for large and mid-size organizations. He specializes in architecture, design and development of Microsoft-based solutions. Mark was honored to be named a Microsoft MVP for application development with C# for the fifth year in a row. You can reach Mark at mark.strawmyer@crowehorwath.com.

Comments

  • How to make Line Graphs in VC#.NET?

    Posted by blue_diamond11ph on 11/24/2005 06:14am

    Anybody who can give me a sample code in creating a line graph where the X and Y data are determined by user input will be greatly appreciated.

    Reply
  • Image Save Problem

    Posted by mkotaska on 09/07/2005 03:08am

    Hello, please help me. I don't know how to set an image filename in case of saving rendered image (by right mouse click on image and selecting Save Picture as.. in MSIE)

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • The explosion in mobile devices and applications has generated a great deal of interest in APIs. Today's businesses are under increased pressure to make it easy to build apps, supply tools to help developers work more quickly, and deploy operational analytics so they can track users, developers, application performance, and more. Apigee Edge provides comprehensive API delivery tools and both operational and business-level analytics in an integrated platform. It is available as on-premise software or through …

  • Live Event Date: September 10, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild". This loop of continuous delivery and continuous feedback is …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds