欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

ASP.NET中实时图表的实现方法分享

程序员文章站 2024-02-29 16:31:28
 在对大批量的数据进行分析比较时,最常用也是最直观明了的表现方法莫过于绘制趋势图表。一般情况下,我们利用excel制作各种类型的趋势图表,但它们都是基于静态数据的...

 在对大批量的数据进行分析比较时,最常用也是最直观明了的表现方法莫过于绘制趋势图表。一般情况下,我们利用excel制作各种类型的趋势图表,但它们都是基于静态数据的,即数据是事先整理好的而不 是动态生成的。如果在网上发布,只能将绘制好的图表以静态gif图像发布,这无法从根本上满足不同用户对不同数据的需求。
asp擅长服务器端的web编程,操作后台数据库更是它的强项。但是用asp制作实时数据库图表有点困难,因为asp本身并不支持图表功能,只能借助第三方控件进行开发,如vb的mschart控件。微软推出的.net framework较好地解决了这个问题。微软在.net平台上集成了实时数据库图表制作组件—owc(microsoft office web components)。通过在asp.net页面中调用owc,我们可以轻松地绘制出各种类型的实时图表。owc支持近50种图表类型,包括曲线图、折线图、柱状图、面积图、k线图等。与mschart相比,owc功能强大,操作简单。此外,由于owc是基于服务端的,而mschart只能应用在客户端,因此在服务器端的web开发中,mschart要比owc逊色不少。

下面笔者将结合实例来具体阐述owc在asp.net页面中的应用,这个实例是笔者开发的项目《化纤产品及其原料市场分析系统》中的一个子系统,笔者在该项目中用到owc,充分享受到了owc的强大功能给开发工作带来的方便。

三层结构

系统整体架构采用了b/s三层结构模式,将系统分为用户界面层(也称为表现层)、业务逻辑层(也称为功能层)和数据库服务层(也称为数据层),开发平台则采用了.net framework,有效地降低了系统对客户机的要求,避免了在客户机上分发应用程序与版本控制的困难。

● 用户界面层: 用户界面采用的是asp.net技术。asp.net技术的应用增强了系统的通用性,客户端只需安装ie或netscape等任一款浏览器,无需加载任何组件。

● 业务逻辑层: 采用了.net framework调用owc的技术,能够根据用户的要求快速取得数据库中的数据动态生成图表。系统能够支持复杂的检索条件,检索速度快,响应时间短。

● 数据库服务层:数据库服务层可采用任何一款关系型数据库。在本项目中,笔者使用的是sql server,它能与.net framework无缝集成。数据库存取技术则采用了ado.net。

下文我们将着重介绍业务逻辑层的实现方法。

图表元素简介

一张完整的图表由若干个元素组成,我们必须对它们有所了解,才能随心所欲、充分自如地对图表进行全方位的控制,也才能更好地理解本程序。笔者制作了一张简易的图表,在图中标注了程序涉及到的主要部位和元素的名称,借此帮助读者掌握owc以及理解本文所引用的代码。
ASP.NET中实时图表的实现方法分享

使用owc组件

在这一节里所涉及的源代码摘自于《化纤产品及其原料市场分析系统》,该系统在window 2000/xp简体中文专业版、.net framewrok 1 .0环境下通过。使用owc组件的步骤如下:

1. 在当前目录中新建一个存放图表文件的子目录chart,同时把对该目录的“修改”权限赋予asp.net账户。具体步骤如下:用鼠标右键单击chart目录名,选择“属性”菜单项,在弹出的“chart”属性对话框中单击“安全”选项卡,再单击“添加”按钮,找到asp.net账户,赋予“修改”权限,单击“确定”按钮结束。这样,asp.net就可以在chart目录中写入图表文件了。

2. 定义一个服务器端的image图像控件,该图像的属性imageurl将在程序末尾被指向动态生成的图表文件,因此在这里无需为它赋值。

复制代码 代码如下:

< asp:image id=“imgchart” width=“500” height=“300” visible=“false” runat=“server”>< /asp:image>

3. 添加owc引用。

在使用owc之前,首先必须将owc的引用加入到“解决方案资源管理器”中。具体步骤如下:打开“解决方案资源管理器”面板,鼠标右键单击“引用”,选择“添加引用”菜单,在弹出的“添加引用”对话框中单击“com”卡片,找到“microsoft office web components 9.0”,单击“选择”和“确定”按钮,owc就被添加到了引用中。

4. 定义owc空间,并在该空间中加入一个owc图表owcchart。

复制代码 代码如下:

dim owcchartspace as owc.chartspace = new owc.chartspace()

dim owcchart as owc.wcchart = owcchartspace.charts.add

5. 用sql检索条件进行数据库检索,并将检索结果以recordset数据集的方式赋给owcchart。

owc只支持recordset数据集,不支持dataset数据集,因此在检索时不能使用sqlcommand、sqldataadapter等对象,只能使用recordset对象进行检索。

复制代码 代码如下:

'打开connection连接

connado.open(connectionstring)

recordsetado.activeconnection = connado

'设置游标为静态游标

recordsetado.cursortype = adodb.cursortypeenum.adopenstatic

recordsetado.cursorlocation = adodb.cursorlocationenum.aduseclient

'变量strsql中存放了标准sql检索条件

recordsetado.open(strsql)

然后将recordset数据集赋给owc对象:

复制代码 代码如下:

owcchartspace.datasource = recordsetado

在本例中,我们假定用sql语句检索出的数据共有三个字段:产品、日期和价格。这三个字段的值分别与图表中的曲线、分类(x)轴和数值(y)轴的数据一一对应。

6. 确定曲线类型,并确定区别不同曲线的字段名。

首先确定曲线类型为平滑曲线。

复制代码 代码如下:

owcchart.type = owc.chartcharttypeenum.chcharttypesmoothline

owc支持在同一张图表中显示两条以上的曲线。因此我们必须给出区别不同曲线的依据,这个依据就是“产品”字段的取值。具体地说,“产品”字段中有几个不同的取值,就会生成几条不同的曲线。

复制代码 代码如下:

owcchart.setdata(owc.chartdimensionsenum.chdimseriesnames, 0, “产品”)

7. 确定分类(x)轴标签与数值(y)轴标签所对应的字段。

首先需要定义owcseries为owc的曲线集合,然后遍历图表中的每一条曲线,将“日期”字段的值赋给分类(x)轴作为x轴刻度标签,将“价格”字段的值赋给数值(y)轴作为y轴刻度标签。如果我们能够确定图表中只有一条曲线,也可以省略遍历的过程,但这样无疑会降低程序的通用性。

复制代码 代码如下:

dim owcseries as owc.wcseries

for each owcseries in owcchart.seriescollection

owcseries.setdata(owc.chartdimensionsenum.chdimcategories, 0, “日期”)

owcseries.setdata(owc.chartdimensionsenum.chdimvalues, 0, “价格”)

next

8. 对坐标轴的属性进行设置。

这部分代码通过对坐标轴标题的文字内容、颜色、大小、主要和次要刻度线及其标签、主要和次要网络线等方面的设置美化图表。读者如果对本段代码中的概念有些模糊,可以参考前一部分提供的那张图表。具体设置方法请参见以下代码。

复制代码 代码如下:

'先定义axis为坐标轴集合

dim axis as owc.wcaxis

'遍历坐标轴集合

for each axis in owcchart.axes

'显示轴标题

axis.hastitle = true

'先对分类(x)轴进行设置

if axis.type=owc.chartaxistypeenum.

chcategoryaxis then

axis.hasticklabels = true

'显示x轴刻度标签

axis.position = owc.chartaxispositionenum.chaxispositionbottom

'标签的显示位置

axis.title.font.color =”blue”

'x轴的标题文字颜色

axis.title.font.size = “9”

'x轴的标题文字大小

axis.title.caption = “日期范围”

'x轴的标题文字内容

else

'对数值(y)轴进行设置

axis.majorgridlines.line.color = “silver”

'y轴主要网络线的颜色

axis.majortickmarks = owc.charttickmarkenum.chtickmarknone

'不显示y轴主要刻度标记

axis.hasticklabels = true

'显示y轴刻度标签

axis.title.font.color = “blue”

'y轴的标题文字颜色

axis.title.font.size = “9”

'y轴的标题文字大小

axis.title.caption=“价格(千元/吨)”

'y轴的标题文字内容

end if

next

9. 以gif图像格式输出图表,并将图像文件名赋给image控件。

复制代码 代码如下:

'用随机数来生成随机文件名

randomize()

dim nfilenamesuffix as integer

dim sfilenamesuffix as string

nfilenamesuffix = 100000 * rnd()

sfilenamesuffix = system.convert.tostring(nfilenamesuffix)

'以gif格式输出图表,大小为500*300,图表的文件名为:polyesterprice_随机数.gif,存放在chart子目录中

owcchartspace.exportpicture(mappath(“chart/polyesterprice_”) + sfilenamesuffix + “.gif”, “gif”, 500, 300)

'将image控件的url指向该图表文件

imgchart.imageurl=“chart/polyesterprice_” + sfilenamesuffix + “.gif”

通过以上九个步骤,我们就完成了一个实时数据库图表的生成与显示。在此需要指出的是,以上的九个步骤只是生成一张图表必不可少的基本过程,通过设置owc的其他属性可以更好、更精确地控制图表的生成与显示方式,如图例、线条的粗细与颜色、坐标轴刻度线及标签的显示频度、网络线等。这部分笔者不再介绍,请参见本文第四部分的源代码。

本文代码生成的图表效果请见下图。

ASP.NET中实时图表的实现方法分享

优化

上文中所有实时生成的图表文件都存放在chart文件夹中,由于采用了随机文件名的方式,因此这些文件不会互相覆盖。但是如此日积月累,越来越多的文件不仅占用了硬盘空 间,也妨碍了管理,降低了性能。我们能不能在程序中自动删除以前的图表文件呢?答案是肯定的。我们只要在代码文件的page_load()函数中放置如下一段代码,程序运行的时候,就会自动删除当日以前的文件。这样,chart文件夹中存放的就总是当日生成的图表文件,从而有效地避免了文件垃圾。

复制代码 代码如下:

'先取得chart文件夹中的文件列表

dim fileentries() as string = system.io.directory.getfiles(mappath(“chart”))

dim sfile as string

'遍历文件列表

for each sfile in fileentries

'将文件的生成日期与系统日期相比,如果是当日以前生成的文件,删除它

if datetime.compare(system.io.file.getcreationtime(sfile).adddays(1), datetime.now) < 0 then

system.io.file.delete(sfile)

end if

next

虽然用owc生成的图表功能齐全,界面美观,但它也存在着不少的缺陷。首先,owc不支持dataset数据集,这样我们就无法在生成图表的同时使用datagrid显示数据表,除非我们用循环依次取出recordset记录集中的全部数据手工生成表格,或用同样的检索条件对数据库进行二次检索,但这无疑要增加服务器的负担。其次,在同一张图表中绘制的曲线只能是同一种类型,或同为平滑曲线图,或同为柱状图,它不能在同一张图表中显示不同类型的曲线。最后,在某些细节方面,如分类(x)轴的设置方面,owc无法提供更加详细、人性化的设置途径。如果读者要追求更强大的功能和更好的显示效果,笔者向您推荐两个专业的基于.net的图表控件,这两个控件分别由dundas和softwarefx公司出品,都同时支持web form和win form开发,只是这两个控件都是付费的。读者如果有兴趣,可以到它们的网站去下载demo版本,以亲身体验一下专业图表控件带来的强大功能。