author: terrylee From: cnblogs
棒图有时又称为"Bar"图,在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数据库名称为"db2.mdb",在此数据库中只定义了一张数据表"MonthSale",此表的结构如表01所示:
| 字段名称 |
类型 |
说明 |
| ID |
自动编号 |
主键 ,递增 |
| YF |
数字 |
销售月份 |
| SL |
数字 |
销量 |
表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:Table01数据表中的记录情况
在MonthSale数据表中添加完这12条记录后,保存"db2.mdb"数据库到C盘的根目录中。
三.ASP.NET页面中实现数据Bar图的关键步骤及其实现方法:
在ASP.NET页面中实现数据Bar图首先必须解决二大问题:
(1).首先要解决在ASP.NET页面中实现数据库连接和从数据库中读取数据的方法。
程序要实现从数据库中一条条的读取数据,则要使用OleDbDataReader类,OleDbDataReader类提供了从数据库中逐条读取数据的方法。下面代码是连接C盘根目录下的"db2.mdb"数据库,逐条读取MonthSale数据表中的记录,并把数据存放到定义的二个数组中:
1
string sRouter = "c:\\db2.mdb" ;
2
//获得当前Access数据库在服务器端的绝对路径
3
4
string strCon = " Provider = Microsoft.Jet.OLEDB.4.0; Data Source = " + sRouter ;
5
//创建一个数据库连接
6
7
OleDbConnection myConn = new OleDbConnection ( strCon ) ;
8
string strCom = " SELECT YF ,SL FROM MonthSale ORDER BY YF" ;
9
myConn.Open ( ) ;
10
OleDbCommand myCommand = new OleDbCommand ( strCom , myConn ) ;
11
OleDbDataReader myOleDbDataReader = myCommand.ExecuteReader ( ) ;
12
//创建OleDbDataReader实例,并以此实例来获取数据库中各条记录数据
13
14
int [ ] iXiaoSH = new int [ 12 ] ;
15
//定义一个数组,用以存放从数据库中读取的销售数据
16
17
string [ ] sMoth = new string [ 12 ] ;
18
//定义一个数组,用以存放从数据库中读取的销售月份
19
20
int iIndex = 0 ;
21
while ( myOleDbDataReader.Read ( ) )
22
{
23
iXiaoSH [ iIndex ] = myOleDbDataReader.GetInt32 ( 1 ) ;
24
sMoth [ iIndex ] = myOleDbDataReader.GetInt32 ( 0 ) . ToString ( ) + "月" ;
25
iIndex++ ;
26
}
27
//读取Table01数据表中的各条数据,并存放在先前定义的二个数组中
28
29
myConn . Close ( ) ;
30
myOleDbDataReader . Close ( ) ;
31
//关闭各种资源
根据得到数据,绘制图片,并显示出来:
通过第一步,已经把从数据库中的读取的数据存放到"iXiaoSH"和"sMoth"数组中。下面就要解决依据这些数据绘制出Bar图?首先先了解一下在ASP.NET页面中将要实现的数据Bar图的模样。具体可如图01所示:

图01:在ASP.NET中实现的数据Bar图
程序中把图01所示各个元素,按照区域分成了五个部分,这五个部分将在后面介绍的程序中分别实现:
1. 构建整个图片
首先要创建一Bitmap实例,并以此来构建一个Graphics实例,Graphics实例提供了各种绘制方法,这样才能按照数据的要求在Bitmap实例上绘制各种图形。下面代码是在ASP.NET中创建Bitmap实例,并以此实例来构建 Graphics实例的具体方法:
1
Bitmap bm = new Bitmap ( 600 , 250 ) ;
2
//创建一个长度为600,宽带为250的Bitmap实例
3
4
Graphics g ;
5
g = Graphics.FromImage ( bm ) ;
6
//由此Bitmap实例创建Graphic实例
7
8
g . Clear ( Color.Snow) ;
9
//用Snow色彩为背景色填充此绘画图面
2. 图01中的标题部分文字:
这是通过Graphics实例中提供的DrawString方法以指定的字体、颜色、在指定的位置绘制指定的字符串。下面代码的作用是绘制图01中标题:
1
g . DrawString ( " ××公司××××年度销售情况统计表" , new Font ( "黑体" , 16 ) , Brushes . Black , new Point ( 5 , 5 ) ) ;
2
//在绘画图面的指定位置,以指定的字体、指定的颜色绘制指定的字符串。即为图表标题
3. 图01中的提示区域,即图01中的右上角显示的内容:
要绘制这部分内容首先要定位,可以把这部分要绘制的内容分成三个小部分:
其一,是图01中的"单位:万套"文字,这部分处理起来比较简单,当选定要在图片中输出的文字坐标后,调用Graphics实例中提供的DrawString方法就可以了;
其二,是绘制图01中的小方块,首先要调用Graphics实例中的DrawRectangle方法在指定位置,以指定的颜色,绘制指定大小的方块,然后再条约Graphics实例中的FillRectangle填充这个小方块就完成了;
其三,是绘制小方块右边的文字。同样要使用Graphics实例中提供的DrawString方法,只不过位置坐标和字体要进行相应改变罢了。下面代码功能是绘制图01右上角显示的内容:
1
//以下代码是是实现图右上部
2
Point myRec = new Point ( 535 , 30 ) ;
3
Point myDec = new Point ( 560 , 26 ) ;
4
5
//以上是在图01中为下面绘制定位
6
g . DrawString ( "单位:万套" , new Font ( "宋体" , 9 ) , Brushes . Black , new Point ( 525 , 12 ) ) ;
7
8
9
for ( int i = 0 ; i < sMoth.Length ; i++ )
10
{
11
g . DrawRectangle ( Pens.Black , myRec . X , myRec . Y , 20 , 10 ) ;
12
//绘制小方块
13
14
g . FillRectangle ( new SolidBrush ( GetColor ( i ) ) , myRec.X , myRec.Y , 20 , 10 ) ;
15
//填充小方块
16
17
g . DrawString ( sMoth [ i ] . ToString ( ) , new Font ( "宋体" , 9 ) , Brushes . Black , myDec ) ;
18
//绘制小方块右边的文字
19
20
myRec . Y += 15 ;
21
myDec . Y += 15 ;
22
}
4. 根据从数据库中读取的数据,绘制数据Bar图:
此部分与第三部分比较类似,最主要的区别在于,绘制的位置不相同,下面代码是在图01中绘制数据Bar图,并提示Bar图所代表的数量:
1
//以下代码是绘制Bar图,及其销售数量
2
int iBarWidth = 40 ;
3
int scale = 10 ;
4
for ( int i = 0 ; i < iXiaoSH . Length ; i++ )
5
{
6
g . DrawRectangle ( Pens.Black, ( i * iBarWidth ) + 15 , 250 - ( iXiaoSH [ i ] * scale ) , 20 , ( iXiaoSH [ i ] * scale ) + 5 ) ;
7
//绘制Bar图
8
9
g . FillRectangle ( new SolidBrush (GetColor ( i )) , ( i * iBarWidth ) + 15 , 250 - ( iXiaoSH [ i ] * scale ) , 20 , ( iXiaoSH [ i ] * scale ) + 5 ) ;
10
//以指定的色彩填充Bar图
11
12
g . DrawString ( iXiaoSH [ i ] . ToString ( ) , new Font ( "宋体" , 9 ) , Brushes . Black , ( i * iBarWidth ) + 20 , 235 - ( iXiaoSH [ i ] * scale ) ) ;
13
//显示Bar图代表的数据
14
}
5. 绘制图片边框,并形成Jpeg文件格式在客户端显示:
绘制图片边框,使用的Graphics实例中的DrawRectangle方法。至于采用Jpeg格式文件在客户端显示,是因为Jpeg文件占用的空间较小,利于网络传送。下面代码是绘制图01中的边框,并形成GIF文件:
1
//以下代码是绘制边框,并形成Jpeg文件,供浏览器显示出来
2
Pen p = new Pen ( Color.Black , 2 ) ;
3
g . DrawRectangle ( p , 1 , 1 , 598 , 248 ) ;
4
bm.Save ( Response . OutputStream , ImageFormat.Gif) ;
四.ASP.NET页面中实现数据Bar图实现步骤:
掌握了上面的关键步骤及其解决方法后,在ASP.NET实现数据Bar相对就容易许多了,下面是ASP.NET页面中实现数据Bar图的具体实现步骤,在开发工具上选用的是Visual Stuido .Net企业构建版,采用的开发语言是C#。
1. 启动Visual Studio .Net
2. 选择菜单【文件】|【新建】|【项目】后,弹出【新建项目】对话框
3. 将【项目类型】设置为【Visual C#项目】
4. 将【模板】设置为【ASP.NET Web 应用程序】
5. 在【位置】的文本框中输入"http://localhost/Bar"。然后单击【确定】按钮,这样在Visual Studio .Net就会在当前项目文件所在目录中建立一个名称为"WebBarDemo"文件夹,里面存放是此项目的项目文件,项目中的其他文件存放的位置是计算机Internet信息服务的默认的Web站点所在的目录中新建的一个名称为"WebBarDemo"的文件夹中。具体如图02所示:
图02:新建一个ASP.NET项目对话框
6. 把Visual Studio .Net的当前窗口切换到WebForm的代码编辑窗口,即:WebForm1.aspx.cs文件的编辑窗口。
7. 在WebForm1.aspx.cs文件首部,用下列代码替换WebForm1.aspx.cs中导入命名空间的代码:
1
//下面程序中使用的ImageFormat类所在的命名空间
2
using System.Drawing.Imaging;
3
//下面程序中使用到关于数据库方面的类所在的命名空间
4
using System.Data.OleDb;
8. WebForm1.aspx.cs文件中的Page_Load事件处理代码中添加下列代码,下列代码的作用是打开数据库,读取数据,并以此数据形成数据Bar图:
1
private void Page_Load(object sender, System.EventArgs e)
2
{
3
// 在此处放置用户代码以初始化页面
4
5
string sRouter = "c:\\db2.mdb" ;
6
//获得当前Access数据库在服务器端的绝对路径
7
8
string strCon = " Provider = Microsoft.Jet.OLEDB.4.0; Data Source = " + sRouter ;
9
//创建一个数据库连接
10
11
OleDbConnection myConn = new OleDbConnection ( strCon ) ;
12
string strCom = " SELECT YF ,SL FROM MonthSale ORDER BY YF" ;
13
myConn.Open ( ) ;
14
OleDbCommand myCommand = new OleDbCommand ( strCom , myConn ) ;
15
OleDbDataReader myOleDbDataReader = myCommand.ExecuteReader ( ) ;
16
//创建OleDbDataReader实例,并以此实例来获取数据库中各条记录数据
17
18
int [ ] iXiaoSH = new int [ 12 ] ;
19
//定义一个数组,用以存放从数据库中读取的销售数据
20
21
string [ ] sMoth = new string [ 12 ] ;
22
//定义一个数组,用以存放从数据库中读取的销售月份
23
24
int iIndex = 0 ;
25
while ( myOleDbDataReader.Read ( ) )
26
{
27
iXiaoSH [ iIndex ] = myOleDbDataReader.GetInt32 ( 1 ) ;
28
sMoth [ iIndex ] = myOleDbDataReader.GetInt32 ( 0 ) . ToString ( ) + "月" ;
29
iIndex++ ;
30
}
31
//读取Table01数据表中的各条数据,并存放在先前定义的二个数组中
32
33
myConn . Close ( ) ;
34
myOleDbDataReader . Close ( ) ;
35
//关闭各种资源
36
37
Bitmap bm = new Bitmap ( 600 , 250 ) ;
38
//创建一个长度为600,宽带为250的Bitmap实例
39
40
Graphics g ;
41
g = Graphics.FromImage ( bm ) ;
42
//由此Bitmap实例创建Graphic实例
43
44
g . Clear ( Color.Snow) ;
45
//用Snow色彩为背景色填充此绘画图面
46
47
g . DrawString ( " ××公司××××年度销售情况统计表" , new Font ( "黑体" , 16 ) , Brushes . Black , new Point ( 5 , 5 ) ) ;
48
//在绘画图面的指定位置,以指定的字体、指定的颜色绘制指定的字符串。即为图表标题
49
50
//以下代码是是实现图右上部
51
Point myRec = new Point ( 535 , 30 ) ;
52
Point myDec = new Point ( 560 , 26 ) ;
53
54
//以上是在图01中为下面绘制定位
55
g . DrawString ( "单位:万套" , new Font ( "宋体" , 9 ) , Brushes . Black , new Point ( 525 , 12 ) ) ;
56
57
58
for ( int i = 0 ; i < sMoth.Length ; i++ )
59
{
60
g . DrawRectangle ( Pens.Black , myRec . X , myRec . Y , 20 , 10 ) ;
61
//绘制小方块
62
63
g . FillRectangle ( new SolidBrush ( GetColor ( i ) ) , myRec.X , myRec.Y , 20 , 10 ) ;
64
//填充小方块
65
66
g . DrawString ( sMoth [ i ] . ToString ( ) , new Font ( "宋体" , 9 ) , Brushes . Black , myDec ) ;
67
//绘制小方块右边的文字
68
69
myRec . Y += 15 ;
70
myDec . Y += 15 ;
71
}
72
73
//以下代码是绘制Bar图,及其销售数量
74
int iBarWidth = 40 ;
75
int scale = 10 ;
76
for ( int i = 0 ; i < iXiaoSH . Length ; i++ )
77
{
78
g . DrawRectangle ( Pens.Black, ( i * iBarWidth ) + 15 , 250 - ( iXiaoSH [ i ] * scale ) , 20 , ( iXiaoSH [ i ] * scale ) + 5 ) ;
79
//绘制Bar图
80
81
g . FillRectangle ( new SolidBrush (GetColor ( i )) , ( i * iBarWidth ) + 15 , 250 - ( iXiaoSH [ i ] * scale ) , 20 , ( iXiaoSH [ i ] * scale ) + 5 ) ;
82
//以指定的色彩填充Bar图
83
84
g . DrawString ( iXiaoSH [ i ] . ToString ( ) , new Font ( "宋体" , 9 ) , Brushes . Black , ( i * iBarWidth ) + 20 , 235 - ( iXiaoSH [ i ] * scale ) ) ;
85
//显示Bar图代表的数据
86
}
87
88
//以下代码是绘制边框,并形成Jpeg文件,供浏览器显示出来
89
Pen p = new Pen ( Color.Black , 2 ) ;
90
g . DrawRectangle ( p , 1 , 1 , 598 , 248 ) ;
91
bm.Save ( Response . OutputStream , ImageFormat.Gif) ;
92
}
9. WebForm1.aspx.cs文件中的InitializeComponent过程之后,添加下列代码,下列代码的作用是定义一个名称为GetColor函数,此函数的功能根据索引号得到相应的系统颜色:
1
/**//// <summary>
2
/// 获取颜色
3
/// </summary>
4
/// <param name="itemIndex">数组的索引</param>
5
/// <returns></returns> 6
private Color GetColor ( int itemIndex )
7
{
8
Color MyColor ;
9
int i = itemIndex ;
10
switch (i)
11
{
12
case 0 :
13
MyColor = Color.Green;
14
return MyColor;
15
case 1 :
16
MyColor = Color.Red;
17
return MyColor;
18
case 2:
19
MyColor = Color.Yellow;
20
return MyColor;
21
case 3 :
22
MyColor = Color.Blue;
23
return MyColor;
24
case 4 :
25
MyColor = Color.Orange;
26
return MyColor;
27
case 5 :
28
MyColor = Color.Aqua;
29
return MyColor;
30
case 6:
31
MyColor = Color.SkyBlue;
32
return MyColor;
33
case 7:
34
MyColor = Color.DeepPink;
35
return MyColor;
36
case 8:
37
MyColor = Color.Azure;
38
return MyColor;
39
case 9:
40
MyColor = Color.Brown;
41
return MyColor;
42
case 10:
43
MyColor = Color.Pink;
44
return MyColor;
45
case 11: