资源描述
用C#绘制曲线图
照例先上图:
比以前Cool吧?呵呵,其实就是根据数据自动计算边距和字体等.
///<summary>
///自动根据参数调整图像大小
///</summary>
Public void Fit()
{
//计算字体距离
intFontSpace=FontSize+5;
//计算图像边距
Float fltSpace=Math.Min(Width/6, Height/6);
XSpace=fltSpace;
YSpace=fltSpace;
//计算X轴刻度宽度
XSlice=(Width-2*XSpace)/(Keys.Length-1);
//计算Y轴刻度宽度和Y轴刻度开始值
float fltMinValue=0;
float fltMaxValue=0;
for(int i=0;i<Values.Length;i++)
{
if(Values[i]<fltMinValue)
{
fltMinValue=Values[i];
}
else if(Values[i]>fltMaxValue)
{
fltMaxValue=Values[i];
}
}
if(YSliceBegin>fltMinValue)
{
YSliceBegin= fltMinValue;
}
int intYSliceCount=(int)(fltMaxValue/YSliceValue);
if(fltMaxValue%YSliceValue!=0)
{
intYSliceCount++;
}
YSlice=(Height-2*YSpace)/intYSliceCount;
}
看我把数据缩小一个级别的效果:
因为代码里面充斥了大量注释,也不敲太多文字了..完整代码奉上:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
usingSystem.Drawing;
usingSystem.Data;
usingSystem.Drawing.Drawing2D;
namespaceSarchPMS.Business.Draw
{
publicclassDrawingCurve:DrawingChart
{
///<summary>
///画曲线图
///</summary>
///<paramname="dsParameter"></param>
///<returns></returns>
publicoverrideBitmapDrawImage(DataSetdsParameter)
{
Curve2Dcuv2D=newCurve2D();
cuv2D.Fit();
returncuv2D.CreateImage();
}
}
publicclassCurve2D
{
privateGraphicsobjGraphics;//Graphics类提供将对象绘制到显示设备的方法
privateBitmapobjBitmap;//位图对象
privatefloatfltWidth=480;//图像宽度
privatefloatfltHeight=248;//图像高度
privatefloatfltXSlice=50;//X轴刻度宽度
privatefloatfltYSlice=50;//Y轴刻度宽度
privatefloatfltYSliceValue=20;//Y轴刻度的数值宽度
privatefloatfltYSliceBegin=0;//Y轴刻度开始值
privatefloatfltTension=0.5f;
privatestringstrTitle="曲线图";//标题
privatestringstrXAxisText="月份";//X轴说明文字
privatestringstrYAxisText="万元";//Y轴说明文字
privatestring[]strsKeys=newstring[]{"一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"};//键
privatefloat[]fltsValues=newfloat[]{20.0f,30.0f,50.0f,55.4f,21.6f,12.8f,99.5f,36.4f,78.2f,56.4f,45.8f,66.5f,99.5f,36.4f,78.2f,56.4f,45.8f,66.5f,20.0f,30.0f,50.0f,55.4f,21.6f,12.8f};//值
privateColorclrBgColor=Color.Snow;//背景色
privateColorclrTextColor=Color.Black;//文字颜色
privateColorclrBorderColor=Color.Black;//整体边框颜色
privateColorclrAxisColor=Color.Black;//轴线颜色
privateColorclrAxisTextColor=Color.Black;//轴说明文字颜色
privateColorclrSliceTextColor=Color.Black;//刻度文字颜色
privateColorclrSliceColor=Color.Black;//刻度颜色
privateColor[]clrsCurveColors=newColor[]{Color.Red,Color.Blue};//曲线颜色
privatefloatfltXSpace=100f;//图像左右距离边缘距离
privatefloatfltYSpace=100f;//图像上下距离边缘距离
privateintintFontSize=9;//字体大小号数
privatefloatfltXRotateAngle=30f;//X轴文字旋转角度
privatefloatfltYRotateAngle=0f;//Y轴文字旋转角度
privateintintCurveSize=2;//曲线线条大小
privateintintFontSpace=0;//intFontSpace是字体大小和距离调整出来的一个比较适合的数字
#region公共属性
///<summary>
///图像的宽度
///</summary>
publicfloatWidth
{
set
{
if(value<100)
{
fltWidth=100;
}
else
{
fltWidth=value;
}
}
get
{
if(fltWidth<=100)
{
return100;
}
else
{
returnfltWidth;
}
}
}
///<summary>
///图像的高度
///</summary>
publicfloatHeight
{
set
{
if(value<100)
{
fltHeight=100;
}
else
{
fltHeight=value;
}
}
get
{
if(fltHeight<=100)
{
return100;
}
else
{
returnfltHeight;
}
}
}
///<summary>
///X轴刻度宽度
///</summary>
publicfloatXSlice
{
set{fltXSlice=value;}
get{returnfltXSlice;}
}
///<summary>
///Y轴刻度宽度
///</summary>
publicfloatYSlice
{
set{fltYSlice=value;}
get{returnfltYSlice;}
}
///<summary>
///Y轴刻度的数值宽度
///</summary>
publicfloatYSliceValue
{
set{fltYSliceValue=value;}
get{returnfltYSliceValue;}
}
///<summary>
///Y轴刻度开始值
///</summary>
publicfloatYSliceBegin
{
set{fltYSliceBegin=value;}
get{returnfltYSliceBegin;}
}
///<summary>
///张力系数
///</summary>
publicfloatTension
{
set
{
if(value<0.0f&&value>1.0f)
{
fltTension=0.5f;
}
else
{
fltTension=value;
}
}
get
{
returnfltTension;
}
}
///<summary>
///标题
///</summary>
publicstringTitle
{
set{strTitle=value;}
get{returnstrTitle;}
}
///<summary>
///键,X轴数据
///</summary>
publicstring[]Keys
{
set{strsKeys=value;}
get{returnstrsKeys;}
}
///<summary>
///值,Y轴数据
///</summary>
publicfloat[]Values
{
set{fltsValues=value;}
get{returnfltsValues;}
}
///<summary>
///背景色
///</summary>
publicColorBgColor
{
set{clrBgColor=value;}
get{returnclrBgColor;}
}
///<summary>
///文字颜色
///</summary>
publicColorTextColor
{
set{clrTextColor=value;}
get{returnclrTextColor;}
}
///<summary>
///整体边框颜色
///</summary>
publicColorBorderColor
{
set{clrBorderColor=value;}
get{returnclrBorderColor;}
}
///<summary>
///轴线颜色
///</summary>
publicColorAxisColor
{
set{clrAxisColor=value;}
get{returnclrAxisColor;}
}
///<summary>
///X轴说明文字
///</summary>
publicstringXAxisText
{
set{strXAxisText=value;}
get{returnstrXAxisText;}
}
///<summary>
///Y轴说明文字
///</summary>
publicstringYAxisText
{
set{strYAxisText=value;}
get{returnstrYAxisText;}
}
///<summary>
///轴说明文字颜色
///</summary>
publicColorAxisTextColor
{
set{clrAxisTextColor=value;}
get{returnclrAxisTextColor;}
}
///<summary>
///刻度文字颜色
///</summary>
publicColorSliceTextColor
{
set{clrSliceTextColor=value;}
get{returnclrSliceTextColor;}
}
///<summary>
///刻度颜色
///</summary>
publicColorSliceColor
{
set{clrSliceColor=value;}
get{returnclrSliceColor;}
}
///<summary>
///曲线颜色
///</summary>
publicColor[]CurveColors
{
set{clrsCurveColors=value;}
get{returnclrsCurveColors;}
}
///<summary>
///X轴文字旋转角度
///</summary>
publicfloatXRotateAngle
{
get{returnfltXRotateAngle;}
set{fltXRotateAngle=value;}
}
///<summary>
///Y轴文字旋转角度
///</summary>
publicfloatYRotateAngle
{
get{returnfltYRotateAngle;}
set{fltYRotateAngle=value;}
}
///<summary>
///图像左右距离边缘距离
///</summary>
publicfloatXSpace
{
get{returnfltXSpace;}
set{fltXSpace=value;}
}
///<summary>
///图像上下距离边缘距离
///</summary>
publicfloatYSpace
{
get{returnfltYSpace;}
set{fltYSpace=value;}
}
///<summary>
///字体大小号数
///</summary>
publicintFontSize
{
get{returnintFontSize;}
set{intFontSize=value;}
}
///<summary>
///曲线线条大小
///</summary>
publicintCurveSize
{
get{returnintCurveSize;}
set{intCurveSize=value;}
}
#endregion
///<summary>
///自动根据参数调整图像大小
///</summary>
publicvoidFit()
{
//计算字体距离
intFontSpace=FontSize+5;
//计算图像边距
floatfltSpace=Math.Min(Width/6,Height/6);
XSpace=fltSpace;
YSpace=fltSpace;
//计算X轴刻度宽度
XSlice=(Width-2*XSpace)/(Keys.Length-1);
//计算Y轴刻度宽度和Y轴刻度开始值
floatfltMinValue=0;
floatfltMaxValue=0;
for(inti=0;i<Values.Length;i++)
{
if(Values[i]<fltMinValue)
{
fltMinValue=Values[i];
}
elseif(Values[i]>fltMaxValue)
{
fltMaxValue=Values[i];
}
}
if(YSliceBegin>fltMinValue)
{
YSliceBegin=fltMinValue;
}
intintYSliceCount=(int)(fltMaxValue/YSliceValue);
if(fltMaxValue%YSliceValue!=0)
{
intYSliceCount++;
}
YSlice=(Height-2*YSpace)/intYSliceCount;
}
接上文:
///<summary>
///生成图像并返回bmp图像对象
///</summary>
///<returns></returns>
publicBitmapCreateImage()
{
InitializeGraph();
intintKeysCount=Keys.Length;
intintValuesCount=Values.Length;
if(intValuesCount%intKeysCount==0)
{
intintCurvesCount=intValuesCount/intKeysCount;
for(inti=0;i<intCurvesCount;i++)
{
float[]fltCurrentValues=newfloat[intKeysCount];
for(intj=0;j<intKeysCount;j++)
{
fltCurrentValues[j]=Values[i*intKeysCount+j];
}
DrawContent(refobjGraphics,fltCurrentValues,clrsCurveColors[i]);
}
}
else
{
objGraphics.DrawString("发生错误,Values的长度必须是Keys的整数倍!",newFont("宋体",FontSize+5),newSolidBrush(TextColor),newPoint((int)XSpace,(int)(Height/2)));
}
returnobjBitmap;
}
///<summary>
///初始化和填充图像区域,画出边框,初始标题
///</summary>
privatevoidInitializeGraph()
{
//根据给定的高度和宽度创建一个位图图像
objBitmap=newBitmap((int)Width,(int)Height);
//从指定的objBitmap对象创建objGraphics对象(即在objBitmap对象中画图)
objGraphics=Graphics.FromImage(objBitmap);
//根据给定颜色(LightGray)填充图像的矩形区域(背景)
objGraphics.DrawRectangle(newPen(BorderColor,1),0,0,Width-1,Height-1);//画边框
objGraphics.FillRectangle(newSolidBrush(BgColor),1,1,Width-2,Height-2);//填充边框
//画X轴,注意图像的原始X轴和Y轴计算是以左上角为原点,向右和向下计算的
floatfltX1=XSpace;
floatfltY1=Height-YSpace;
floatfltX2=Width-XSpace+XSlice/2;
floatfltY2=fltY1;
objGraphics.DrawLine(newPen(newSolidBrush(AxisColor),1),fltX1,fltY1,fltX2,fltY2);
//画Y轴
fltX1=XSpace;
fltY1=Height-YSpace;
fltX2=XSpace;
fltY2=YSpace-YSlice/2;
objGraphics.DrawLine(newPen(newSolidBrush(AxisColor),1),fltX1,fltY1,fltX2,fltY2);
//初始化轴线说明文字
SetAxisText(refobjGraphics);
//初始化X轴上的刻度和文字
SetXAxis(refobjGraphics);
//初始化Y轴上的刻度和文字
SetYAxis(refobjGraphics);
//初始化标题
CreateTitle(refobjGraphics);
}
///<summary>
///初始化轴线说明文字
///</summary>
///<paramname="objGraphics"></param>
privatevoidSetAxisText(refGraphicsobjGraphics)
{
floatfltX=Width-XSpace+XSlice/2-(XAxisText.Length-1)*intFontSpace;
floatfltY=Height-YSpace-intFontSpace;
objGraphics.DrawString(XAxisText,newFont("宋体",FontSize),newSolidBrush(AxisTextColor),fltX,fltY);
fltX=XSpace+5;
fltY=YSpace-YSlice/2-intFontSpace;
for(inti=0;i<YAxisText.Length;i++)
{
objGraphics.DrawString(YAxisText[i].ToString(),newFont("宋体",FontSize),newSolidBrush(AxisTextColor),fltX,fltY);
fltY+=intFontSpace;//字体上下距离
}
}
///<summary>
///初始化X轴上的刻度和文字
///</summary>
///<paramname="objGraphics"></param>
privatevoidSetXAxis(refGraphicsobjGraphics)
{
floatfltX1=XSpace;
floatfltY1=Height-YSpace;
floatfltX2=XSpace;
floatfltY2=Height-YSpace;
intiCount=0;
intiSliceCount=1;
floatScale=0;
floatiWidth=((Width-2*XSpace)/XSlice)*50;//将要画刻度的长度分段,并乘以50,以10为单位画刻度线。
floatfltSliceHeight=XSlice/10;//刻度线的高度
objGraphics.TranslateTransform(fltX1,fltY1);//平移图像(原点)
objGraphics.RotateTransform(XRotateAngle,MatrixOrder.Prepend);//旋转图像
objGraphics.DrawString(Keys[0].ToString(),newFont("宋体",FontSize),newSolidBrush(SliceTextColor),0,0);
objGraphics.ResetTransform();//重置图像
for(inti=0;i<=iWidth;i+=10)//以10为单位
{
Scale=i*XSlice/50;//即(i/10)*(XSlice/5),将每个刻度分五部分画,但因为i以10为单位,得除以10
if(iCount==5)
{
objGraphics.DrawLine(newPen(newSolidBrush(AxisColor)),fltX1+Scale,fltY1+fltSliceHeight*1.5f,fltX2+Scale,fltY2-fltSliceHeight*1.5f);
//画网格虚线
PenpenDashed=newPen(newSolidBrush(AxisColor));
penDashed.DashStyle=DashStyle.Dash;
objGraphics.DrawLine(penDashed,fltX1+Scale,fltY1,fltX2+Scale,YSpace-YSlice/2);
//这里显示X轴刻度
if(iSliceCount<=Keys.Length-1)
{
objGraphics.TranslateTransform(fltX1+Scale,fltY1);
objGraphics.RotateTransform(XRotateAngle,MatrixOrder.Prepend);
objGraphics.DrawString(Keys[iSliceCount].ToString(),newFont("宋体",FontSize),newSolidBrush(SliceTextColor),0,0);
objGraphics.ResetTransform();
}
else
{
//超过范围,不画任何刻度文字
}
iCount=0;
iSliceCount++;
if(fltX1+Scale>Width-XSpace)
{
break;
}
}
else
{
objGraphics.DrawLine(newPen(newSolidBrush(SliceColor)),fltX1+Scale,fltY1+fltSliceHeight,fltX2+Scale,fltY2-fltSliceHeight);
}
iCount++;
}
}
///<summary>
///初始化Y轴上的刻度和文字
///</summary>
///<paramname="objGraphics"></param>
privatevoidSetYAxis(refGraphicsobjGraphics)
{
floatfltX1=XSpace;
floatfltY1=Height-YSpace;
floatfltX2=XSpace;
floatfltY2=Height-YSpace;
intiCount=0;
floatScale=0;
intiSliceCount=1;
floatiHeight=((Height-2*YSpace)/YSlice)*50;//将要画刻度的长度分段,并乘以50,以10为单位画刻度线。
floatfltSliceWidth=YSlice/10;//刻度线的宽度
stringstrSliceText=string.Empty;
objGraphics.TranslateTransform(XSpace-intFontSpace*YSliceBegin.ToString().Length,Height-YSpace);//平移图像(原点)
objGraphics.RotateTransform(YRotateAngle,MatrixOrder.Prepend);//旋转图像
objGraphics.DrawString(YSliceBegin.ToString(),newFont("宋体",FontSize),newSolidBrush(SliceTextColor),0,0);
objGraphics.ResetTransform();//重置图像
for(inti=0;i<iHeight;i+=10)
{
Scale=i*YSlice/50;//即(i/10)*(YSlice/5),将每个刻度分五部分画,但因为i以10为单位,得除以10
if(iCount==5)
{
objGraphics.DrawLine(newPen(newSolidBrush(AxisColor)),fltX1-fltSliceWidth*1.5f,fltY1-Scale,fltX2+fltSliceWidth*1.5f,fltY2-Scale);
//画网格虚线
PenpenDashed=newPen(newSolidBrush(AxisColor));
penDashed.DashStyle=DashStyle.Dash;
objGraphics.DrawLine(penDashed,XSpace,fltY1-Scale,Width-XSpace+XSlice/2,fltY2-Scale);
//这里显示Y轴刻度
strSliceText=Convert.ToString(YSliceValue*iSliceCount+YSliceBegin);
objGraphics.TranslateTransform(XSpace-intFontSize*strSliceT
展开阅读全文