Jun 12 2007

Dynamically Generate Charts

Sure, digging through the .NET Framework documentation is a rip-roaring good time, but here are a few shortcuts to get you back to your coding faster.

With just a few lines of code, you can use the System.Drawing namespace to add charts to your Windows Forms program or ASP.NET Web applications.

The System.Drawing namespace includes everything you need to draw line graphs, bar graphs and pie charts. By implementing the IHttpHandler interface, you can even create custom graphics for ASP.NET Web applications.

Tech Tip No. 1 — Draw a Pie Chart

In Windows Forms applications, you can use the PictureBox control to display images. First, call PictureBox.CreateGraphics to generate a Graphics object. Then, call Graphics.Clear to fill the image with a solid color. Finally, call the various Graphics methods to draw the chart. For example, the following code sample uses the Graphics.FillPie method to draw the pie chart shown in Figure 1.

Figure 1: You can draw pie charts with just a few lines of code.

Dim g As Graphics = PictureBox1.CreateGraphics()
g.FillPie(Brushes.Purple, 0, 0, PictureBox1.Width, PictureBox1.Height, 0, 50)
g.FillPie(Brushes.Gold, 0, 0, PictureBox1.Width, PictureBox1.Height, 50, 220)
g.FillPie(Brushes.Green, 0, 0, PictureBox1.Width, PictureBox1.Height, 270, 90)

// C#
Graphics g = pictureBox1.CreateGraphics();
g.FillPie(Brushes.Purple, 0, 0, pictureBox1.Width, pictureBox1.Height, 0, 50);
g.FillPie(Brushes.Gold, 0, 0, pictureBox1.Width, pictureBox1.Height, 50, 220);
g.FillPie(Brushes.Green, 0, 0, pictureBox1.Width, pictureBox1.Height, 270, 90);

Tech Tip No. 2 — Draw a Bar Graph

To draw bar graphs, use Graphics.FillRectangle to draw the bars, and then call Graphics.DrawString to add text. The following code sample demonstrates how to use those methods to create the simple bar graph shown in Figure 2 from data in an array.

Figure 2: Use a “For Each” loop to generate a bar graph from an array.

Dim g As Graphics = PictureBox1.CreateGraphics()
Dim data() As Integer = {50, 72, 57, 84, 65}

Dim w As Integer = PictureBox1.Width / data.Length
Dim i As Integer = 0
Dim d As Integer
For Each d In data
    g.FillRectangle(Brushes.Blue, i, PictureBox1.Height - d, w - 2, d)
    g.DrawString(d.ToString(), New Font("Arial," 12), Brushes.White, i + 10, PictureBox1.Height - d + 10)
    i += w

// C#
Graphics g = pictureBox1.CreateGraphics();
int[] data = { 50, 72, 57, 84, 65 };
int w = pictureBox1.Width / data.Length;
int i = 0;
foreach (int d in data)
    g.FillRectangle(Brushes.Blue, i, pictureBox1.Height - d, w - 2, d);
    g.DrawString(d.ToString(), new Font(“Arial,” 12), Brushes.White, i + 10, pictureBox1.Height - d + 10);
    i += w;

Tech Tip No. 3 — Generate Images in Web Applications

To include images in an ASP.NET Web page, follow these steps to create a handler that generates an image and to configure ASP.NET to process requests for that file type:

Create a class that implements the IHttpHandler interface. Set Response.ContentType to an image type such as “image/jpeg” or “image/gif,” use the Graphics class to generate an image, and then write the image to the output stream. The following example demonstrates this by drawing a line graph:

Public Class DrawChart
    Implements IHttpHandler

    Public ReadOnly Property IsReusable() As Boolean _
            Implements System.Web.IHttpHandler.IsReusable
            Return False
        End Get
    End Property

    Public Sub ProcessRequest (ByVal context As System.Web.HttpContext) Implements _
        ' Set the MIME type
        context.Response.ContentType = "image/gif"
        Dim bm As Bitmap = New Bitmap (200, 200)
        Dim g As Graphics = Graphics.FromImage(bm)
        g.DrawLine(New Pen(Color.Red), 1, 1, 100, 100)
        g.DrawLine(New Pen(Color.Blue), 100, 100, 150, 50)
        g.DrawLine(New Pen(Color.Green), 150, 50, 200, 200)
        bm.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif)
    End Sub
End Class

public class DrawChart : IHttpHandler
            public DrawChart()
            {          }

    public bool IsReusable
        get { return false; }

    public void ProcessRequest(HttpContext context)
             // Set the MIME type
             context.Response.ContentType = "image/gif;"
             Bitmap bm = new Bitmap (200, 200);
             Graphics g = Graphics.FromImage(bm);
             g.DrawLine(new Pen(Color.Red), 1, 1, 100, 100);
             g.DrawLine(new Pen(Color.Blue), 100, 100, 150, 50);
             g.DrawLine(new Pen(Color.Green), 150, 50, 200, 200);
             bm.Save (context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif);

Configure IIS to forward requests for the image type file extension to ASP.NET by following these steps:

  • In Windows Server 2003, open IIS Manager and view your Web application’s properties. On the Directory tab, click Configuration. In Windows Vista, open IIS Manager, click your Web application, and then double-click Handler Mappings.
  • Double-click .ASPX. Copy the path to the aspnet_isapi.dll file, and then click Cancel.
  • In Windows Server 2003, click Add. In Windows Vista, click Add Script Map.
  • In the Executable box, paste the path to the aspnet_isapi.dll file. Then, type your file extension, such as “.jpg” or “.gif.”
  • In Windows Server 2003, clear the Verify That File Exists check box. In Windows Vista, click Request Restrictions, and then clear the Invoke Handler Only If Request Is Mapped To check box.
  • Click OK to close all open dialog boxes.

Update the Web.config file to configure ASP.NET to process requests for the file extension using the IHTTPHandler class you created, as this example shows:

            <add verb= "*" path = "*.gif" type = "DrawChart"/>

Now, all requests for the file extension you configured will be processed by your custom class, causing the browser to display an image.

You can use request parameters (available from the HttpContext.Request.Parameters collection that is passed to your HttpHandler.ProcessRequest method) to pass details about how to render the chart, just as you would in an .ASPX page. For example, if you configured the /images/ folder to send requests for .gif files to your handler, you could use any of the following in your HTML page to display a dynamically generated image:

<img src = "/images/chart.gif">
<img src = "/images/chart.gif?id = 23423">
<img src = "/images/chart.gif?stock = vz&year = 2005&size = large">

Tony Northrup is a developer, security consultant and author with more than 10 years of professional experience developing applications for Microsoft Windows.