For details and to download the latest version, see: http://www.dotnetcharting.com
I guess, like most other developers, I have the occasional need for generating charts or graphical data representations in my applications. And, like most other developers, I've played with many different solutions. Starting with programs such as Visual Basic 1.0, I found that I could easily draw onto a Form and (after suitably refreshing some long-forgotten school mathematics theory) produce something resembling a chart. From there, I discovered the numerous ways you can crash a Windows machine by using the GDI routines directly, and finally blessed Microsoft when they release the .NET Framework—with its safe and relatively painless-to-use managed code interfaces to the graphics subsystem.
Of course, just because you can use .NET to build charts doesn’t mean that you can use it to build really great charts. Though I have generally been satisfied with my efforts over the years, they come nowhere near the features offered by commercial (or even some freeware) components and controls. It all comes down to how much time you are actually prepared to spend on writing the code for a chart when it is only a part of your application.
These days I am a confirmed .NET Web developer, and so I was interested to investigate the latest release of a charting control that runs under the .NET Framework, and is aimed squarely at ASP.NET. The control, called .netCHARTING is produced by a Canadian based team of developers. Originally released in 2002, this control is now at version 2.5, and the list of updates runs to several pages. These updates include new chart types, plus extensions to the API to support new visual effects and tighter control over the placement and appearance of the elements of the chart.
According to the features list, this control can generate 2D and 3D charts with a range of gradient or solid fill colors and variable transparency, in output formats such as JPG, PNG, Tiff, WMF, EMF and BMP. Data series can be specified in many ways, with arithmetic manipulation on the values permitted, and a variety of styles and formatting can be applied to the axes, data point markers and text. Headers, footers, titles and legends can be added to the chart; together with labels, pop-up tool-tips and clickable hyperlinks. The control also contains a caching subsystem that can reduce server loading when many users are accessing the same chart. And all of these features are demonstrated in the many sample pages that are provided with the control.
The .netCHARTING control is supplied as a ZIP file that you simply unzip into a virtual directory on your Web site. This generates a folder tree consisting of a bin folder containing the control assembly, and a folder containing the sample Access database, an XML and an Excel (.XLS) data file, and another subfolder containing SQL scripts to generate the sample database on other database systems.
The demonstration version of the control is not digitally signed with a strong name, and so you can't install it in the Global Assembly Cache (GAC). This is related to the licensing model for the control. However, if you purchase a server license (so that it can be used in multiple Web sites), the version of the control that is supplied is digitally signed, and so is can be installed in the GAC for use in multiple Web sites.
There are also separate folders containing a huge number of ASP.NET sample files in both C# and VB.NET, while the root folder contains the default menu page and a compiled help file (.CHM). This help file is comprehensive, and follows the same format as the .NET SDK. As well as the lists of classes implemented by the control, and their API members, there are useful tutorials covering use of the control, using a data source to power it, plus installation notes and an FAQ.
In fact, it's only when I came to look at the help file that I realized just how much work has gone into creating this control. The control itself has close to 100 properties and methods, while the assembly contains around 30 other classes that are used to specify behaviour of the control, and a large number of enumerations for the property values. So I decided to take a look at the samples provided with the control to see just how difficult it is to use.
To run the samples I simply navigated to the virtual application root folder where I unzipped the files, to be presented with the page shown in Figure 1. This contains links to the samples in three groups, those that demonstrate specific features, a gallery of the latest chart types and effects, and the samples provided with earlier versions of the control. There is also a link to open the documentation/help file for the control.

I started with the Gallery, and selected one of the examples near the top of the list. And I have to admit that I was stunned to see the result (shown in Figure 2). The styling, layout, shadowing, attention to detail and the whole quality of the chart really are impressive. Suddenly my own attempts at creating charts using .NET look decidedly amateurish!

As you can see from the screenshots, the freely-downloadable version
(which is great for experimenting with) marks the resulting chart with a
"Development version" message. When you purchase a license, you get a
key that unlocks the control and removes this message. A single Web site
license cost is $395 (at the time of this review). See
http://www.dotnetcharting.com/licensing.aspx for details.
Despite being extremely impressed by the
samples provided with the control, and the effects it can produce, there are a
couple of issues that I came across—and which should be fixed by the time you
read this. A few of the C# samples that use dates as a value for the axes or
data items have the format hard-coded as the US/Canadian "mm/dd/yyyy" pattern. As I
am located in
The only other minor irritation is that the samples open in the same browser window as the menu page, and don't contain a link back to the menu page. Maybe your own preferences differ, but I would like to see the samples open in a new browser window so that I can compare the different charts, and leave open any that I want to come back later.
The .netCHARTING control is nothing if not comprehensive when it comes to different types of charts. The ChartType enumeration, which is used to specify the type of chart that the control will generate, contains options such as Pie, Donut, Radar, Scatter, Bubble, Financial, Gantt and Gauges—as well as the Combo options that create single and multiple line and bar charts in a seemingly endless variety. Figure 3 shows a Bubble chart with 3D effect, where the transparency capabilities come in really useful.

Meanwhile, one of the more esoteric chart types that the control supports is the Gauges type (see Figure 4). This type of chart is useful for building applications that display a "control panel", allowing users to quickly and easily see the current value of some quantity being monitored (such as disk quotas or bandwidth utilization), and perhaps compare it to some limit or range of acceptable values. In fact, choosing a chart type from the impressive range available might be the hardest part of using the control in your applications!

One point to note is that some of the sample pages create the chart
images as disk files, which are then inserted into the page that is returned to
the browser. This means that the account under which you are running ASP.NET (probably
named ASPNET, or in Windows Server 2003
the account named NETWORK
SERVICE or the account group named IIS_WPG) must have WRITE permission for the target folder. By default this
folder is the one where the .aspx page resides, though you
can specify a different folder in the properties of the control.
Having played with the sample files, the next step is to build a page that uses the control to display some of my own data. But first, like all good developers, I decided to skip through the help file and get a feel for the way that the control works. It looks simple in the sample pages, many of which contain only 10-20 lines of code. But can it really be that easy?
The .netCHARTING control combines two separate features: a data processing engine that can create a "DataGrid" object you can bind to templates to generate a chart; and a chart engine that takes the data and renders the image for display in the browser. Figure 5 (borrowed from the Overview page in the help file) shows this process.

Basically, you have two choices when building a chart. You can create the data series in code, one value at a time, or you can connect to a data source such as a relational database, and XML document or an Excel spreadsheet and let the control pull the data from that source automatically. If you elect to create the data series manually, you just instantiate a Series class instance and call the Add method of the ElementCollection to add Element instances to the series. Each Element represents a data point on the chart, and has a multitude of properties that specify how it will appear. If you need more than one series, you use a SeriesCollection that can contain multiple Series instances.
The alternative approach is to create an instance of the DataEngine class, and use this to connect to your data source through a suitable connection string. Then specify a SQL statement or stored procedure that returns the data as a rowset. Or, if you prefer, you can generate a suitable rowset yourself and then assign this to the Data property of a Series directly. And, amazingly, the objects you can assign to this property include the standard .NET classes DataSet, DataTable, DataView and IDataReader (all from the System.Data namespace), OleDbDataReader and SqlDataReader (from the System.Data.OleDb and System.Data.SqlClient namespaces respectively), and a System.String instance that contains the path and name of an XML document stored as a disk file.
Although I didn't test it myself, the fact that you can use an IDataReader instance means that you
should be able to read data from an Oracle database using the System.Data.OracleClient.OracleDataReader class, or any other
database for which there is a managed code provider available.
To create the chart, values in the data source are then mapped (as "Tokens") to the properties of the Series or the individual Element instances that make up the chart, such as the Name, XAxis, XAxis, XValue and YValue. There is also a templating feature you can use to control the appearance of sections of the chart. For example, you can set the LabelTemplate property using LabelTemplate="%YValue". This flexibility in data source type, and the mapping of the data to the control's internal classes, is what makes the it so extremely adaptable and suited to almost any situation.
OK, so now I fell a little more at ease about how the control works, I'm ready to try creating a chart of my own. I have several pages on my own Web site that display traffic information, and it would be nice to see if I can use the control in these pages. Figure 6 shows the page I use now to display details of the page views (hits) and unique visitors (sessions). It uses custom ASP.NET code with the classes from the System.Drawing and System.Drawing.Imaging namespaces.

The data to create this chart comes from a DataSet that is generated using the following SQL statement:
sSQL
= "SELECT YearNumber = MAX(TYearNumber),"
_
& " WeekNumber = MAX(TWeekNumber), TotalHits = SUM(HitCount)," _
& " TotalSessions = SUM(Sessions), TotalKBytes = SUM(KBytes) "
_
& " FROM WeekSummary WHERE
" & sWhere _
& " GROUP BY TYearNumber, TWeekNumber" _
& " ORDER BY TYearNumber, TWeekNumber"
So there are actually three data series here, although the existing chart only shows two of them (when I tried to find a better way to display all three using the existing chart page, the whole thing just got messy). So, after stripping all the existing ASP.NET controls from the page, the first step is to import the .netCHARTING assembly so that I can reference the control:
<%@ Register TagPrefix="dotnet" Namespace="dotnetCHARTING"
Assembly="dotnetCHARTING"%>
The assembly must be placed in the bin directory of the application, of course. Then I can insert an instance of the control into the page using the ID "Chart":
<dotnet:Chart
id="Chart" runat="server"/>
Now it's just a matter of writing the code in the Page_Load event handler to set the control properties and feed it some data. The "global" properties for the Chart class are set to enable debugging (so that error messages are displayed rather than just a "No data" message and an empty chart), and to provide a "Combo"-style chart (in other words, a standard line/area/bar/column chart—depending on which other properties are specified):
Chart.Debug
= True
Chart.Type
= ChartType.Combo
The text for the title and X-axis are specified next, and the template for the "legend box" that displays the key to the series in the chart. Using "%Icon%Name" means that I'll get the icon for the series (the color block) followed by the series name. Finally, I specify that I want a 3D chart:
Chart.Title
= "Hits and Visitors to our Site"
Chart.ChartArea.XAxis.Label.Text
= "Week Number"
Chart.LegendBox.Template
= "%Icon%Name"
Chart.Use3D = True
Now I can specify the data. I create the first series by instantiating a new Series class with the name "Hits", and set the Data property to the DataSet that I generate in code elsewhere in the page. This is the same DataSet I used to power the original chart, of course. However, I have to map the columns in the DataTable within the DataSet to the properties of the Element instance that will be used to create the series in the chart. This is done by specifying a comma-delimited string of tokens for the DataFields property of the Series instance. Each token maps one property—in the code below I am mapping the WeekNumber column in the DataTable (see the SQL statement shown earlier) to the XAxis property of this series, and the TotalHits column to the YAxis property.
Dim s1 As New Series("Hits")
s1.Data = dsTrafficData
s1.DataFields = "XAxis=WeekNumber,YAxis=TotalHits"
Tokens are, in many way, at the heart of
using the control, and are well covered in the help file. For example, you can
map high and low values to each Element in a series, or set the text and color
for each one, by mapping these properties to columns in the data source.
Next I specify the type of line/bar/column that I want all the Element instances in this series to use. I've chosen AreaLine here, and I specify the color and the transparency level as well. Then it's just a matter of adding the series to the default SeriesCollection of the control:
s1.Type = SeriesType.AreaLine
s1.DefaultElement.Color = System.Drawing.Color.FromArgb(255,
255, 0) s1.DefaultElement.Transparency = 20
Chart.SeriesCollection.Add(s1)
All that remains is to repeat the process for the other two data series. The next one is named "KBytes" and is mapped to the TotalKBytes column in the DataSet. The third series is named "Visitors", and is mapped to the TotalSessions column. I also specify different colors for these two series:
Dim s2 As New Series("KBytes")
s2.Data = dsTrafficData
s2.DataFields = "XAxis=WeekNumber,YAxis=TotalKBytes"
s2.Type = SeriesType.AreaLine
s2.DefaultElement.Color = System.Drawing.Color.FromArgb(255,
99, 49) s2.DefaultElement.Transparency = 20
Chart.SeriesCollection.Add(s2)
Dim s3 As New Series("Visitors")
s3.Data = dsTrafficData
s3.DataFields = "XAxis=WeekNumber,YAxis=TotalSessions"
s3.Type = SeriesType.AreaLine
s3.DefaultElement.Color = System.Drawing.Color.FromArgb(0,
156, 255) s3.DefaultElement.Transparency = 20
Chart.SeriesCollection.Add(s3)
And that's it. Now I can run the page and view the results—and they are stunning! As you can see from Figure 7, it really shows the difference between an amateur's effort at drawing charts, and the end results you can quickly achieve by using a purpose-designed control.

While it's only fair to admit that I haven’t used many of the commercial and free charting components in the past, I was impressed by the .netCHARTING control. Although it may be priced a little high for occasional chart users and those running small or community Web sites, the comprehensive and high quality output it generates makes it a good buy for commercial and specialist sites.
I liked the easy installation, and the fact that the samples worked "out of the box". Getting to see results so quickly is a great confidence booster. And the first impressions certainly are stunning—for maximum "Gee Whizz!" effect go straight to the Gallery section of the samples. These samples alone should convince you to get out your credit card.
Another good point is that the object model, method and property names, SDK content and general features closely follow .NET development guidelines, making using the control seem quite intuitive once you get your head around the huge and seemingly complex API it exposes. Working with the basic hierarchy of classes, from Chart through Series to Element, soon becomes second nature.
And the control really does seem to offer a good combination of sensible default values and considerable flexibility. You can specify the size and type of the image that it generates (it supports almost all modern graphic formats), and you can control in minute detail almost every aspect of every item in a chart, right down to the color, depth and "softness" of the shadows cast by boxes and annotation objects. Of course, there is a converse to this in that it's very easy to just accept the defaults, leaving all your charts with that same general "feel". But maybe, as the default appearance is so good, this is no bad thing.
Getting started using the control can be confusing at first, due mainly to the large and somewhat complex interface that it has to implement in order to support the flexibility it offers. A simple step-by-step guide in the help file for the different ways that you can specify the source data and generate a chart would be useful. You'll probably end up doing as I did—copying and modifying the sample files to see the effects.
Other points that I came across include the fact that the ability to apply operators to a series is not supported using VB.NET at present (though it is supported when coding in C#). This feature will be implemented under .NET version 2.0, presumably due to enhancements to the VB.NET language it contains. It would have been useful in the ASP.NET "traffic data" chart I created—when using ordinary lines instead of "area lines", applying a multiplier to one series is a good way of arranging for the lines to be placed nearer together.
However, this leads to another issue I came across The Features list for the control says that you can create "shadow axes" if you need to have more than one Y axis value set (as in the original traffic data chart shown in Figure 6). This is an example of the more complex features of the control that really need better support in the help file. I finally found an example (SeriesAxisBindingdb.aspx in the "Feature" section of the demo pages) that uses multiple axes, and figured out the process from this. Like so many things, it turns out to be easy once you know how!
©2004 - Reviewed September 2004 by Alex Homer