• home
  • forum
  • my
  • kt
  • download
  • Making Charts in ASP

    Author: 2007-07-02 11:38:31 From:

    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.

    discuss this topic to forum

    relation tutorial

    No relevant information

    New

    Hot