C#生成饼形图及添加文字说明实例代码
本文以实例形式说明了C#生成饼形图,圆饼图,并为图表添加文字注释的方法。可实现文字显示在图表周围,直观形象的展示各个数据分量的走抛情况的效果。通常在编写系统报表过程中,使用图表显示数据是很多人认可的方式。本文所述的就是一个用VisualC#生成圆饼型图表,并且在图表外围添加数据分量报表说明的一个例子。
具体功能代码如下:
usingSystem; usingSystem.Collections.Generic; usingSystem.ComponentModel; usingSystem.Data; usingSystem.Drawing; usingSystem.Linq; usingSystem.Text; usingSystem.Windows.Forms; namespace在饼型图的外围显示说明文字 { publicpartialclassForm1:Form { publicForm1() { InitializeComponent(); } publicstaticstring[]XText=newstring[7]{"商品1","商品2","商品3","商品4","商品5","商品6","商品7"};//存储数据的名称数组 publicstaticfloat[]SzData=newfloat[7]{5F,17F,7F,2F,10F,5F,4F};//获取每列的和 publicstaticColor[]WearColor=newColor[]{Color.Red,Color.Gold,Color.Chartreuse,Color.Teal,Color.RoyalBlue,Color.Fuchsia,Color.Firebrick, Color.Goldenrod,Color.ForestGreen,Color.Aqua,Color.Blue,Color.PaleVioletRed,Color.Salmon,Color.Yellow,Color.LimeGreen,Color.LightBlue,Color.LightSteelBlue,Color.MediumPurple}; publicstaticstring[]AreaText;//临时存储数据的名称数组 Penmypen; floatAreaAngle=0F; publicstaticfloatXSize=50;//X轴的大小 publicstaticfloatYSize=50;//Y轴的大小 publicstaticfloatASum=50;//记录饼形的总和 publicstaticfloatTemXSize=0;//X轴的临时大小 publicstaticfloatXLeft=0;//X轴的左端点 publicstaticfloatXRight=0;//X轴的右端点 publicstaticfloatYUp=0;//Y轴的上端点 publicstaticfloatYDown=50;//Y轴的下端点 publicstaticSolidBrushmybrush=newSolidBrush(Color.Red); publicstaticfloatAline=20;//标识文字的前端线长 publicstaticfloatAsash=3;//标识文本名边框的宽度 publicstaticfloattemXLeft=0;//X轴的左端点初始化 #region绘制饼形图(Area) publicstaticfloatAreaXMaxWidth=0;//获取字符串的宽度 publicstaticfloatAreaXMaxHeight=0;//获取字符串的高度 //获取饼形图的标识文字 publicvoidAreaValue() { stringtemTextSize="";//存储最长的名称 FontLSfont=newSystem.Drawing.Font("宋体",8);//设置说明文字的字体 AreaText=newstring[XText.Length];//实例化一个临时数组 for(inti=0;i<AreaText.Length;i++)//获取名称 { AreaText[i]=XText[i]; } floatAresF=0;//记录百分比 for(inti=0;i<AreaText.Length;i++)//通过名称及百分比,组合说明文字 { AresF=(SzData[i]/ASum)*100;//获取当前记录的百分比 AresF=(float)Math.Round(AresF,3);//对百分比进行四舍五入 AreaText[i]=AreaText[i]+""+AresF.ToString()+"%";//组合说明文字 if(AreaText[i].Length>temTextSize.Length)//获取最长的说明文件 temTextSize=AreaText[i]; } GraphicsTitG=this.CreateGraphics();//创建Graphics类对象 SizeFXMaxSize=TitG.MeasureString(temTextSize+Asash*2,LSfont);//将绘制的字符串进行格式化 AreaXMaxWidth=XMaxSize.Width;//获取字符串的宽度 AreaXMaxHeight=XMaxSize.Height;//获取字符串的高度 } //绘制饼形图表 publicvoidProtractArea(Graphicsg) { AreaValue();//计算最长说明文字的大小 //初始化变量 mypen=newPen(Color.Black,1);//设置画笔的颜色及大小 floatf=0;//记录百分比 floatTimeNum=0;//扇形的绘制度数 floatAXLeft=0;//设置饼形图的X坐标 floatAYUp=0;//设置饼形图的Y坐标 floatAXSize=0;//设置饼形图的宽度 floatAYSize=0;//设置饼形图的高度 floatAtop=0;//记录饼形的高度为长和宽的最小值 floatAleft=0;//记录饼形的高度为长和宽的最小值 TimeNum=AreaAngle;//设置饼形图的起始度数 //计算饼形图的初始位置 XLeft=panel1.Width-(panel1.Width-5);//去了边框后饼形图的X位置 XSize=panel1.Width-10;//设置饼形图的宽度 temXLeft=AXLeft;//记录饼形图的X坐标 AXLeft=XLeft;//记录饼形图的X坐标 AXSize=XSize;//记录饼形图的宽度 //通过说明文字的大小计算饼形图的位置 AXLeft=AXLeft+AreaXMaxWidth+Aline;//设置去除说明文字后的饼形图X坐标 AYUp=AYUp+AreaXMaxHeight;//设置去除说明文字后的饼形图Y坐标 AXSize=XSize-AreaXMaxWidth*2-Aline*2;//设置去除说明文字后的饼形图宽度 AYSize=YSize-AreaXMaxHeight*2;//设置去除说明文字后的饼形图高度 if(AXSize>=AYSize)//如果饼形图的宽度大于等于高度 { Aleft=AXSize-AYSize;//记录饼形图的X坐标 AXSize=AYSize;//将高度设为宽度 } else { Atop=AYSize-AXSize;//记录饼形图的Y坐标 AYSize=AXSize;//将宽度设为高度 } if(Aleft!=0)//如果宽大于高 { AXLeft=AXLeft+Aleft/2;//设置饼形图横向局中 } if(Atop!=0)//如果高大于宽 { AYUp=AYUp+Atop/2;//设置饼形图纵向局中 } temXLeft=XLeft; //绘制饼形图 if(AXSize>0&&AYSize>0)//如果饼形图的宽和高大于0 { for(inti=0;i<SzData.Length;i++)//遍历数据 { f=SzData[i]/ASum;//获取当前数据的百分比 //设置当前扇形图的填充颜色 if(i>=WearColor.Length)//如果没有超出颜色数组 mybrush=newSolidBrush(WearColor[i-WearColor.Length]); else mybrush=newSolidBrush(WearColor[i]); g.FillPie(mybrush,AXLeft,AYUp,AXSize,AYSize,TimeNum,f*360);//绘制扇形图 TimeNum+=f*360;//设置下一个扇形图的度数 } ProAreaSign(g);//绘制饼形图的说明文字 } else return; } #endregion #region绘制饼形图标识(Area) publicvoidProAreaSign(Graphicsg) { AreaValue();//存储最长的名称 mypen=newPen(Color.Black,1);//设置画笔的颜色及大小 FontLSfont=newSystem.Drawing.Font("宋体",8);//设置说明文字的字体样式 SolidBrushZbrush=newSolidBrush(Color.Black);//设置存放说明文字边框的画刷 SolidBrushATbrush=newSolidBrush(Color.Khaki);//设置存放说明文字方块的背景画刷 //初始化变量 floatf=0;//记录百分比 floatTimeNum=0;//扇形的绘制度数 floatAXLeft=0;//设置饼形图的X坐标 floatAYUp=0;//设置饼形图的Y坐标 floatAXSize=0;//设置饼形图的宽度 floatAYSize=0;//设置饼形图的高度 floatAtop=0;//记录饼形的高度为长和宽的最小值 floatAleft=0;//记录饼形的高度为长和宽的最小值 GraphicsTitG=panel1.CreateGraphics();//创建Graphics类对象 SizeFXMaxSize=TitG.MeasureString("",LSfont);//将绘制的字符串进行格式化 floatSWidth=0;//获取字符串的宽度 floatSHeight=0;//获取字符串的高度 //计算饼形图的初始位置 XLeft=panel1.Width-(panel1.Width-5);//去了边框后饼形图的X位置 XSize=panel1.Width-10;//设置饼形图的宽度 temXLeft=AXLeft;//记录饼形图的X坐标 AXLeft=XLeft;//记录饼形图的X坐标 AXSize=XSize;//记录饼形图的宽度 //通过说明文字的大小计算饼形图的位置 AXLeft=AXLeft+AreaXMaxWidth+Aline;//设置去除说明文字后的饼形图X坐标 AYUp=AYUp+AreaXMaxHeight;//设置去除说明文字后的饼形图Y坐标 AXSize=XSize-AreaXMaxWidth*2-Aline*2;//设置去除说明文字后的饼形图宽度 AYSize=YSize-AreaXMaxHeight*2;//设置去除说明文字后的饼形图高度 if(AXSize>=AYSize)//如果饼形图的宽度大于等于高度 { Aleft=AXSize-AYSize;//记录饼形图的X坐标 AXSize=AYSize;//将高度设为宽度 } else { Atop=AYSize-AXSize;//记录饼形图的Y坐标 AYSize=AXSize;//将宽度设为高度 } if(Aleft!=0)//如果宽大于高 { AXLeft=AXLeft+Aleft/2;//设置饼形图横向局中 } if(Atop!=0)//如果高大于宽 { AYUp=AYUp+Atop/2;//设置饼形图纵向局中 } temXLeft=XLeft; //初始化说明文字前横线的变量 floatX1=0; floatY1=0; floatX2=0; floatY2=0; //初始化说明文字位置的变量 floatTX1=0; floatTY1=0; floatTX2=0; floatTY2=0; floattemf=0;//记录百分比 doubleradians=0;//记录扇形的角度 temf=(this.AreaAngle*(ASum/360)/ASum);//记录起始位置的度数 TimeNum=this.AreaAngle;//记录扇形的起始角度 //绘制说明文字 if(AXSize>0&&AYSize>0) { for(inti=0;i<SzData.Length;i++)//遍历所有说明文字 { f=SzData[i]/ASum;//获取当前记录的百分比 if(f==0)//如果当前值为0 continue;//执行下一次循环 radians=((double)((temf+f/2)*360)*Math.PI)/(double)180; X1=Convert.ToSingle(AXLeft+(AXSize/2.0+(int)((float)(AXSize/2.0)*Math.Cos(radians)))); Y1=Convert.ToSingle(AYUp+(AYSize/2.0+(int)((float)(AYSize/2.0)*Math.Sin(radians)))); XMaxSize=TitG.MeasureString(AreaText[i].Trim(),LSfont);//将绘制的字符串进行格式化 SWidth=XMaxSize.Width;//获取字符串的宽度 SHeight=XMaxSize.Height;//获取字符串的高度 if((temf+f/2)*360>90&&(temf+f/2)*360<=270) { X2=X1-Aline; TX1=X2-1-SWidth; TY1=Y1-SHeight/2-Asash; TX2=SWidth; TY2=SHeight+Asash*2; g.FillRectangle(ATbrush,TX1,TY1,TX2,TY2);//绘制内矩形 g.DrawRectangle(newPen(Color.Black,1),TX1,TY1,TX2,TY2);//绘制矩形 g.DrawString(AreaText[i].Trim(),LSfont,Zbrush,newPointF(X2-SWidth+Asash-1,Y1-SHeight/2)); } else { X2=X1+Aline; TX1=X2+1; TY1=Y1-SHeight/2-Asash; TX2=SWidth; TY2=SHeight+Asash*2; g.FillRectangle(ATbrush,TX1,TY1,TX2,TY2);//绘制内矩形 g.DrawRectangle(newPen(Color.Black,1),TX1,TY1,TX2,TY2);//绘制矩形 g.DrawString(AreaText[i].Trim(),LSfont,Zbrush,newPointF(X2+Asash+1,Y1-SHeight/2)); } Y2=Y1; g.DrawLine(newPen(newSolidBrush(Color.Black),1),X1,Y1,X2,Y2); TimeNum+=f*360; temf=temf+f; } } else return; } #endregion privatevoidpanel1_Paint(objectsender,PaintEventArgse) { XSize=panel1.Width;//X轴的大小 YSize=panel1.Height;//Y轴的大小 YDown=panel1.Height;//Y轴的下端点 ProtractArea(e.Graphics); } privatevoidForm1_Load(objectsender,EventArgse) { } } }
本例附有详细的注释说明,相信不难理解,读者还可以对其进行功能的修改或扩展,以实现更丰富的图文表现形式。