ASP 101 - Active Server Pages 101 - Web01
The Place ASP Developers Go!

Please visit our partners


Windows Technology Windows Technology
15 Seconds
4GuysFromRolla.com
ASP 101
ASP Wire
VB Forums
VB Wire
WinDrivers.com
internet.commerce internet.commerce
Partners & Affiliates














ASP 101 is an
internet.com site
ASP 101 is an internet.com site
IT
Developer
Internet News
Small Business
Personal Technology

Search internet.com
Advertise
Corporate Info
Newsletters
Tech Jobs
E-mail Offers

ASP 101 News Flash ASP 101 News Flash



 Top ASP 101 Stories Top ASP 101 Stories
The Top 10 ASP Links @ Microsoft.com
What is Adovbs.inc and Why Do I Need It?
An Overview of ASP.NET

QUICK TIP:
Keep Track of Multiple Current Records
Show All Tips >>
ASP 101 RSS Feed ASP 101 Updates


Making Charts in ASP

Making Charts in ASP

by Chris Payne

Introduction

Charts are very useful for internet applications. Imagine an online stock brokerage, or perhaps you have a scientific site that tracks population patterns. You can use charts virtually anywhere. The problem is that most people believe to create a chart, you must use a separate program and create a GIF or JPG to insert into your web page, not to mention the fact that there are not many resources out there to show you how. Here, we'll show you how to do it dynamically and through ASP, so no more chart GIFs!

This article will assume you have basic knowledge of chart types and terminology.

How Do I Make a Dynamic Chart?

We're going to discuss a couple different methods to do so, and you'll get to choose depending on the type of your application and the resources you have available to you. We'll show you the basics, and discuss a bit on the usage patterns of each. Without further ado, let's get on with it!

Array Building

There is an excellent example of this technique here, so we won't go into much depth. The basic technique works as follows: you supply arrays of the numbers you wish to graph, and graph properties (such as axis labels, etc) to a function which uses a single image that is resized to the proper height depending on the value to graph.

It's difficult to understand fully without seeing the code, so go here to check it out, and follow along in this tutorial. The function first sets up some variables such as graph (which is actually only a table) height and width. Then, using the array of values passed to it, we determine the number of columns and width of each. In the actual HTML body, then, we use for loops to simply loop through the array of values and assign the proper height and width values for each image. In this example, they use a simple 1x1 red pixel that can be resized to any height. And voila, you have a dynamic chart!

This is a very simple example, but also very clever. This technique requires no outside resources (other than a knowledge of simple ASP), is easy to set up, and can be implemented anywhere. However, it may take some finagling to properly set the charts up in your existing application.

Office Web Components (OWC)

Oftentimes, however, the above solution may not be flexible enough. You may require more detailed charts with legends and different axes, as well as some analytical capability, or perhaps you simply want a prettier chart. The Office Web Components provide a great set of tools for data displays, including spreadsheet, pivot table, and chart components. We'll use the chart component here to dynamically generate charts without having to create a ridiculous number of GIFs.

NOTE: The Office Web Components are only available with a valid Office 2000 license, so your server must have some part of Office 2000 installed for these examples to work.

Normally, the OWC Chart component requires you to create a GIF image to display in your web page. However, we can get around this limitation by streaming binary image data to the web page. The binary data then does not have to be stored anywhere (except in local memory) and there is no erroneous images lying around anywhere.

Let's take a look at some code:

chart.asp
<%
Option Explicit
Response.ContentType = "image/gif"
%>

Since we're going to be displaying an image (even though the actual image is not stored anywhere), we need to instruct the browser to display the following as a GIF image.

NOTE: Option Explicit requires that we declare all variables before their use. This declaration helps speed up performance, as well as aid developers in creating better and stronger code.

Now let's assume we're taking the data to be displayed from a database.

<%
'declare our variables
Dim strSQL, rst, strConnectionString
Dim objConstants, objFont, objChart, objCSpace, objAxis
Dim objBinaryFile, FSO
'the connection string
strConnectionString = "provider=microsoft.jet.oledb.4.0;" _
     & "data source=" & Server.MapPath(".") & "\data.mdb"
'create the recordset object
set rst = Server.CreateObject("ADODB.Recordset")
%>

The connection string tells ADO that we're going to use an Access database called data.mdb located in the same directory as this ASP. (Note that you can create a DSN (Data Source Name) and use it here instead, so that you don't need to store the database in the same directory as the ASP). Then we simply create the recordset object. Next, let's grab some data.

<%
'the SQL query
strSQL = "SELECT Price, ProductName, NumberSold " _
     & "FROM tblProducts " _
     & "WHERE Price BETWEEN 5 AND 10 " _
     & "GROUP BY ProductName, Price"
'get the data with a client side cursor, and static dataset
rst.open strSQL, strConnectionString, 3, 3
'Now create the chart object
set objCSpace = Server.CreateObject("OWC.Chart")
%>

Our SQL statement returns three items - Price, ProductName, and NumberSold. By grouping by ProductName and Price, we will be able to chart the number sold of each product at each price. In essence, NumberSold will be the data points, while Price and ProductName will the categories.

With the last line, we actually created a chart space. We must then add individual charts to this space using the data we retrieved.

<%
'set up chart and properties
set objChart = objCSpace.Charts.Add()
set objConstants = objCSpace.Constants
'create a clustered column chart
objChart.Type = objConstants.chChartTypeColumnClustered
'add a legend
objChart.HasLegend = True
%>

Note that we retrieve the chart space's constants collection so that it is easier to specify our chart properties later. It would be easy to simply use the numerical values as well, but this example is designed to show the full use of the OWC components.

Next, we'll tell the chart component where to get the data, and how to use it. The following code should be self explanatory - we simply set up the chart as we described above, and set some additional properties.

<%
'set the data source to the recordset
set objCSpace.DataSource = rst
'set the data points and categories
objChart.SetData objConstants.chDimSeriesNames, 0, "ProductName"
objChart.SetData objConstants.chDimCategories, 0, "Price"
objChart.SetData objConstants.chDimValues, 0, "NumberSold"
'set up some additional properties
'add and format the chart title
objChart.HasTitle = True
objChart.Title.Caption = "Sales by Products"
set objFont = objChart.Title.Font
objFont.Name = "Tahoma"
objFont.Size = 10
objFont.Bold = True
'add and format a title to the category axis
set objAxis = objChart.Axes(objConstants.chAxisPositionBottom)
objAxis.HasTitle = True
objAxis.Title.Caption = "Price"
set objFont = objAxis.Title.Font
objFont.Name = "Tahoma"
objFont.Size = 8
objFont.Bold = True
'add and format a title to the value axis
set objAxis = cht.Axes(objConstants.chAxisPositionLeft)
objAxis.NumberFormat = "Currency"
objAxis.HasTitle = True
objAxis.Title.Caption = "Dollars"
set objFont = objAxis.Title.Font
objFont.Name = "Tahoma"
objFont.Size = 8
objFont.Bold = True
%>

The Categories and SeriesNames properties correspond to the x and y axis respectively.

Now for the interesting part. We will create the GIF image using the ExportPicture method of the Chart control, then stream and delete the binary data. To handle binary data, we will use the traditional file IO methods from VB in a COM object. First, let's look at the ASP code.

<%
'Save the current chart to a GIF file with a temporary
'filename using the FSO
set fso = Server.CreateObject("Scripting.FileSystemObject")
strFileName = Server.MapPath(".") & "\" & fso.GetTempName()
objCSpace.ExportPicture strFileName, "gif", 800, 400
'Use On Error Resume Next to make sure we eventually delete
'the temporary GIF file even if something fails in the next
'couple of functions
on error resume next
'The GIF file has been created. Return the contents of the
'GIF file as binary data using the BinaryFileStream COM object
set objBinaryFile = Server.CreateObject("BinaryFileStream.Object")
Response.BinaryWrite objBinaryFile.GetFileBytes(CStr(strFileName))
'Delete the GIF file since it is no longer needed
objBinaryFile.DeleteFile CStr(sFullFileName)
'clear variables
set objBinaryFile = nothing
set FSO = nothing
set objCSpace = nothing
%>

The first bit of code is easy to understand - we simply grab the current directory using the File System Object (see here for a tutorial), and export the chart as a GIF image. Next we spit out the binary file information using the COM object's GetFileBytes method, which will be described below. Finally, since the GIF is not needed anymore, we delete it using the COM object, and then clear any variables we have left over.

We're not going to go in depth with the COM object's innards, but here is the code that you can compile in Visual Basic as an ActiveX DLL. Once you compile the code below, it may be necessary to register the DLL on your server, assuming your development environment is not your server (VB automatically registers DLL on your computer once you compile them).

BinaryFileStream.vbp
Object.Cls
Option Explicit
Public Function GetFileBytes(FullFilePath As String) As Variant
  Dim ctBytes As Long
  Dim bytes() As Byte
  Dim fno As Long
  On Error GoTo errReadAll
  fno = FreeFile()
  Open FullFilePath For Binary Access Read As fno
  ctBytes = LOF(fno)
  ReDim bytes(ctBytes)
  Get fno, , bytes
  Close fno
  GetFileBytes = bytes
  Exit Function
errReadAll:
  Err.Raise vbObjectError + 1, "GetFileBytes", Err.Description
  GetFileBytes = Array(0)
  Exit Function
End Function 'GetFileBytes()
Public Function DeleteFile(FullFilePath As String) As Boolean
  DeleteFile = False
  On Error GoTo ErrDel
  Kill FullFilePath
  DeleteFile = True
  Exit Function
ErrDel:
  Exit Function
End Function 'DeleteFile()

Note that the preceding code was taken directly from MSDN.

And that's it. No stray GIFs lying around, and dynamic charts every time!

Conclusion

We've touched on a number of different technologies in this article, but our main focus was to show how to dynamically create charts for any type of data. With the two methods we described, you can cover nearly any type of chart needs you have.

References

Check out these links for further resources on Dynamic Charts in Web Pages:


Home |  News |  Samples |  Articles |  Lessons |  Resources |  Forum |  Links |  Search |  Feedback

Internet.com
The Network for Technology Professionals

Search:

About Internet.com

Legal Notices, Licensing, Permissions, Privacy Policy.
Advertise | Newsletters | E-mail Offers