[转载]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

posted @ 2012-12-04 21:10  one light  阅读(735)  评论(0编辑  收藏  举报