Using Microsoft's Chart Controls In An ASP.NET Application: Serializing Chart Data
By Scott Mitchell
Introduction
In most usage scenarios, the data displayed in a Microsoft Chart control comes from some dynamic source, such as from a database query. The appearance of the chart can be modified dynamically, as well; past installments in this article series showed how to programmatically customize the axes, labels, and other appearance-related settings. However, it is possible to statically define the chart's data and appearance strictly through the control's declarative markup. One of the demos examined in the Getting Started article rendered a column chart with seven columns whose labels and values were defined statically in the
<asp:Series>
tag's <Points>
collection.
Given this functionality, it should come as no surprise that the Microsoft Chart Controls also support serialization. Serialization is the process of persisting the state of a control or an object to some other medium, such as to disk. Deserialization is the inverse process, and involves taking the persisted data and recreating the control or object. With just a few lines of code you can persist the appearance settings, the data, or both to a file on disk or to any stream. Likewise, it takes just a few lines of codes to reconstitute a chart from the persisted information.
This article shows how to use the Microsoft Chart Control's serialization functionality by examining a demo application that allows users to create custom charts, specifying the data to plot and some appearance-related settings. The user can then save a "snapshot" of this chart, which persists its appearance and data to a record in a database. From another page, users can view these saved chart snapshots. Read on to learn more!
An Overview of the Demo Application
Before we dig into how to serialize and deserialize chart data, let's take a moment to explore the demo application available for download at the end of this article. The demo includes a chart that plots the sales per month for a particular category of products from the Northwind database. The user viewing the chart must select the category and year for which to display the sales data, and can optionally choose a color palette. The screen shot below shows this page in action. Here the user has selected to view the sales for the products in the Condiments category for 1996, displayed in a SeaGreen palette.

Note that there's also a "Save Chart As Snapshot" button. If the user clicks this they are shown an interface where they can enter a name for the snapshot.

Entering a name and clicking the "Save Chart Snapshot" button serializes the chart's appearance settings and its data, storing the resulting serialized information to a
database table (ChartSnapshots
).
On another page users can select from the saved snapshots and view a chart. A drop-down list shows each saved snapshot. Selecting displays the snapshot title, the date the snapshot was taken, and the chart data. The screen shot below shows this page when the user has opted to load the "Condiments, 1996, SeaGreen" snapshot, which is the one we created and saved in the above screen shot.

Keep in mind that the serialized chart information in this demo includes both the appearance-related settings (the palette selection, the chart's height and width, and so forth) and chart data, meaning that if a user views the snapshot at a later point in time they will be seeing the data from when the snapshot was generated. In other words, if the user creates a snapshot on February 1st, 2010 that shows the year to date sales for 2010 and then views that snapshot again on February 15th, it's vital to realize that the data will show the year to date sales as of February 1st, when the snapshot was taken, and not as of the date when the snapshot is viewed. If the charts are being populated with historical data then this is of no concern, but such a snapshot feature would not be useful when viewing charts whose data is still being updated.
Serializing Chart Information
Serializing a chart's data and/or appearance settings is easy and can be accomplished in just a few lines of code. The actual serialization logic is handled by the
ChartSerializer
class, which is accessible from the Chart control via the Serializer
property. To serialize a chart, do the following:
- Indicate whether you want to serialize the chart data, the appearance properties, or both by setting the
Serializer
'sContent
property to one of the following values:Setting Description Appearance
Serializes all non-default appearance-related properties, such as line color, chart height, etc. Data
Serializes all data values in the chart; does not serialize appearance-related properties. Default
Serializes all non-default chart content, including the chart data and the appearance-related properties. All
Serializes all chart content, including the chart data and the appearance-related properties. - Call the Serializer property's Save method, passing in either: a file name (if you want to serialize to disk); a stream; or an
XmlWriter
orTextWriter
object.
serializedChartContent
:
'Need to rebind the data to the chart so that the Series Points collection is populated (otherwise the data won't be serialized)
|
The above code starts by rebinding the data to the Chart control. By default, the chart data is not persisted in view state and must be rebound on each page load.
If you bind the chart to a data source control, as this example does, then this happens automatically during the page lifecycle, but that automatic binding occurs later
in the page lifecycle than the Button's Click
event handler, which is where the above code lives. Consequently, if we do not explicitly rebind the data to the
chart then the serialized output will not contain any of the chart's data points (since they haven't been added to the chart yet).
Next, a StringWriter
object is created (writer
). This object will be used to hold the serialized content. The Serializer
's Content
property is then
set to Default
, indicating that we want to serialize all data points and non-default appearance-related settings. The actual serialization occurs on the next line,
when we call the Serializer
object's Save
method, passing in the StringWriter
. Finally, the contents written to the StringWriter
are dumped out to a string, serializedChartContent
, and the StringWriter
is closed.
After the above code runs, the contents of serializedChartContent
along with the snapshot title entered by the user are added to a new record in the
ChartSamples
table.
If you look at the serialized data in the database table you'll see that the Chart control serializes its appearance-related settings and data points using XML that's nearly
identical to the Chart control's declarative syntax. Here's a snippet. You can see the full XML by examining the contents in the ChartSamples
table. (They are also
displayed in a TextBox at the bottom of the ViewChartSnapshots.aspx
page.)
<?xml version="1.0" encoding="utf-16"?>
|
Deserializing The Persisted Chart Information
Now that we have the a chart snapshot saved in the database all that remains is to allow the user to view one of these snapshots. The Microsoft Chart Controls make deserialization just as easy as serialization:
- Add a Chart control to the page
- Indicate what data to deserialize by setting the Chart control's
Serializer
object'sContent
property accordingly. - Call the
Serializer
object'sLoad
method, passing in the serialized information either as: a file name (if the chart was serialized to disk); as a stream; or as anXmlReader
orTextReader
object.
ViewChartSnapshots.aspx
page in the demo performs this deserialization logic. The page contains a Chart control named chtViewer
. Note that it
does not have any properties set - these properties (and its data) will be set for us during the deserialization process.
<asp:Chart ID="chtViewer" runat="server" />
|
The page also includes a DropDownList control that's populated with the records in the ChartSnapshots
table. Selecting an option from the list causes a postback.
On postback the code connects to the database, gets back the snapshot's title, date created, and serialized information, and then runs the following code:
'Display the snapshot in the Chart control
|
Here, the variables SnapshotTitle
, SnapshotDate
, and SnapshotData
hold the values returned from the database. A StringReader
object
is created to read the contents of the chart's persisted information (SnapshotData
). The Chart control's Serializer
object has its Content
configured to deserialize the data and non-default appearance-related properties, while the Load
method does the actual deserialization logic, reconstituting the
chart based on the contents of SnapshotData
.
And that's all there is to it. With the above code, a user
Conclusion
The Microsoft Chart Controls make it amazingly simple to serialize and deserialize chart data. This state can be persisted to disk, to any stream, or to a string. The demo available for download at the end of this article shows how to persist this information to a database, but it could have been saved to disk or cached in memory. Keep in mind that if you serialize chart data to a persistent store then when re-hydrating that data users will be seeing chart data as of the date it was serialized. This is a non-issue when charting historical data, but should not be used when charting data that is still being updated.
The Chart control's serialization capabilities can be used for shorter-term serialization. For example, if you have a Chart control that gets its data from a slow data source, you could cache the chart data in view state or for a short duration in the .NET data cache. The Samples Environment for Microsoft Chart Controls includes a demo that stores the serialized content in view state so that the chart can be reconstructed on postbacks without having to re-query its underlying data store.
Happy Programming!
Attachments: