`
happmaoo
  • 浏览: 4335440 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

GDI+实现统计图表控件

阅读更多

目录:<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

GDI+概述

数据图表绘制函数

数据图表用户控件

总结

摘要

本文是在概述GDI+的基础上,简单的介绍如何绘制数据图表,并在此基础上将其做成一个用户控件。便于读者及用户的使用。

GDI+概述

提到GDI+,我们不得不先提到一个大家都比较熟悉的概念GDIGraphical Device Interface),GDI就像是加在操作系统和显卡之间的一个中间层。用来屏蔽不同的显卡给绘图带来的差异。有了它,用户只用调用专门的Windows API 函数来执行用户所要的绘图操作,而此时的GDI让你的不同的显卡去做你要做的事情。虽然GDI提供了相当方便的应用程序开发接口给开发者,但是它依然是基于过去比较老的Windows API版本,而且都是C语言风格的函数。所以使用起来就并不是太方便。

所谓GDI+呢,它就像一个位于GDI和你的应用程序之间的一个中间层。它提供了更加直观,基于继承的对象模型。尽管GDI+GDI外面包裹的一层表皮,但是微软声称GDI+提供了新的特色并且有着一些性能上的提高。

数据图表绘制函数:

下面我先提供一个简单的绘制图表文件的函数:

public void Render(string title,string subTitle,int width,int height,ChartData chartData,Graphics tempGraphics)

{

const int SIDE_LENGTH = 400;

const int PIE_DIAMETER = 200;

ChartData cd = chartData;

float sumData = 0;

for(int i=0;i<cd.DataName.Count;i++)

{

sumData += float.Parse(cd.DataValue[i].ToString());

}

//产生一个image对象,并由此产生一个Graphics对象

Bitmap bm = new Bitmap(width,height);

Graphics g = tempGraphics;

//设置对象g的属性

g.ScaleTransform((Convert.ToSingle(width))/SIDE_LENGTH,(Convert.ToSingle(height))/SIDE_LENGTH);

g.SmoothingMode = SmoothingMode.Default;

g.TextRenderingHint = TextRenderingHint.AntiAlias;

//画布和边的设定

g.Clear(Color.White);

g.DrawRectangle(Pens.Black,0,0,SIDE_LENGTH-1,SIDE_LENGTH-1);

//画饼图标题

g.DrawString(title,new Font("Tahoma",24),Brushes.Black,new PointF(5,5));

//画饼图的图例

g.DrawString(subTitle,new Font("Tahoma",14),Brushes.Black,new PointF(7,35));

//画饼图

float curAngle = 0;

float totalAngle = 0;

for(int i=0;i<cd.DataValue.Count;i++)

{

curAngle = Convert.ToSingle(float.Parse(cd.DataValue[i].ToString())) / sumData * 360;

g.FillPie(new SolidBrush(ChartUtil.GetChartItemColor(i)),100,65,PIE_DIAMETER,PIE_DIAMETER,totalAngle,curAngle);

g.DrawPie(Pens.Black,100,65,PIE_DIAMETER,PIE_DIAMETER,totalAngle,curAngle);

totalAngle += curAngle;

}

//画图例框及其文字

g.DrawRectangle(Pens.Black,200,300,199,99);

g.DrawString("Unique",new Font("Tahoma",12,FontStyle.Bold),Brushes.Black,new PointF(200,300));

//画图例各项

PointF boxOrigin = new PointF(210,330);

PointF textOrigin = new PointF(235,326);

float percent = 0;

for(int i=0;i<cd.DataValue.Count;i++)

{

g.FillRectangle(new SolidBrush(ChartUtil.GetChartItemColor(i)),boxOrigin.X,boxOrigin.Y,20,10);

g.DrawRectangle(Pens.Black,boxOrigin.X,boxOrigin.Y,20,10);

percent = Convert.ToSingle(float.Parse(cd.DataValue[i].ToString())) / sumData * 100;

g.DrawString(cd.DataName[i].ToString()+ " (" + percent.ToString("0") + "%)",new Font("Tahoma",10),Brushes.Black,textOrigin);

boxOrigin.Y += 15;

textOrigin.Y += 15;

}

}

上述函数是绘制一个简单的饼型的数据视图,它的参数表中有Title是该图的标题信息。SubTitle是该图的副标题信息,同时后面两个为该图的尺寸信息WidthHeight。接下来为提供给该数据视图的数据源ChartData,它是一个笔者必定义的一个类,专门用来提供给数据视图的数据源。后面将专门提到。最后就是一个Graphics对象,函数中的绘制操作都是针对这个Graphics来做的,同时这个函数是没有返回值的,但是这个外部传入的Graphics对象其实就相当一个返回值。

数据图表用户控件:

为了便于以后的重用,所以将其写成一个用户控件,然后再次使用时候只要像使用开发环境自带的那些控件一样,先将此用户控件注册到Visual Studio .net左则的工具箱选项卡中。然后你使用就可以将它托到你的界面上,同时你可以使用开发环境右边的属性诓来设置你相应的属性,比如上面提到的Title,SubTitle,DataSource等等。

我们回顾上面提到的绘制函数中的数据源ChartData;在用户控件中我们将其设置为该用户控件DataChart的一个属性DataSource。在此我们为什么要自己写一个专门的类来存储数据,关键在于笔者设计时遇到的数据一般都是像(星期一,100)这样的数据对。当然由于我们绘制的是二维的数据图表,显然我们的有用数据都会像这样的模式。这就存在着如何提供更加优美的数据接口的问题。当然你可以就用一个DataTable,但是这样就会给我们测试或者用户的使用带来灵活性的局限,特别是当你要临时添加或者删除一个数据对的时候。同时也会让我们上面的这个绘制函数显的不直观。当然你也可以用其他的数据源方式,我们在此用了自己设计的一个类如下:

#region 图表数据源类型

public class ChartData

{

#region 字段和属性

private ArrayList dataName;

private ArrayList dataValue;

public ArrayList DataName

{

get{return dataName;}

set{dataValue = value;}

}

public ArrayList DataValue

{

get{return dataValue;}

set{dataValue = value;}

}

#endregion

#region 公开的构造函数和方法

//无参数构造函数

public ChartData()

{

dataName = new ArrayList();

dataValue = new ArrayList();

}

//参数为两个ArrayList构造函数

public ChartData(ArrayList tempDataName,ArrayList tempDataValue)

{

dataName = tempDataName;

dataValue = tempDataValue;

}

//参数为一个DataTable构造函数

public ChartData(DataTable tempData)

{

DataTable dt = tempData;

foreach(DataRow dr in dt.Rows)

{

this.dataName.Add(dr[0].ToString());

this.dataValue.Add(dr[1].ToString());

}

}

public void Add(string tempName, float tempValue)

{

dataName.Add(tempName);

dataValue.Add(tempValue);

}

//Remove 方法存在很大的问题,就是不能够知道ArrayList中是否存在当前的变量。导致无法得知操作结果

//我使用了binarySearch,不知道可不可以实现功能

public bool Remove(string tempName,float tempValue)

{

if(dataName.BinarySearch(tempName) > 0 && dataValue.BinarySearch(tempValue) > 0)

{

dataName.Remove(tempName);

dataValue.Remove(tempValue);

return true;

}

else

{

return false;

}

}

#endregion

}

#endregion

在这个数据类中定义了两个ArrayList分别来存储我们有用的数据对,同时提供了三种不同的构造函数来提供多样话的数据接口,如果你只是为了测试这个用户控件、或者你是一个小型的应用程序你的数据来源于非数据库的方式。你可以使用无参数或者是提供两个ArrayList参数的构造函数,这样你可以通过Add方法来添加你的数据对,同时也可以使用Remove方法来删除你不需要的数据对。当然如果你的数据来源于一个数据库。你也可以使用提供一个DataTable参数的构造函数。

接下来就是提供几个属性用来设置用户控件的相应参数,比如前面提到的Title,SubTitle,DataSource以及Height,Width.让用户根据自己的需要去定制这些参数。同时我们复写OnPaint方法来绘制我们的用户控件的区域。

protected override void OnPaint(PaintEventArgs e)

{

Graphics gr = e.Graphics;

PieChart pc = new PieChart();

pc.Render(this.Title,this.SubTitle,this.ChartWidth,this.ChartHeight,this.DataSource,gr); base.OnPaint(e);

}

总结:

上面提供了如何去绘制一个简单的数据图表,并且将其写成一个用户控件。同时里面提到如何去提供一个灵活的数据接口。虽然比较简单,但是还是值得我们去思考的。同时也存在一定的问题,比如标题的位置信息,以及图表视图中图例框的位置及信息都是相当的死板。还是希望读者能够加以改进。


分享到:
评论

相关推荐

    TeeChart(.net 图型控件)

    TeeChart Pro提供了数以百计的2D、3D图形风格、40种数学统计函数,以及不限数量的坐标轴和22种调色板控件。  产品试用版(for C++ Builder 6)(license:4180099 password:847363625921436):  产品试用版(for ...

    利用控件实现柱形图分析

    本实例通过GDI+绘制图表方法来实现统计图形的效果,对于想把数据库的数据统计输出图形的设计人来是很有帮助的。

    jsp统计图(xml解析数据)

    习惯了使用Office Web Component(OWC),Report Viewer控件,以及GDI+进行绘制图标,下面介绍下可以生成图表更生动的FusionCharts Free画图,它可以更简洁地与用户进行交互,更重要的是,这基本上是一个完全免费的...

    Visual C#.NET程序设计(含书籍和源码) 李兰友 杨晓光 清华出版社,北交出版社

    非常经典的高校C# .net开发教程,《Visual C#.NET程序设计》作者,李兰友,杨晓光,清华出版社,北交出版社,含有书籍和源码。 本书主要介绍Visual C#.NET应用...11.4 统计图表 11.5 五子棋 本章小结 习题 参考文献

    VC++.NET案例开发集锦源代码.part1

    案例10 动态创建MSChart统计图表 第七章 网络应用 案例1 获取DNS 案例2 获取自己的IP地址 案例3 在窗口中PING一个IP地址 案例4 显示指定工作组内的所有计算机 案例5 电子邮件的发送与接收 案例6 简易WEB...

    数据库MIS系统 11.0

    6、强大的统计图表功能。7、能自动设计出地理信息系统,以及专家系统。8、强大的图形处理功能。9、强大的多媒体处理功能。10、强大的报表功能,能随心所欲的实现各种表格打印。11、能处理数据库复杂的SQL语句,并且...

    C# winform典型系统开发模板

    第7章 自定义图表控件   7.1 设计思路 136  7.2 关键技术 137  7.2.1 控件的生成 137  7.2.2 如何在项目中添加控件 137  7.2.3 在“属性”对话框中添加属性 137  7.2.4 用GDI+绘制图形 139...

    C#开发典型模块大全(光盘)

    第7章 自定义图表控件 7.1 设计思路 7.2 关键技术 7.2.1 控件的生成 7.2.2 如何在项目中添加控件 7.2.3 在“属性”对话框中添加属性 7.2.4 用GDI+绘制图形 7.2.5 如何在控件上绘制图形 7.2.6 获取扇形外弧中心点的...

    C#开发典型模块大全(光盘)第一部分

    第7章 自定义图表控件 7.1 设计思路 7.2 关键技术 7.2.1 控件的生成 7.2.2 如何在项目中添加控件 7.2.3 在“属性”对话框中添加属性 7.2.4 用GDI+绘制图形 7.2.5 如何在控件上绘制图形 7.2.6 获取扇形外弧中心点的...

    C#开发典型模块大全(光盘)第二部分

    第7章 自定义图表控件 7.1 设计思路 7.2 关键技术 7.2.1 控件的生成 7.2.2 如何在项目中添加控件 7.2.3 在“属性”对话框中添加属性 7.2.4 用GDI+绘制图形 7.2.5 如何在控件上绘制图形 7.2.6 获取扇形外弧中心点的...

    C#开发典型模块大全

    第7章 自定义图表控件 7.1 设计思路 136 7.2 关键技术 137 7.2.1 控件的生成 137 7.2.2 如何在项目中添加控件 137 7.2.3 在“属性”对话框中添加属性 137 7.2.4 用GDI+绘制图形 139 7.2.5 如何在控件...

    C#与.NET技术平台实战演练.part2

    4 使用BindingContext浏览数据第17章设计WindowsFrom应用程序17-1 设计MDI应用程序17-1-1 使用StatusBar与Timer控件17-1-2 设计选单17-1-3 编写选单程序代码17-2 设计GDI十应用程序17-2-1 绘制统计图表17-2-2...

    C#与.NET技术平台实战演练.part1

    4 使用BindingContext浏览数据第17章设计WindowsFrom应用程序17-1 设计MDI应用程序17-1-1 使用StatusBar与Timer控件17-1-2 设计选单17-1-3 编写选单程序代码17-2 设计GDI十应用程序17-2-1 绘制统计图表17-2-2...

Global site tag (gtag.js) - Google Analytics