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