C#绘制曲线图的方法
程序员文章站
2022-06-09 10:29:39
本文实例讲述了c#绘制曲线图的方法。分享给大家供大家参考。具体如下:
1. 曲线图效果:
2. c#代码:
///
//...
本文实例讲述了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#程序设计有所帮助。
上一篇: 红糖姜茶什么时候喝最好呢