直接上效果图如下

public partial class WaveChartUserCtrl : UserControl{Color axisColor = Color.FromArgb(69, 200, 255);//坐标颜色Color scaleColor = Color.FromArgb(129, 137, 156);//刻度颜色Font axisFont = new Font("宋体", 9, FontStyle.Bold);//坐标字体/// <summary>/// 画板宽度/// </summary>private float boardWidth;/// <summary>/// 画板高度/// </summary>private float boardHeight;/// <summary>/// 垂直(纵向)边距(画图区域距离左右两边长度)/// </summary>private float verticalMargin;/// <summary>/// 平行(横向)边距(画图区域距离左右两边长度)/// </summary>private float horizontalMargin;/// <summary>/// 水平间距像素/// </summary>private float horizontalBetween;/// <summary>/// 垂直间距像素/// </summary>private float verticalBetween;/// <summary>/// 图表区域宽度/// </summary>float chartWidth;/// <summary>/// 图表区域高度/// </summary>float charHeight;/// <summary>/// 画图区域起点/// </summary>PointF startPostion;/// <summary>/// 画图区域终点/// </summary>PointF endPostion;/// <summary>/// 左边Y轴每个间隔值/// </summary>private int leftIntervalValueY;/// <summary>/// 右边Y抽每个间隔值/// </summary>private int rightIntervalValueY;/// <summary>/// X轴每个间隔值/// </summary>//private int intervalValueX;/// <summary>/// X轴刻度线数量/// </summary>private int xScaleCount = 20;/// <summary>/// X轴刻度线数量/// </summary>public int XscaleCount{get{return xScaleCount;}set{xScaleCount = value;}}/// <summary>/// Y轴刻度线数量/// </summary>private int yScaleCount = 8;/// <summary>/// Y轴刻度线数量/// </summary>public int YscaleCount{get{return yScaleCount;}}private float leftmaxValue = 300;[Category("wyl")][Description("左边坐标最大值")]public float LeftMaxValue{get{return leftmaxValue;}set{if (value <= LeftMinValue){MessageBox.Show("最大值不能低于最小值!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);//maxValue = 300;}else{leftmaxValue = value;}}}private float leftminValue = 0;/// <summary>/// 仪表盘显示的最小值/// </summary>[Category("wyl")][Description("左边坐标最小值")]public float LeftMinValue{get{return leftminValue;}set{if (value >= LeftMaxValue){MessageBox.Show("最小值不能超过最大值!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);//minValue = 0;}else{leftminValue = value;}}}private float rightmaxValue = 100;[Category("wyl")][Description("右边坐标最大值")]public float RightMaxValue{get{return rightmaxValue;}set{if (value <= RightMinValue){MessageBox.Show("最大值不能低于最小值!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);}else{rightmaxValue = value;}}}private float rightminValue = 0;/// <summary>/// 仪表盘显示的最小值/// </summary>[Category("wyl")][Description("右边坐标最小值")]public float RightMinValue{get{return rightminValue;}set{if (value >= RightMaxValue){MessageBox.Show("最小值不能超过最大值!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);}else{rightminValue = value;//InitCanvas();}}}private List<Color> lineColor = new List<Color> { Color.Red, Color.FromArgb(0, 192, 0) };[Category("wyl")][Description("线条颜色")]public List<Color> LineColor{get{return lineColor;}set{if (value != null && value.Count > 1){lineColor = value;}}}/// <summary>/// 显示文字/// </summary>string titlText1 = "";/// <summary>/// 显示文字/// </summary>[Category("wyl")][Description("标题1")]public string TitlText1{get{return titlText1;}set{titlText1 = value;}}/// <summary>/// 显示文字/// </summary>string titlText2 = "";/// <summary>/// 显示文字/// </summary>[Category("wyl")][Description("标题2")]public string TitlText2{get{return titlText2;}set{titlText2 = value;}}/// <summary>/// 数据源1/// </summary>private Series SeriesData1 = new Series();/// <summary>/// 数据源2/// </summary>private Series SeriesData2 = new Series();/// <summary>/// 真实画布宽度为画板的80% ,其余部分预留。/// </summary>private float canvasWidth;/// <summary>/// 最大X抽坐标为24H,最后记录一分钟记录一次/// </summary>private int MaxXScaleCount = 720;//24 * 60 / 2;//2秒通讯一次,最大每一分钟记录一次//private List<float> dataLst1 = new List<float>();//private List<float> dataLst2 = new List<float>();public DateTime startTime = DateTime.Now;public void InitCanvas(){boardWidth = this.ClientSize.Width;boardHeight = this.ClientSize.Height;horizontalMargin = 40;verticalMargin = 40;chartWidth = boardWidth - 2 * horizontalMargin;//画图区域宽度charHeight = boardHeight - 2 * verticalMargin; //画图区域高度,axisY 避免与X轴重合canvasWidth = chartWidth * 0.86F;//实际画布为画板的80%startPostion = new PointF(horizontalMargin, verticalMargin);endPostion = new PointF(boardWidth - horizontalMargin, boardHeight - verticalMargin);//SeriesData1.LineColor = Color.Red;//SeriesData2.LineColor = Color.FromArgb(0, 192, 0);}public WaveChartUserCtrl(){InitializeComponent();this.SetStyle(ControlStyles.OptimizedDoubleBuffer| ControlStyles.AllPaintingInWmPaint| ControlStyles.DoubleBuffer, true);InitCanvas();}/// <summary>/// 画图/// </summary>/// <param name="gp"></param>private void Drawing(Graphics gs){System.Diagnostics.Stopwatch runstopwatch = new System.Diagnostics.Stopwatch();runstopwatch.Start();if (SeriesData1.Datas.Count > 20){XscaleCount = SeriesData1.Datas.Count;}horizontalBetween = canvasWidth / XscaleCount;verticalBetween = charHeight / YscaleCount;//intervalValueX = 1;//leftIntervalValueY = (int)(LeftMaxValue - LeftMinValue) / YscaleCount;rightIntervalValueY = (int)(RightMaxValue - RightMinValue) / YscaleCount;try{StringFormat strFmt = new System.Drawing.StringFormat();strFmt.Alignment = StringAlignment.Center; //文本水平居中strFmt.LineAlignment = StringAlignment.Center; //文本垂直居中Pen axisPen = new Pen(scaleColor, 1.0F);//坐标文字Bitmap bit = new Bitmap((int)boardWidth, (int)boardHeight);Graphics g = Graphics.FromImage(bit);//g.DrawString(TitlText, new Font("宋体", 9, FontStyle.Bold), new SolidBrush(SeriesData1.LineColor), 5, 10);float tempEndPointY = endPostion.Y;//Y轴格for (int i = 0; i <= YscaleCount; i++){float y = tempEndPointY - i * verticalBetween;g.DrawLine(axisPen, startPostion.X, y, endPostion.X, y);string leftText = (LeftMinValue + (i * leftIntervalValueY)).ToString();SizeF sf = g.MeasureString(leftText, axisFont);RectangleF rf = new RectangleF(startPostion.X - 30, y - sf.Height / 2, 30, sf.Height);g.DrawString(leftText, axisFont, new SolidBrush(LineColor[0]), rf, strFmt);string rightText = (RightMinValue + (i * rightIntervalValueY)).ToString();sf = g.MeasureString(rightText, axisFont);RectangleF rf1 = new RectangleF(endPostion.X + 5, y - sf.Height / 2, 30, sf.Height);g.DrawString(rightText, axisFont, new SolidBrush(LineColor[1]), rf1, strFmt);}//画曲线if (SeriesData1 != null){strFmt.Alignment = StringAlignment.Near; //RectangleF rf = new RectangleF(0, 0, 70, 30);g.DrawString(TitlText1, new Font("宋体", 10, FontStyle.Bold), new SolidBrush(LineColor[0]), rf, strFmt);//计算0值的坐标int tempv = (int)((Math.Abs(LeftMinValue) - 0) / leftIntervalValueY);//得到0到最小值的间隔距离;float zeroY = tempEndPointY - tempv * verticalBetween;//值为0点Y抽坐标;if (SeriesData1.Datas.Count > 1){int dataIndex = 0;PointF[] arrDataPoint = new PointF[SeriesData2.Datas.Count];int index = 0;foreach (PointF pf in SeriesData1.Datas){PointF p = new PointF();p.X = startPostion.X + horizontalBetween * index;p.Y = zeroY - verticalBetween * pf.Y / leftIntervalValueY;arrDataPoint[dataIndex++] = p;index++;}g.DrawCurve(new Pen(new SolidBrush(LineColor[0]), 2F), arrDataPoint);PointF[] AreaPf = new PointF[arrDataPoint.Length + 2];int AreaIndxe = 0;AreaPf[AreaIndxe++] = new PointF(startPostion.X, zeroY);foreach (PointF p in arrDataPoint){AreaPf[AreaIndxe++] = p;}AreaPf[AreaIndxe++] = new PointF(arrDataPoint[arrDataPoint.Length - 1].X, zeroY);g.FillPolygon(new SolidBrush(Color.FromArgb(50, LineColor[0])), AreaPf);//g.FillClosedCurve(new SolidBrush(Color.FromArgb(50, SeriesData1.LineColor)), AreaPf);//g.DrawEllipse(new Pen(Brushes.Red), startPostion.X, zeroY, 10, 10);}}if (SeriesData2 != null){strFmt.Alignment = StringAlignment.Far; //RectangleF rf = new RectangleF(boardWidth - 70, 0, 70, 30);g.DrawString(TitlText2, new Font("宋体", 10, FontStyle.Bold), new SolidBrush(LineColor[1]), rf, strFmt);//计算0值的坐标int tempv = (int)((Math.Abs(RightMinValue) - 0) / rightIntervalValueY);//得到0到最小值的间隔距离;float zeroY = tempEndPointY - tempv * verticalBetween;//值为0点Y抽坐标;if (SeriesData2.Datas.Count > 1){int dataIndex = 0;PointF[] arrDataPoint = new PointF[SeriesData2.Datas.Count];int index = 0;foreach (PointF pf in SeriesData2.Datas){PointF p = new PointF();p.X = startPostion.X + horizontalBetween * index;p.Y = zeroY - verticalBetween * pf.Y / rightIntervalValueY;arrDataPoint[dataIndex++] = p;index++;}g.DrawCurve(new Pen(new SolidBrush(LineColor[1]), 2F), arrDataPoint);PointF[] AreaPf = new PointF[arrDataPoint.Length + 2];int AreaIndxe = 0;AreaPf[AreaIndxe++] = new PointF(startPostion.X, zeroY);foreach (PointF p in arrDataPoint){AreaPf[AreaIndxe++] = p;}AreaPf[AreaIndxe++] = new PointF(arrDataPoint[SeriesData2.Datas.Count - 1].X, zeroY);g.FillPolygon(new SolidBrush(Color.FromArgb(50, LineColor[1])), AreaPf);}}g.DrawString(startTime.ToString("HH:mm:ss"), new Font("宋体", 10, FontStyle.Regular), Brushes.White, 10, this.ClientSize.Height - 30);g.DrawString(DateTime.Now.ToString("HH:mm:ss"), new Font("宋体", 10, FontStyle.Regular), Brushes.White, this.ClientSize.Width - 80, this.ClientSize.Height - 30);g.DrawString("Time/H", new Font("宋体", 12, FontStyle.Regular), Brushes.Wheat, 0, this.ClientSize.Height - 15);gs.DrawImage(bit, 0, 0);g.Dispose();runstopwatch.Stop();TimeSpan timespan = runstopwatch.Elapsed;Console.WriteLine("Drawing:" + timespan.ToString());}catch (Exception ex){Console.WriteLine(ex.Message);}}private void WaveChartUserCtrl_Resize(object sender, EventArgs e){InitCanvas();this.Refresh();}private void WaveChartUserCtrl_Paint(object sender, PaintEventArgs e){Drawing(e.Graphics);}public void AddSeriesData(List<float> dataLst1, List<float> dataLst2){//System.Diagnostics.Stopwatch runstopwatch = new System.Diagnostics.Stopwatch();//runstopwatch.Start();//dataLst1.Add(y1);//dataLst2.Add(y2);//if (dataLst1.Count > 86400)//{//    dataLst1.RemoveAt(0);//}//if (dataLst2.Count > 86400)//{//    dataLst2.RemoveAt(0);//}int tempx = dataLst1.Count / MaxXScaleCount + 1;SeriesData1.Datas.Clear();for (int index = 0; index < dataLst1.Count; index++){PointF p1 = new PointF(0, dataLst1[index]);if (index % tempx == 0 || index == dataLst1.Count){SeriesData1.Datas.Add(p1);}}SeriesData2.Datas.Clear();for (int index = 0; index < dataLst2.Count; index++){PointF p2 = new PointF(0, dataLst2[index]);if (index % tempx == 0 || index == dataLst2.Count){SeriesData2.Datas.Add(p2);}}//runstopwatch.Stop();//TimeSpan timespan = runstopwatch.Elapsed;//Console.WriteLine(timespan.ToString());//this.Refresh();}}/// <summary>/// 数据系列管理/// </summary>public class Series{/// <summary>/// 标题/// </summary>public string HeadText = "title";Color lineColor = Color.Red;/// <summary>/// 当前画笔颜色/// </summary>public Color LineColor{get{return lineColor;}set{lineColor = value;}}public List<PointF> Datas = new List<PointF>();}

  

转载于:https://www.cnblogs.com/wangyonglai/p/10109782.html

C# GDI绘制波形图相关推荐

  1. java wav 波形_java读取wav文件(波形文件)并绘制波形图的方法

    本文实例讲述了java读取wav文件(波形文件)并绘制波形图的方法.分享给大家供大家参考.具体如下: 因为最近有不少网友询问我波形文件读写方面的问题,出于让大家更方便以及让代码能够得到更好的改进,我将 ...

  2. GDI绘制时钟效果,与系统时间保持同步,基于Winform

    2019独角兽企业重金招聘Python工程师标准>>> 这是直接在Winform的基础上进行绘制的.接下来,我对时钟进行了封装,封装成一个名为CSharpQuartz的类,效果如下: ...

  3. C# 数据库系统中使用GDI+绘制柱状图

    在C#+SQL Server数据库做系统中,通常需要对数据库中的数据进行绘制图形报表方便经理查看,虽然有很多实用的水晶报表控件和图表控件实现该功能,但我还是想讲讲如何使用GDI绘制简单的柱状图.(推荐 ...

  4. MFC+GDI+绘制出雷达余晖效果

    MFC+GDI+绘制出雷达余晖效果 1.首先要画出静态的坐标轴,用双缓冲方法在onpain消息中绘制.绘制方法都比较简单.声明一个内存DC,绘制一个圆形,再把坐标轴画上去. void CDlg_Rad ...

  5. 用多媒体库 Bass.dll 播放 mp3 [9] - 绘制波形图

    本例效果图: 代码文件: unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Contr ...

  6. Windows平台RTMP|RTSP播放器为什么要兼容GDI绘制

    为什么要支持GDI 先说结论,Windows平台播放渲染这块,一般来说99%以上的机器都是支持D3D的,实现GDI模式绘制,除了为了好的兼容性外,在远程连接的场景下,D3D创建不成功,需要使用GDI模 ...

  7. 使用GDI+绘制高质量图和字体(2)

    还记得前段时间的一篇文章写了"使用GDI+绘制高质量图和字体",里面用到了SmoothingMode.HighQuality,CompositingQuality.HighQual ...

  8. 椭圆形印章核心算法浅析及使用GDI+绘制椭圆印章的方法

    1. 引言 几年前,笔者在做某项目时,需要根据开票方的实际信息(含企业名称,社会信用代码,印章编号)绘制某椭圆形的专用章,加盖到PDF版式文件上,并使用开票方的证书信息进行签名,以防范版式文件伪造.抵 ...

  9. D2D引擎与GDI\GDI+绘制效果对比

    本例主要是对比D2D和GDI在绘制文字.线条的区别,以及D2D与GDI+在绘制图片时的区别. D2D是基于COM组件开发的,使用前的CoInitialize(NULL)是必须的:另外,GDI+的初始化 ...

最新文章

  1. 利用Vlan控制与隔离广播风暴
  2. OpenCV在图像中寻找轮廓的实例(附完整代码)
  3. 单继承-继承的传递性
  4. 一个不错的讲解flex 3中自定义事件的文章
  5. ibm量子计算机科学家,重磅!IBM发布全球首个独立商用量子计算机
  6. LeetCode 1392. 最长快乐前缀(KMP)
  7. Oracle 练习题P256
  8. 聚合 aggregate
  9. 宁德时代机器人编程开发_高通发布5G机器人开发平台,内置强大AI算力。各大厂商竞相发布机器人处理平台,万物互联的时代即将到来...
  10. 家用无线路由器的相关设置
  11. hdu1558计算几何加并查集
  12. 斯坦福CS229(吴恩达授)学习笔记(2)
  13. 10分钟带你进入Swagger的世界,快来看一看吧
  14. 数学与计算机学院女生节标语,女生节标语理学院
  15. linux下批量替换文件内容
  16. 产品回顾本讲谈社汉字学习词典(kald)对于卡西欧EX-字的DataPlus系列
  17. 浙大计算机科学基础实验,想加实验室的看过来-浙大计算机实验室详细推介
  18. Java 老矣,尚能饭否?
  19. 如何实现可靠UDP传输
  20. 上市公司开源的HIS系统,可下载源代码体验

热门文章

  1. windows/browser ---- cmd命令/powershell命令/chrome插件vimuim命令
  2. zookeeper应用 - FIFO 队列 分布式队列
  3. 图 | 为什么存在关于图的研究
  4. hdu 1133 Buy the Ticket(递推+精度精算)
  5. ASP.NET实现数据采集
  6. vue中的VNode
  7. chrome http请求,测试webapp接口之DHC - REST/HTTP API Client
  8. 【Vue2.0】—默认插槽、具名插槽、作用域插槽(二十四)
  9. python工程师干什么的_大数据开发工程师薪资待遇及招聘要求?
  10. 为什么在加油站上班,一个月休3天,工资2000元,却有人干?