ASP.NET中實(shí)時(shí)圖表的實(shí)現(xiàn)

2010-08-28 10:48:44來源:西部e網(wǎng)作者:

在對(duì)大批量的數(shù)據(jù)進(jìn)行分析比較時(shí),最常用也是最直觀明了的表現(xiàn)方法莫過于繪制趨勢(shì)圖表。一般情況下,我們利用EXCEL制作各種類型的趨勢(shì)圖表,但它們都是基于靜態(tài)數(shù)據(jù)的,即數(shù)據(jù)是事先整理好的而不 是動(dòng)態(tài)生成的。如果在網(wǎng)上發(fā)布,只能將繪制好的圖表以靜態(tài)GIF圖像發(fā)布,這無法從根本上滿足不同用戶對(duì)不同數(shù)據(jù)的需求。

ASP擅長(zhǎng)服務(wù)器端的Web編程,操作后臺(tái)數(shù)據(jù)庫更是它的強(qiáng)項(xiàng)。但是用ASP制作實(shí)時(shí)數(shù)據(jù)庫圖表有點(diǎn)困難,因?yàn)锳SP本身并不支持圖表功能,只能借助第三方控件進(jìn)行開發(fā),如VB的MSChart控件。微軟推出的.NET Framework較好地解決了這個(gè)問題。微軟在.NET平臺(tái)上集成了實(shí)時(shí)數(shù)據(jù)庫圖表制作組件—OWC(Microsoft Office Web Components)。通過在ASP.NET頁面中調(diào)用OWC,我們可以輕松地繪制出各種類型的實(shí)時(shí)圖表。OWC支持近50種圖表類型,包括曲線圖、折線圖、柱狀圖、面積圖、K線圖等。與MSChart相比,OWC功能強(qiáng)大,操作簡(jiǎn)單。此外,由于OWC是基于服務(wù)端的,而MSChart只能應(yīng)用在客戶端,因此在服務(wù)器端的Web開發(fā)中,MSChart要比OWC遜色不少。

下面筆者將結(jié)合實(shí)例來具體闡述OWC在ASP.NET頁面中的應(yīng)用,這個(gè)實(shí)例是筆者開發(fā)的項(xiàng)目《化纖產(chǎn)品及其原料市場(chǎng)分析系統(tǒng)》中的一個(gè)子系統(tǒng),筆者在該項(xiàng)目中用到OWC,充分享受到了OWC的強(qiáng)大功能給開發(fā)工作帶來的方便。

三層結(jié)構(gòu)

系統(tǒng)整體架構(gòu)采用了B/S三層結(jié)構(gòu)模式,將系統(tǒng)分為用戶界面層(也稱為表現(xiàn)層)、業(yè)務(wù)邏輯層(也稱為功能層)和數(shù)據(jù)庫服務(wù)層(也稱為數(shù)據(jù)層),開發(fā)平臺(tái)則采用了.NET Framework,有效地降低了系統(tǒng)對(duì)客戶機(jī)的要求,避免了在客戶機(jī)上分發(fā)應(yīng)用程序與版本控制的困難。

● 用戶界面層: 用戶界面采用的是ASP.NET技術(shù)。ASP.NET技術(shù)的應(yīng)用增強(qiáng)了系統(tǒng)的通用性,客戶端只需安裝IE或Netscape等任一款瀏覽器,無需加載任何組件。

● 業(yè)務(wù)邏輯層: 采用了.NET Framework調(diào)用OWC的技術(shù),能夠根據(jù)用戶的要求快速取得數(shù)據(jù)庫中的數(shù)據(jù)動(dòng)態(tài)生成圖表。系統(tǒng)能夠支持復(fù)雜的檢索條件,檢索速度快,響應(yīng)時(shí)間短。

● 數(shù)據(jù)庫服務(wù)層:數(shù)據(jù)庫服務(wù)層可采用任何一款關(guān)系型數(shù)據(jù)庫。在本項(xiàng)目中,筆者使用的是SQL Server,它能與.NET Framework無縫集成。數(shù)據(jù)庫存取技術(shù)則采用了ADO.NET。

下文我們將著重介紹業(yè)務(wù)邏輯層的實(shí)現(xiàn)方法。

圖表元素簡(jiǎn)介

一張完整的圖表由若干個(gè)元素組成,我們必須對(duì)它們有所了解,才能隨心所欲、充分自如地對(duì)圖表進(jìn)行全方位的控制,也才能更好地理解本程序。筆者制作了一張簡(jiǎn)易的圖表,在圖中標(biāo)注了程序涉及到的主要部位和元素的名稱,借此幫助讀者掌握OWC以及理解本文所引用的代碼。

  \

使用OWC組件

在這一節(jié)里所涉及的源代碼摘自于《化纖產(chǎn)品及其原料市場(chǎng)分析系統(tǒng)》,該系統(tǒng)在Window 2000/XP簡(jiǎn)體中文專業(yè)版、.NET Framewrok 1 .0環(huán)境下通過。使用OWC組件的步驟如下:

1. 在當(dāng)前目錄中新建一個(gè)存放圖表文件的子目錄chart,同時(shí)把對(duì)該目錄的“修改”權(quán)限賦予ASP.NET賬戶。具體步驟如下:用鼠標(biāo)右鍵單擊chart目錄名,選擇“屬性”菜單項(xiàng),在彈出的“Chart”屬性對(duì)話框中單擊“安全”選項(xiàng)卡,再單擊“添加”按鈕,找到ASP.NET賬戶,賦予“修改”權(quán)限,單擊“確定”按鈕結(jié)束。這樣,ASP.NET就可以在chart目錄中寫入圖表文件了。

2. 定義一個(gè)服務(wù)器端的Image圖像控件,該圖像的屬性imageURL將在程序末尾被指向動(dòng)態(tài)生成的圖表文件,因此在這里無需為它賦值。

< asp:image id=“imgChart” Width=“500” Height=“300” Visible=“False” Runat=“server”>< /asp:image>

3. 添加OWC引用。

在使用OWC之前,首先必須將OWC的引用加入到“解決方案資源管理器”中。具體步驟如下:打開“解決方案資源管理器”面板,鼠標(biāo)右鍵單擊“引用”,選擇“添加引用”菜單,在彈出的“添加引用”對(duì)話框中單擊“COM”卡片,找到“Microsoft Office Web Components 9.0”,單擊“選擇”和“確定”按鈕,OWC就被添加到了引用中。

4. 定義OWC空間,并在該空間中加入一個(gè)OWC圖表owcChart。

Dim owcChartSpace As OWC.ChartSpace = New OWC.ChartSpace()

Dim owcChart As OWC.WCChart = owcChartSpace.Charts.Add

5. 用SQL檢索條件進(jìn)行數(shù)據(jù)庫檢索,并將檢索結(jié)果以RecordSet數(shù)據(jù)集的方式賦給owcChart。

OWC只支持RecordSet數(shù)據(jù)集,不支持DataSet數(shù)據(jù)集,因此在檢索時(shí)不能使用sqlCommand、sqlDataAdapter等對(duì)象,只能使用RecordSet對(duì)象進(jìn)行檢索。

’打開connection連接

ConnADO.Open(connectionString)

RecordsetADO.ActiveConnection = ConnADO

’設(shè)置游標(biāo)為靜態(tài)游標(biāo)

RecordsetADO.CursorType = ADODB.CursorTypeEnum.adOpenStatic

RecordsetADO.CursorLocation = ADODB.CursorLocationEnum.adUseClient

’變量strSQL中存放了標(biāo)準(zhǔn)SQL檢索條件

RecordsetADO.Open(strSQL)

然后將RecordSet數(shù)據(jù)集賦給OWC對(duì)象:

owcChartSpace.DataSource = RecordsetADO

在本例中,我們假定用SQL語句檢索出的數(shù)據(jù)共有三個(gè)字段:產(chǎn)品、日期和價(jià)格。這三個(gè)字段的值分別與圖表中的曲線、分類(X)軸和數(shù)值(Y)軸的數(shù)據(jù)一一對(duì)應(yīng)。

6. 確定曲線類型,并確定區(qū)別不同曲線的字段名。

首先確定曲線類型為平滑曲線。

owcChart.Type = OWC.ChartChartTypeEnum.chChartTypeSmoothLine

OWC支持在同一張圖表中顯示兩條以上的曲線。因此我們必須給出區(qū)別不同曲線的依據(jù),這個(gè)依據(jù)就是“產(chǎn)品”字段的取值。具體地說,“產(chǎn)品”字段中有幾個(gè)不同的取值,就會(huì)生成幾條不同的曲線。

owcChart.SetData(OWC.ChartDimensionsEnum.chDimSeriesNames, 0, “產(chǎn)品”)

7. 確定分類(X)軸標(biāo)簽與數(shù)值(Y)軸標(biāo)簽所對(duì)應(yīng)的字段。

首先需要定義owcSeries為OWC的曲線集合,然后遍歷圖表中的每一條曲線,將“日期”字段的值賦給分類(X)軸作為X軸刻度標(biāo)簽,將“價(jià)格”字段的值賦給數(shù)值(Y)軸作為Y軸刻度標(biāo)簽。如果我們能夠確定圖表中只有一條曲線,也可以省略遍歷的過程,但這樣無疑會(huì)降低程序的通用性。

Dim owcSeries As OWC.WCSeries

For Each owcSeries In owcChart.SeriesCollection

owcSeries.SetData(OWC.ChartDimensionsEnum.chDimCategories, 0, “日期”)

owcSeries.SetData(OWC.ChartDimensionsEnum.chDimValues, 0, “價(jià)格”)

Next

8. 對(duì)坐標(biāo)軸的屬性進(jìn)行設(shè)置。

這部分代碼通過對(duì)坐標(biāo)軸標(biāo)題的文字內(nèi)容、顏色、大小、主要和次要刻度線及其標(biāo)簽、主要和次要網(wǎng)絡(luò)線等方面的設(shè)置美化圖表。讀者如果對(duì)本段代碼中的概念有些模糊,可以參考前一部分提供的那張圖表。具體設(shè)置方法請(qǐng)參見以下代碼。

’先定義axis為坐標(biāo)軸集合

Dim axis As OWC.WCAxis

’遍歷坐標(biāo)軸集合

For Each axis In owcChart.Axes

’顯示軸標(biāo)題

axis.HasTitle = True

’先對(duì)分類(X)軸進(jìn)行設(shè)置

If axis.Type=OWC.ChartAxisTypeEnum.

chCategoryAxis Then

axis.HasTickLabels = True

’顯示X軸刻度標(biāo)簽

axis.Position = OWC.ChartAxisPositionEnum.chAxisPositionBottom

’標(biāo)簽的顯示位置

axis.Title.Font.Color =”blue”

’X軸的標(biāo)題文字顏色

axis.Title.Font.Size = “9”

’X軸的標(biāo)題文字大小

axis.Title.Caption = “日期范圍”

’X軸的標(biāo)題文字內(nèi)容

Else

’對(duì)數(shù)值(Y)軸進(jìn)行設(shè)置

axis.MajorGridlines.Line.Color = “silver”

’Y軸主要網(wǎng)絡(luò)線的顏色

axis.MajorTickMarks = OWC.ChartTickMarkEnum.chTickMarkNone

’不顯示Y軸主要刻度標(biāo)記

axis.HasTickLabels = True

’顯示Y軸刻度標(biāo)簽

axis.Title.Font.Color = “blue”

’Y軸的標(biāo)題文字顏色

axis.Title.Font.Size = “9”

’Y軸的標(biāo)題文字大小

axis.Title.Caption=“價(jià)格(千元/噸)”

’Y軸的標(biāo)題文字內(nèi)容

End If

Next

9. 以GIF圖像格式輸出圖表,并將圖像文件名賦給Image控件。

’用隨機(jī)數(shù)來生成隨機(jī)文件名

Randomize()

Dim nFileNameSuffix As Integer

Dim sFileNameSuffix As String

nFileNameSuffix = 100000 * Rnd()

sFileNameSuffix = System.Convert.ToString(nFileNameSuffix)

’以GIF格式輸出圖表,大小為500*300,圖表的文件名為:polyesterprice_隨機(jī)數(shù).gif,存放在chart子目錄中

owcChartSpace.ExportPicture(MapPath(“chart/PolyesterPrice_”) + sFileNameSuffix + “.gif”, “gif”, 500, 300)

’將Image控件的URL指向該圖表文件

imgChart.ImageUrl=“chart/PolyesterPrice_” + sFileNameSuffix + “.gif”

通過以上九個(gè)步驟,我們就完成了一個(gè)實(shí)時(shí)數(shù)據(jù)庫圖表的生成與顯示。在此需要指出的是,以上的九個(gè)步驟只是生成一張圖表必不可少的基本過程,通過設(shè)置OWC的其他屬性可以更好、更精確地控制圖表的生成與顯示方式,如圖例、線條的粗細(xì)與顏色、坐標(biāo)軸刻度線及標(biāo)簽的顯示頻度、網(wǎng)絡(luò)線等。這部分筆者不再介紹,請(qǐng)參見本文第四部分的源代碼。

本文代碼生成的圖表效果請(qǐng)見下圖。

\ 

優(yōu)化

上文中所有實(shí)時(shí)生成的圖表文件都存放在chart文件夾中,由于采用了隨機(jī)文件名的方式,因此這些文件不會(huì)互相覆蓋。但是如此日積月累,越來越多的文件不僅占用了硬盤空 間,也妨礙了管理,降低了性能。我們能不能在程序中自動(dòng)刪除以前的圖表文件呢?答案是肯定的。我們只要在代碼文件的Page_Load()函數(shù)中放置如下一段代碼,程序運(yùn)行的時(shí)候,就會(huì)自動(dòng)刪除當(dāng)日以前的文件。這樣,chart文件夾中存放的就總是當(dāng)日生成的圖表文件,從而有效地避免了文件垃圾。

’先取得chart文件夾中的文件列表

Dim fileEntries() As String = System.IO.Directory.GetFiles(MapPath(“chart”))

Dim sFile As String

’遍歷文件列表

For Each sFile In fileEntries

’將文件的生成日期與系統(tǒng)日期相比,如果是當(dāng)日以前生成的文件,刪除它

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數(shù)據(jù)集,這樣我們就無法在生成圖表的同時(shí)使用DataGrid顯示數(shù)據(jù)表,除非我們用循環(huán)依次取出Recordset記錄集中的全部數(shù)據(jù)手工生成表格,或用同樣的檢索條件對(duì)數(shù)據(jù)庫進(jìn)行二次檢索,但這無疑要增加服務(wù)器的負(fù)擔(dān)。其次,在同一張圖表中繪制的曲線只能是同一種類型,或同為平滑曲線圖,或同為柱狀圖,它不能在同一張圖表中顯示不同類型的曲線。最后,在某些細(xì)節(jié)方面,如分類(X)軸的設(shè)置方面,OWC無法提供更加詳細(xì)、人性化的設(shè)置途徑。如果讀者要追求更強(qiáng)大的功能和更好的顯示效果,筆者向您推薦兩個(gè)專業(yè)的基于.NET的圖表控件,這兩個(gè)控件分別由Dundas和Softwarefx公司出品,都同時(shí)支持Web Form和Win Form開發(fā),只是這兩個(gè)控件都是付費(fèi)的。讀者如果有興趣,可以到它們的網(wǎng)站去下載DEMO版本,以親身體驗(yàn)一下專業(yè)圖表控件帶來的強(qiáng)大功能。

關(guān)鍵詞:ASP.NET

贊助商鏈接: