Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

A look inside the ASP.NET Charting conlrol

4.68/5 (16 votes)
22 Oct 2010CPOL5 min read 64.9K   868  
The Chart control gives you freedom to develop graphic reports.

Introduction

When you develop an application, sometimes you have to develop some reporting tools. As an example, your database holds information of how many sales was done daily by any sales rep, and you want to report this in a nice graphic format for executive usage. It would be nice to be able to select a date range, select a couple of sales reps, and display their total sales for every day. What would you need to accomplish this? Well, the recorded data first, and the ability to display this data in the graphical format. There is no problem with the data itself. Using database tools and C# tools, you can do anything you want with the data. You can filter, group, make calculations etc. Fortunately, there is a far simple but really cool solution for this, which is called ASP.NET Charting Control. In this article, I would like to take a close look into the control. I am sure it will help you to master this control in no time. It is fun to work with, and it has a lot of possibilities.

ASP.NET Charting Control

Picture 1 below shows a charting control for two series of data. The architecture of the control is simple and straightforward. It has three very important collections:

  1. Titles
  2. Chart Areas
  3. Series

Collection of Titles may have several Title objects; each of them represents a title. They display sequentially one under another or one above anther, you can control the settings. Collection of Chart Areas has several CharArea objects; each of them represents an area where you display the graph data. They also display sequentially one above/under another, and also are highly configurable. Collection of Series has several Series objects; each of them represents the series of data itself. It is the set of corresponding numbers, and those numbers represent the vertical and horizontal direction of the chart. For this picture:

Series 1:
X0123456789
Y7862834153
Series 2:
X0123456789
Y6569744432

The picture below is self-explanatory:

Chart.gif

There is no need to add more than one title and/or chart area. Usually, all you need is just one title and chart area. If you want to compare data from two or more series, you can place them inside one chart area. This control allows you a lot of tweaking. Picture 2 shows a different configuration for the control.

Chart1.gif

Implementation

The good news is that ASP.NET Charting Control is a Microsoft creation, and it is free. You can find and download it from the internet. It is an assembly with the name System.Web.DataVisualization.dll. Usually, during installation from the internet, it will be placed into the GAC (Global Assembly Cache) and it will appear among the other system references available, but you may also just place the file into your bin folder and make a reference to the file by browsing. It will work like a private assembly. It is very convenient if you want to deploy your application onto a shared hosting server and this server does not have the assembly in GAC. I supplied my article with the file, so you can download it from here:

When rendering, the chart is presented by an image in your HTML source. Something like this:

HTML
<img id="Chart1" 
  src="http://www.codeproject.com/ChartImg.axd?i=
       chart_e12f8822706a422ea567f6b4dc5974ef_1.png&
       g=45d8c6d5ff874c67a29fe91059a8cbe5"
  alt="" style="height:300px;width:800px;border-width:0px;" />

In order to process the source of the image with the extension .axd, you have to add an HTTP handler into your web configuration file. Find the section <httpHandlers> under <system.web> and add the following:

XML
<httpHandlers>
<add path="ChartImg.axd" verb="GET,HEAD" 
    type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, 
           System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, 
           PublicKeyToken=31bf3856ad364e35"
    validate="false" />
</httpHandlers>

For the newer version of IIS, you may add the handler into the <handlers> section under <system.webServer>:

XML
<handlers>
<remove name="ChartImageHandler"/>
<add name="ChartImageHandler" preCondition="integratedMode" 
   verb="GET,HEAD"
   path="ChartImg.axd" 
   type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, 
         System.Web.DataVisualization, Version=3.5.0.0, 
         Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</handlers>

Also find the section <controls> under <system.web> and add the control:

XML
<controls>
<add tagPrefix="asp" namespace="System.Web.UI.DataVisualization.Charting"
     assembly="System.Web.DataVisualization, Version=3.5.0.0, 
               Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</controls>

Code

This is a very simple ASP.NET application which has only one Default.aspx file with the corresponding Default.aspx.cs. Before proceed, you want to install ASP.NET Charting control into your Visual Studio Toolbox.

  1. Bring up your Toolbox.
  2. Point the mouse pointer onto the tab that you want to use for your Chart control.
  3. Click the right mouse button and select "Choose items..."; wait until a window "Choose toolbox items" appears.
  4. Under .NET Framework Components, click the Browse button and browse down to the System.Web.DataVisualization.dll file.
  5. Select the file and click OK - the chart control will appear in your Toolbox.

After the installation, just drag and drop the Chart onto the page in the Design view.

ASP.NET
<%@ Page Language="C#" AutoEventWireup="true" 
   CodeBehind="Default.aspx.cs" Inherits="Chart._Default" %>

<%@ Register Assembly="System.Web.DataVisualization, Version=3.5.0.0, 
                       Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    Namespace="System.Web.UI.DataVisualization.Charting" 
    TagPrefix="asp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Chart ID="Chart1" runat="server" Width="800" >
            <Series>
                <asp:Series Name="Series1">
                </asp:Series>
                <asp:Series Name="Series2">
                </asp:Series>
            </Series>
            <ChartAreas>
                <asp:ChartArea Name="ChartArea1">
                </asp:ChartArea>
            </ChartAreas>
        </asp:Chart>
    </div>
    <asp:CheckBox ID="chkCompare" runat="server" 
       Text="Compare two sets of data" AutoPostBack="true" /><br />
    <asp:CheckBox ID="chkDisplay3D" runat="server" 
       Text="Display 3D" AutoPostBack="true" /><br />
    <asp:CheckBox ID="chkShowValues" runat="server" 
       Text="Show Metrics Values" AutoPostBack="true" /><br />
    <asp:DropDownList ID="ddlChartType" 
             runat="server" AutoPostBack="true">
        <asp:ListItem Text="Column"></asp:ListItem>
        <asp:ListItem Text="Line"> </asp:ListItem>
        <asp:ListItem Text="StepLine"></asp:ListItem>
        <asp:ListItem Text="Pie"></asp:ListItem>
        <asp:ListItem Text="Area"></asp:ListItem>
        <asp:ListItem Text="Bar"></asp:ListItem>
        <asp:ListItem Text="BoxPlot"></asp:ListItem>
        <asp:ListItem Text="Doughnut"></asp:ListItem>
    </asp:DropDownList>
    </form>
</body>
</html>

The class:

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.DataVisualization.Charting;
using System.Drawing;

namespace Chart
{
    public class DataInfo
    {
        public int X { get; set; }
        public int Y1 { get; set; }
        public int Y2 { get; set; }
    }

    public partial class _Default : System.Web.UI.Page
    {
        private bool compare;
        private bool display3d;
        private bool showValues;
        private string charType = "Column";

        protected void Page_Load(object sender, EventArgs e)
        {

            List<DataInfo> list = new List<DataInfo>();
            Random r = new Random(23);
            for (int i = 0; i < 10; i++)
            {
                DataInfo di = new DataInfo();
                di.X = i;
                di.Y1 = r.Next(1, 10);
                di.Y2 = r.Next(1, 10);
                list.Add(di);
            }

            this.Chart1.DataSource = list;

            GetChartPreferences();
        }

        protected void Page_Prerender(object sender, EventArgs e)
        {
            ConfigureChart();
            if (!compare)
                Chart1.Series.Remove(Chart1.Series[1]);
        }

        private void ConfigureChart()
        {
            Chart1.Titles.Add(new Title("Title 1: my chart"));
            ConfigurTitle(Chart1.Titles[0]);
            ConfigureArea(Chart1.ChartAreas[0]);
            ConfigureSeries(Chart1.Series[0], "X", "Y1");
            ConfigureSeries(Chart1.Series[1], "X", "Y2");
            Chart1.Series[1].ChartArea = Chart1.ChartAreas[0].Name;
        }

        private void ConfigureArea(ChartArea area)
        {
            //configure Chart Areas:
            area.ShadowColor = Color.Gray;
            area.ShadowOffset = 10;
            area.AxisY.Title = area.Name + " -  v e r t i c a l";
            area.AxisX.Title = area.Name + " -  H o r i z o n t a l";
            area.AxisX.IsMarginVisible = true;
            area.Area3DStyle.Enable3D = display3d;
        }

        private void ConfigurTitle(Title title)
        {
            //configure Title:
            title.BorderColor = Color.Silver;
            title.BorderDashStyle = ChartDashStyle.Solid;
            title.ShadowColor = Color.Gray;
            title.ShadowOffset = 6;

            title.Font = new Font(FontFamily.GenericSansSerif, (float)13);
        }

        private void ConfigureSeries(Series series, string xValue, string vValue)
        {

            //configure Series:
            series.XValueMember = xValue;
            series["ShowMarkerLines"] = "True";
            series.YValueMembers = vValue;
            series.MarkerStyle = MarkerStyle.Square;
            series.IsValueShownAsLabel = showValues;

            switch (charType)
            {
                case "Line":
                    series.ChartType = SeriesChartType.Line;
                    break;
                case "Column":
                    series.ChartType = SeriesChartType.Column;
                    break;
                case "Pie":
                    series.ChartType = SeriesChartType.Pie;
                    break;
                case "Area":
                    series.ChartType = SeriesChartType.Area;
                    break;
                case "Bar":
                    series.ChartType = SeriesChartType.Bar;
                    break;
                case "BoxPlot":
                    series.ChartType = SeriesChartType.BoxPlot;
                    break;
                case "Doughnut":
                    series.ChartType = SeriesChartType.Doughnut;
                    break;
                case "StepLine":
                    series.ChartType = SeriesChartType.StepLine;
                    break;
            }
        }

        private void GetChartPreferences()
        {
            if (!string.IsNullOrEmpty(Request[chkShowValues.UniqueID]))
                showValues = true;

            if (!string.IsNullOrEmpty(Request[chkDisplay3D.UniqueID]))
                display3d = true;

            if (!string.IsNullOrEmpty(Request[chkCompare.UniqueID]))
                compare = true;

            if (!string.IsNullOrEmpty(Request[ddlChartType.UniqueID]))
                charType = Request[ddlChartType.UniqueID];
        }
    }
}

Explanations

Default.aspx:

ASP.NET
<asp:Chart ID="Chart1" runat="server" Width="800" >
    <Series>
        <asp:Series Name="Series1">
        </asp:Series>
        <asp:Series Name="Series2">
        </asp:Series>
    </Series>
    <ChartAreas>
        <asp:ChartArea Name="ChartArea1">
        </asp:ChartArea>
    </ChartAreas>
</asp:Chart>

I created a chart with one chart area and two series of data. There are some check boxes and a drop-down list on the page with auto-postback set to true. Every time I change the settings, the graph is displayed differently. I can make it 3D, display/hide values of data, compare two series of data, or just display only first, and/or change the style of the graph.

Default.aspx.cs:

I declared a new class:

C#
public class DataInfo
{
    public int X { get; set; }
    public int Y1 { get; set; }
    public int Y2 { get; set; }
}

The public property X will represent the X axis for both series of data, the public property Y1 will represent the Y axis for the first series, and the public property Y2 will represent the Y axis for the second series.

In the Load event, I create a list of DataInfo and randomly populate it. Then I assign the list as a data source for my Chart. After that, the rest is just a matter of chart configuration.

C#
protected void Page_Load(object sender, EventArgs e)
{
    List<DataInfo> list = new List<DataInfo>();
    Random r = new Random(23);
    for (int i = 0; i < 10; i++)
    {
        DataInfo di = new DataInfo();
        di.X = i;
        di.Y1 = r.Next(1, 10);
        di.Y2 = r.Next(1, 10);
        list.Add(di);
    }

    this.Chart1.DataSource = list;
    GetChartPreferences();
}

To make my code better readable, I broke the configuration into several simple procedures:

  1. ConfigureArea
  2. ConfigurTitle
  3. ConfigureSeries

Take your time and play with these functions, you will find that there are many configuration options available. I used just a couple of them to give you a flavor for the control.

Conclusions

This is a very cool and simple way to display graphical data for your application. It saves you a lot of development time. The control is very customizable. Please vote if you liked the article.

License

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