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:
- Titles
- Chart Areas
- 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:
Series 2:
The picture below is self-explanatory:
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.
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:
<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:
<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>
:
<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:
<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.
- Bring up your Toolbox.
- Point the mouse pointer onto the tab that you want to use for your
Chart
control. - Click the right mouse button and select "Choose items..."; wait until a window "Choose toolbox items" appears.
- Under .NET Framework Components, click the Browse button and browse down to the System.Web.DataVisualization.dll file.
- 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.
<%@ 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:
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)
{
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)
{
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)
{
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: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:
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.
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:
ConfigureArea
ConfigurTitle
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.