本文实例讲述了c#绘制曲线图的方法。分享给大家供大家参考。具体如下:
1. 曲线图效果:
2. c#代码:
/// <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;
}
3. 数据缩小一个级别的效果:
4. 完整代码 drawingcurve.cs:
using system;
using system.collections.generic;
using system.text;
using system.drawing;
using system.data;
using system.drawing.drawing2d;
namespace sarchpms.business.draw
{
public class drawingcurve : drawingchart
{
/// <summary>
/// 画曲线图
/// </summary>
/// <param name="dsparameter"></param>
/// <returns></returns>
public override bitmap drawimage(dataset dsparameter)
{
curve2d cuv2d = new curve2d();
cuv2d.fit();
return cuv2d.createimage();
}
}
public class curve2d
{
private graphics objgraphics; //graphics 类提供将对象绘制到显示设备的方法
private bitmap objbitmap; //位图对象
private float fltwidth = 480; //图像宽度
private float fltheight = 248; //图像高度
private float fltxslice = 50; //x轴刻度宽度
private float fltyslice = 50; //y轴刻度宽度
private float fltyslicevalue = 20; //y轴刻度的数值宽度
private float fltyslicebegin = 0; //y轴刻度开始值
private float flttension = 0.5f;
private string strtitle = "曲线图" ; //标题
private string strxaxistext = "月份" ; //x轴说明文字
private string stryaxistext = "万元" ; //y轴说明文字
private string [] strskeys = new string [] { "一月" , "二月" , "三月" , "四月" , "五月" , "六月" , "七月" , "八月" , "九月" , "十月" , "十一月" , "十二月" }; //键
private float [] fltsvalues = new float [] { 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 }; //值
private color clrbgcolor = color.snow; //背景色
private color clrtextcolor = color.black; //文字颜色
private color clrbordercolor = color.black; //整体边框颜色
private color clraxiscolor = color.black; //轴线颜色
private color clraxistextcolor = color.black; //轴说明文字颜色
private color clrslicetextcolor = color.black; //刻度文字颜色
private color clrslicecolor = color.black; //刻度颜色
private color[] clrscurvecolors = new color[] { color.red, color.blue }; //曲线颜色
private float fltxspace = 100f; //图像左右距离边缘距离
private float fltyspace = 100f; //图像上下距离边缘距离
private int intfontsize = 9; //字体大小号数
private float fltxrotateangle = 30f; //x轴文字旋转角度
private float fltyrotateangle = 0f; //y轴文字旋转角度
private int intcurvesize = 2; //曲线线条大小
private int intfontspace = 0; //intfontspace 是字体大小和距离调整出来的一个比较适合的数字
#region 公共属性
/// <summary>
/// 图像的宽度
/// </summary>
public float width
{
set
{
if (value < 100)
{
fltwidth = 100;
}
else
{
fltwidth = value;
}
}
get
{
if (fltwidth <= 100)
{
return 100;
}
else
{
return fltwidth;
}
}
}
/// <summary>
/// 图像的高度
/// </summary>
public float height
{
set
{
if (value < 100)
{
fltheight = 100;
}
else
{
fltheight = value;
}
}
get
{
if (fltheight <= 100)
{
return 100;
}
else
{
return fltheight;
}
}
}
/// <summary>
/// x轴刻度宽度
/// </summary>
public float xslice
{
set { fltxslice = value; }
get { return fltxslice; }
}
/// <summary>
/// y轴刻度宽度
/// </summary>
public float yslice
{
set { fltyslice = value; }
get { return fltyslice; }
}
/// <summary>
/// y轴刻度的数值宽度
/// </summary>
public float yslicevalue
{
set { fltyslicevalue = value; }
get { return fltyslicevalue; }
}
/// <summary>
/// y轴刻度开始值
/// </summary>
public float yslicebegin
{
set { fltyslicebegin = value; }
get { return fltyslicebegin; }
}
/// <summary>
/// 张力系数
/// </summary>
public float tension
{
set
{
if (value < 0.0f && value > 1.0f)
{
flttension = 0.5f;
}
else
{
flttension = value;
}
}
get
{
return flttension;
}
}
/// <summary>
/// 标题
/// </summary>
public string title
{
set { strtitle = value; }
get { return strtitle; }
}
/// <summary>
/// 键,x轴数据
/// </summary>
public string [] keys
{
set { strskeys = value; }
get { return strskeys; }
}
/// <summary>
/// 值,y轴数据
/// </summary>
public float [] values
{
set { fltsvalues = value; }
get { return fltsvalues; }
}
/// <summary>
/// 背景色
/// </summary>
public color bgcolor
{
set { clrbgcolor = value; }
get { return clrbgcolor; }
}
/// <summary>
/// 文字颜色
/// </summary>
public color textcolor
{
set { clrtextcolor = value; }
get { return clrtextcolor; }
}
/// <summary>
/// 整体边框颜色
/// </summary>
public color bordercolor
{
set { clrbordercolor = value; }
get { return clrbordercolor; }
}
/// <summary>
/// 轴线颜色
/// </summary>
public color axiscolor
{
set { clraxiscolor = value; }
get { return clraxiscolor; }
}
/// <summary>
/// x轴说明文字
/// </summary>
public string xaxistext
{
set { strxaxistext = value; }
get { return strxaxistext; }
}
/// <summary>
/// y轴说明文字
/// </summary>
public string yaxistext
{
set { stryaxistext = value; }
get { return stryaxistext; }
}
/// <summary>
/// 轴说明文字颜色
/// </summary>
public color axistextcolor
{
set { clraxistextcolor = value; }
get { return clraxistextcolor; }
}
/// <summary>
/// 刻度文字颜色
/// </summary>
public color slicetextcolor
{
set { clrslicetextcolor = value; }
get { return clrslicetextcolor; }
}
/// <summary>
/// 刻度颜色
/// </summary>
public color slicecolor
{
set { clrslicecolor = value; }
get { return clrslicecolor; }
}
/// <summary>
/// 曲线颜色
/// </summary>
public color[] curvecolors
{
set { clrscurvecolors = value; }
get { return clrscurvecolors; }
}
/// <summary>
/// x轴文字旋转角度
/// </summary>
public float xrotateangle
{
get { return fltxrotateangle; }
set { fltxrotateangle = value; }
}
/// <summary>
/// y轴文字旋转角度
/// </summary>
public float yrotateangle
{
get { return fltyrotateangle; }
set { fltyrotateangle = value; }
}
/// <summary>
/// 图像左右距离边缘距离
/// </summary>
public float xspace
{
get { return fltxspace; }
set { fltxspace = value; }
}
/// <summary>
/// 图像上下距离边缘距离
/// </summary>
public float yspace
{
get { return fltyspace; }
set { fltyspace = value; }
}
/// <summary>
/// 字体大小号数
/// </summary>
public int fontsize
{
get { return intfontsize; }
set { intfontsize = value; }
}
/// <summary>
/// 曲线线条大小
/// </summary>
public int curvesize
{
get { return intcurvesize; }
set { intcurvesize = value; }
}
#endregion
/// <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;
}
/// <summary>
/// 生成图像并返回bmp图像对象
/// </summary>
/// <returns></returns>
public bitmap createimage()
{
initializegraph();
int intkeyscount = keys.length;
int intvaluescount = values.length;
if (intvaluescount % intkeyscount == 0)
{
int intcurvescount = intvaluescount / intkeyscount;
for ( int i = 0; i < intcurvescount; i++)
{
float [] fltcurrentvalues = new float [intkeyscount];
for ( int j = 0; j < intkeyscount; j++)
{
fltcurrentvalues[j] = values[i * intkeyscount + j];
}
drawcontent( ref objgraphics, fltcurrentvalues, clrscurvecolors[i]);
}
}
else
{
objgraphics.drawstring( "发生错误,values的长度必须是keys的整数倍!" , new font( "宋体" , fontsize + 5), new solidbrush(textcolor), new point(( int )xspace, ( int )(height / 2)));
}
return objbitmap;
}
/// <summary>
/// 初始化和填充图像区域,画出边框,初始标题
/// </summary>
private void initializegraph()
{
//根据给定的高度和宽度创建一个位图图像
objbitmap = new bitmap(( int )width, ( int )height);
//从指定的 objbitmap 对象创建 objgraphics 对象 (即在objbitmap对象中画图)
objgraphics = graphics.fromimage(objbitmap);
//根据给定颜色(lightgray)填充图像的矩形区域 (背景)
objgraphics.drawrectangle( new pen(bordercolor, 1), 0, 0, width - 1, height - 1); //画边框
objgraphics.fillrectangle( new solidbrush(bgcolor), 1, 1, width - 2, height - 2); //填充边框
//画x轴,注意图像的原始x轴和y轴计算是以左上角为原点,向右和向下计算的
float fltx1 = xspace;
float flty1 = height - yspace;
float fltx2 = width - xspace + xslice / 2;
float flty2 = flty1;
objgraphics.drawline( new pen( new solidbrush(axiscolor), 1), fltx1, flty1, fltx2, flty2);
//画y轴
fltx1 = xspace;
flty1 = height - yspace;
fltx2 = xspace;
flty2 = yspace - yslice / 2;
objgraphics.drawline( new pen( new solidbrush(axiscolor), 1), fltx1, flty1, fltx2, flty2);
//初始化轴线说明文字
setaxistext( ref objgraphics);
//初始化x轴上的刻度和文字
setxaxis( ref objgraphics);
//初始化y轴上的刻度和文字
setyaxis( ref objgraphics);
//初始化标题
createtitle( ref objgraphics);
}
/// <summary>
/// 初始化轴线说明文字
/// </summary>
/// <param name="objgraphics"></param>
private void setaxistext( ref graphics objgraphics)
{
float fltx = width - xspace + xslice / 2 - (xaxistext.length - 1) * intfontspace;
float flty = height - yspace - intfontspace;
objgraphics.drawstring(xaxistext, new font( "宋体" , fontsize), new solidbrush(axistextcolor), fltx, flty);
fltx = xspace + 5;
flty = yspace - yslice / 2 - intfontspace;
for ( int i = 0; i < yaxistext.length; i++)
{
objgraphics.drawstring(yaxistext[i].tostring(), new font( "宋体" , fontsize), new solidbrush(axistextcolor), fltx, flty);
flty += intfontspace; //字体上下距离
}
}
/// <summary>
/// 初始化x轴上的刻度和文字
/// </summary>
/// <param name="objgraphics"></param>
private void setxaxis( ref graphics objgraphics)
{
float fltx1 = xspace;
float flty1 = height - yspace;
float fltx2 = xspace;
float flty2 = height - yspace;
int icount = 0;
int islicecount = 1;
float scale = 0;
float iwidth = ((width - 2 * xspace) / xslice) * 50; //将要画刻度的长度分段,并乘以50,以10为单位画刻度线。
float fltsliceheight = xslice / 10; //刻度线的高度
objgraphics.translatetransform(fltx1, flty1); //平移图像(原点)
objgraphics.rotatetransform(xrotateangle, matrixorder.prepend); //旋转图像
objgraphics.drawstring(keys[0].tostring(), new font( "宋体" , fontsize), new solidbrush(slicetextcolor), 0, 0);
objgraphics.resettransform(); //重置图像
for ( int i = 0; i <= iwidth; i += 10) //以10为单位
{
scale = i * xslice / 50; //即(i / 10) * (xslice / 5),将每个刻度分五部分画,但因为i以10为单位,得除以10
if (icount == 5)
{
objgraphics.drawline( new pen( new solidbrush(axiscolor)), fltx1 + scale, flty1 + fltsliceheight * 1.5f, fltx2 + scale, flty2 - fltsliceheight * 1.5f);
//画网格虚线
pen pendashed = new pen( new solidbrush(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(), new font( "宋体" , fontsize), new solidbrush(slicetextcolor), 0, 0);
objgraphics.resettransform();
}
else
{
//超过范围,不画任何刻度文字
}
icount = 0;
islicecount++;
if (fltx1 + scale > width - xspace)
{
break ;
}
}
else
{
objgraphics.drawline( new pen( new solidbrush(slicecolor)), fltx1 + scale, flty1 + fltsliceheight, fltx2 + scale, flty2 - fltsliceheight);
}
icount++;
}
}
/// <summary>
/// 初始化y轴上的刻度和文字
/// </summary>
/// <param name="objgraphics"></param>
private void setyaxis( ref graphics objgraphics)
{
float fltx1 = xspace;
float flty1 = height - yspace;
float fltx2 = xspace;
float flty2 = height - yspace;
int icount = 0;
float scale = 0;
int islicecount = 1;
float iheight = ((height - 2 * yspace) / yslice) * 50; //将要画刻度的长度分段,并乘以50,以10为单位画刻度线。
float fltslicewidth = yslice / 10; //刻度线的宽度
string strslicetext = string .empty;
objgraphics.translatetransform(xspace - intfontspace * yslicebegin.tostring().length, height - yspace); //平移图像(原点)
objgraphics.rotatetransform(yrotateangle, matrixorder.prepend); //旋转图像
objgraphics.drawstring(yslicebegin.tostring(), new font( "宋体" , fontsize), new solidbrush(slicetextcolor), 0, 0);
objgraphics.resettransform(); //重置图像
for ( int i = 0; i < iheight; i += 10)
{
scale = i * yslice / 50; //即(i / 10) * (yslice / 5),将每个刻度分五部分画,但因为i以10为单位,得除以10
if (icount == 5)
{
objgraphics.drawline( new pen( new solidbrush(axiscolor)), fltx1 - fltslicewidth * 1.5f, flty1 - scale, fltx2 + fltslicewidth * 1.5f, flty2 - scale);
//画网格虚线
pen pendashed = new pen( new solidbrush(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 * strslicetext.length, flty1 - scale); //平移图像(原点)
objgraphics.rotatetransform(yrotateangle, matrixorder.prepend); //旋转图像
objgraphics.drawstring(strslicetext, new font( "宋体" , fontsize), new solidbrush(slicetextcolor), 0, 0);
objgraphics.resettransform(); //重置图像
icount = 0;
islicecount++;
}
else
{
objgraphics.drawline( new pen( new solidbrush(slicecolor)), fltx1 - fltslicewidth, flty1 - scale, fltx2 + fltslicewidth, flty2 - scale);
}
icount++;
}
}
/// <summary>
/// 画曲线
/// </summary>
/// <param name="objgraphics"></param>
private void drawcontent( ref graphics objgraphics, float [] fltcurrentvalues, color clrcurrentcolor)
{
pen curvepen = new pen(clrcurrentcolor, curvesize);
pointf[] curvepointf = new pointf[keys.length];
float keys = 0;
float values = 0;
for ( int i = 0; i < keys.length; i++)
{
keys = xslice * i + xspace;
values = (height - yspace) + yslicebegin - yslice * (fltcurrentvalues[i] / yslicevalue);
curvepointf[i] = new pointf(keys, values);
}
objgraphics.drawcurve(curvepen, curvepointf, tension);
}
/// <summary>
/// 初始化标题
/// </summary>
/// <param name="objgraphics"></param>
private void createtitle( ref graphics objgraphics)
{
objgraphics.drawstring(title, new font( "宋体" , fontsize), new solidbrush(textcolor), new point(( int )(width - xspace) - intfontsize * title.length, ( int )(yspace - yslice / 2 - intfontspace)));
}
}
}
希望本文所述对大家的c#程序设计有所帮助。
dy("nrwz");