用C#绘制曲线图.pdf

上传人:无*** 文档编号:90896194 上传时间:2023-05-18 格式:PDF 页数:107 大小:11.40MB
返回 下载 相关 举报
用C#绘制曲线图.pdf_第1页
第1页 / 共107页
用C#绘制曲线图.pdf_第2页
第2页 / 共107页
点击查看更多>>
资源描述

《用C#绘制曲线图.pdf》由会员分享,可在线阅读,更多相关《用C#绘制曲线图.pdf(107页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、用 C#绘制曲线图照例先上图:比以前Cool吧?呵呵,其实就是根据数据自动计算边距和字体等./自动根据参数调整图像大小/Public void Fit()(/计算字体距离intFontS pace=FontS ize+5;/计算图像边距Float fltS pace=Math.Min(Width/6,Height/6);XS pace=fltS pace;YS pace=fltS pace;计算X 轴刻度宽度XS Iice=(Width-2*XS pace)/(Keys.Length-1);计算Y 轴刻度宽度和Y 轴刻度开始值float 租MinValue=O;float fltMaxValu

2、e=O;for(int i=O;iValues.Length;i+)(if(ValuesifltMaxValue)(fltMaxValue=Valuesi;)if(YS IiceBeginfltMinValue)(YS IiceBegin=fltMinValue;)int intYS IiceCount=(int)(fltMaxValue/YS IiceValue);if(fltMaxValue%YS IiceValue!=O)(intYS IiceCount+;)YS Iice=(Height-2*YS pace)/intYS IiceCount;看我把数据缩小一个级别的效果:因为代码里面充

3、斥了大量注释,也不敲太多文字了.完整代码奉上:/#region公共属性/Y 轴刻度宽度/Y轴说明文字/setfltXRotateAngle=value;/自动根据参数调整图像大小接上文:ht/2);floatfltYI=Height-YS pace;一个较能通用的C#画曲线类源码如下,思想以后面机会再说明:曲线类返回一个画好的图片曲线类源码开始-using System;using System.Collections.Generic;using System.Text;using System.Drawing;namespace testPictureBoxpublic class Curv

4、ePaintpublic CurvePaint()/刻度线条数private int _X_KeduCount=12;private int _Y_KeduCount=12;/刻度值位置对应刻度线左移像素private float _X_valueStrMoveleft=5f;private float _Y_valueStrMoveleft=45f;格式化刻度值private string _X_Format=#0.0;private string _Y_Format 二 ”#0.00;x 轴刻度值文字方向private bool _X_DirectionVertical=false;pub

5、lic int XkeduCountget return _X_KeduCount;set _X_KeduCount=value;)public int YkeduCount(get return _Y_KeduCount;set _Y_KeduCount=value;)public float XvalueStrMoveleft(get return _X_valueStrMoveleft;set _X_valueStrMoveleft=value;public float YvalueStrMoveleft(get return _Y_valueStrMoveleft;set _Y_val

6、ueStrMoveleft=value;public bool XdirectionVerticalget return _X_DirectionVertical;set _X_DirectionVertical=value;)public string Xformat(get return _X_Format;set _X_Format=value;)public string Yformat(get return _Y_Format;set _Y_Format=value;)private void setExtremeValues(float arr,ref float smallest

7、Value,ref float greatestValue)(if(arr=null|arr.Length=0)throw new Exception(用于绘曲线图的数组为空”);smallest Value=arr0;greatestValue=arr0;for(int i=1;i aiTi)smallestValue=aiTi;if(greatestValue arrfi)greatestValue=arri;private void setKeduStringArray(lloat keduArr,float increment)(for(int i=1;i keduArr.Length

8、;i+)keduArri=keduAiTi-1+increment;)/数据规格化f(x)=ax+bprivate float Standard(float x,float A,float B,float C,float D)(return C*(A*x+B)+D;)public Bitmap drawCurve(float X_array,float Y_array,string chartTitle,string X_title,string Y_title)画图初始化Bitmap bmap=new Bitmap(500,500);图片.大、Graphics gph=Graphics.Fr

9、omlmage(bmap);gph.Clear(Color.White);曲线图左、下、右、上的空隙均为60像素PointF cpt=new PointF(60f,bmap.Height-60f);坐标原点,坐标轴起始点(60,440)PointF X.EndPoint=new PointF(bmap.Width-60f,cpt.Y);/X 轴终点(440,440)PointF Y_EndPoint=new PointF(cpt.X,60f);/Y 轴终点(60,60)坐标轴三角形箭头PointFJ xpt=new PointF3 new PointF(X_EndPoint.X+15,X_En

10、dPoint.Y),newPointF(X_EndPoint.X,X_EndPoint.Y-4),new PointF(X_EndPoint.X,X_EndPoint.Y+4);/x轴三角形PointF ypt=new PointF3 new PointF(Y_EndPoint.X,Y_EndPoint.Y-15),newPointF(Y_EndPoint.X-4,Y_EndPoint.Y),new PointF(Y_EndPoint.X+4,Y_EndPoint.Y);/y轴三角形画图表标题gph.DrawString(chartTitle,new Font(“宋体,14),Brushes.

11、Black,newPointF(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(new SolidBrush(Color.Black),xpt);gph.DrawString(X_title,new Font(“宋体”,12),Brushes.Black,newPointF(X_EndPoint.X+10,X_EndPoint.

12、Y+10);画y 轴三角箭头、标题gph.DrawLine(Pens.Black,cpt.X,cpt.Y,Y_EndPoint.X,Y_EndPoint.Y);gph.DrawPolygon(Pens.Black,ypt);gph.FillPolygon(new SolidBrush(Color.Black),ypt);gph.DrawString(Y_title,new Font(“宋体,12),Brushes.Black,new PointF(0,Y_EndPoint.Y-30);float X_smallestValue=Of,X_greatestValue=Of;float Y_sma

13、llestValue=Of,Y_greatestValue=Of;猎取横、纵坐标的最大最小值setExtremeValues(X_array,ref X_smallestValue,ref X_greatestValue);setExtremeValues(Y_array,ref Y_smallestValue,ref Y_greatestValue);增量=(最大值一最小值)float X_Increment=(X_greatestValue-X_smallestValue);float YJncrement=(Y_greatestValue-Y_smallestValue);平均增量=(最

14、大值一最小值)/刻度间隔数,刻度间隔数=刻度线数一 1float X_AvgIncrement=X_Increment/(XkeduCount-1);float Y_AvgIncrement=Y_Increment/(YkeduCount-1);float X.KeduArr=new floatXkeduCount;/X 轴刻度值floatf Y_KeduArr=new floatYkeduCount;/Y 轴刻度值X_KeduArrO=X_smallest Value;Y_KeduArrOJ=Y_smal lest V al ue;/给刻度值数组赋值setKeduStringArray(X_

15、KeduArr,X_AvgIncrement);setKeduStringArray(Y_KeduArr,Y_AvgIncrement);刻度线起始位置PointF X_KeduStart=new PointF(cpt.X+30,cpt.Y);(90,440)x 轴第一根刻度线PointF X_KeduEnd=new PointF(X_EndPoint.X-10,X_EndPoint.Y);(430,440)x 轴最后一根刻度线PointF Y_KeduStart=new PointF(cpt.X,cpt.Y-30);(60,410)y 轴第一根刻度线PointF Y_KeduEnd=new

16、PointF(Y_EndPoint.X,Y_EndPoint.Y+10);/(60,70)y 轴最后一根刻度线刻度线位置坐标平均增量float X_KeduIncrement=(X_KeduEnd.X-X_KeduStart.X)/(XkeduCount-1);float Y_KeduIncrement=(Y_KeduStart.Y-Y_KeduEnd.Y)/(YkeduCount-1);设置X 轴刻度值显示方向StringFormat X_StringFormat=new StringFormat();if(XdirectionVertical)(X_StringFormat.FormatF

17、lags=StringFormatFlags.DirectionVertical;)画x 轴刻度线、刻度值for(int i=1;i=XkeduCount;i+)(if(i=1)(gph.DrawString(X_KeduArri-1 .ToString(Xformat),new Font(nTimes NewRoman,11),Brushes.Black,new PointF(X_KeduStart.X-XvalueStrMoveleft,X_KeduStart.Y+5),X_StringFormat);/new StringFormat(StringFormatFlags.Directio

18、nVertical);/SJn 一个参数实现文字竖排,默认为横排gph.DrawLine(Pens.LightGray,X_KeduStart.X,X_KeduStart.Y,X_KeduStart.X,Y_EndPoint.Y);elsegph.DrawString(X_KeduArri-1 .ToString(Xformat),new Font(Times NewRoman1,11),Brushes.Black,new PointF(X_KeduStart.X+(i-1)*X_KeduIncrement-XvalueStrMoveleft,cpt.Y+5),X_StringFormat);

19、/newStringFormat(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(int i=1;i=YkeduCount;i+)(if(i=1)(gph.DrawString(Y_KeduArri-l.ToString(Yformat),new Font(nTi

20、mes NewRoman*,11),Brushes.Black,new PointF(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_KeduArri-l.ToString(Yformat),new Font(uTimes NewRoman”,11),Brushes.Black,new PointF(Y_KeduStart.X-Yva

21、lueStrMoveleft,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-

22、410),规格化函数 F(x)=A*x+B因为窗口 丫轴坐标方向与正常坐标丫轴方向相反,故需要将丫坐标再变换一次,变换函数G(x)=C*x+D下面是X 坐标变换因子A,B,Y 坐标对应的变换因子A,B,C,Dfloat X_A=340.0f/X_Increment;float X_B=90.0f-(340.0f*X.smallestValue)/XJncrement;float Y_A=340.0f/Y_Increment;float Y_B=70.0f-(340.0f*Y_smallestValue)/Yncrement;float Y_C=-lf,Y_D=480f;for(int i=1;

23、i 1)gph.DrawLine(Pens.Red,Standard(X_arrayi-2,X_A,X_B,1,0),Standard(Y_arrayi-2,Y_A,Y_B,Y_C,Y_D),Standard(X_arrayi-1,X_A,X_B,1,0),Standard(Y_arrayi-1,Y_A,Y_B,Y_C,Y_D);)return bmap;保存输出图片static public Bitmap drawCurveOnImage(float X_array,float Y_array,string chartTitle,string X_title,string Y_title)(

24、CurvePaint CI=new CurvePaint();return CI.drawCurve(X_array,Y_array,chartTitle,X_title,Y_title);)static public Bitmap drawCurveOnImage(floatl X_array,floatf Y_array,string chartTitle,string X_title,string Y_title,int X_KeduCount,int Y_KeduCount)(CurvePaint CI=new CurvePaint();CLXkeduCount=X_KeduCount

25、;CI.YkeduCount=Y_KeduCount;return CLdrawCurve(X_array,Y_array,chartTitle,X_title,Y_title);)static public Bitmap drawCurveOnImage(float X_array,floatf Y_array,string chartTitle,string X_title,string Y_title,int X_KeduCount,int Y_KeduCount,float X_valueStrMoveleft,floatY_valueStrMoveleft,bool X_Direct

26、ionVertical)CurvePaint CI=new CurvePaint();CLXkeduCount=X_KeduCount;CI.YkeduCount=Y_KeduCount;Cl.XvalueStrMoveleft=X_val ueS tr M o vel eft;CL Y valueStrMoveleft=Y_valueStrMoveleft;CL_X_Direction Vertical=X_Direction V ertical;return CLdrawCurve(X_array,Y_array,chartTitle,X_title,Y_title);)曲线类源码结束-测

27、试工程源码开始-using System;using System.Conections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;namespace testPictureBox(public partial class Forml:Form(public Form 1()(InitializeComponent();)private void picBox_Paint(object sender

28、,PaintEventArgs e)(float month=new floatfl2;for(int i=0;i 12;i+)monthli=i+l;)float d=new float12 20.5f,60,10.8f,15.6f,30,70.9f,50.3f,30.7f,70,50.4f,30.8f,20);picBox.SizeMode=PictureBoxSizeMode.Zoom;CurvePaint cp=new CurvePaint();cp.XkeduCount=10;cp.YkeduCount=10;cp.XvalueStrMoveleft=15;picBox.Image=

29、cp.drawCurve(month,d,”某工厂某产品月生产量图表,“月份”,“产量(万);测试工程源码结束这里的测试工程在V S 2 0 0 5 下,新建一个w i nd o w s 窗口工程t e s t P i c t u r e B o x,拖入一个p i c t u r e b o x 控件,命名为p i c B o x。在 p i c B o x 的p a i nt 事件中调用曲线类得到画好的曲线图片,将该图片载入p ic t u r e b o x 即可。C#制作曲线图源码using System;using System.Collections.Generic;using S

30、ystem.Text;using System.Drawing;using System.Drawing.Imaging;namespace RealtimeCurve(/说明:实时图片生成类,在本例中横向坐标上每个像素都会有一个控制点/实际开发中可以减少控制点,比如每5个像素用一个控制点/这样的效果或许更加逼真/作者:周公/日期:2008-07-21/首 发 地 址:hllp:/ /2682O27.aspx/public class RealTimelmageMaker(private int width;要生成的曲线图的宽度private int height;耍生成的曲线图的高度priv

31、ate Point|l pointList;用来绘制曲线图的关键点,依次将这些点连接起来即得到曲线图private Random random=new Random。;/用于生成随机数private Bitm叩currentimage;/当前要绘制的图片private Color backColor;图片背景色private Color foreColor;图片前景色/图片的高度/public int Height(get return height;set height=value;)/图片的宽度/public int Width(get return width;set width=val

32、ue;)/构造函数,指定生成的曲线图的宽度和高度/PARAM name二 width”,要生成的曲线图的宽度/要生成的曲线图的高度v/PARAMpublic RealTimeImageMaker(int width,intheight):this(width,height,Color.Gray,Color.Blue)/构造函数,指定生成的曲线图的宽度、高度及背景色和前景色/PARAM name二 width”,要生成的曲线图的宽度/要生成的曲线图的高度v/PARAM/曲线图背景色v/PARAM/曲线图前景色public RealTimeImageMaker(int width,int heig

33、ht,Color backColor,Color foreColor)(this.width=width;this.height=height;this.backColor=backColor;this.foreColor=foreColor;pointList=new Pointwidth;Point tempPoint;初始化曲线上的所有点坐标for(int i=0;i width;i+)tempPoint=new Point();曲线的横坐标沿X轴依次递增,在横向位置上每个像素都有一个点tempPoint.X=i;曲线上每个点的纵坐标随机生成,但保证在显示区域之内tempPoint.Y=

34、random.Next()%height;pointListi=tempPoint;/获取当前依次连接曲线上每个点绘制成的曲线/public Image GetCurrentCurve()(/currentimage=historyImage.Clone(new Rectangle(l,0,width-1,height),PixelFormat.Format24bppRgb);currentimage=new Bitmap(width,height);Point p;将当前定位曲线图的坐标点前移,并且将横坐标减1,/这样做的效果相当于移除当前第一个点for(int i=0;i width-1;

35、i+)(p=pointListi+1;pointListli=new Point(p.X-Lp.Y);Point tempPoint=new Point();新生成曲线图定位点的最后一个点的坐标tempPoint.X=width;曲线上每个点的纵坐标随机生成,但保证在显示区域之内tempPoint.Y=random.Next(DateTime.Now.Millisecond)%height;在最后再添加一个新坐标点pointListwidth-l J=tempPoint;Graphics g=Graphics.Fromlmage(currentlmage);g.Clear(backColor)

36、;绘制曲线图g.DrawLines(new Pen(foreColor),pointList);g.Dispose();return currentimage;)using System;using System.Collections.Generic;using System.Text;using System.Drawing;using System.Drawing.Imaging;namespace RealtimeCurve(/说明:实时图片生成类,在本例中横向坐标上每个像素都会有一个控制点/实际开发中可以减少控制点,比 如 每5个像素用一个控制点/这样的效果或许更加逼真/作者:周公/

37、日期:2008-07-21III 首发地址:http:/ class RealTimelmageMakerprivate血width;要生成的曲线图的宽度private int height;要生成的曲线图的高度private Point pointList;用来绘制曲线图的关键点,依次将这些点连接起来即得到曲线图private Random random=new Random。;/用于生成随机数private Bitmap currentlmage;当前要绘制的图片private Color backColor;图片背景色private Color foreColor;图片前景色/图片的高度

38、/public int Height(get return height;set height=value;/图片的宽度/public int Widthget return width;set width=value;)/构造函数,指定生成的曲线图的宽度和高度/要生成的曲线图的宽度/要生成的曲线图的高度public RealTimeImageMaker(int width,intheight):this(width,height,Color.Gray,Color.Blue)/构造函数,指定生成的曲线图的宽度、高度及背景色和前景色/要生成的曲线图的宽度III要生成的曲线图的高度/曲线图背景色/

39、曲线图前景色public RealTimeImageMaker(int width,int height,Color backColor,Color foreColor)(this.width=width;this.height=height;this.backColor=backColor;this.fbreColor=foreColor;pointList=new Pointwidth;Point tempPoint;初始化曲线上的所有点坐标for(int i=0;i width;i+)(tempPoint=new Point();曲线的横坐标沿X轴依次递增,在横向位置上每个像素都有一个点

40、tempPoint.X=i;/曲线上每个点的纵坐标随机生成,但保证在显示区域之内tempPoint.Y=random.Next()%height;pointListi=tempPoint;)/获取当前依次连接曲线上每个点绘制成的曲线/public Image GetCurrentCurve()/currentimage=historyImage.Clone(new Rectangle(1,0,width-1,height),PixelFormat.Format24bppRgb);cuiTentlmage=new Bitmap(width,height);Point p;/将当前定位曲线图的坐标

41、点前移,并且将横坐标减1,这样做的效果相当于移除当前第一个点for(int i=0;i width-1;i+)(p=pointListi+1;pointListi=new Point(p.X-l,p.Y);)Point tempPoint=new Point();/新生成曲线图定位点的最后一个点的坐标tempPoint.X=width;曲线上每个点的纵坐标随机生成,但保证在显示区域之内tempPoint.Y=random.Next(DateTime.Now.Millisecond)%height;/在最后再添加一个新坐标点pointListwidth-1 =tempPoint;Graphics

42、 g=Graphics.Fromlmage(currentlmage);g.Clear(backColor);绘制曲线图g.DrawLines(new Pen(foreColor),pointList);g.Dispose();return currentimage;)窗体关键代码:view plaincopy to clipboardprint?using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System

43、.Text;using System.Windows.Forms;using System.Threading;namespace RealtimeCurve(/III说明:显示实时曲线图的窗体/作者:周公/日期:2008-07-21/首 发 地 址:http:/ /2682027.aspx/public partial class FormRealTime:FormThread thread;RealTimelmageMaker rti;Color backColor=Color.Black;指定绘制曲线图的背景色public FormRealTime()(InitializeCompone

44、nt();rti=new RealTimeImageMaker(Width,Height,backColor,Color.Green);由 read=new Thread(new ThreadStart(Run);thread.Start();private void Run()(while(true)(Image image=rti.GetCunentCurve();Graphics g=CreateGraphics();用指定背景色清除当前窗体上的图象g.Clear(backColor);g.Draw I mage(i mage,0,0);g.Dispose();每秒钟刷新一次Thread

45、.Sleep(1000);)private void FormRealTime_FormClosing(object sender,FormClosingEventArgs e)(在窗体即将关闭之前中止线程thread.Abort();c#绘制圆柱和曲线在我们程序开发的过程中经常会需要绘制曲线图和柱状图等,尤其是在做统计功能时。但是有时候我们有觉得没有必要使用第三方控件(例如:ZedGraph等),这是我们可以自己编写代码来实现这些图形绘制的功能。以下是我在开发过程中所使用过的两段代码,现共享大家,希望能给大家带来一定的帮助,如有不妥敬请斧正!1.柱状图,效果图如下出蓝,咨父统红:交矗ano

46、8D008-10-01 08-10-21 08-11-10Q Q08-11-30U Q08-12-20代码如下:注意:请注意参数chartTable图形里的一些元素需要从chartTable里面取。具体请查看代码。“Render是图形大标题,图开小标题,图形宽度,图形长度,饼图的数据集和饼图的数据集public Image Render(string title,int width,int height,DataTable chartTable)(Bitmap bm=new Bitmap(width,height);Graphics g=Graphics.Fromlmage(bm);g.Cle

47、ar(Color.White);DataTable dt=chartTable;const int top=30;const int left=35;if(width left*2|height top*2)g.DrawString(绘图区域太小,new Font(Tahoma,8),Brushes.Blue,new PointF(0,0);return bm;)计算最高的点float highPoint=1;foreach(DataRow dr in dt.Rows)(if(highPoint Convert.ToSingle(dr0)(highPoint=Convert.ToSingle(

48、dr0);1if(highPoint 2*top/3)(topFontSize=2*top/3;if(topFontSize 5)topFontSize=5;)for(int i=0;i 2*top/3)(bottomFontSize=2*top/3;)barHeight=Convert.ToSingle(dt.Rowsi0)*(height-2*top)/highPoint*1;barOrigin.Y=height-barHeight-top;g.FillRectangle(new SolidBrush(Color.Red),barOrigin.X,barOrigin.Y,barWidth,

49、barHeight);柱状图底部g.DrawString(dt.Rowsi 2.ToStringO,new Font(TahomabottomFontSize),Brushes.Black,new PointF(barOrigin.X,height-top);柱状图顶部g.DrawString(dt.Rowsi0.ToString(),new Font(TahomaM,topFontSize),Brushes.Red,new PoinlF(barOrigin.X,barOrigin.Y-3*topFontSize/2);barOrigin.X=barOrigin.X+barWidth;barH

50、eight=Convert.ToSingle(dt.Rowsi 1 )*(height-2*top)/highPoint*1;barOrigin.Y=height-barHeight-top;g.FillRectangle(new SolidBrush(Color.Blue),barOrigin.X,barOrigin.Y,barWidth,barHeight);柱状图顶部g.DrawString(dt.Rowsil.ToString(),new Font(nTahomaM,topFontSize),Brushes.Blue,new PointF(barOrigin.X,barOrigin.Y

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 教案示例

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com