One of the cool new features in Visual Studio 2010 is the Chart control. (A very similar control is available as a free download to work with Visual Studio 2008, but charting is now built into the 4.0 framework. You can find the 2008 version here .) The native support in 4.0 is a big help for ASP.NET developers, because we no longer need to worry about getting permission to install a DLL in shared server environments.
Here's an example of a chart I created in ASP.NET with the new control.

In my last post, I talked about Scrum and "Burndown Charts". A "Burndown Chart" shows remaining work over time. In the above example, I show such a chart, and I've given weekends a different color from weekdays. Let's talk about how I did this.
First, start a new ASP.Net web form. Go to the toolbox, and select "Chart". (It's under "Data".) Drag it onto your form. There are a number of nice chart styles, as you can see:

I've selected "StackedColumn", for reasons I will explain shortly.
Below is my finished ASPX markup code. You'll see that the Chart control has a section called "Series". A Series is a set of data on the Chart. For a "Line" graph, a series would be one line. You might want to show several series and have them overlay each other (for example "Revenue", "Forecast" and "Expenses"). My chart contains separate series for "data" and "weekends".
<div>
<asp:Chart ID="Chart1" runat="server" Height="400px" Width="550px">
<Series>
<asp:Series Name="weekends" ChartType="StackedColumn" Color="Beige">
</asp:Series>
<asp:Series Name="data" ChartType="StackedColumn" Color="DarkOrchid">
</asp:Series>
</Series>
<ChartAreas>
<asp:ChartArea Name="ChartArea1">
<Area3DStyle Enable3D="True"></Area3DStyle>
<AxisX Interval="1"></AxisX>
</asp:ChartArea>
</ChartAreas>
</asp:Chart>
</div>
"Area3DStyle Enable3D" does pretty much what it sounds like.
Useful tip: The "AxisX Interval" is important. When set to 1, it insures that every data point has a label. (If your X axis contains numbers, it's easy enough to infer the unlabeled points. But if X is "apples", "bananas", "oranges", "grapefruits", you don't want an unlabeled point between "apples" and "oranges". It took me a long time to find this.)
Here's my code to fill the chart, in both VB and C#. Right now, the GetData() routine uses random numbers; in reality you would use a database.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim st As DateTime = New DateTime(2010, 6, 1)
Dim dys As Integer = 12
Dim dict As Dictionary(Of DateTime, Long) = GetData(st, dys)
For Each d As DateTime In dict.Keys
Dim xlab As String = d.ToString("M/d")
If (d.DayOfWeek = DayOfWeek.Sunday OrElse d.DayOfWeek = DayOfWeek.Saturday) Then
Chart1.Series("weekends").Points.AddXY(xlab, dict(d))
Chart1.Series("data").Points.AddXY(xlab, 0)
Else
Chart1.Series("weekends").Points.AddXY(xlab, 0)
Chart1.Series("data").Points.AddXY(xlab, dict(d))
End If
Next
End Sub
Private Function GetData(ByVal stDt As DateTime, ByVal days As Integer) As Dictionary(Of DateTime, Long)
Dim gd As New Dictionary(Of DateTime, Long)
Dim r As New Random()
Dim wkDt As New DateTime(stDt.Year, stDt.Month, stDt.Day)
Dim wkVal As Long = 171
For i As Integer = 1 To days
gd.Add(wkDt, wkVal)
wkDt = wkDt.AddDays(1)
If (wkDt.DayOfWeek <> DayOfWeek.Sunday AndAlso wkDt.DayOfWeek <> DayOfWeek.Saturday) Then wkVal -= r.Next(31)
Next i
Return gd
End Function
protected void Page_Load(object sender, EventArgs e)
{
DateTime st = new DateTime(2010, 6, 1);
int dys = 12;
Dictionary<DateTime, long> dict = GetData(st, dys);
foreach (DateTime d in dict.Keys)
{
string xlab = d.ToString("M/d");
DayOfWeek wd = d.DayOfWeek;
if (wd == DayOfWeek.Sunday || wd == DayOfWeek.Saturday)
{
Chart1.Series["weekends"].Points.AddXY(xlab, dict[d ]);
Chart1.Series["data"].Points.AddXY(xlab, 0);
}
else
{
Chart1.Series["weekends"].Points.AddXY(xlab, 0);
Chart1.Series["data"].Points.AddXY(xlab, dict[d ]);
}
}
}
private Dictionary<DateTime, long> GetData(DateTime stDt, int days)
{
Dictionary<DateTime, long> gd = new Dictionary<DateTime, long>();
Random r = new Random();
DateTime wkDt = new DateTime(stDt.Year, stDt.Month, stDt.Day);
long wkVal = 171;
for (int i = 0; i < days; i++)
{
gd.Add(wkDt, wkVal);
wkDt = wkDt.AddDays(1);
DayOfWeek wd = wkDt.DayOfWeek;
if (wd != DayOfWeek.Sunday && wd != DayOfWeek.Saturday) wkVal -= r.Next(31);
}
return gd;
}
There's really very little code here. I load a Dictionary object with pairs of String (the formatted date) and numeric value. Then I loop through the Dictionary and load a named series with Points.AddXY.
Another useful tip: The tricky part is my logic for showing different colors based on the day of the week. I accomplished this by using a stacked column with one part of the stack set to zero. On weekdays, it's purple with no beige on top. On weekends, it's beige with no purple underneath. This also took a while to figure out.
Hope this helps. Charts are a great way to make your data more understandable, and give your applications a snazzier look.