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

编程|对象

        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[i] ;

                    //计算所占百分比
                    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[i] ;

                    //开始时从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[i] ;

                    //计算所占百分比
                    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 ;
        }
    }
}

时间: 2024-10-21 02:14:14

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

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

编程|对象     一般的web程序员刚刚转到.net或jsp时,往往编程观念转不过来,还是按照以前那种结构化的编程思 路来,而不从面向对象的角度考虑,造成业务逻辑与页面html代码混杂在一起,一旦页面原型改变,相应 的程序也要修改,这样造成代码的可重用性太低.而asp.net或jsp比asp最大的一个进步就是面向对象, 使代码可重用性达到最高.作为一个典型的web程序来说,一般把它分为三层比较理想,业务层,数据层 和页面显示层.下面以一个舆论调查的例子来讲一下.    让我们先来看一下如果一个

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

编程|对象 好了,现在万事俱备,只欠东风了,让我们看看现在做一个舆论调查多么简单: file : vote.aspx <%@ Page language="c#" Codebehind="vote.cs" AutoEventWireup="false" Inherits="Football.vote" %> <html>  <head>  <title>532.com.cn --

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

编程|对象      现在你是不是发现已经可以用这个类来进行舆论调查的操作了?但这个类里还没有任何的页面html 输出,所以现在的问题就是做页面显示层了,但现在又面临一个问题,那就是如何显示调查结果的问题, 比较流行的做法是用图表来表示,可以根据需要选择条形图.饼性图或折线图等等,那么如果在这个调查 类里来做也可以,但实在太不上算,应该单独做这么一个图表类,可以根据条件画这种图表,下面就是这 个类的定义: namespace MyClass.Util{    using System;    u

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

编程|对象 首先,我们要来定义一个数据库表,以保存舆论调查的想关数据,看下面这个表:/*新闻调查表*/if exists(select * from sysobjects where id = object_id('Survey'))   drop table Surveygo create table Survey(  ID        int         identity Primary key    not null ,  SurveyID    varchar(20)    def

Javascript基础与面向对象基础~第八讲 从人类的起源谈面向对象

我很荣幸来写这个结局,有时,我们看人,物,事需要用心去看,而不是用眼睛,因为用眼睛看到的往往是事物的假像,在这里对我最可爱的兄弟说一声,对不起. 从人类的起源谈面向对象,事实上主要说的是面向对象,现在我简单来说一下面向对象的特性吧,当你把一个程序写成面向对象的之后,它将有三个好处,即 封装,继承和多态,这是所有面向对象语言的一个共性,而对于JS这个语言来说,也可以借鉴一下,如JS里实现封装,JS里的继承等等. JS封装: 当我们干某件事时,需要将一些代码组织在一起,形成一个function,而这

一个用纯CSS制作的网页下拉菜单

网页特效代码实例:一个用纯CSS制作的网页下拉菜单. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN""http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"[ <!ELEMENT a (#PCDATA | table)* > ]><html xmlns="http://www.w3.org/1999/xhtml" xml:lang

从一个圈套For循环来谈软件设计[原创]

设计|循环|原创 从一个圈套For循环来谈软件设计 武汉华中师范大学信管系 谢刚 摘要:就自己的一次实际经历来谈谈软件设计过程中应该注意的一些细节 关键字:软件设计 需求分析      前段时间,跟外面公司设计一个MIS系统(使用工具是PB8.0+MSSQL),是一个关于安全生产的.为了体现我们设计人员的高质量服务,我在<需求说明>之外又帮他们设计了一个功能,就是:在每次这个功能窗口打开时,到数据库中去自动检测看看有没有冲突数据:也就是说,两个一模一样的器材是否被安装了到了两个不同的机器上.这

用ASP学做一个在线调查

关于在线调查大家一定不会陌生吧,给出一个问题和数个答案,让用户填写,然后把结果保存到数据库,自动进行统计,最后给出个统计的图.这期的跟我学做就来做一个在线调查系统. 一.功能设计 这么简单的系统也要做功能设计?有的人也许会觉得奇怪,不过话说回来不管怎么样的系统,先做功能设计总是能对系统有个比较清析的了解.让我们来看看在线调查的功能吧.基本的功能上面已经说了,就是要给出一个问题和数个答案,然后统计,最后给出图.在这个基础上,我们可以考虑给一个调查加上一个时间段(有效期),在这个时间段里调查是有效的

一个在C#以及类似的面向对象系統(Java中估计也是如此)中常见的错误

错误|对象   using System; namespace demo{    class ClassA    {        protected string a = "test";         public void Display()        {            Console.WriteLine(a);        }    }     class ClassB:ClassA    {        protected string a = "a