[转载]asp.net下使用C#实现动态绘制图表
BS结构的程序最头疼的就是web报表的制作,虽然有水晶报表这一控件。
但是那是付费的,要正版啊亲,再说了我们只是实现简单的功能有木有,所以不用那么复杂吧。
总之,本文的目的是通过C#提供的System.Drawing2D下的绘图类动态生成报表。
项目中一共用到了饼图和折现图,所以也就实现了这两个图形的回执功能。
先来看看类图:
先放上GraphicBase类和IGraphic的接口:
/************************************************ **GraphicBase.cs **绘图基类,实现动态图表的绘制 **编译环境:VS2010,Windows7 C#4.0 **2012-5-18 **************************************************/ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Drawing; namespace Graphic { public abstract class GraphicBase { #region Properties public String Title { get { return this._titletxt; } set { this._titletxt = value; } } public int Width { get { return this._width; } set { this._width = value; } } public int Height { get { return this._height; } set { this._height = value; } } public Font TitleFont { get { return this._titlefont; } set { this._titlefont = value; } } public Font TxtFont { get { return this._txtfont; } set { this._txtfont = value; } } public Color BKColor { get { return this._bkcolor; } set { this._bkcolor = value; } } #endregion #region Fields protected int _width; protected int _height; protected String _titletxt; protected Font _titlefont; protected Font _txtfont; protected Color _bkcolor=Color.White; protected Bitmap _image; protected Graphics _g; #endregion #region Methods protected virtual void intiGraphic() { this._image = new Bitmap(_width, _height); this._g = Graphics.FromImage(this._image); } public virtual void setBkgColor() { this._g.FillRectangle( new SolidBrush(BKColor), 0, 0, _width, _height); } public virtual void setFont() { this._txtfont= new Font("verdana", 9); this._titlefont = new Font("verdana", 10, FontStyle.Bold); } public virtual System.IO.MemoryStream getGraphic() { System.IO.MemoryStream ms = new System.IO.MemoryStream(); _image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif); return ms; } protected virtual void drawTitle() { } protected virtual void drawIdentification() { } protected virtual void drawGraphic() { } #endregion } }
/************************************************ **IGraphic.cs **绘图基类,实现动态图表的绘制 **编译环境:VS2010,Windows7 C#4.0 **2012-5-18 **************************************************/ using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Grphics { public interface IGraphic { //设置字体 void setFont(); //设置背景颜色 void setBkgColor(); //实现绘图操作 void doDraw(); //将绘制的图形以流的形式返回 System.IO.MemoryStream getGraphic(); } }
下面将饼图的绘制代码贴上:
/************************************************ **PieGraphic.cs **绘图基类,实现动态图表的绘制 **编译环境:VS2010,Windows7 C#4.0 **2012-5-18 **************************************************/ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Drawing; using System.Collections; namespace Grphics { public class PieGraphic:GraphicBase,IGraphic { //饼图数据类 public class pieData { #region Fields private float _total=0; private Dictionary<String,float>_parts= new Dictionary<string,float>(); #endregion #region Properties public float Total { get { return this._total; } set { this._total = value; } } public Dictionary<String, float> Parts { get { return this._parts; } set { this._parts = value; } } #endregion #region Methods public void addPart(String text,float value) { this.Parts.Add(text,value); } public void removePart(String text) { this.Parts.Remove(text); } #endregion } #region Fields private int _diameter; private pieData _data; private Rectangle _pierect; private ArrayList _colors=new ArrayList(); #endregion #region Properties //饼图周长 public int Diameter { get { return this._diameter; } set { this._diameter = value; } } public pieData PieData { get { return this._data; } set { this._data = value; } } #endregion #region Methods public PieGraphic(pieData data, int diameter, String title) { this.Title = title; this.Diameter = diameter; this._data = data; } protected override void intiGraphic() { int bufferspace = 15; int titleheight = this.TitleFont.Height + bufferspace; this._height = _diameter + titleheight; int lendwidth = _diameter * 2; this._width = _diameter + lendwidth + bufferspace; this._pierect = new Rectangle(0, titleheight, _diameter, _diameter); base.intiGraphic(); } public override void setBkgColor() { //设置背景色 base.setBkgColor(); //给扇形图区域加上一个背景色 this._g.FillRectangle(new SolidBrush(Color.Beige), _pierect); } protected override void drawTitle() { //标题设置颜色,黑色和蓝色 SolidBrush blackbrush = new SolidBrush(Color.Black); SolidBrush bluebrush = new SolidBrush(Color.Blue); this.Title += "\n \n\n"; StringFormat stringFormat = new StringFormat(); stringFormat.Alignment = StringAlignment.Center; stringFormat.LineAlignment = StringAlignment.Center; int titleheight = 15 + TitleFont.Height;/*15=bufferspace*/ this._g.DrawString(Title, TitleFont, blackbrush, new Rectangle(0, 20, _width, titleheight), stringFormat); } protected override void drawIdentification() { int count = 1; int colum = 0; int size = 8; int tmp; SolidBrush blackbrush = new SolidBrush(Color.Black); List<float> list = new List<float>(_data.Parts.Values); foreach (KeyValuePair<String, float> part in _data.Parts) { count++; tmp = count % size; if (count / size > 0) tmp += 2; _g.FillRectangle( new SolidBrush( (Color)_colors[count - 2]), new Rectangle( _diameter + 15 + colum * 200, tmp * 30, 35, 15)); colum = count / size; String str = part.Key + ":" + part.Value + " " + (part.Value / _data.Total * 100).ToString() + "%"; _g.DrawString(str, TxtFont, blackbrush, new PointF(_diameter + 50 + colum * 200, tmp * 30)); } } protected void getcolors() { Random rnd = new Random(); for (int i = 0; i < _data.Parts.Count(); i++) _colors.Add( Color.FromArgb(rnd.Next(255), rnd.Next(255), rnd.Next(255))); } protected override void drawGraphic() { //当前位置 float currentAngle = 0.0f; int count = 0; foreach (KeyValuePair<String, float> part in _data.Parts) { //画出部分扇区 float part_degree = part.Value / this._data.Total * 360.0f; this._g.FillPie( new SolidBrush( (Color)_colors[count++]), _pierect, currentAngle, part_degree); currentAngle += part_degree; } } public void doDraw() { try { this.getcolors(); this.setFont(); this.intiGraphic(); this.setBkgColor(); this.drawGraphic(); this.drawIdentification(); this.drawTitle(); } catch (Exception ex) { ex.Message.ToString(); } } #endregion } }
下面使用法介绍:
protected void Page_Load(object sender, EventArgs e) { Dictionary<String, float> dic = new Dictionary<string, float>(); dic.Add("test1",1); dic.Add("test2",3); dic.Add("test3",4); dic.Add("test4",2); float total=Convert.ToSingle(10); String title="测试用饼图"; PieGraphic.pieData data = new PieGraphic.pieData(); data.Parts = dic; data.Total = total; pie = new PieGraphic(data, 250, title); Response.ClearContent(); Response.ContentType = "image/gif"; pie.doDraw(); byte[] bytes=pie.getGraphic().ToArray(); Response.BinaryWrite(bytes); }
结果如下图:
http://blog.csdn.net/dasama/article/details/7555194