Using Microsoft's Chart Controls In An ASP.NET Application: Plotting Chart DataBy Scott Mitchell
The Microsoft Chart Controls enable developers to specify chart data in a number of ways. Chart data may be specified statically via the Chart Web control's declarative markup. Chart data may also be specified programmatically using a variety of techniques. For starters, you can add the points to plot one at a time via the
AddXYmethod. The Chart Controls API offers methods for binding enumerable data to the chart in one line of code. For example, you can pass an enumerable data source (such as a
SqlDataReader) into the Chart control's
DataBindTablemethod. Alternatively, you can assign data to the Chart's controls
DataSourceproperty and then call its
The first installment in this article series - Getting Started - showed some simple examples of plotting chart data. This article delves into more intricate examples, showing how to plot database data, data from an XML file, and data from other types of data sources. We'll also look at plotting data using a library created by K. Scott Allen for his MSDN Magazine article, Charting With ASP.NET And LINQ. Read on to learn more!
Plotting Chart Data Point By Point
The most straightforward way to get your data onto a chart is to specify the data point by point. Each series in a chart has a
Pointscollection that specifies the data points to plot for that series. As we saw in the previous installment, the
Pointscollection data may be specified statically via the
<Points>section in the Chart Web control's declarative markup. The values for this collection can also be defined programmatically via the
The following example shows how to specify chart data point by point by displaying a chart that shows the total number of sales per day of week for a fictional online retailer. (The complete code for this example, as well as all of the other demos in this article series, are available for download at the end of this article.) The data is shown in a three-dimensional area chart using the Earth Tones palette. This information - the chart type, the instructions to render the chart as a 3D chart, and the palette choice - are all configured in the Chart control's declaratively syntax:
The chart data is specified programmatically. The following code is from the
Page_Load event handler. It starts by defining a string array that holds the X
values, namely the days of the week. For each day of the week a point is added to the chart with the day of the week as the X value and the total number of sales
(generated randomly) as the Y value. (While the chart data for this example is randomly generated, it could have been pulled from a database query, Web Service call, or
some other data source. The main point to take away here is that it is possible to specify the points in a series one at a time via the
The screen shot below shows this chart when viewed through a browser. Note that each data point's value is determined randomly, so the screen shot you see below will not mirror what you see when you download and run the demo application available at the end of this article. In fact, the chart will change each time you reload or revisit the page.
Binding Data to the
As we just saw, points can be added to the
Pointscollection one at a time. Alternatively, any enumeration of data may be bound to a series in a single line of code using the
DataBindXYmethod. For example, the above example's code could be rewritten to gather the total sales per day of week in an array and then use the
DataBindXYmethod to bind the X values (
DaysOfWeek) and the Y values (
SalesPerDOW) to the chart's first series:
The end result is the same as specifying the data points one by one. The
DataBindXY method enumerates the elements in the passed in data sources
SalesPerDOW, in this example) and creates a
DataPoint object for each element. It sets the
object's X and Y values using the current enumerated element and then adds it to the
Points collection. Long story short, the
DataBindXY method is
just an alternative way to get the data to plot into to the
DataBindXY method can also be used to bind database data. The following demo shows how to display the number of products
in each category in the Northwind database using the
DataBindXY method. The Chart control's declarative syntax follows. Note that it differs from the
previous example's declarative syntax in that the series has been given a
Name value (
Categories) and is of type
Bar instead of type
Area. Also, it uses the Chocolate palette instead of Earth Tones.
The chart data is retrieved by connecting to the Northwind database and issuing an ad-hoc SQL query to retrieve the number of products associated with each category.
This data is loaded into a
SqlDataReader object named
myReader, which is then bound to the Chart control's
Points collection via the
DataBindXY method. In this case we have one object (
myReader) that contains both the X and Y values to plot.
Therefore, we pass
myReader into the
DataBindXY method twice - once for the X values and once for the Y values. (In the previous example we
had one object that held the X values -
DaysOfWeek - and one object that held the Y values -
SalesPerDOW.) Because the X and Y values are in the
same object we need to specify what field to use for the X values ("CategoryName") and what field to use for the Y value ("ProductCount"). This information is provided
as additional inputs to the
The screen shot below shows the resulting chart.
Binding Tabular Data to the Chart Control
In addition to binding data to a particular series, the Chart control enables developers to programmatically bind data directly to the chart itself. This can be done by calling the Chart control's
DataBindTablemethod or by assigning the data to display to the Chart control's
DataSourceproperty and then calling its
DataBindmethod. We already examined using the
DataBindTablemethod and the
DataSourceproperty in the previous installment, Getting Started.
Another option for binding tabular data to the chart is to use a declarative data source control, such as a SqlDataSource or ObjectDataSource. From the Visual Studio Designer,
expand the Chart control's smart tag to reveal a Choose Data Source drop-down list. From that drop-down list choose the New Data Source option and create and configure
a data source control. (For more information on using data source controls see my article series,
Accessing and Updating Data in ASP.NET.) Assigning a data source control to the Chart in this manner both
adds a new data source control to the page and assigns the Chart's
DataSourceID property to the
ID of the data source control.
After adding the data source control, make sure to tell the Chart control what fields from the data source should be used for the X and Y values via the
YValueMembers property of the Series. The following declarative markup shows the markup for a Chart control that renders a bar
chart showing the number of products per category in the Northwind database; when viewed through a browser, the chart appears precisely as the screen shot above. However,
instead of assigning the data programmatically, in this case its assigned declaratively through the SqlDataSource control on the page (
Plotting XML Data
If you need to plot data from an XML file, Excel file, comma separated value (CSV) file, or some data store other than a relational database, you have a couple of options. One option is to write code that retrieves the data of interest and then adds it to the chart point by point. The other option is to use ADO.NET to connect to the data store. Most alternative data stores - including XML documents, Excel spreadsheets and CSV files - can be accessed by ADO.NET and queried similar to how you'd query a relational database. If this is the case with the data store of interest, you can get the data into a DataReader or DataTable or DataSet and then bind that object to the Chart control or one of its Series using any one of the techniques we've discussed in this article. The Samples Environment for Microsoft Chart Controls includes demos that plot data from an XML file, from Excel, and from a CSV file using this latter approach.
The download available at the end of this article includes a demo that displays XML data using the former method. The code uses the
LINQ to XML API to access the XML elements of
interest and then loops through them, adding the points to the series. The XML file that contains the data is named
SalesSummary.xml and resides in the
App_Data folder, although it would certainly be possible to specify a URL to the XML file instead. The XML file contains information about the number of sales
per day of week and has the following structure:
The Chart control's declarative markup defines a single series of type Column using the palette Earth Tones. The code in the
Page_Load event handler, shown below,
loads the XML document and then traverses through each
dayOfWeek element. For each
dayOfWeek element it grabs out the value from the element's
totalSales elements and then plots those as the X and Y values, respectively.
The following screen shot shows the chart when viewed through a browser.
Generating Chart Data Using Scott Allen's
All of the techniques for plotting chart data that we have looked at so far have required that we write code in the ASP.NET page's code-behind class or that we used declarative data binding techniques in the ASP.NET page's declarative portion. While such approaches are fine for prototyping and one-off projects, they are not the best choice when building real-world projects where readability and maintainability is important. Ideally, the logic for formatting and plotting the chart's data should be handled by a specific class for which this task is its sole responsibility.
In his MSDN Magazine article, Charting With ASP.NET
And LINQ, author K. Scott Allen presents a class named
ChartBuilder that can be used as a base
class for building such chart construction-specific classes and for moving the chart formatting and plotting-specific code out of your ASP.NET pages. I've included the
Visual Basic version of this class in the download available at the end of this article, but I encourage you to
download the complete
ChartBuilder class code, which
is available in both C# and Visual Basic and includes a number of demos.
In a nutshell, you use the
ChartBuilder class by creating your own class that extends
ChartBuilder class has a
constructor where you pass in the Chart Web control and the number of series. There's a
that, when called, adds a chart area to the Chart, a title, a legend (if there are more than one series), and then each of the series. At each step a "customize" method is
called which you can override to customize the formatting of the chart area, title, legend, or series, as well as specify the data added to the series.
Once you have your custom class created you use it from an ASP.NET page like so: first, add a Chart control to the declarative markup. You don't need to specify the chart areas,
series, or other formatting information as this should be handled by your class. Next, in the ASP.NET page's code-behind class you create an instance of your class, set any
properties needed, and then call the
The download at the end of this article includes a demo that uses the
ChartBuilder class. Specifically, I've created a class named
SalesByCategoryChartBuilder defines two public properties -
OrderYear. It overrides
CustomizeChartSeries method and in that override it customizes the formatting of the series, specifying that the series is a line
graph with a border width of 5 and no palette. It then connects to the Northwind database and calls the
stored procedure, passing in its
OrderYear property values as inputs to the stored procedure. This stored procedure then computes
and returns the gross number of sales for each product in the specified category. This information is added to the series one point at a time via the
SalesByCategoryChartBuilder class also overrides the
CustomizeChartTitle method and provides a custom title based on the values of the
OrderYear properties, displaying a title like: "Sales For CategoryName In OrderYear."
In addition to a Chart control, the ASP.NET page also includes drop-down lists that allow the user to pick a category and order year. After making these selections and clicking
a Button, there is a postback and the Button's
Click event handler executes. In the
Click event handler an instance of the
SalesByCategoryChartBuilder class is created, its
OrderYear properties are assigned to the values selected by the
user, and the
BuildChart method is called.
The following screen shot shows the gross sales for products in the Seafood category for 1998.
ChartBuilderClass (available in C# and VB)