ASP.NET之所以能夠在客戶(hù)端瀏覽器中形成各種數據圖片,是因為在A(yíng)SP.NET中提供了繪圖功能,具體的作法是先在服務(wù)器端創(chuàng )建一個(gè)Bitmap實(shí)例,然后利用ASP.NET中提供的繪圖功能,按照要生成的圖片的模樣,進(jìn)行繪制,最后把繪制好的實(shí)例以數據流的方式傳送到客戶(hù)端的瀏覽器上,并形成圖片顯示出來(lái)。本文要介紹的在A(yíng)SP.NET頁(yè)面中實(shí)現數據餅圖采用的基本也是這種方法。餅圖有時(shí)稱(chēng)為"Pie"圖,本文要實(shí)現的數據餅圖模樣具體如圖01所示:
圖01:在A(yíng)SP.NET頁(yè)面中產(chǎn)生的數據餅圖
一.本文程序設計和運行的軟件環(huán)境: ?。?).微軟公司視窗2000服務(wù)器版。
?。?).Visual Studio .Net正式版,.Net FrameWork SDK版本號3705。
?。?).MDAC 2.6(Microsoft Data Acess Component)以上版本。
二.數據字典:
為了方便起見(jiàn),本文選擇的數據庫類(lèi)型為本地數據庫--Access 2000,如果你使用的是其他數據庫類(lèi)型,只需對下面介紹的程序中的關(guān)于數據庫連接的代碼進(jìn)行相應的修改就可以了。Access數據庫名稱(chēng)為"db2.mdb",在此數據庫中只定義了一張數據表"MonthSale",此表的結構如表01所示:
| 字段名稱(chēng) | 類(lèi)型 | 說(shuō)明 |
| ID | 自動(dòng)編號 | 主鍵 ,遞增 |
| YF | 數字 | 銷(xiāo)售月份 |
| SL | 數字 | 銷(xiāo)量 |
表01:MonthSale數據表的結構
在定義完"db2.mdb"數據庫中的"MonthSale"數據表后,在MonthSale數據表中按照表02所示添加記錄:
| ID | YF | SL |
| 1 | 1 | 12 |
| 2 | 2 | 5 |
| 3 | 3 | 7 |
| 4 | 4 | 20 |
| 5 | 5 | 16 |
| 6 | 6 | 10 |
| 7 | 7 | 19 |
| 8 | 8 | 8 |
| 9 | 9 | 7 |
| 10 | 10 | 13 |
| 11 | 11 | 11 |
| 12 | 12 | 15 |
表02:MonthSale數據表中的記錄情況
在MonthSale數據表中添加完這12條記錄后,保存"db2.mdb"數據庫到C盤(pán)的根目錄中。
下面就要解決根據從數據庫中讀取的數據繪制Pie圖的方法。
?。?).繪制數據Pie圖的實(shí)現方法:
圖01所示的Pie圖看似是由一個(gè)圓形按照從數據庫中得到數據值的大小分割而成的,其實(shí)在具體實(shí)現時(shí)并非如此,圖01所示的Pie圖其實(shí)由許多根據從數據庫中數值大小,繪制相應的扇型,并由這些扇型組合而成的
?。?).簡(jiǎn)介ASP.NET頁(yè)面中繪制扇型要使用到的類(lèi)及其方法:
在本文和前文中,在A(yíng)SP.NET頁(yè)面中實(shí)現繪圖功能主要使用的是Graphics類(lèi),Graphics類(lèi)被封裝在命名空間"System.Drawing"中。Graphics類(lèi)中定義了很多方法和屬性,這些方法和屬性都與繪圖有關(guān),Graphics類(lèi)中的常用成員具體可參閱表01和表02,表01是Graphics類(lèi)中的常用方法及其說(shuō)明,表02是Graphics類(lèi)中常用屬性及其說(shuō)明:
| 方法 | 說(shuō)明 |
| Clear | 清除整個(gè)繪圖面并以指定背景色填充。 |
| Dispose | 釋放由此Graphics對象使用的所有資源。 |
| DrawArc | 繪制一段弧線(xiàn),它表示由一對坐標、寬度和高度指定的橢圓部分。 |
| DrawEllipse | 繪制一個(gè)由邊框定義的橢圓。 |
| DrawIcon | 在指定坐標處繪制由指定的Icon對象表示的圖像。 |
| DrawIconUnstretched | 繪制指定的Icon對象表示的圖像,而不縮放該圖像。 |
| DrawImage | 在指定位置并且按原始大小繪制指定的Image對象。 |
| DrawImageUnscaled | 在坐標對所指定的位置并且按其原始大小繪制指定的Image對象。 |
| DrawLine | 繪制一條連接由坐標對指定的兩個(gè)點(diǎn)的線(xiàn)條。 |
| DrawLines | 繪制一系列連接一組Point結構的線(xiàn)段。 |
| DrawPie | 繪制一個(gè)扇形,該扇形由一個(gè)坐標對、寬度和高度以及兩條射線(xiàn)所指定的橢圓定義。 |
| DrawPolygon | 繪制由一組Point結構定義的多邊形。 |
| DrawRectangle | 繪制由坐標對、寬度和高度指定的矩形。 |
| DrawRectangles | 繪制一系列由Rectangle結構指定的矩形。 |
| DrawString | 在指定位置并且用指定的Brush和Font對象繪制指定的文本字符串。 |
| FillClosedCurve | 填充由Point結構數組定義的閉合基數樣條曲線(xiàn)的內部。 |
| FillEllipse | 填充邊框所定義的橢圓的內部,該邊框由一對坐標、一個(gè)寬度和一個(gè)高度指定。 |
| FillPie | 填充由一對坐標、一個(gè)寬度、一個(gè)高度以及兩條射線(xiàn)指定的橢圓所定義的扇形區的內部。 |
| FillPolygon | 填充Point結構指定的點(diǎn)數組所定義的多邊形的內部。 |
| FillRectangle | 填充由一對坐標、一個(gè)寬度和一個(gè)高度指定的矩形的內部。 |
| FillRectangles | 填充由Rectangle結構指定的一系列矩形的內部。 |
| FillRegion | 填充Region 對象的內部。 |
| Flush | 強制執行所有掛起的圖形操作并立即返回而不等待操作完成。 |
| FromHdc | 從設備上下文的指定句柄創(chuàng )建新的Graphics對象。 |
| FromHwnd | 從窗口的指定句柄創(chuàng )建新的Graphics對象。 |
| FromImage | 從指定的Image對象創(chuàng )建新Graphics對象。 |
| GetHdc | 獲取與此Graphics對象關(guān)聯(lián)的設備上下文的句柄。 |
| ReleaseHdc | 釋放通過(guò)以前對此Graphics對象GetHdc方法的調用獲得的設備上下文句柄。 |
| ResetClip | 將此Graphics對象的剪輯區域重置為無(wú)限區域。 |
| ResetTransform | 將此Graphics對象的全局變換矩陣重置為單位矩陣。 |
表01:Graphics類(lèi)中的常用方法及其說(shuō)明
在本文中使用最多,也是最重要的方法就是:FillPie和DrawPie方法。這二個(gè)方法的具體使用方法,在下文中又詳細介紹。
| 屬性 | 說(shuō)明 |
| Clip | 獲取或設置Region對象,該對象限定此Graphics對象的繪圖區域。 |
| ClipBounds | 獲取RectangleF結構,該結構限定此Graphics對象的剪輯區域。 |
| DpiX | 獲取此Graphics對象的水平分辨率。 |
| DpiY | 獲取此Graphics對象的垂直分辨率。 |
| PageScale | 獲取或設置此Graphics對象的全局單位和頁(yè)單位之間的比例。 |
| PageUnit | 獲取或設置用于此Graphics對象中的頁(yè)坐標的度量單位。 |
| PixelOffsetMode | 獲取或設置一個(gè)值,該值指定在呈現此Graphics對象的過(guò)程中像素如何偏移。 |
| RenderingOrigin | 為抵色處理和陰影畫(huà)筆獲取或設置此Graphics對象的呈現原點(diǎn)。 |
| SmoothingMode | 獲取或設置此Graphics對象的呈現質(zhì)量。 |
| TextRenderingHint | 獲取或設置與此Graphics對象關(guān)聯(lián)的文本的呈現模式。 |
| Transform | 獲取或設置此Graphics對象的全局變換。 |
| VisibleClipBounds | 獲取或設置此Graphics對象的可見(jiàn)剪輯區域的邊框。 |
表02:Graphics類(lèi)中的常用屬性及其說(shuō)明
?。?).利用FillPie和DrawPie方法繪制扇型的具體方法:
DrawPie方法功能是繪制一個(gè)扇型,下面是 DrawPie方法的一種調用語(yǔ)法,此語(yǔ)法也是本文中主要的調用方式,具體如下:
public void DrawPie ( Pen , float , float , float , float , float , float ) ;
此種DrawPie調用方法是由七個(gè)參數組成,這七個(gè)參數的具體說(shuō)明如下:
第一個(gè)參數:定義繪制扇型的畫(huà)筆類(lèi)型;
第二和第三個(gè)參數:定義扇型的坐標;
第四和第五個(gè)參數:定義組成扇型的二個(gè)射線(xiàn)的長(cháng)度;
第六和第七個(gè)參數:定義扇型的開(kāi)始角度和扇型旋轉的角度大小。其中把X坐標的正方向定為0度角,計算扇型的開(kāi)始角度的按照順時(shí)針?lè )较蛐D,最先到達的扇型的那條射線(xiàn)和0度角之間的夾角。
下列代碼就是在A(yíng)SP.NET頁(yè)面中繪制一個(gè)扇型:
Bitmap bm = new Bitmap ( 600 , 300 ) ; //創(chuàng )建一個(gè)長(cháng)度為600,寬帶為300的Bitmap實(shí)例 Graphics g ; g = Graphics.FromImage ( bm ) ; //由此Bitmap實(shí)例創(chuàng )建Graphic實(shí)例 g . Clear ( Color . Snow ) ; g.DrawPie ( Pens.Red , 50 , 50 , 150 , 150 , 0 , 30 ) ; |
四.ASP.NET頁(yè)面中實(shí)現數據Pie圖實(shí)現步驟 在實(shí)現數據Pie圖之前,首先要確保在C盤(pán)的根目錄存在"db.mdb"數據庫,并且此數據庫已經(jīng)設定完畢,并且存在《在A(yíng)SP.NET頁(yè)面中實(shí)現數據棒圖》一文中的數據。下面是ASP.NET實(shí)現數據Pie圖的具體步驟,開(kāi)發(fā)工具使用的是Visual Studio .Net,采用的是C#語(yǔ)言。
1. 啟動(dòng)Visual Studio .Net。
2. 選擇菜單【文件】|【新建】|【項目】后,彈出【新建項目】對話(huà)框。
3. 將【項目類(lèi)型】設置為【Visual C#項目】。
4. 將【模板】設置為【ASP.NET Web 應用程序】。
5. 在【位置】的文本框中輸入"http://localhost/Pie"。然后單擊【確定】按鈕,這樣在Visual Studio .Net就會(huì )在當前項目文件所在目錄中建立一個(gè)名稱(chēng)為"Pie"文件夾,里面存放是此項目的項目文件,項目中的其他文件存放的位置是計算機Internet信息服務(wù)的默認的Web站點(diǎn)所在的目錄中新建的一個(gè)名稱(chēng)為"WebPieDemo"的文件夾中
6. 把Visual Studio .Net的當前窗口切換到WebForm的代碼編輯窗口,即:WebForm1.aspx.cs文件的編輯窗口。
7. 在WebForm1.aspx.cs文件首部,用下列代碼替換WebForm1.aspx.cs中導入命名空間的代碼:
1//下面程序中使用的ImageFormat類(lèi)所在的命名空間
2using System . Drawing . Imaging ;
3//下面程序中使用到關(guān)于數據庫方面的類(lèi)所在的命名空間
4using System . Data . OleDb ; 8. WebForm1.aspx.cs文件中的Page_Load事件處理代碼中添加下列代碼,下列代碼的作用是打開(kāi)數據庫,讀取數據,并以此數據形成數據Pie圖:
1private void Page_Load(object sender, System.EventArgs e)
2 {
3 // 在此處放置用戶(hù)代碼以初始化頁(yè)面
4 string sRouter = "c:\\db2.mdb" ;
5
6 //獲得當前Access數據庫在服務(wù)器端的絕對路徑
7 string strCon = " Provider = Microsoft.Jet.OLEDB.4.0; Data Source = " + sRouter ;
8
9 //創(chuàng )建一個(gè)數據庫連接
10 OleDbConnection myConn = new OleDbConnection ( strCon ) ;
11 string strCom = " SELECT YF ,SL FROM MonthSale ORDER BY YF" ;
12 myConn.Open ( ) ;
13 OleDbCommand myCommand = new OleDbCommand ( strCom , myConn ) ;
14 OleDbDataReader myOleDbDataReader = myCommand.ExecuteReader ( ) ;
15 //創(chuàng )建OleDbDataReader實(shí)例,并以此實(shí)例來(lái)獲取數據庫中各條記錄數據
16
17 int [ ] iXiaoSH = new int [ 12 ] ;
18 //定義一個(gè)數組,用以存放從數據庫中讀取的銷(xiāo)售數據
19
20 string [ ] sMoth = new string [ 12 ] ;
21 //定義一個(gè)數組,用以存放從數據庫中讀取的銷(xiāo)售月份
22
23 int iIndex = 0 ;
24 while ( myOleDbDataReader.Read ( ) )
25 {
26 iXiaoSH [ iIndex ] = myOleDbDataReader.GetInt32 ( 1 ) ;
27 sMoth [ iIndex ] = myOleDbDataReader.GetInt32 ( 0 ) . ToString() + "月" ;
28 iIndex++ ;
29 }
30 //讀取Table01數據表中的各條數據,并存放在先前定義的二個(gè)數組中
31
32 myConn . Close ( ) ;
33 myOleDbDataReader . Close ( ) ;
34
35 Bitmap bm = new Bitmap ( 600 , 300 ) ;
36 //創(chuàng )建一個(gè)長(cháng)度為600,寬帶為300的Bitmap實(shí)例
37
38 Graphics g ;
39 g = Graphics.FromImage ( bm ) ;
40 g . Clear ( Color . Snow ) ;
41 g . DrawString ( " ××公司××××年度銷(xiāo)售情況一覽表" , new Font ( "宋體" , 16 ) , Brushes . Black , new Point ( 5 , 5 ) ) ;
42 //在繪畫(huà)圖面的指定位置,以指定的字體、指定的顏色繪制指定的字符串。即為圖表標題
43
44 //以下代碼是是實(shí)現圖01中的右上部區域
45 //以上是在圖01中為下面繪制定位
46 Point myRec = new Point ( 515 , 30 ) ;
47 Point myDec = new Point ( 540 , 30 ) ;
48 Point myTxt = new Point ( 565 , 30 ) ;
49 g . DrawString ( "單位:萬(wàn)套" , new Font ( "宋體" , 9 ) , Brushes . Black , new Point ( 515 , 12 ) ) ;
50 for ( int i = 0 ; i < sMoth.Length ; i++ )
51 {
52 g . FillRectangle ( new SolidBrush ( GetColor ( i ) ) , myRec . X , myRec . Y , 20 , 10 ) ;
53 //填充小方塊
54
55 g . DrawRectangle ( Pens.Black , myRec . X , myRec . Y , 20 , 10 ) ;
56 //繪制小方塊
57
58 g . DrawString ( sMoth [ i ] . ToString ( ) , new Font ( "宋體", 9 ) , Brushes . Black , myDec ) ;
59 //繪制小方塊右邊的文字
60
61 g . DrawString ( iXiaoSH[i].ToString (), new Font ( "宋體", 9 ) , Brushes . Black , myTxt ) ;
62 myRec . Y += 15 ;
63 myDec . Y += 15 ;
64 myTxt . Y += 15 ;
65 }
66
67 //以下代碼是根據從數據庫中得到的數值大小,繪制扇型,并以相應色彩填充扇型,//從而構成圖01中的Pie圖
68 int iTatal = 0 ;
69 float fCurrentAngle = 0 ;
70 float fStartAngle = 0;
71 for ( int i = 0 ; i < iXiaoSH . Length ; i++ )
72 {
73 iTatal = iTatal + iXiaoSH [ i ] ;
74 }
75 for ( int i = 0 ; i < iXiaoSH . Length ; i++ )
76 {
77 //以下代碼是獲得要繪制扇型的開(kāi)始角度
78 if ( i == iXiaoSH . Length - 1 )
79 {
80 fCurrentAngle = 360- fStartAngle ;
81 }
82 else
83 {
84 int iTemp = iXiaoSH [ i ] ;
85 fCurrentAngle = ( iTemp * 360 ) / iTatal ;
86