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 ; } } }
|