用C#绘制曲线图_第1页
用C#绘制曲线图_第2页
用C#绘制曲线图_第3页
用C#绘制曲线图_第4页
用C#绘制曲线图_第5页
已阅读5页,还剩102页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

用C#绘制曲线图

照例先上图:

比以前Cool吧?呵呵,其实就是根据数据自动计算边距和字体等.

///<summary>

〃/自动根据参数调整图像大小

///</summary>

PublicvoidFit()

(

//计算字体距离

intFontSpace=FontSize+5;

//计算图像边距

FloatfltSpace=Math.Min(Width/6,Height/6);

XSpace=fltSpace;

YSpace=fltSpace;

〃计算X轴刻度宽度

XSIice=(Width-2*XSpace)/(Keys.Length-1);

〃计算Y轴刻度宽度和Y轴刻度开始值

float租MinValue=O;

floatfltMaxValue=O;

for(inti=O;i<Values.Length;i++)

(

if(Values[i]<fltMinValue)

(

fltMinValue=Values[i];

)

elseif(Values[i]>fltMaxValue)

(

fltMaxValue=Values[i];

)

)

if(YSIiceBegin>fltMinValue)

(

YSIiceBegin=fltMinValue;

)

intintYSIiceCount=(int)(fltMaxValue/YSIiceValue);

if(fltMaxValue%YSIiceValue!=O)

(

intYSIiceCount++;

)

YSIice=(Height-2*YSpace)/intYSIiceCount;

看我把数据缩小一个级别的效果:

因为代码里面充斥了大量注释,也不敲太多文字了..完整代码奉上:

///</summary>

#region公共属性

///Y轴刻度宽度

///<summary>

〃/Y轴说明文字

///<summary>

set{fltXRotateAngle=value;}

〃/自动根据参数调整图像大小

接上文:

ht/2)));

floatfltYI=Height-YSpace;

一个较能通用的C#画曲线类

源码如下,思想以后面机会再说明:

曲线类返回一个画好的图片

曲线类源码开始

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Text;

usingSystem.Drawing;

namespacetestPictureBox

publicclassCurvePaint

publicCurvePaint(){}

//刻度线条数

privateint_X_KeduCount=12;

privateint_Y_KeduCount=12;

//刻度值位置对应刻度线左移像素

privatefloat_X_valueStrMoveleft=5f;

privatefloat_Y_valueStrMoveleft=45f;

〃格式化刻度值

privatestring_X_Format="#0.0";

privatestring_Y_Format二”#0.00";

〃x轴刻度值文字方向

privatebool_X_DirectionVertical=false;

publicintXkeduCount

{

get{return_X_KeduCount;}

set{_X_KeduCount=value;}

)

publicintYkeduCount

(

get{return_Y_KeduCount;}

set{_Y_KeduCount=value;}

)

publicfloatXvalueStrMoveleft

(

get{return_X_valueStrMoveleft;}

set{_X_valueStrMoveleft=value;}

}

publicfloatYvalueStrMoveleft

(

get{return_Y_valueStrMoveleft;}

set{_Y_valueStrMoveleft=value;}

publicboolXdirectionVertical

get{return_X_DirectionVertical;}

set{_X_DirectionVertical=value;}

)

publicstringXformat

(

get{return_X_Format;}

set{_X_Format=value;}

)

publicstringYformat

(

get{return_Y_Format;}

set{_Y_Format=value;}

)

privatevoidsetExtremeValues(float[]arr,reffloatsmallestValue,reffloatgreatestValue)

(

if(arr==null||arr.Length==0)thrownewException("用于绘曲线图的数组为空”);

smallestValue=arr[0];

greatestValue=arr[0];

for(inti=1;i<aiT.Length;i++)

(

if(smallestValue>aiT[i])smallestValue=aiT[i];

if(greatestValue<arrfi])greatestValue=arr[i];

privatevoidsetKeduStringArray(lloat[]keduArr,floatincrement)

(

for(inti=1;i<keduArr.Length;i++)

{

keduArr[i]=keduAiT[i-1]+increment;

)

}

//数据规格化f(x)=ax+b

privatefloatStandard(floatx,floatA,floatB,floatC,floatD)

(

returnC*(A*x+B)+D;

)

publicBitmapdrawCurve(float[]X_array,float[]Y_array,stringchartTitle,stringX_title,

stringY_title)

〃画图初始化

Bitmapbmap=newBitmap(500,500);〃图片.大〃、

Graphicsgph=Graphics.Fromlmage(bmap);

gph.Clear(Color.White);

〃曲线图左、下、右、上的空隙均为60像素

PointFcpt=newPointF(60f,bmap.Height-60f);〃坐标原点,坐标轴起始点(60,440)

PointFX.EndPoint=newPointF(bmap.Width-60f,cpt.Y);//X轴终点(440,440)

PointFY_EndPoint=newPointF(cpt.X,60f);//Y轴终点(60,60)

〃坐标轴三角形箭头

PointF[Jxpt=newPointF[3]{newPointF(X_EndPoint.X+15,X_EndPoint.Y),new

PointF(X_EndPoint.X,X_EndPoint.Y-4),newPointF(X_EndPoint.X,X_EndPoint.Y+4)};//x

轴三角形

PointF[]ypt=newPointF[3]{newPointF(Y_EndPoint.X,Y_EndPoint.Y-15),new

PointF(Y_EndPoint.X-4,Y_EndPoint.Y),newPointF(Y_EndPoint.X+4,Y_EndPoint.Y)};//y

轴三角形

〃画图表标题

gph.DrawString(chartTitle,newFont(“宋体",14),Brushes.Black,new

PointF(Y_EndPoint.X+60,Y_EndPoint.Y-30));〃图表标题

〃画x轴三角箭头、标题

gph.DrawLine(Pens.Black,cpt.X,cpt.Y,X_EndPoint.X,X_EndPoint.Y);

gph.DrawPolygon(Pens.Black,xpt);

gph.FillPolygon(newSolidBrush(Color.Black),xpt);

gph.DrawString(X_title,newFont(“宋体”,12),Brushes.Black,new

PointF(X_EndPoint.X+10,X_EndPoint.Y+10));

〃画y轴三角箭头、标题

gph.DrawLine(Pens.Black,cpt.X,cpt.Y,Y_EndPoint.X,Y_EndPoint.Y);

gph.DrawPolygon(Pens.Black,ypt);

gph.FillPolygon(newSolidBrush(Color.Black),ypt);

gph.DrawString(Y_title,newFont(“宋体",12),Brushes.Black,newPointF(0,

Y_EndPoint.Y-30));

floatX_smallestValue=Of,X_greatestValue=Of;

floatY_smallestValue=Of,Y_greatestValue=Of;

〃猎取横、纵坐标的最大最小值

setExtremeValues(X_array,refX_smallestValue,refX_greatestValue);

setExtremeValues(Y_array,refY_smallestValue,refY_greatestValue);

〃增量=(最大值一最小值)

floatX_Increment=(X_greatestValue-X_smallestValue);

floatYJncrement=(Y_greatestValue-Y_smallestValue);

〃平均增量=(最大值一最小值)/刻度间隔数,刻度间隔数=刻度线数一1

floatX_AvgIncrement=X_Increment/(XkeduCount-1);

floatY_AvgIncrement=Y_Increment/(YkeduCount-1);

float[]X.KeduArr=newfloat[XkeduCount];//X轴刻度值

floatf]Y_KeduArr=newfloat[YkeduCount];//Y轴刻度值

X_KeduArr[O]=X_smallestValue;

Y_KeduArr[OJ=Y_smallestValue;

//给刻度值数组赋值

setKeduStringArray(X_KeduArr,X_AvgIncrement);

setKeduStringArray(Y_KeduArr,Y_AvgIncrement);

〃刻度线起始位置

PointFX_KeduStart=newPointF(cpt.X+30,cpt.Y);〃(90,440)x轴第一根刻度

线

PointFX_KeduEnd=newPointF(X_EndPoint.X-10,X_EndPoint.Y);〃(430,440)x轴最

后一根刻度线

PointFY_KeduStart=newPointF(cpt.X,cpt.Y-30);〃(60,410)y轴第一根刻度

线

PointFY_KeduEnd=newPointF(Y_EndPoint.X,Y_EndPoint.Y+10);//(60,70)y轴最

后一根刻度线

〃刻度线位置坐标平均增量

floatX_KeduIncrement=(X_KeduEnd.X-X_KeduStart.X)/(XkeduCount-1);

floatY_KeduIncrement=(Y_KeduStart.Y-Y_KeduEnd.Y)/(YkeduCount-1);

〃设置X轴刻度值显示方向

StringFormatX_StringFormat=newStringFormat();

if(XdirectionVertical)

(

X_StringFormat.FormatFlags=StringFormatFlags.DirectionVertical;

)

〃画x轴刻度线、刻度值

for(inti=1;i<=XkeduCount;i++)

(

if(i==1)

(

gph.DrawString(X_KeduArr[i-1].ToString(Xformat),newFont(nTimesNew

Roman",11),Brushes.Black,newPointF(X_KeduStart.X-XvalueStrMoveleft,X_KeduStart.Y+

5),X_StringFormat);//newStringFormat(StringFormatFlags.DirectionVertical));//SJn一个参数

实现文字竖排,默认为横排

gph.DrawLine(Pens.LightGray,X_KeduStart.X,X_KeduStart.Y,X_KeduStart.X,

Y_EndPoint.Y);

else

gph.DrawString(X_KeduArr[i-1].ToString(Xformat),newFont("TimesNew

Roman'1,11),Brushes.Black,newPointF(X_KeduStart.X+(i-1)*X_KeduIncrement-

XvalueStrMoveleft,cpt.Y+5),X_StringFormat);//new

StringFormat(StringFormatFlags.DirectionVertical));//最后一个参数实现文字竖排,默认为横排

gph.DrawLine(Pens.LightGray,X_KeduStart.X+(i-1)*X_KeduIncrement,cpt.Y,

X_KeduStart.X+(i-1)*X_KeduIncrement,Y_EndPoint.Y);

)

)

〃画y轴刻度线、刻度值

for(inti=1;i<=YkeduCount;i++)

(

if(i==1)

(

gph.DrawString(Y_KeduArr[i-l].ToString(Yformat),newFont(nTimesNew

Roman'*,11),Brushes.Black,newPointF(Y_KeduStart.X-YvalueStrMoveleft,Y_KeduStarl.Y-

6));

gph.DrawLine(Pens.LightGray,Y_KeduStart.X,Y_KeduStart.Y,X_EndPoint.X,

Y_KeduStart.Y);

)

else

(

gph.DrawString(Y_KeduArr[i-l].ToString(Yformat),newFont(uTimesNew

Roman”,11),Brushes.Black,newPointF(Y_KeduStart.X-YvalueStrMoveleft,Y_KeduStart.Y-

(i-1)*Y_KeduIncrement-6));

gph.DrawLine(Pens.LightGray,Y_KeduStart.X,Y_KeduStart.Y-(i-1)*

Y_KeduIncrement,X_EndPoint.X,Y_KeduStart.Y-(i-1)*Y_KeduIncrement);

)

)

//(90,440)x轴第一根刻度线起点,(430,440)x轴最后一根刻度线起点,(60,410)y轴

第一根刻度线起点,(60,70)y轴最后一根刻度线起点

〃为了方便画图,将原二维数据规格化到固定的画图区间(90-430,70-410),规格化函

数F(x)=A*x+B

〃因为窗口丫轴坐标方向与正常坐标丫轴方向相反,故需要将丫坐标再变换一次,

变换函数G(x)=C*x+D

〃下面是X坐标变换因子A,B,Y坐标对应的变换因子A,B,C,D

floatX_A=340.0f/X_Increment;

floatX_B=90.0f-(340.0f*X.smallestValue)/XJncrement;

floatY_A=340.0f/Y_Increment;

floatY_B=70.0f-(340.0f*Y_smallestValue)/Y」ncrement;

floatY_C=-lf,Y_D=480f;

for(inti=1;i<=Y_array.Length;i++)

{

〃画点

gph.DrawEllipse(Pens.Black,Standard(X_array[i-1],X_A,X_B,1,0)-1.5f,

Standard(Y_array[i-1],Y_A,Y_B,Y_C,Y_D)-1.5f,3,3);

gph.FillEllipse(newSolidBrush(Color.Black),Standard(X_array[i-1],X_A,X_B,1,0)

-1.5f,Standard(Y_array[i-1],Y_A,Y_B,Y_C,Y_D)-1.5f,3,3);

〃画数值

gph.DrawString(Y_array[i-l].ToString(),newFont(uTimesNewRoman'1,11),

Brushes.Black,newPointF(Standard(X_array[i-1],X_A,X_B,1,0),Standard(Y_array[i-1],

Y_A,Y_B,Y_C,Y_D)));

〃画折线

if(i>1)gph.DrawLine(Pens.Red,Standard(X_array[i-2],X_A,X_B,1,0),

Standard(Y_array[i-2],Y_A,Y_B,Y_C,Y_D),Standard(X_array[i-1],X_A,X_B,1,0),

Standard(Y_array[i-1],Y_A,Y_B,Y_C,Y_D));

)

returnbmap;

〃保存输出图片

}

staticpublicBitmapdrawCurveOnImage(float[]X_array,float[]Y_array,stringchartTitle,

stringX_title,stringY_title)

(

CurvePaintCI=newCurvePaint();

returnCI.drawCurve(X_array,Y_array,chartTitle,X_title,Y_title);

)

staticpublicBitmapdrawCurveOnImage(float[lX_array,floatf]Y_array,stringchartTitle,

stringX_title,stringY_title,intX_KeduCount,intY_KeduCount)

(

CurvePaintCI=newCurvePaint();

CLXkeduCount=X_KeduCount;

CI.YkeduCount=Y_KeduCount;

returnCLdrawCurve(X_array,Y_array,chartTitle,X_title,Y_title);

)

staticpublicBitmapdrawCurveOnImage(float[]X_array,floatf]Y_array,stringchartTitle,

stringX_title,stringY_title,intX_KeduCount,intY_KeduCount,floatX_valueStrMoveleft,float

Y_valueStrMoveleft,boolX_DirectionVertical)

{

CurvePaintCI=newCurvePaint();

CLXkeduCount=X_KeduCount;

CI.YkeduCount=Y_KeduCount;

Cl.XvalueStrMoveleft=X_valueStrMoveleft;

CLYvalueStrMoveleft=Y_valueStrMoveleft;

CL_X_DirectionVertical=X_DirectionVertical;

returnCLdrawCurve(X_array,Y_array,chartTitle,X_title,Y_title);

)

曲线类源码结束

测试工程源码开始

usingSystem;

usingSystem.Conections.Generic;

usingSystem.ComponentModel;

usingSystem.Data;

usingSystem.Drawing;

usingSystem.Text;

usingSystem.Windows.Forms;

namespacetestPictureBox

(

publicpartialclassForml:Form

(

publicForm1()

(

InitializeComponent();

)

privatevoidpicBox_Paint(objectsender,PaintEventArgse)

(

float[]month=newfloatfl2];

for(inti=0;i<12;i++)

{

monthli]=i+l;

)

float[]d=newfloat[12]{20.5f,60,10.8f,15.6f,30,70.9f,50.3f,30.7f,70,50.4f,30.8f,

20);

picBox.SizeMode=PictureBoxSizeMode.Zoom;

CurvePaintcp=newCurvePaint();

cp.XkeduCount=10;

cp.YkeduCount=10;

cp.XvalueStrMoveleft=15;

picBox.Image=cp.drawCurve(month,d,”某工厂某产品月生产量图表",“月份”,“产量

(万)");

测试工程源码结束

这里的测试工程在VS2005下,新建一个windows窗口工程testPictureBox,拖

入一个picturebox控件,命名为picBox。在picBox的paint事件中调用曲线

类得到画好的曲线图片,将该图片载入picturebox即可。

C#制作曲线图源码

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Text;

usingSystem.Drawing;

usingSystem.Drawing.Imaging;

namespaceRealtimeCurve

(

///<SUMMARY>

///说明:实时图片生成类,在本例中横向坐标上每个像素都会有一个控制点

///实际开发中可以减少控制点,比如每5个像素用一个控制点

///这样的效果或许更加逼真

〃/作者:周公

///日期:2008-07-21

///首发地址:<A

href="hltp:///zhoufoxcn/archive/2008/07/21/2682027.aspx">hllp:///zho

ufoxcn/archive/2008/07/21/2682O27.aspx</A>

///</SUMMARY>

publicclassRealTimelmageMaker

(

privateintwidth;〃要生成的曲线图的宽度

privateintheight;〃耍生成的曲线图的高度

privatePoint|lpointList;〃用来绘制曲线图的关键点,依次将这些点连接起来即得到

曲线图

privateRandomrandom=newRandom。;//用于生成随机数

privateBitm叩currentimage;//当前要绘制的图片

privateColorbackColor;〃图片背景色

privateColorforeColor;〃图片前景色

///<SUMMARY>

///图片的高度

///</SUMMARY>

publicintHeight

(

get{returnheight;}

set{height=value;}

)

///<SUMMARY>

///图片的宽度

///</SUMMARY>

publicintWidth

(

get{returnwidth;}

set{width=value;}

)

///<SUMMARY>

///构造函数,指定生成的曲线图的宽度和高度

///</SUMMARY>

///<PARAMname二"width”,要生成的曲线图的宽度</PARAM>

///<PARAMname="height”>要生成的曲线图的高度v/PARAM>

publicRealTimeImageMaker(intwidth,int

height):this(width,height,Color.Gray,Color.Blue)

///<SUMMARY>

///构造函数,指定生成的曲线图的宽度、高度及背景色和前景色

///</SUMMARY>

///<PARAMname二"width”,要生成的曲线图的宽度</PARAM>

///<PARAMname="height”>要生成的曲线图的高度v/PARAM>

///<PARAMname="backColor”>曲线图背景色v/PARAM>

///<PARAMname="foreColor”>曲线图前景色</PARAM>

publicRealTimeImageMaker(intwidth,intheight,ColorbackColor,ColorforeColor)

(

this.width=width;

this.height=height;

this.backColor=backColor;

this.foreColor=foreColor;

pointList=newPoint[width];

PointtempPoint;

〃初始化曲线上的所有点坐标

for(inti=0;i<width;i++)

tempPoint=newPoint();

〃曲线的横坐标沿X轴依次递增,在横向位置上每个像素都有一个点

tempPoint.X=i;

〃曲线上每个点的纵坐标随机生成,但保证在显示区域之内

tempPoint.Y=random.Next()%height;

pointList[i]=tempPoint;

///<SUMMARY>

///获取当前依次连接曲线上每个点绘制成的曲线

///</SUMMARY>

///<RETURNS></RETURNS>

publicImageGetCurrentCurve()

(

//currentimage=historyImage.Clone(newRectangle(l,0,width-1,height),

PixelFormat.Format24bppRgb);

currentimage=newBitmap(width,height);

Pointp;

〃将当前定位曲线图的坐标点前移,并且将横坐标减1,

//这样做的效果相当于移除当前第一个点

for(inti=0;i<width-1;i++)

(

p=pointList[i+1];

pointListli]=newPoint(p.X-Lp.Y);

}

PointtempPoint=newPoint();

〃新生成曲线图定位点的最后一个点的坐标

tempPoint.X=width;

〃曲线上每个点的纵坐标随机生成,但保证在显示区域之内

tempPoint.Y=random.Next(DateTime.Now.Millisecond)%height;

〃在最后再添加一个新坐标点

pointList[width-lJ=tempPoint;

Graphicsg=Graphics.Fromlmage(currentlmage);

g.Clear(backColor);

〃绘制曲线图

g.DrawLines(newPen(foreColor),pointList);

g.Dispose();

returncurrentimage;

)

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Text;

usingSystem.Drawing;

usingSystem.Drawing.Imaging;

namespaceRealtimeCurve

(

///

///说明:实时图片生成类,在本例中横向坐标上每个像素都会有一个控制点

///实际开发中可以减少控制点,比如每5个像素用一个控制点

///这样的效果或许更加逼真

〃/作者:周公

///日期:2008-07-21

III首发地址:/zhoufoxcn/archive/2008/07/21/2682027.aspx

///

publicclassRealTimelmageMaker

{

private血width;〃要生成的曲线图的宽度

privateintheight;〃要生成的曲线图的高度

privatePoint[]pointList;〃用来绘制曲线图的关键点,依次将这些点连接起来即得到

曲线图

privateRandomrandom=newRandom。;//用于生成随机数

privateBitmapcurrentlmage;〃当前要绘制的图片

privateColorbackColor;〃图片背景色

privateColorforeColor;〃图片前景色

///

///图片的高度

///

publicintHeight

(

get{returnheight;}

set{height=value;}

}

///

///图片的宽度

///

publicintWidth

get{returnwidth;}

set{width=value;}

)

///

///构造函数,指定生成的曲线图的宽度和高度

///

///要生成的曲线图的宽度

///要生成的曲线图的高度

publicRealTimeImageMaker(intwidth,int

height):this(width,height,Color.Gray,Color.Blue)

///

///构造函数,指定生成的曲线图的宽度、高度及背景色和前景色

///

///要生成的曲线图的宽度

III要生成的曲线图的高度

///曲线图背景色

///曲线图前景色

publicRealTimeImageMaker(intwidth,intheight,ColorbackColor,ColorforeColor)

(

this.width=width;

this.height=height;

this.backColor=backColor;

this.fbreColor=foreColor;

pointList=newPoint[width];

PointtempPoint;

〃初始化曲线上的所有点坐标

for(inti=0;i<width;i++)

(

tempPoint=newPoint();

〃曲线的横坐标沿X轴依次递增,在横向位置上每个像素都有一个点

tempPoint.X=i;

//曲线上每个点的纵坐标随机生成,但保证在显示区域之内

tempPoint.Y=random.Next()%height;

pointList[i]=tempPoint;

)

)

///

///获取当前依次连接曲线上每个点绘制成的曲线

///

///

publicImageGetCurrentCurve()

{

//currentimage=historyImage.Clone(newRectangle(1,0,width-1,height),

PixelFormat.Format24bppRgb);

cuiTentlmage=newBitmap(width,height);

Pointp;

//将当前定位曲线图的坐标点前移,并且将横坐标减1,

〃这样做的效果相当于移除当前第一个点

for(inti=0;i<width-1;i++)

(

p=pointList[i+1];

pointList[i]=newPoint(p.X-l,p.Y);

)

PointtempPoint=newPoint();

//新生成曲线图定位点的最后一个点的坐标

tempPoint.X=width;

〃曲线上每个点的纵坐标随机生成,但保证在显示区域之内

tempPoint.Y=random.Next(DateTime.Now.Millisecond)%height;

//在最后再添加一个新坐标点

pointList[width-1]=tempPoint;

Graphicsg=Graphics.Fromlmage(currentlmage);

g.Clear(backColor);

〃绘制曲线图

g.DrawLines(newPen(foreColor),pointList);

g.Dispose();

returncurrentimage;

}

)

}窗体关键代码:

viewplaincopytoclipboardprint?

usingSystem;

usingSystem.Collections.Generic;

usingSystem.ComponentModel;

usingSystem.Data;

usingSystem.Drawing;

usingSystem.Text;

usingSystem.Windows.Forms;

usingSystem.Threading;

namespaceRealtimeCurve

(

///<SUMMARY>

III说明:显示实时曲线图的窗体

///作者:周公

///日期:2008-07-21

///首发地址:<A

href="/zhoufoxcn/archive/2008/07/21/2682027.aspx">/zho

ufoxcn/archive/2008/07/21/2682027.aspx</A>

///</SUMMARY>

publicpartialclassFormRealTime:Form

{

Threadthread;

RealTimelmageMakerrti;

ColorbackColor=Color.Black;〃指定绘制曲线图的背景色

publicFormRealTime()

(

InitializeComponent();

rti=newRealTimeImageMaker(Width,Height,backColor,Color.Green);

由read=newThread(newThreadStart(Run));

thread.Start();

}

privatevoidRun()

(

while(true)

(

Imageimage=rti.GetCunentCurve();

Graphicsg=CreateGraphics();

〃用指定背景色清除当前窗体上的图象

g.Clear(backColor);

g.DrawImage(image,0,0);

g.Dispose();

〃每秒钟刷新一次

Thread.Sleep(1000);

)

)

privatevoidFormRealTime_FormClosing(objectsender,FormClosingEventArgse)

(

〃在窗体即将关闭之前中止线程

thread.Abort();

c#绘制圆柱和曲线

在我们程序开发的过程中经常会需要绘制曲线图和柱状图等,尤其是在做统计功

能时。但是有时候我们有觉得没有必要使用第三方控件(例如:ZedGraph等),

这是我们可以自己编写代码来实现这些图形绘制的功能。以下是我在开发过程中

所使用过的两段代码,现共享大家,希望能给大家带来一定的帮助,如有不妥敬

请斧正!

1.柱状图,效果图如下

ano8D0

QQUQ

08-10-0108-10-2108-11-1008-11-3008-12-20

代码如下:

注意:请注意参数chartTable图形里的一些元素需要从chartTable里面取。具体

请查看代码。

“Render是图形大标题,图开小标题,图形宽度,图形长度,饼图的数据集和饼图

的数据集

publicImageRender(stringtitle,intwidth,intheight,DataTablechartTable)

(

Bitmapbm=newBitmap(width,height);

Graphicsg=Graphics.Fromlmage(bm);

g.Clear(Color.White);

DataTabledt=chartTable;

constinttop=30;

constintleft=35;

if(width<left*2||height<top*2)

g.DrawString("绘图区域太小",newFont("Tahoma",8),

Brushes.Blue,newPointF(0,0));

returnbm;

)

〃计算最高的点

floathighPoint=1;

foreach(DataRowdrindt.Rows)

(

if(highPoint<Convert.ToSingle(dr[0]))

(

highPoint=Convert.ToSingle(dr[0]);

1

if(highPoint<Convert.ToSingle(dr[1]))

(

highPoint=Convert.ToSingle(dr[1]);

〃画大标题

g.DrawString(title,newFont("Tahoma",12),Brushes.Black,newPointF(2,

2));

StringFormatdrawFormat=newStringFormat();

drawFormat.FormatFlags=StringFormatFlags.DirectionVertical;

g.DrawString("[红+dt.Columns[0].ToString()+newFont("TahomaM,

8),

Brushes.Red,newPointF(2,top),drawFormat);

g.DrawString("[蓝—"+dt.Columns[1].ToString()+”]",newFont(HTahomaM,

8),

Brushes.Blue,newPointF(17,top),drawFormat);

〃画条形图

floatbarWidth=(Convert.ToSingle(width)-left)/(dt.Rows.Count*3+1);

PointFbarOrigin=newPointF(left+barWidth,0);

floatbarHeight=dt.Rows.Count;

floattopFontSize=(barWidth/highPoint.ToString().Length);

if(topFontSize>2*top/3)

(

topFontSize=2*top/3;

if(topFontSize<5)

topFontSize=5;

)

for(inti=0;i<dt.Rows.Count;i++)

(

〃底部字体的大小

floatbottomFontSize=(2*barWidth/dt.Rows[i][2].ToString().Length)

+2;

if(bottomFontSize>2*top/3)

(

bottomFontSize=2*top/3;

)

barHeight=Convert.ToSingle(dt.Rows[i][0])*(height-2*top)/

highPoint*1;

barOrigin.Y=height-barHeight-top;

g.FillRectangle(newSolidBrush(Color.Red),barOrigin.X,barOrigin.Y,

barWidth,barHeight);

〃柱状图底部

g.DrawString(dt.Rows[i][2].ToStringO,newFont("Tahoma'\

bottomFontSize),Brushes.Black,

newPointF(barOrigin.X,height-top));

〃柱状图顶部

g.DrawString(dt.Rows[i][0].ToString(),newFont("TahomaM,

topFontSize),Brushes.Red,

newPoinlF(barOrigin.X,barOrigin.Y-3*topFontSize/2));

barOrigin.X=barOrigin.X+barWidth;

barHeight=Convert.ToSingle(dt.Rows[i][1])*(height-2*top)/

highPoint*1;

barOrigin.Y=height-barHeight-top;

g.FillRectangle(newSolidBrush(Color.Blue),barOrigin.X,barOrigin.Y,

barWidth,

barHeight);

〃柱状图顶部

g.DrawString(dt.Rows[i][l].ToString(),newFont(nTahomaM,

topFontSize),Brushes.Blue,

newPointF(barOrigin.X,barOrigin.Y-3*topFontSize/2));

barOrigin.X=barOrigin.X+(barWidth*2);

〃设置边

g.DrawLine(newPen(Color.Blue,2),newPoint(left,top),

newPoint(left,height-top));

g.DrawLine(newPen(Color.Blue,2),newPoint(left,height-top),

newPoint(left+width,height-top));

g.Dispose();

returnbm;

)

catch

{

returnbm;

)

)

2.线状图,效果如下:

55500

〔〔

;:

36年

\\18500

代码如下:

注意:请注意参数chartTable图形里的一些元素需要从chartTable里面取。具体

请查看代码。

//Render是图形大标题,图开小标题,图形宽度,图形长度,饼图的数据集和饼图

的数据集

publicImageRender(stringtitle,intwidth,intheight,DataTablechartTable)

(

Bitmapbm=newBitmap(width,height);

Graphicsg=Graphics.Fromlmage(bm);

g.Clear(Color.White);

constinttop=30;

constintleft=35;

if(width<left*2||height<top*2)

g.DrawString("绘图区域太小”,newFont(nTahoman,8),

Brushes.Blue,newPointF(0,0));

returnbm;

)

if(chartTable==null)

(

g.DrawString("没有数据“,newFont("Tahoma",7),

Brushes.Blue,newPointF(0,0));

returnbm;

)

DataTabledt=chartTable;

〃计算最高的点

floathighPoint=1;

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论