棒圖有時又稱為"Bar"圖。在我的上一篇文章《在ASP.NET實現數據圖表》中已經介紹了在浏覽器看到的圖表,一般都是圖片文件。那麼在ASP.NET中是否也可以生成這些圖表?答案是肯定的,因為在ASP.NET中擁有了一個新功能--繪圖功能,通過此功能就能夠按照要實現的圖表的模樣來繪制,最後在客戶端的浏覽器中形成一個圖片,從而顯示出圖表來。
本文就在上一篇文章的基礎上,進一步介紹在ASP.NET頁面中實現Bar圖的具體方法。希望本篇文章不僅能夠讓您領會到ASP.NET中強大的繪圖功能,更希望能夠彌補上一篇文章的一個缺憾,就是上一篇實現的圖表的數據來自固定數值,而我們知道圖表只有在和數據庫關聯以後,才能夠顯示出更強大的優勢。下面就來介紹在ASP.NET頁面中從數據庫中提起數據,並以此數據形成Bar圖的具體實現方法。
一.本文程序設計和運行的軟件環境:
(1).微軟公司視窗2000服務器版。
(2).Visual Studio .Net正式版,.Net FrameWork SDK版本號3705。
(3).MDAC 2.6(Microsoft Data Acess Component)以上版本。
二.建立數據源
為了方便起見,本文選擇的數據庫類型為本地數據庫--Access 2000,如果你使用的是其他數據庫類型,只需對下面介紹的程序中的關於數據庫連接的代碼進行相應的修改就可以了。Access數據庫名稱為"db.mdb",在此數據庫中只定義了一張數據表"Table01",此表的結構如表01所示:
字段名稱 類型 說明 ID 自動編號 主鍵 ,遞增 YF 數字 銷售月份 SL 數字 銷量
表01:Table01數據表的結構
在定義完"db.mdb"數據庫中的"Table01"數據表後,在Table01數據表中按照表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:Table01數據表中的記錄情況
在Table01數據表中添加完這12條記錄後,保存"db.mdb"數據庫到C盤的根目錄中。
三.ASP.NET頁面中實現數據Bar圖的關鍵步驟及其實現方法:
在ASP.NET頁面中實現數據Bar圖首先必須解決二大問題:
(1).首先要解決在ASP.NET頁面中實現數據庫連接和從數據庫中讀取數據的方法。
程序要實現從數據庫中一條條的讀取數據,則要使用OleDbDataReader類,OleDbDataReader類提供了從數據庫中逐條讀取數據的方法。下面代碼是連接C盤根目錄下的"db.mdb"數據庫,逐條讀取Table01數據表中的記錄,並把數據存放到定義的二個數組中:
string sRouter = "c:db.mdb" ;
//獲得當前Access數據庫在服務器端的絕對路徑
string strCon = " Provider = Microsoft.Jet.OLEDB.4.0; Data Source = " + sRouter ;
//創建一個數據庫連接
OleDbConnection myConn = new OleDbConnection ( strCon ) ;
string strCom = " SELECT YF ,SL FROM Table01 ORDER BY YF" ;
myConn.Open ( ) ;
OleDbCommand myCommand = new OleDbCommand ( strCom , myConn ) ;
OleDbDataReader myOleDbDataReader = myCommand.ExecuteReader ( ) ;
//創建OleDbDataReader實例,並以此實例來獲取數據庫中各條記錄數據
int [ ] iXiaoSH = new int [ 12 ] ;
//定義一個數組,用以存放從數據庫中讀取的銷售數據
string [ ] sMoth = new string [ 12 ] ;
//定義一個數組,用以存放從數據庫中讀取的銷售月份
int iIndex = 0 ;
while ( myOleDbDataReader.Read ( ) )
{
iXiaoSH [ iIndex ] = myOleDbDataReader.GetInt32 ( 1 ) ;
sMoth [ iIndex ] = myOleDbDataReader.GetInt32 ( 0 ) . ToString ( ) + "月" ;
iIndex++ ;
}
//讀取Table01數據表中的各條數據,並存放在先前定義的二個數組中
myConn . Close ( ) ;
myOleDbDataReader . Close ( ) ;
//關閉各種資源
(2).根據得到數據,繪制圖片,並顯示出來:
通過第一步,已經把從數據庫中的讀取的數據存放到"iXiaoSH"和"sMoth"數組中。下面就要解決依據這些數據繪制出Bar圖?首先先了解一下在ASP.NET頁面中將要實現的數據Bar圖的模樣。具體可如圖01所示:
圖01:在ASP.NET中實現的數據Bar圖
程序中把圖01所示各個元素,按照區域分成了五個部分,這五個部分將在後面介紹的程序中分別實現:
1. 構建整個圖片
首先要創建一Bitmap實例,並以此來構建一個Graphics實例,Graphics實例提供了各種繪制方法,這樣才能按照數據的要求在Bitmap實例上繪制各種圖形。下面代碼是在ASP.NET中創建Bitmap實例,並以此實例來構建 Graphics實例的具體方法:
Bitmap bm = new Bitmap ( 600 , 250 ) ;
//創建一個長度為600,寬帶為250的Bitmap實例
Graphics g ;
g = Graphics.FromImage ( bm ) ;
//由此Bitmap實例創建Graphic實例
g . Clear ( Color . Snow ) ;
//用Snow色彩為背景色填充此繪畫圖面
g . DrawString ( " ××公司××器件2002年度銷售情況一覽表" , new Font ( "宋體" , 16 ) , Brushes . Black , new Point ( 5 , 5 ) ) ;
//在繪畫圖面的指定位置,以指定的字體、指定的顏色繪制指定的字符串。即為圖表標題
Point myRec = new Point ( 535 , 30 ) ;
Point myDec = new Point ( 560 , 26 ) ;
//以上是在圖01中為下面繪制定位
g . DrawString ( "單位:萬套" , new Font ( "宋體" , 9 ) , Brushes . Black , new Point ( 525 , 12 ) ) ;
for ( int i = 0 ; i < sMoth.Length ; i++ )
{
g . DrawRectangle ( Pens.Black , myRec . X , myRec . Y , 20 , 10 ) ;
//繪制小方塊
g . FillRectangle ( new SolidBrush ( GetColor ( i ) ) , myRec . X , myRec . Y , 20 , 10 ) ;
//填充小方塊
g . DrawString ( sMoth [ i ] . ToString ( ) , new Font ( "宋體" , 9 ) , Brushes . Black , myDec ) ;
//繪制小方塊右邊的文字
myRec . Y += 15 ;
myDec . Y += 15 ;
}
int iBarWidth = 40 ;
int scale = 10 ;
for ( int i = 0 ; i < iXiaoSH . Length ; i++ )
{
g . DrawRectangle ( Pens.Black , ( i * iBarWidth ) + 15 , 250 - ( iXiaoSH [ i ] * scale ) , 20 , ( iXiaoSH [ i ] * scale ) + 5 ) ;
//繪制Bar圖
g . FillRectangle ( new SolidBrush ( GetColor ( i ) ) , ( i * iBarWidth ) + 15 , 250 - ( iXiaoSH [ i ] * scale ) , 20 , ( iXiaoSH [ i ] * scale ) + 5 ) ;
//以指定的色彩填充Bar圖
g . DrawString ( iXiaoSH [ i ] . ToString ( ) , new Font ( "宋體" , 9 ) , Brushes . Black , ( i * iBarWidth ) + 20 , 235 - ( iXiaoSH [ i ] * scale ) ) ;
//顯示Bar圖代表的數據
}
Pen p = new Pen ( Color.Black , 2 ) ;
g . DrawRectangle ( p , 1 , 1 , 598 , 248 ) ;
bm.Save ( Response . OutputStream , ImageFormat . Jpeg ) ;
using System ;
using System . Collections ;
using System . ComponentModel ;
using System . Data ;
using System . Drawing ;
using System . Web ;
using System . Web . SessionState ;
using System . Web . UI ;
using System . Web . UI . WebControls ;
using System . Web . UI . HtmlControls ;
using System . Drawing . Imaging ;
//下面程序中使用的ImageFormat類所在的命名空間
using System . Data . OleDb ;
//下面程序中使用到關於數據庫方面的類所在的命名空間
string sRouter = "c:db.mdb" ;
//獲得當前Access數據庫在服務器端的絕對路徑
string strCon = " Provider = Microsoft.Jet.OLEDB.4.0; Data Source = " + sRouter ;
//創建一個數據庫連接
OleDbConnection myConn = new OleDbConnection ( strCon ) ;
string strCom = " SELECT YF ,SL FROM Table01 ORDER BY YF" ;
myConn.Open ( ) ;
OleDbCommand myCommand = new OleDbCommand ( strCom , myConn ) ;
OleDbDataReader myOleDbDataReader = myCommand.ExecuteReader ( ) ;
//創建OleDbDataReader實例,並以此實例來獲取數據庫中各條記錄數據
int [ ] iXiaoSH = new int [ 12 ] ;
//定義一個數組,用以存放從數據庫中讀取的銷售數據
string [ ] sMoth = new string [ 12 ] ;
//定義一個數組,用以存放從數據庫中讀取的銷售月份
int iIndex = 0 ;
while ( myOleDbDataReader.Read ( ) )
{
iXiaoSH [ iIndex ] = myOleDbDataReader.GetInt32 ( 1 ) ;
sMoth [ iIndex ] = myOleDbDataReader.GetInt32 ( 0 ) . ToString ( ) + "月" ;
iIndex++ ;
}
//讀取Table01數據表中的各條數據,並存放在先前定義的二個數組中
myConn . Close ( ) ;
myOleDbDataReader . Close ( ) ;
//關閉各種資源
Bitmap bm = new Bitmap ( 600 , 250 ) ;
//創建一個長度為600,寬帶為250的Bitmap實例
Graphics g ;
g = Graphics.FromImage ( bm ) ;
//由此Bitmap實例創建Graphic實例
g . Clear ( Color . Snow ) ;
//用Snow色彩為背景色填充此繪畫圖面
g . DrawString ( " ××公司××器件2002年度銷售情況一覽表" , new Font ( "宋體" , 16 ) , Brushes . Black , new Point ( 5 , 5 ) ) ;
//在繪畫圖面的指定位置,以指定的字體、指定的顏色繪制指定的字符串。即為圖表標題
//以下代碼是是實現圖01中的右上部
Point myRec = new Point ( 535 , 30 ) ;
Point myDec = new Point ( 560 , 26 ) ;
//以上是在圖01中為下面繪制定位
g . DrawString ( "單位:萬套" , new Font ( "宋體" , 9 ) , Brushes . Black , new Point ( 525 , 12 ) ) ;
for ( int i = 0 ; i < sMoth.Length ; i++ )
{
g . DrawRectangle ( Pens.Black , myRec . X , myRec . Y , 20 , 10 ) ;
//繪制小方塊
g . FillRectangle ( new SolidBrush ( GetColor ( i ) ) , myRec . X , myRec . Y , 20 , 10 ) ;
//填充小方塊
g . DrawString ( sMoth [ i ] . ToString ( ) , new Font ( "宋體" , 9 ) , Brushes . Black , myDec ) ;
//繪制小方塊右邊的文字
myRec . Y += 15 ;
myDec . Y += 15 ;
}
//以下代碼是繪制圖01中的Bar圖,及其銷售數量
int iBarWidth = 40 ;
int scale = 10 ;
for ( int i = 0 ; i < iXiaoSH . Length ; i++ )
{
g . DrawRectangle ( Pens.Black , ( i * iBarWidth ) + 15 , 250 - ( iXiaoSH [ i ] * scale ) , 20 , ( iXiaoSH [ i ] * scale ) + 5 ) ;
//繪制Bar圖
g . FillRectangle ( new SolidBrush ( GetColor ( i ) ) , ( i * iBarWidth ) + 15 , 250 - ( iXiaoSH [ i ] * scale ) , 20 , ( iXiaoSH [ i ] * scale ) + 5 ) ;
//以指定的色彩填充Bar圖
g . DrawString ( iXiaoSH [ i ] . ToString ( ) , new Font ( "宋體" , 9 ) , Brushes . Black , ( i * iBarWidth ) + 20 , 235 - ( iXiaoSH [ i ] * scale ) ) ;
//顯示Bar圖代表的數據
}
//以下代碼是繪制圖01中的邊框,並形成Jpeg文件,供浏覽器顯示出來
Pen p = new Pen ( Color.Black , 2 ) ;
g . DrawRectangle ( p , 1 , 1 , 598 , 248 ) ;
bm.Save ( Response . OutputStream , ImageFormat . Jpeg ) ;
private Color GetColor ( int itemIndex )
{
Color MyColor ;
int i = itemIndex ;
switch ( i )
{
case 0 :
MyColor = Color . Cornsilk ;
return MyColor ;
case 1 :
MyColor = Color . Red ;
return MyColor ;
case 2 :
MyColor = Color . Yellow ;
return MyColor ;
case 3 :
MyColor = Color . Peru ;
return MyColor ;
case 4 :
MyColor = Color . Orange ;
return MyColor ;
case 5 :
MyColor = Color . Coral ;
return MyColor ;
case 6:
MyColor = Color . Gray ;
return MyColor ;
case 7:
MyColor = Color . Maroon ;
return MyColor ;
case 8:
MyColor = Color . Azure ;
return MyColor ;
case 9:
MyColor = Color.AliceBlue ;
return MyColor ;
case 10:
MyColor = Color . Bisque ;
return MyColor ;
case 11:
MyColor = Color . BurlyWood ;
return MyColor ;
case 12:
MyColor = Color . Chartreuse ;
return MyColor ;
default:
MyColor = Color . Green ;
return MyColor ;
}
}