ASP.NET之所以能够在客户端浏览器中形成各种数据图片,是因为在ASP.NET中提供了绘图功能,具体的作法是先在服务器端创建一个Bitmap实例,然后利用ASP.NET中提供的绘图功能,按照要生成的图片的模样,进行绘制,最后把绘制好的实例以数据流的方式传送到客户端的浏览器上,并形成图片显示出来。本文要介绍的在ASP.NET页面中实现数据饼图采用的基本也是这种方法。饼图有时称为"Pie"图,本文要实现的数据饼图模样具体如图01所示:

图01:在ASP.NET页面中产生的数据饼图
一.本文程序设计和运行的软件环境:
(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:MonthSale数据表中的记录情况
在MonthSale数据表中添加完这12条记录后,保存"db2.mdb"数据库到C盘的根目录中。
下面就要解决根据从数据库中读取的数据绘制Pie图的方法。
(1).绘制数据Pie图的实现方法:
图01所示的Pie图看似是由一个圆形按照从数据库中得到数据值的大小分割而成的,其实在具体实现时并非如此,图01所示的Pie图其实由许多根据从数据库中数值大小,绘制相应的扇型,并由这些扇型组合而成的
(2).简介ASP.NET页面中绘制扇型要使用到的类及其方法:
在本文和前文中,在ASP.NET页面中实现绘图功能主要使用的是Graphics类,Graphics类被封装在命名空间"System.Drawing"中。Graphics类中定义了很多方法和属性,这些方法和属性都与绘图有关,Graphics类中的常用成员具体可参阅表01和表02,表01是Graphics类中的常用方法及其说明,表02是Graphics类中常用属性及其说明:
| 方法 |
说明 |
| Clear |
清除整个绘图面并以指定背景色填充。 |
| Dispose |
释放由此Graphics对象使用的所有资源。 |
| DrawArc |
绘制一段弧线,它表示由一对坐标、宽度和高度指定的椭圆部分。 |
| DrawEllipse |
绘制一个由边框定义的椭圆。 |
| DrawIcon |
在指定坐标处绘制由指定的Icon对象表示的图像。 |
| DrawIconUnstretched |
绘制指定的Icon对象表示的图像,而不缩放该图像。 |
| DrawImage |
在指定位置并且按原始大小绘制指定的Image对象。 |
| DrawImageUnscaled |
在坐标对所指定的位置并且按其原始大小绘制指定的Image对象。 |
| DrawLine |
绘制一条连接由坐标对指定的两个点的线条。 |
| DrawLines |
绘制一系列连接一组Point结构的线段。 |
| DrawPie |
绘制一个扇形,该扇形由一个坐标对、宽度和高度以及两条射线所指定的椭圆定义。 |
| DrawPolygon |
绘制由一组Point结构定义的多边形。 |
| DrawRectangle |
绘制由坐标对、宽度和高度指定的矩形。 |
| DrawRectangles |
绘制一系列由Rectangle结构指定的矩形。 |
| DrawString |
在指定位置并且用指定的Brush和Font对象绘制指定的文本字符串。 |
| FillClosedCurve |
填充由Point结构数组定义的闭合基数样条曲线的内部。 |
| FillEllipse |
填充边框所定义的椭圆的内部,该边框由一对坐标、一个宽度和一个高度指定。 |
| FillPie |
填充由一对坐标、一个宽度、一个高度以及两条射线指定的椭圆所定义的扇形区的内部。 |
| FillPolygon |
填充Point结构指定的点数组所定义的多边形的内部。 |
| FillRectangle |
填充由一对坐标、一个宽度和一个高度指定的矩形的内部。 |
| FillRectangles |
填充由Rectangle结构指定的一系列矩形的内部。 |
| FillRegion |
填充Region 对象的内部。 |
| Flush |
强制执行所有挂起的图形操作并立即返回而不等待操作完成。 |
| FromHdc |
从设备上下文的指定句柄创建新的Graphics对象。 |
| FromHwnd |
从窗口的指定句柄创建新的Graphics对象。 |
| FromImage |
从指定的Image对象创建新Graphics对象。 |
| GetHdc |
获取与此Graphics对象关联的设备上下文的句柄。 |
| ReleaseHdc |
释放通过以前对此Graphics对象GetHdc方法的调用获得的设备上下文句柄。 |
| ResetClip |
将此Graphics对象的剪辑区域重置为无限区域。 |
| ResetTransform |
将此Graphics对象的全局变换矩阵重置为单位矩阵。 |
表01:Graphics类中的常用方法及其说明
在本文中使用最多,也是最重要的方法就是:FillPie和DrawPie方法。这二个方法的具体使用方法,在下文中又详细介绍。
| 属性 |
说明 |
| Clip |
获取或设置Region对象,该对象限定此Graphics对象的绘图区域。 |
| ClipBounds |
获取RectangleF结构,该结构限定此Graphics对象的剪辑区域。 |
| DpiX |
获取此Graphics对象的水平分辨率。 |
| DpiY |
获取此Graphics对象的垂直分辨率。 |
| PageScale |
获取或设置此Graphics对象的全局单位和页单位之间的比例。 |
| PageUnit |
获取或设置用于此Graphics对象中的页坐标的度量单位。 |
| PixelOffsetMode |
获取或设置一个值,该值指定在呈现此Graphics对象的过程中像素如何偏移。 |
| RenderingOrigin |
为抵色处理和阴影画笔获取或设置此Graphics对象的呈现原点。 |
| SmoothingMode |
获取或设置此Graphics对象的呈现质量。 |
| TextRenderingHint |
获取或设置与此Graphics对象关联的文本的呈现模式。 |
| Transform |
获取或设置此Graphics对象的全局变换。 |
| VisibleClipBounds |
获取或设置此Graphics对象的可见剪辑区域的边框。 |
表02:Graphics类中的常用属性及其说明
(3).利用FillPie和DrawPie方法绘制扇型的具体方法:
DrawPie方法功能是绘制一个扇型,下面是 DrawPie方法的一种调用语法,此语法也是本文中主要的调用方式,具体如下:
public void DrawPie ( Pen , float , float , float , float , float , float ) ;
此种DrawPie调用方法是由七个参数组成,这七个参数的具体说明如下:
第一个参数:定义绘制扇型的画笔类型;
第二和第三个参数:定义扇型的坐标;
第四和第五个参数:定义组成扇型的二个射线的长度;
第六和第七个参数:定义扇型的开始角度和扇型旋转的角度大小。其中把X坐标的正方向定为0度角,计算扇型的开始角度的按照顺时针方向旋转,最先到达的扇型的那条射线和0度角之间的夹角。
下列代码就是在ASP.NET页面中绘制一个扇型:
Bitmap bm = new Bitmap ( 600 , 300 ) ;
//创建一个长度为600,宽带为300的Bitmap实例
Graphics g ;
g = Graphics.FromImage ( bm ) ;
//由此Bitmap实例创建Graphic实例
g . Clear ( Color . Snow ) ;
g.DrawPie ( Pens.Red , 50 , 50 , 150 , 150 , 0 , 30 ) ; |
四.ASP.NET页面中实现数据Pie图实现步骤
在实现数据Pie图之前,首先要确保在C盘的根目录存在"db.mdb"数据库,并且此数据库已经设定完毕,并且存在《在ASP.NET页面中实现数据棒图》一文中的数据。下面是ASP.NET实现数据Pie图的具体步骤,开发工具使用的是Visual Studio .Net,采用的是C#语言。
1. 启动Visual Studio .Net。
2. 选择菜单【文件】|【新建】|【项目】后,弹出【新建项目】对话框。
3. 将【项目类型】设置为【Visual C#项目】。
4. 将【模板】设置为【ASP.NET Web 应用程序】。
5. 在【位置】的文本框中输入"http://localhost/Pie"。然后单击【确定】按钮,这样在Visual Studio .Net就会在当前项目文件所在目录中建立一个名称为"Pie"文件夹,里面存放是此项目的项目文件,项目中的其他文件存放的位置是计算机Internet信息服务的默认的Web站点所在的目录中新建的一个名称为"WebPieDemo"的文件夹中
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事件处理代码中添加下列代码,下列代码的作用是打开数据库,读取数据,并以此数据形成数据Pie图:
1
private void Page_Load(object sender, System.EventArgs e)
2
{
3
// 在此处放置用户代码以初始化页面
4
string sRouter = "c:\\db2.mdb" ;
5
6
//获得当前Access数据库在服务器端的绝对路径
7
string strCon = " Provider = Microsoft.Jet.OLEDB.4.0; Data Source = " + sRouter ;
8
9
//创建一个数据库连接
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
//创建OleDbDataReader实例,并以此实例来获取数据库中各条记录数据
16
17
int [ ] iXiaoSH = new int [ 12 ] ;
18
//定义一个数组,用以存放从数据库中读取的销售数据
19
20
string [ ] sMoth = new string [ 12 ] ;
21
//定义一个数组,用以存放从数据库中读取的销售月份
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数据表中的各条数据,并存放在先前定义的二个数组中
31
32
myConn . Close ( ) ;
33
myOleDbDataReader . Close ( ) ;
34
35
Bitmap bm = new Bitmap ( 600 , 300 ) ;
36
//创建一个长度为600,宽带为300的Bitmap实例
37
38
Graphics g ;
39
g = Graphics.FromImage ( bm ) ;
40
g . Clear ( Color . Snow ) ;
41
g . DrawString ( " ××公司××××年度销售情况一览表" , new Font ( "宋体" , 16 ) , Brushes . Black , new Point ( 5 , 5 ) ) ;
42
//在绘画图面的指定位置,以指定的字体、指定的颜色绘制指定的字符串。即为图表标题
43
44
//以下代码是是实现图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 ( "单位:万套" , 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
//以下代码是获得要绘制扇型的开始角度
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
}
87
//根据参数绘制扇型
88
89
g.DrawPie ( Pens.Black , 100 , 40 , 250 , 250 , fStartAngle , fCurrentAngle ) ;
90
//以指定色彩填充绘制的扇型
91
92
g.FillPie ( new SolidBrush ( GetColor ( i ) ) , 100 , 40 , 250 , 250 , fStartAngle , fCurrentAngle ) ;
93
fStartAngle += fCurrentAngle ;
94
}
95
96
//画出图片的边框
97
Pen p = new Pen ( Color.Black , 2 ) ;
98
g . DrawRectangle ( p , 1 , 1 , 598 , 298 ) ;
99
100
//向客户端输出数据流,并以此数据流形成Jpeg图片
101
bm.Save ( Response . OutputStream , ImageFormat . Jpeg ) ;
102
}
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:
46
MyColor = Color.BurlyWood;
47
return MyColor;
48
case 12:
49
MyColor = Color.Chartreuse;
50
return MyColor;
51
default:
52
MyColor = Color.Pink;
53
return MyColor;
54
}
55
}
至此,在上述步骤都正确执行后,在ASP.NET页面中实现数据Pie图的全部工作就完成了。此时单击快捷键F5,就可以得到如图01所示的数据Pie图了。
五.总结:
由于ASP.NET提供了丰富的绘图功能,所以结合这二篇文章的介绍,我想再实现其他的数据图表,应该也不算很困难。
完整的例子代码:
1
using System;
2
using System.Collections;
3
using System.ComponentModel;
4
using System.Data;
5
using System.Drawing;
6
using System.Web;
7
using System.Web.SessionState;
8
using System.Web.UI;
9
using System.Web.UI.WebControls;
10
using System.Web.UI.HtmlControls;
11
//下面程序中使用的ImageFormat类所在的命名空间
12
using System . Drawing . Imaging ;
13
//下面程序中使用到关于数据库方面的类所在的命名空间
14
using System . Data . OleDb ;
15
16
17
namespace WebPieDemo
18

{
19
/**//// <summary>
20
/// WebForm1 的摘要说明。
21
/// </summary>
22
public class WebForm1 : System.Web.UI.Page
23
{
24
private void Page_Load(object sender, System.EventArgs e)
25
{
26
// 在此处放置用户代码以初始化页面
27
string sRouter = "c:\\db2.mdb" ;
28
29
//获得当前Access数据库在服务器端的绝对路径
30
string strCon = " Provider = Microsoft.Jet.OLEDB.4.0; Data Source = " + sRouter ;
31
32
//创建一个数据库连接
33
OleDbConnection myConn = new OleDbConnection ( strCon ) ;
34
string strCom = " SELECT YF ,SL FROM MonthSale ORDER BY YF" ;
35
myConn.Open ( ) ;
36
OleDbCommand myCommand = new OleDbCommand ( strCom , myConn ) ;
37
OleDbDataReader myOleDbDataReader = myCommand.ExecuteReader ( ) ;
38
//创建OleDbDataReader实例,并以此实例来获取数据库中各条记录数据
39
40
int [ ] iXiaoSH = new int [ 12 ] ;
41
//定义一个数组,用以存放从数据库中读取的销售数据
42
43
string [ ] sMoth = new string [ 12 ] ;
44
//定义一个数组,用以存放从数据库中读取的销售月份
45
46
int iIndex = 0 ;
47
while ( myOleDbDataReader.Read ( ) )
48
{
49
iXiaoSH [ iIndex ] = myOleDbDataReader.GetInt32 ( 1 ) ;
50
sMoth [ iIndex ] = myOleDbDataReader.GetInt32 ( 0 ) . ToString() + "月" ;
51
iIndex++ ;
52
}
53
//读取Table01数据表中的各条数据,并存放在先前定义的二个数组中
54
55
myConn . Close ( ) ;
56
myOleDbDataReader . Close ( ) ;
57
58
Bitmap bm = new Bitmap ( 600 , 300 ) ;
59
//创建一个长度为600,宽带为300的Bitmap实例
60
61
Graphics g ;
62
g = Graphics.FromImage ( bm ) ;
63
g . Clear ( Color . Snow ) ;
64
g . DrawString ( " ××公司××××年度销售情况一览表" , new Font ( "宋体" , 16 ) , Brushes . Black , new Point ( 5 , 5 ) ) ;
65
//在绘画图面的指定位置,以指定的字体、指定的颜色绘制指定的字符串。即为图表标题