ASP.NET Charting with NPlotBy Olav Lerflaten
Three years ago I wrote an article here on 4Guys titled ASP.NET Charting Using Office Web Components (OWC) that examined how to use OWC as a charting engine in ASP.NET applications. OWC is still a very powerful charting engine, but unfortunately it carries with it some serious drawbacks:
- OWC is a COM library, which needs to be installed on the ASP.NET web server. If you do not run your own web server, you may have difficulty getting these libraries installed.
- Calling COM libraries from .NET code introduces additional difficulty and overhead that can be avoided by using native .NET DLL's.
In contrast to COM components, a .NET library is simply a DLL file that needs only to be distributed with the web application in its
/Bindirectory. There is no need for a separate installation on the web server.
- Microsoft's support for OWC has dwindled. Earlier versions of OWC came bundled with Microsoft Office, but this has been discontinued in Office 2007. OWC11, which came bundled with Office 2003, seems to be the final version. There are no signs of a similar .NET library being developed by Microsoft.
Choosing a .NET Charting Engine
When deciding on a charting engine it is important to compare and contrast a number of metrics, such as price, features, support, documentation, and ease of use. As a frugal developer, I strongly prefer freeware options over commercial ones. There are lots of different chart types, and few charting libraries support them all. In particular, there is a distinct difference between business charting - pie and bar charts - and scientific charting - XY or scatter charts. Business-orientated charting libraries usually do a poor job with scientific charting, and vice versa. My primary interest is in scientific charting; more specific, in charting of time series. A time series is a sequence of data points over a time interval. One example is weather data, where you measure the air temperature every minute (or every hour, if you are satisfied with lower resolution). The collection of air temperature data is then known as a time series.
When charting time series, we usually use a XY chart with the X axis as the time axis, and the Y axis as the value axis. The following chart illustrates a time series and shows real weather data. Here, two time series (air pressure and wind speed) are shown within the same chart. This is useful for visual data correlation (sharply falling air pressure usually means increased wind speed). As wind speed and air pressure have different units of measurement, and differ widely in their absolute values of measurement, separate Y axes are used to place the curves close to each other.
A good listing of available charting controls (both freeware and commercial) can be found at Microsoft's official ASP.NET website under the Control Gallery's Charting Controls section. I have personally tested two freeware charting controls:
- WebChart, by Carlos Aguilar. For an overview of WebCharts, see A Look at WebCharts, a Free .NET Charting Control.
- NPlot, an open source charting library for .NET.
NPlot scared me away initially because of an almost total lack of documentation and coding examples. However, the few available screenshots
looked promising, so I decided to do some research work. This resulted in a number of coding examples using NPlot version 0.9.10.0.
These examples are available for download at the end of this article; I believe they may be very useful as a template for other developers.
After working through NPlot's quirks, I am happy to say that it is a very good charting engine, which (almost) completely covers my needs. The
design focus seems to be scientific charting, although basic business charts (bar charts, line charts, stock charts) seem to be present (although
I have not tested business charting extensively).
The NPlot library (
NPlot.dll) can be downloaded from the NPlot home page. There are different DLLs for the .NET
versions 1.1 and 2.0.
NPlot's Programming Philosophy
When generating a chart using NPlot or any other charting engine, the actual chart must be rendered as a temporary image file on the web server. To view this page from a web browser you must use an
<img>tag (or an Image Web control) that specifies the URL of this temporary image file. While a chart can be rendered in any image format, I prefer GIF images for charting purposes, as high-contrast images (e.g., black lines on white backgrounds) cause compression artifacts on JPG files.
There are two ways to work with temporary image files on a web server:
- Save the temporary image as a file in a directory on the web server, and then provide an image link to this file on the web page. This concept is easy to understand, but a bit difficult in practice. The ASP.NET user id on the web server needs write permissions on the directory, you need to create unique file names, and you need logic to erase the temporary files after use, or the directory will soon fill up with old chart images.
- Alternatively, you can create the temporary image in the web server's memory, and then "stream" the image to the web page as a Memory
Stream. This requires a separate ASP.NET page whose purpose is to generate the chart (in memory) and then send the chart image's binary
contents down to the web browser. To display this chart in a web page, simply use an
<img>element or Image Web control that points to this chart-generating ASP.NET page, like so:
<img src="Demo1.aspx" />. Any parameters that need to be supplied can be passed from the main page to the image page using the query string or session variables.
An NPlot Coding Example
While evaluating NPlot I wrote a number of VB.NET demos illustrating how to use NPlot to generate time series. Many of these demos are available for download at the end of this article. Let's examine the first of these demos. Keep in mind that these demos illustrate creating an ASP.NET page whose express purpose is to generate a temporary chart image file in memory and to return this binary data to the client. Therefore, these demos do not contain any markup in the
.aspxportion contains just a reference to the code-behind file and, optionally, an
@OutputCachedirective to improve performance.
@OutputCache directive specifies the cache lifetime (5 seconds in this example). If the database contains frequently updated
info (such as weather data or stock prices), you need to set the cache lifetime low in order to get an updated chart each time this image is viewed.
If the underlying data is updated less frequently, you can increase the cache's duration in order to improve performance. For more information
on output caching, see Caching with ASP.NET and
Output Caching in ASP.NET 2.0.
The code-behind file (
Demo1.aspx.vb) contains the code that generates the image file and streams it to the visitor's browser.
It's where all of the action takes place!
As you can see, the code-behind class requires a good deal of code. The code, though, is fairly straightforward as it simply generates the underlying data, specifies the plot surface settings, creates the series, plots the points of the series, and streams the binary contents of the chart image file to the browser. The NPlot data model is based on a "Plot Surface", analogous to a blank sheet of paper. To this surface, you can add one or more plots (collections of X and Y values). Each plot can be bound to the left or right Y axis, and the bottom or top X axis. Usually, only one X and Y axis are used; but if you wish to fit two time series with widely different amplitudes and/or different time intervals within the same chart, two independent X and Y axes are useful.
DataSource property of each plot is the collection of Y values, while the
AbscissaData property is the
collection of X values. If the
AbscissaData property is not specified, the X values are assumed to be 0, 1, 2, 3...; and you get
in effect a business type charting, where the X axis is a categorization rather than a measured value.
The most unfamiliar part of the code for most developers is probably the
MemoryStream concept (used in the last few lines of the code).
As explained earlier, this is done to avoid saving temporary image files on the web server. The entire
Demo1.aspx page, in effect,
is transformed into an image, which can be referenced by other web pages using the
<img> HTML tag or via the ASP.NET Image Web
To run this code, download the ZIP file at the end of this article. The ZIP file includes a Visual Studio 2003 project, but you can open
it in Visual Studio 2005. If you are using Visual Studio 2002, simply create a new project then manually copy over the files from the download
into your project. In addition to the above demo, the ZIP file includes three other demos and the NPlot assembly in its
directory. The screenshot below shows the output of
Demo1.aspx when viewed through a browser.
The time series are generated from a random seed, so they will change each time the page is visited. Therefore, the chart on your screen might not look exactly like the one above.
Chart Types in NPlot
The Demo1 example uses the
LinePlotchart type. This is a familiar chart type, with straight lines drawn between each data point. However, for scientific charting, two other chart types might also be considered:
StepPlot: Each measurement is assumed to be stable until the next measurement, that is, we do not assume interpolated values between each measurement. Graphically, this is shown as horizontal "steps" between each measurement. One example where this might be useful is if each new measurement reflects a mean value since the last measurement.
PointPlot: Each measurement is represented by a dot symbol rather than as a line between two points.
PointPlotdata models are almost identical to the
LinePlotdata model. For charts like Demo1, where the data points are close together, the
PointPlottypes are less useful. But for less populated charts they should be considered as an alternative. The following chart illustrates these three separate chart types.
If you are looking for a free charting engine for your ASP.NET applications, NPlot might be what you are looking for. NPlot does not cover every conceivable chart type, but for scientific and simple business use, it is certainly worth considering. The documentation is extremely poor, but the coding examples in this article should get you started.
About the Author
Olav Lerflaten is an IT professional living in Trondheim, Norway. He specializes in industrial data processing.