深圳升蓝软件
数据库开发 .Net技术  |  ASP技术 PHP技术 JSP技术 应用技术类   
Hiblue Software

从一个舆论调查的制作谈面向对象的编程思路(四)


March 25,2004
        public MyChart()
        {
            //
            // TODO: Add Constructor Logic here
            //
            m_arrItems = new ArrayList() ;
            m_strTitle = "" ;
            m_objBackColor = Color.White ;
            m_intWidth = 200 ;
            m_intHeight = 200 ;
            m_intChartType = ChartType.Pie ;
            m_strUnit = "" ;
        }

        /// <summary>
        /// 重载构造函数
        /// </summary>
        /// <param name="a_strTitle"> </param>
        /// <param name="a_objBackColor"> </param>
        /// <param name="a_intWidth"> </param>
        /// <param name="a_intHeight"> </param>
        /// <param name="a_intChartType"> </param>
        /// <param name="a_strUnit"> </param>
        public MyChart(string a_strTitle , System.Drawing.Color a_objBackColor ,
                        int a_intWidth , int a_intHeight , ChartType  a_intChartType , string a_strUnit)
        {
            m_arrItems = new ArrayList() ;
            m_strTitle = a_strTitle ;
            m_objBackColor = a_objBackColor ;
            m_intWidth = a_intWidth ;
            m_intHeight = a_intHeight ;
            m_intChartType = a_intChartType ;
            m_intTotalCount = 0 ;
            m_strUnit = a_strUnit ;
        }

        /// <summary>
        /// 添加一个新的统计图项目
        /// </summary>
        /// <param name="a_objItem"> </param>
        public void AddItem(object a_objItem)
        {
            if(a_objItem is MyClass.Util.ChartItem)
            {
                m_arrItems.Add(a_objItem) ;
                m_intTotalCount += ((ChartItem)a_objItem).Count ;
            }
            else
            {
                throw(new Exception("对象类型错误,要加入的必须是ChartItem对象")) ;
            }
        }

        /// <summary>
        /// 产生统计图图片
        /// </summary>
        /// <param name="a_strFileName">要保存的文件名 </param>
        /// <remarks>
        ///  a_strFileName必须是绝对物理路径
        /// </remarks>
        public void Create(string a_strFileName)
        {
            //如果没有定义统计图项,则抛出异常
            if (m_arrItems.Count == 0)
            {
                throw(new Exception("没有定义统计图项")) ;
            }


            //根据不同统计图类型选择函数
            switch(m_intChartType)
            {
                case ChartType.Bar:
                    DrawBar(a_strFileName) ;
                    break;

                case ChartType.Pie:
                    DrawPie(a_strFileName) ;
                    break ;

                case ChartType.Curve:
                    DrawCurve(a_strFileName) ;
                    break ;

                default:
                    DrawPie(a_strFileName) ;
                    break ;
            }

        }

        /// <summary>
        /// 画条形图
        /// </summary>
        /// <param name="a_strFileName">要保存的图片名称</param>
        protected void DrawBar(string a_strFileName)
        {
            //绘图准备,新建一个image对象,一个graphics对象
            System.Drawing.Image myBmp = new Bitmap(m_intWidth , m_intHeight ) ;
            System.Drawing.Graphics g = Graphics.FromImage(myBmp) ;

            //填充背景
            g.FillRectangle(new System.Drawing.SolidBrush(m_objBackColor) , 0 , 0 , m_intWidth , m_intHeight) ;

            //如果没有任何回答,则显示没有结果
            if (this.m_intTotalCount == 0)
            {
                g.DrawString("没有统计数字!" , new Font("宋体" , m_intWidth / 14) ,
                        new SolidBrush(Color.Red) , (m_intWidth - m_intWidth / 8 * 6) / 2 ,
                        m_intHeight / 2 - m_intWidth / 8) ;
            }
            else
            {
            
                //写题目

                //g.DrawString(m_strTitle , new System.Drawing.Font("黑体" , m_intWidth / 30) ,
                //        new System.Drawing.SolidBrush(Color.Black) , (m_intWidth - m_strTitle.Length * (m_intWidth / 30))/2  , 10 ,
                //        System.Drawing.StringFormat.GenericDefault) ;




                //画统计图项目的矩形
                //计算每个矩形的宽度
                int intWidth = m_intWidth / (m_arrItems.Count * 2 - 1) ;

                //定义一个一个像素宽的黑色的笔
                System.Drawing.Pen pen = new System.Drawing.Pen(new System.Drawing.SolidBrush(Color.Black) , 1) ;

                for (int i = 0 ; i < m_arrItems.Count ; i ++)
                {
                    ChartItem item = (ChartItem)m_arrItems ;

                    //计算所占百分比
                    float intPercent = (float)Decimal.Divide(item.Count * 100 , m_intTotalCount) ;

                    //计算矩形高度
                    int intHeight = (int)(m_intHeight/ 3 * 2 * intPercent / 100 - 10) ;

                    //计算矩形坐标
                    int ix = intWidth * i * 3 / 2 + intWidth ;
                    int iy = m_intHeight /  3 * 2  - intHeight ;


                    //画矩形
                    g.FillRectangle(new System.Drawing.SolidBrush(item.Color) ,
                                    ix , iy , intWidth , intHeight + 10) ;

                    //写字
                    //计算字体大小
                    int intFontSize = intWidth / this.TotalCount.ToString().Length ;
                    //限制一下,字体大小不能超过12
                    intFontSize = intFontSize > 12 ? 12 : intFontSize ;
                    g.DrawString(item.Count.ToString() + m_strUnit ,
                                new System.Drawing.Font("宋体" , intFontSize) ,
                                new System.Drawing.SolidBrush(item.Color) ,
                                ix , iy - intFontSize * 2) ;

                    //画图例

                    //计算字体大小
                    intFontSize = m_intHeight / 3 / m_arrItems.Count / 2 - 1 ;
                    intFontSize = intFontSize > 12 ? 12 : intFontSize ;
                    g.FillRectangle(new System.Drawing.SolidBrush(item.Color) , 20 ,
                                    m_intHeight / 3 * 2 + intFontSize * (i * 2 + 1) + 5 ,
                                    intFontSize , intFontSize) ;
                    g.DrawString( intPercent.ToInt32().ToString() + "%" ,
                                    new System.Drawing.Font("宋体" , intFontSize) ,
                                    new System.Drawing.SolidBrush(item.Color) ,
                                    20 + intFontSize ,
                                    m_intHeight /  3 * 2 + intFontSize * (i * 2 + 1) + 5) ;
                    g.DrawString(item.Text  ,
                                    new System.Drawing.Font("宋体" , intFontSize) ,
                                    new System.Drawing.SolidBrush(item.Color) , 80 ,
                                    m_intHeight / 3 * 2 + intFontSize * (i * 2 + 1) + 5) ;
               
                }

                //画标志线
                g.DrawLine(pen , 0 , 10 , 0 , m_intHeight / 3 * 2 + 10) ;
                g.DrawLine(pen , 0 , m_intHeight / 3 * 2 + 10 , m_intWidth ,
                            m_intHeight / 3 * 2 + 10) ;
                for (int i = 0 ; i < 10 ; i++)
                {
                    g.DrawLine( pen , 0 , m_intHeight / 3 * 2 / 10 * i + 10 ,
                                5 , m_intHeight / 3 * 2 / 10 * i + 10) ;
                }

                //写单位
                //g.DrawString("单位:" + m_strUnit , new System.Drawing.Font("宋体" , m_intWidth/40) ,
                //        new SolidBrush(Color.Black) , 10 , 10) ;

                //清空
                pen.Dispose() ;
            }

            //清控对象
            g.Dispose() ;

            //保存为jpg格式
            try
            {
                myBmp.Save(a_strFileName , System.Drawing.Imaging.ImageFormat.JPEG) ;
            }
            catch(Exception e)
            {
                throw(new Exception("保存图片失败:" + e.ToString())) ;
            }

            myBmp.Dispose() ;
            
        }

        /// <summary>
        /// 画饼形图
        /// </summary>
        /// <param name="a_strFileName"> </param>
        /// <remarks>
        /// 这段程序很难懂,因为需要根据图片大小决定饼图及文字的大小,所以所有计算方法
        /// 都是试验出来的。
        /// </remarks>
        protected void DrawPie(string a_strFileName)
        {
            //绘图准备,新建一个image对象,一个graphics对象
            System.Drawing.Image myBmp = new Bitmap(m_intWidth , m_intHeight ) ;
            System.Drawing.Graphics g = Graphics.FromImage(myBmp) ;

            //填充背景
            g.FillRectangle(new System.Drawing.SolidBrush(m_objBackColor) , 0 , 0 , m_intWidth , m_intHeight) ;

            //如果没有任何回答,则显示没有结果
            if (this.m_intTotalCount == 0)
            {
                g.DrawString("没有统计数字!" , new Font("宋体" , m_intWidth / 14) ,
                        new SolidBrush(Color.Red) , (m_intWidth - m_intWidth / 8 * 6) / 2 ,
                        m_intHeight / 2 - m_intWidth / 8) ;
            }
            else
            {
                //定义一个浮点变量,记住上一个项目结束的角度
                int intAngel = 180 ;
            
                //画饼形图
                for (int i = 0 ; i < m_arrItems.Count ; i ++)
                {
                    ChartItem item = (ChartItem)m_arrItems ;

                    //开始时从180度开始

                    //计算所占百分比
                    float intPercent = (float)Decimal.Divide(item.Count * 100 , m_intTotalCount) ;
                    if (i == m_arrItems.Count - 1)
                    {
                        g.FillPie(new SolidBrush(item.Color) , 0 , 0 , m_intWidth * 2 / 3 ,
                                m_intHeight * 2 / 3 , intAngel , 540 - intAngel) ;
                    }
                    else
                    {
                        g.FillPie(new SolidBrush(item.Color) , 0 , 0 , m_intWidth * 2 / 3,
                                m_intHeight * 2 / 3 , intAngel , 360 * intPercent/100) ;
                        intAngel += (int)(360 * intPercent/100) ;
                    }

                    //画饼图右边图例百分数
                    //计算矩形大小
                    int intRectSize = m_intHeight / 30 ;

                    //画颜色方块
                    g.FillRectangle(new SolidBrush(item.Color) , m_intWidth * 2 / 3 + intRectSize ,
                        intRectSize * (i * 2 + 1) + m_intHeight / 2 - m_arrItems.Count * 2 * intRectSize
                        ,intRectSize , intRectSize) ;  

                    //写百分数
                    g.DrawString(item.Count.ToString() + m_strUnit ,
                            new Font("宋体" , intRectSize) ,
                            new SolidBrush(item.Color) ,
                            m_intWidth * 2 / 3 + intRectSize * 3 ,
                            intRectSize * (i * 2 + 1) + m_intHeight / 2
                            - m_arrItems.Count * 2 * intRectSize);

                    //画饼图下方图例文字
                    //计算矩形大小
                    intRectSize = m_intHeight / 3 / (m_arrItems.Count * 2) - 1 ;
                    intRectSize = intRectSize > 12 ? 12 : intRectSize ;

                    //画颜色方块
                    g.FillRectangle(new SolidBrush(item.Color) , intRectSize * 2 ,
                        intRectSize * (i * 2 + 1) + m_intHeight / 3 * 2  
                        ,intRectSize , intRectSize) ;  
                    //写文字
                    g.DrawString(intPercent.ToInt32().ToString() + "%  " + item.Text ,
                                new Font("宋体" , intRectSize) ,
                                new SolidBrush(item.Color) , intRectSize * 4 ,
                                intRectSize * ( i * 2 + 1) + m_intHeight / 3 * 2) ;
               
                }
            }
            //清控对象
            g.Dispose() ;

            //保存为jpg格式
            try
            {
                myBmp.Save(a_strFileName , System.Drawing.Imaging.ImageFormat.JPEG) ;
            }
            catch(Exception e)
            {
                throw(new Exception("保存图片失败:" + e.ToString())) ;
            }

            myBmp.Dispose() ;

        }

        /// <summary>
        /// 画折线图
        /// </summary>
        /// <param name="a_strFileName"> </param>
        protected void DrawCurve(string a_strFileName)
        {
            //绘图准备,新建一个image对象,一个graphics对象
            System.Drawing.Image myBmp = new Bitmap(m_intWidth , m_intHeight ) ;
            System.Drawing.Graphics g = Graphics.FromImage(myBmp) ;

            //填充背景
            g.FillRectangle(new System.Drawing.SolidBrush(m_objBackColor) , 0 , 0 , m_intWidth , m_intHeight) ;

            //如果没有任何回答,则显示没有结果
            if (this.m_intTotalCount == 0)
            {
                g.DrawString("没有统计数字!" , new Font("宋体" , m_intWidth / 14) ,
                        new SolidBrush(Color.Red) , (m_intWidth - m_intWidth / 8 * 6) / 2 ,
                        m_intHeight / 2 - m_intWidth / 8) ;
            }
            else
            {
                //定义一个一个像素宽的黑色的笔
                System.Drawing.Pen pen = new System.Drawing.Pen(new System.Drawing.SolidBrush(Color.Black) , 1) ;
            
                //画标志线
                g.DrawLine(pen , 0 , 10 , 0 , m_intHeight / 3 * 2 + 10) ;
                g.DrawLine(pen , 0 , m_intHeight / 3 * 2 + 10 , m_intWidth , m_intHeight / 3 * 2 + 10) ;
                for (int i = 0 ; i < 10 ; i++)
                {
                    g.DrawLine( pen , 0 , m_intHeight / 3 * 2 / 10 * i + 10 , 5 , m_intHeight / 3 * 2 / 10 * i + 10) ;
                }

                //写单位
                g.DrawString("单位:" + m_strUnit , new System.Drawing.Font("宋体" , m_intWidth/40) ,
                        new SolidBrush(Color.Black) , 10 , 10) ;

                //画折线

                //计算宽度
                int intWidth = m_intWidth / (m_arrItems.Count * 2) ;

                //定义两个变量,记住上一个点的x , y
                int ix = 0 ;
                int iy = 0 ;

                for ( int i = 0 ; i < m_arrItems.Count ; i ++)
                {
                    ChartItem item = (ChartItem)m_arrItems ;

                    //计算所占百分比
                    float intPercent = (float)Decimal.Divide(item.Count * 100 , m_intTotalCount) ;

                    //计算点高度
                    int intHeight = (int)(m_intHeight / 3 * 2 * intPercent / 100) ;

                    //画点
                    g.FillEllipse(new SolidBrush(item.Color) , intWidth * (i * 2 + 1) ,
                        m_intHeight / 3 * 2 - intHeight , 10 , 10) ;
               
                    //连接线
                    //定义笔,如果是升则为蓝颜色,否则是红色
                    if (iy > m_intHeight /3 * 2 - intHeight + 5)
                    {
                        pen = new Pen(new SolidBrush(Color.Blue) , 3) ;
                    }
                    else
                    {
                        pen = new Pen(new SolidBrush(Color.Red) , 3) ;
                    }
                    if (i != 0)
                    {
                        g.DrawLine(pen , ix , iy , intWidth * (i * 2 + 1) + 5 , m_intHeight /3 * 2 - intHeight + 5) ;                    
                    }
                    ix = intWidth * (i * 2 + 1) + 5 ;                                 
                    iy = m_intHeight / 3 * 2 - intHeight + 5 ;

                    //画饼图下方图例文字
                    //计算矩形大小
                    int intRectSize = m_intHeight / 3 / (m_arrItems.Count * 2) - 1 ;
                    intRectSize = intRectSize > 12 ? 12 : intRectSize ;

                    //画颜色方块
                    g.FillRectangle(new SolidBrush(item.Color) , intRectSize * 2 ,
                        intRectSize * (i * 2 + 1) + m_intHeight / 3 * 2 + 5
                        ,intRectSize , intRectSize) ;  
                    //写文字
                    g.DrawString(intPercent.ToInt32().ToString() + "%  " + item.Text ,
                                new Font("宋体" , intRectSize) ,
                                new SolidBrush(item.Color) , intRectSize * 4 ,
                                intRectSize * ( i * 2 + 1) + m_intHeight / 3 * 2 + 5) ;
                }

                //清空
                pen.Dispose() ;
            }

            //清控对象
            g.Dispose() ;

            //保存为jpg格式
            try
            {
                myBmp.Save(a_strFileName , System.Drawing.Imaging.ImageFormat.JPEG) ;
            }
            catch(Exception e)
            {
                throw(new Exception("保存图片失败:" + e.ToString())) ;
            }

            myBmp.Dispose() ;

            
            
        }

    }

    /// <summary>
    /// 统计图项目类
    /// </summary>
    /// <remarks>
    ///  构造一个统计图项目,属性有要显示的文字、所占的百分比以及想显示的颜色。
    /// </remarks>
    public class ChartItem : object
    {
        /// <summary>
        /// 要显示的文字
        /// </summary>
        private string m_strText ;

        /// <summary>
        /// 数量
        /// </summary>
        private int m_intCount ;


        /// <summary>
        /// 颜色
        /// </summary>
        private System.Drawing.Color m_objColor ;

        //属性
        public string Text
        {
            get
            {
                return m_strText ;
            }
            set
            {
                m_strText = value ;
            }
        }


        public int Count
        {
            get
            {
                return m_intCount ;
            }
            set
            {
                m_intCount = value ;
            }
        }
        public System.Drawing.Color Color
        {
            get
            {
                return m_objColor ;
            }
            set
            {
                m_objColor = value ;
            }
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        public ChartItem()
        {
            m_strText = "" ;
            m_intCount = 0 ;
            m_objColor = Color.White ;
        }

        /// <summary>
        /// 重载构造函数
        /// </summary>
        /// <param name="a_strText"> </param>
        /// <param name="a_intPercent"> </param>
        /// <param name="a_objColor"> </param>
        public ChartItem(string a_strText , int a_intCount , System.Drawing.Color a_objColor)
        {
            m_strText = a_strText ;
            m_objColor = a_objColor ;
            m_intCount = a_intCount ;
        }
    }
}
       
Copyright © 2001-2008 Shenzhen Hiblue Software Team All rights reserved