使用 Office 2000 图表组件建立服务端图表

你们中的一些人可能已被要求写那些为不断变化的数据建立图表的ASP 页面。通常的解决方案是要买一个商业服务端图表生成组件。好,Office 2000中包含一个自身使用的图表组件 ,并且你不需要载服务器上安装整个 Office 或是 Excel  。 而且 ,作为一个动态链接库(DLL),你不必为了允许组件处理而改变元数据(译注: 描述数据的数据)。这篇文章将向你介绍如何编写ASP应用程序,它的功能是从XML文件接收股票行情 ,并将数据存储在数据库中而后建立用户自定义的图表。

安装图表组件 

  为了安装服务端组件,需要在服务器上运行Office2000安装程序并且选择安装Microsoft Office Web Componets。注意你的需要有一份Office2000的许可协议,哪怕不安装其它的应用(Word、Excel)。 

建立数据库

  我们要建立一个数据表来存放我们获得的股票行情 。建立一个  Access  的数据库叫做 quotes.mdb,包括一个叫做 quotes 的表。使用以下图示的表设计,或者使用本文提供的示 例。
 

取得并储存XML格式的股票行情

  股票行情数据来自一个XML文件,它包括在下载的示例中。我将用微软的XML格式来存储XML 文件,它允许直接载入数据到ADO记录。如果数据源存在几种不同的格式,我们将不得不翻译 XML 文件为此格式或是写一些语法解析代码来获得相关数据。我们用loadxml.asp页面来完成此功能: 

Dim Stock, Last
file = server.mappath("xmlquote.xml")
objrecordset.open "file://" & ' file open recordset
objrecordset.movefirst
while not objrecordset.eof
  Stock = objrecordset("stock")
  Last = replace(objrecordset("last"), ",", ".")
  data = date()
  Set objRecordSet1 = objDataCon.Execute("INSERT INTO quotes (Stock, Last) VALUES _
  ('" & stock & "', " & last & ") ", lRecordsFound)
  objrecordset.movenext
wend
objrecordset.close

  这个例子是从本地的文件系统来载入XML文件,但是更为现实的情况将是从一个Internet服务器中载入: 

objrecordset.open "http://www.webservername.com/stock/quotes/" & file

  一旦装载的记录集同其它的记录集是一样的。这段代码叠代所有的记录并在数据库中载入其值。Replace 函数在我的计算机上是必须使用的,因为我的区域设置中数字的分隔符是逗号不是点。如果XML源文件也使用点作为数字分隔符则你可不必使用它。

  在一个真实的环境中这个页面应该假如一个时间表,每隔一点时间调用来获取股票行情的采样。图表的精确程度受限于采样的间隔和其一致性。

  将XML文件直接保存为ADO记录集是ADO2.1的新功能并且在ADO2.5中得到了加强。如果你希望知道更多的ADO 和XML记录集的信息,请点击在相关链接中的参考。 

让用户来定义图表

  即时图表(Just-In-Time)将变得越来越吸引人,特别是用户能够定义图表的参数。这类选项是很多的,我为用户输入选择了三个参数: 

  • 日期间隔(起迄日期)
  • 图表的大小(宽、高)用象素表示 
  • 标股票(多重选择)

  更多的选包括图的类型(line,bars,etc),式样 (2D、3D)并且几乎是和Excel图表向导中的一样多。这些值在default.asp页面中被用户输入,并在下面的作图页面quotes.asp 中被显示。 

  日期范围是自动地根据可用股票行情的时间跨度进行调整的,并且股票列表是动态的从行情 数据库中生成的。 

生成图表

  我们一旦让用户做出选择,我们就能生成相应的图表。quotes.asp页面读取发送的参数并分三步生成图表: 

 建立对象并设置全局属性 

  图表对象支持多个图,其中每一个都是一个对象。在这个页面中我们仅仅需要一个。一些全 局属性属于绘制对象,但大多数用来设置图表本身。有很多的属性可以使用,下面仅是我选择的:

' Create a Chart Object
Set oChart = Server.CreateObject("OWC.Chart")
Set c = oChart.Constants 'object with charting constants

' Set the different parameters for the ChartSpace
oChart.Border.Color = c.chColorNone

' Add chart object and define its type (line)
Set Chart = oChart.Charts.Add
Chart.Type = oChart.Constants.chChartTypeLine
Chart.HasLegend = True
Chart.HasTitle = False
Chart.Legend.Position=oChart.Constants.chLegendPositionBottom

 载入数据值

  每一个图表都有几种数据值集合,表现为不同的线段。每一个股票是一个值集并且所有的值 集共享一个定义好的日期范围。这组值通过已经建立的数组载入。此数组从数据库中生成。 自然我们不知道将来的数组中会包含多少的元素,所以不得不建立动态数组,并根据从读数 据库中读取的数据改变大小: 

' Add a value set for the chart
Set Serie = Chart.SeriesCollection.Add
Serie.Caption = stock 'parameter, stock name
' Load x朼xis labels
Serie.SetData c.chDimCategories, c.chDataLiteral, Categories 
' Load values
Serie.SetData c.chDimValues, c.chDataLiteral, Vals

 保存图表为一个GIF文件

  一旦所有的数据被载入,图表已准备好生成。输出必须被加入到回应页面,为了这样做图表 要被保存为一个唯一名字的GIF文件。而回应页面应包括一个该图像的链接: 

' Get a temporary filename to save chart in that file
' The filesystem object is already open

sFname = FS.GetTempName & session.SessionID & ".gif"

' Export the chart to the temporary file (width and height from user parameters)
oChart.ExportPicture server.MapPath(sFname), "gif", cint(wchart), cint(hchart)

' Create a link to the generated file
Response.Write "
" ' Destroy objects set fs = nothing set oChart = nothing set Chart = nothing set Series = nothing set c = nothing

临时文件的删除

  你现在有了即时图表,但是但是也留下了很多的临时文件。每次用户建立一个图表 ,一个临时文件就会留在硬盘上,不再被使用。一种解决方案是建立另一个asp页面来删除这些文件,但是这要求一个调度机及时地激活此页面。

  我的方案是例用绘图页面自身。每次一个用户要求一张图时,页面首先删除超过一分钟的老文件。此函数如下:

Sub DeleteOldCharts()
' Delete temporary files older than one minute
on error resume next
Dim fileSystem, File, File1, FileColl, s
Dim cnt, globalcnt, fname
dim path, dir

   file = "charts.asp" 'Use the page own filename
   path = server.mappath(file)
   dir = left(path,len(path)杔en(file))

Set filesystem = server.CreateObject("Scripting.FileSystemObject")
Set file = filesystem.GetFolder(dir)
Set filecoll = file.Files    

cnt = 0: globalcnt = 0
For Each file1 in filecoll
   filedate = file1.datecreated
   globalcnt = globalcnt + 1
   if timevalue(filedate) < timevalue(dateadd("m",?,now())) then
      fname = file1.name
      if instr(ucase(fname), ".GIF") then
         filesystem.deletefile dir & fname, true
         cnt = cnt + 1
      end if
   end if
Next

Set filesystem = nothing
Set file = nothing
Set filecoll = nothing

End Sub

  一分钟的间隔足以避免删除正在使用中的文件,不过你也可以根据需要增加时间间隔。这个方案会将一些文件同时留在硬盘上,但有效的阻止了硬盘空间占用的无限增长,使其保持在一个可以接受的水平。

可能的改进

  这个示例应用只是一个起点。凡是了解Excel图表的人都知道,Office2000的图表组件是一个有着许多属性和方法的复杂对象,浏览它的文档资料是值得的。

  • 不要为每个X轴的值设置标签:如果采样值大于图表的大小,X轴将会不可读。解决办法是使用选定的值来设置标签,并使用固定的间隔。
  • 为多重选择的图表定义Y轴的范围:绘制图表的例子代码中设置Y轴的范围为一个股票图表使用的合适的间隔。如果你需要多个股票的图表则Y轴的范围要设置为从零到这组数据中的最大值。这样做看起来像是图表组件中的一个bug。此方案是直接在代码中设置Y轴的最小值和最大值。

示例程序

  包括在本篇文章中的例子,由以下的文件组成:

  • Default.asp 默认的页面,用户参数入口表单
  • Quotes.asp 图表生成页面
  • Fuctions.inc 共享的函数库,所有的ASP页面都调入此页
  • Loadxml.asp 载入XML格式的股票行情到数据库
  • Quotes.mdb Access2000数据库存放股票行情
  • Xmlquotes.asp 一个XML行情文件

  为了使用此例子,请在IIS的根目录下任何位置建立一个文件夹,并将所有文件复制到此目录。不需要任何调整或设置ODBC DSN。

概要

  我希望我能够展示如何利用MS Office 2000图表组件来轻松建立强大的绘制图表的应用程序。如果你拥有一份Office 2000 或是Excel的许可协议,那么它和其他可用的图表组件一样用途繁多。


翻译、制作:iven OICQ:1917460 
电子信箱:[email protected]

iCestuDio © 2000

 

你可能感兴趣的:(ASP)