-- 作者:cwzb
-- 发布时间:6/14/2004 1:08:00 PM
--
以上是做好后的次果图片; 我先把代码先放上去,日后,再进行一些说明。如果朋友们觉得没有必要,那,讲解部门,我就不讲了。 在放代码前,我先介绍代码里一个重要的问题: 1。在第一张图片,跟第三张图片,还不能把字往下斜。不过,我会把它改过来的:) 现在放代码。 我先建了一个库项目,共有五个文件: 1,AnalyseBase.cs 2,DataSource.cs 3,Hismap.cs 4,Linmap.cs 5,Primap.cs 我为这个类库项目取名为:Report;namespace:Biisomsoft.Report. 以下把各文件的源代码贴上去: 1,AnalyseBase.cs using System; using System.Drawing; using System.Drawing.Text; using System.Drawing.Imaging; using System.Drawing.Drawing2D; namespace Biisomsoft.Report { public class AnalyseBase { private DataSource _dataSource; public DataSource dataSource { get { return _dataSource; } set { _dataSource=value; } } private Pen[] _map_pens;//画笔 protected Pen[] map_pens { get { return _map_pens; } } private Font _font; protected Font font { get { return this._font; } } private Bitmap _map_canvas;//画布 protected Bitmap map_canvas { get { return _map_canvas; } } ////////////////////////////////////////////////// protected AnalyseBase(){} protected void DataBind() { this._map_canvas=new Bitmap(this._dataSource.map_width,this._dataSource.map_hieght); this._map_pens =new Pen[]{Pens.Blue, Pens.Red, Pens.Green, Pens.Orange, Pens.Black, Pens.Purple, Pens.SlateGray, Pens.Olive, Pens.DarkSlateBlue, Pens.Violet, Pens.CadetBlue, Pens.Goldenrod, Pens.DarkGreen, Pens.Brown, Pens.HotPink, Pens.BlueViolet, }; this._font =new Font("宋体",9); } public virtual Bitmap CreateMap() { return null; } } } 2,DataSource.cs using System; namespace Biisomsoft.Report { /// <summary> /// DataSource 的摘要说明。 /// </summary> public class DataSource { #region -- 画布大小 -- private int _map_width; public int map_width { get { return _map_width; } set { _map_width=value; } } private int _map_hieght; public int map_hieght { get { return _map_hieght; } set { _map_hieght=value; } } #endregion 画布大小 #region 定义折线图的数据源 private string[] _lin_titles; public string[] lin_titles { get { return _lin_titles; } set { _lin_titles=value; } } private string[] _lin_texts; public string[] lin_texts { get { return _lin_texts; } set { _lin_texts=value; } } private float[,] _lin_values; public float[,] lin_values { get { return _lin_values; } set { _lin_values=value; } } #endregion 定义折线图的数据源 #region 饼图与柱图的数据源 private string[] _texts; public string[] pri_texts { get { return _texts; } set { _texts=value; } } public string[] his_texts { get { return _texts; } set { _texts=value; } } private float[] _values; public float[] pri_values { get { return _values; } set { _values=value; } } public float[] his_values { get { return _values; } set { _values=value; } } #endregion 饼图与柱图的数据源 public DataSource() { this._map_width =650; this._map_hieght=400; } } } 3,Hismap.cs using System; using System.Drawing; using System.Drawing.Text; using System.Drawing.Imaging; using System.Drawing.Drawing2D; namespace Biisomsoft.Report { /// <summary> /// Hismap 的摘要说明。 /// </summary> public class Hismap:AnalyseBase { public override Bitmap CreateMap() { base.DataBind(); string[] texts=base.dataSource.his_texts; float[] valus =base.dataSource.his_values; Pen[] pens =base.map_pens; Graphics g=Graphics.FromImage(base.map_canvas); //给出数据源 int area_width =570;// int area_hieght=300; int defalt_span=80; //作为数据源的可控部份 if(area_width>texts.Length*defalt_span) area_width=texts.Length*defalt_span; Rectangle area=new Rectangle(50,50,area_width,area_hieght); g.Clear(Color.Snow); g.SmoothingMode=SmoothingMode.AntiAlias; g.DrawRectangle(Pens.Black,area); g.FillRectangle(new LinearGradientBrush(area,Color.Snow,Color.LightSteelBlue,LinearGradientMode.BackwardDiagonal), area.X, area.Y-1, area.Width+2, area.Height+1); //画出区域 int y_count=5; int y_width=20; int y_span =area.Height/y_count; long y_top =(this.Work_Top(valus)/10)*11; int his_side;//柱的底面边长 if(valus.Length>16) { g.DrawString("我感到非常抱歉,因为我只能帮你显示16支以内的柱子。建议更改分析段!谢谢。",base.font,Brushes.Red,area.Left+20,area.Height/2); return base.map_canvas; }//如果要画的柱子多于16,装先行退出程序 if(texts.Length<10) his_side=30; else { his_side=((area_width-20)/texts.Length)/2-1; } Pen line_pen=Pens.Blue; for(int i=0;i<y_count;i++) { g.DrawLine(Pens.Black,area.Left-y_width,area.Y+y_span*i,area.Left ,area.Y+y_span*i); g.DrawLine(line_pen,area.Left ,area.Y+y_span*(i+1) ,area.Left+his_side/2,area.Y+y_span*(i+1)-his_side/2); g.DrawLine(line_pen,area.Left+area.Width,area.Y+y_span*(i+1)-his_side/2,area.Left+his_side/2,area.Y+y_span*(i+1)-his_side/2); g.DrawString(Convert.ToString(y_top-y_top/y_count*i),base.font,Brushes.Black,area.Left-y_width*2,area.Y+y_span*i,StringFormat.GenericTypographic); } g.DrawLine(line_pen,area.Left+his_side/2,area.Bottom-his_side/2,area.Left+his_side/2,area.Top); //画出Y轴 int x_count =texts.Length; int x_span =area.Width/x_count; int his_span =his_side*2/3; float his_hieght=0; RectangleF temp_r; GraphicsPath temp_p; for(int i=0;i<x_count;i++) { if(valus[i]<1) his_hieght=1; else his_hieght=valus[i]; temp_r=new RectangleF(area.Left+his_span+(his_side*3/2+his_span)*i,area.Bottom-(area.Height*(his_hieght/y_top)),his_side,(area.Height*(his_hieght/y_top))); temp_p=new GraphicsPath(new PointF[]{ new PointF(temp_r.Left ,temp_r.Top), new PointF(temp_r.Left+his_side/2 ,temp_r.Top-his_side/2), new PointF(temp_r.Left+his_side*3/2,temp_r.Top-his_side/2), new PointF(temp_r.Left+his_side*3/2,temp_r.Bottom-his_side/2), new PointF(temp_r.Left+his_side ,temp_r.Bottom), new PointF(temp_r.Left+his_side ,temp_r.Top) }, new byte[] { (byte)PathPointType.Start, (byte)PathPointType.Line, (byte)PathPointType.Line, (byte)PathPointType.Line, (byte)PathPointType.Line, (byte)PathPointType.Line }); g.FillRectangle(new LinearGradientBrush(temp_r,Color.Snow,pens[i].Color,LinearGradientMode.BackwardDiagonal),temp_r); g.FillPath(new SolidBrush(pens[i].Color),temp_p); g.DrawString(texts[i],base.font,Brushes.Black,temp_r.Left,area.Bottom+2,new StringFormat(StringFormatFlags.DirectionVertical)); g.DrawString(valus[i].ToString(),base.font,Brushes.Black,temp_r.Left+his_side/2,temp_r.Top-his_side); } //画出柱子 return base.map_canvas; } private int Work_Top(float[] valus) { int temp=0; for(int i=0;i<valus.GetLength(0);i++) { if(temp<valus[i]) temp=(int)valus[i]; } temp=(int.Parse(temp.ToString().Substring(0,1))+1)*(int)Math.Pow(10,temp.ToString().Length-1); if(temp<2) return 100; else return (temp); } } } 4,Linmap.cs using System; using System.Drawing; using System.Drawing.Text; using System.Drawing.Imaging; using System.Drawing.Drawing2D; namespace Biisomsoft.Report { /// <summary> /// Linmap 的摘要说明。 /// </summary> public class Linmap:AnalyseBase { public override Bitmap CreateMap() { base.DataBind(); string[] texts =base.dataSource.lin_texts; string[] titles=base.dataSource.lin_titles; float[,] valus =base.dataSource.lin_values; Pen[] pens =base.map_pens; Graphics g=Graphics.FromImage(base.map_canvas); //给出数据源 int area_width =520;// int area_hieght=300; int defalt_span=80; //作为数据源的可控部份 if(area_width>texts.Length*defalt_span) area_width=texts.Length*defalt_span; Rectangle area=new Rectangle(50,50,area_width,area_hieght); g.Clear(Color.Snow); g.SmoothingMode=SmoothingMode.AntiAlias; g.DrawRectangle(Pens.Black,area); g.FillRectangle(new LinearGradientBrush(area,Color.Snow,Color.LightSteelBlue,LinearGradientMode.BackwardDiagonal), area.X, area.Y-1, area.Width+1, area.Height+1); //画出区域 int y_count=5; int y_width=20; if(valus.GetLength(1)>16) { g.DrawString("我感到非常抱歉,因为我只能帮你显示16个以内的段。建议更改分析段!谢谢。",base.font,Brushes.Red,area.Left+20,area.Height/2); return base.map_canvas; }//如果要画的段数多于16,装先行退出程序 int y_span =area.Height/y_count; long y_top =(this.Work_Top(valus)/10)*11; for(int i=0;i<y_count;i++) { g.DrawLine(Pens.Black,area.Left-y_width,area.Y+y_span*i,area.Left ,area.Y+y_span*i); g.DrawLine(new Pen(new HatchBrush(HatchStyle.DarkVertical,Color.White,Color.Green),1) ,area.Left ,area.Y+y_span*i,area.Left+area.Width,area.Y+y_span*i); g.DrawString(Convert.ToString(y_top-y_top/y_count*i),base.font,Brushes.Black,area.Left-y_width*2,area.Y+y_span*i); } //画出Y轴 int x_count =texts.Length; int x_hieght=20; int x_span =area.Width/x_count; for(int i=0;i<x_count;i++) { g.DrawLine(Pens.Black,area.Left+x_span*i,area.Bottom,area.Left+x_span*i,area.Bottom+x_hieght); g.DrawString(texts[i],base.font,Brushes.Black,area.Left+x_span*i,area.Bottom+2); } //画出X轴 for(int i=0;i<valus.GetLength(0);i++) { for(int j=0;j<x_count-1;j++) { g.DrawLine(pens[i], area.Left+x_span*j, area.Bottom-area.Height*(valus[i,j]/y_top), area.Left+x_span*(j+1), area.Bottom-area.Height*(valus[i,j+1]/y_top)); } } //画出折线图 int block_height=15; int block_width =50; int block_span =8; Rectangle r=new Rectangle( area.Right-(x_span*2/3), area.Top-block_height*2, block_span*2+block_width, (block_height+block_span)*valus.GetLength(0)+block_span); g.DrawRectangle(Pens.Black,r); g.FillRectangle(Brushes.Snow,r); for(int i=0;i<valus.GetLength(0);i++) { g.FillRectangle(new SolidBrush(pens[i].Color), r.Left+block_span, r.Top+block_span+(block_height+block_span)*i, block_width,block_height); g.DrawString( titles[i], base.font,Brushes.Black, r.Right, r.Top+block_span+(block_height+block_span)*i); } //画出示意目录 return map_canvas; //输出并结束 } private int Work_Top(float[,] valus) { int temp=0; for(int i=0;i<valus.GetLength(0);i++) { for(int j=0;j<valus.GetLength(1);j++) { if(temp<valus[i,j]) temp=(int)valus[i,j]; } } temp=(int.Parse(temp.ToString().Substring(0,1))+1)*(int)Math.Pow(10,temp.ToString().Length-1); if(temp<2) return 100; else return (temp); } } } 5,Primap.cs using System; using System.Drawing; using System.Drawing.Text; using System.Drawing.Imaging; using System.Drawing.Drawing2D; namespace Biisomsoft.Report { /// <summary> /// Primap 的摘要说明。 /// </summary> public class Primap:AnalyseBase { public override Bitmap CreateMap() { base.DataBind(); string[] texts =base.dataSource.pri_texts; float[] valus =base.dataSource.pri_values; Pen[] pens =base.map_pens; Graphics g=Graphics.FromImage(base.map_canvas); int area_width =300;// float value_sum=0; for(int i=0;i<valus.Length;i++) { value_sum+=valus[i]; } Rectangle area=new Rectangle(80,50,area_width,area_width); int area_span=30; g.Clear(Color.Snow); g.SmoothingMode=SmoothingMode.AntiAlias; g.DrawRectangle(Pens.Black,area.Left-area_span,area.Top-area_span,area.Width+area_span*2,area.Height+area_span*2); float degree=10; double radian; float x1,x2,y1,y2; int svalue_width=40; for(int i=0;i<valus.Length;i++) { g.FillPie(new LinearGradientBrush(area,Color.White,pens[i].Color,LinearGradientMode.BackwardDiagonal),area,degree,360*(valus[i]/value_sum)); radian=Math.PI*(180*valus[i]/value_sum+degree)/180; x1=(float)(area.Left+area_width/2+(area_width/2-50)*Math.Cos(radian)); y1=(float)(area.Top +area_width/2+(area_width/2-50)*Math.Sin(radian)); x2=(float)(area.Left+area_width/2+(area_width/2+15)*Math.Cos(radian)); y2=(float)(area.Top +area_width/2+(area_width/2+15)*Math.Sin(radian)); g.DrawLine( pens[i],x1,y1,x2,y2); if(Math.Cos(radian)>0) { g.DrawLine( pens[i],x2,y2,x2+svalue_width,y2); g.DrawString(valus[i].ToString(),base.font,new SolidBrush(pens[i].Color),x2,y2+2); } else { g.DrawLine( pens[i],x2,y2,x2-svalue_width,y2); g.DrawString(valus[i].ToString(),base.font,new SolidBrush(pens[i].Color),x2-svalue_width,y2+2); } degree+=360*(valus[i]/value_sum); } //画出饼块 int block_width =40; int block_hieght=20; int block_span =10; Rectangle r=new Rectangle( area.Right+area_span+block_span, area.Top-area_span, block_width+block_span*2, (block_hieght+block_span)*valus.Length+block_span); g.DrawRectangle(Pens.Black,r); g.FillRectangle(Brushes.Snow,r); for(int i=0;i<valus.Length;i++) { g.FillRectangle( new LinearGradientBrush( new Rectangle(r.Left+block_span,r.Top+block_span+(block_hieght+block_span)*i,block_width,block_hieght), pens[i].Color, Color.Snow, LinearGradientMode.BackwardDiagonal), r.Left+block_span, r.Top+block_span+(block_hieght+block_span)*i, block_width, block_hieght); g.DrawString(Convert.ToString((valus[i]/value_sum*100))+"% "+texts[i],base.font,Brushes.Black,r.Right+2,r.Top+block_span+(block_hieght+block_span)*i); } //画出标志方块 return base.map_canvas; } } } ///////////////////////以上为DLL文件里的内容; DLL的使用方法,例: Primap primap=new Primap(); DataSource source=new DataSource(); source.pri_texts =new string[]{"a","b"}; source.pri_values=new float[](100,500); primap.datasource=source; primap.CreateMap().Sava(Respone.OutStream,ImageFormat.jpeg);//这是在WEB上的用法.
|