#region 曲线数据显示

#region 绘制背景网格
   /// <summary>
   /// 刷新背景网格线,并返回背景图片(背景不判断是否滚动)
   /// </summary>
   /// <returns>返回背景图片</returns>
   private System.Drawing.Bitmap RefBackground()
   {
    if(this.picCurveShow.Height<1 || this.picCurveShow.Width < 1)
    {
     return null;
    }

//创建网格背景线画笔
    System.Drawing.Pen gridPen = new Pen(this.gridColor,this.gridPenWidth);
    //创建网格文字画笔
    System.Drawing.Pen gridCompartPen = new Pen(this.gridForeColor,this.gridCompart);

System.Drawing.Bitmap bitmap = new Bitmap(this.picCurveShow.Width,this.picCurveShow.Height);
    System.Drawing.Graphics backGroundImage = System.Drawing.Graphics.FromImage(bitmap);
   
    //坐标原点偏移
    backGroundImage.TranslateTransform(this.coordinate,0);
  
    //填充背景色
    backGroundImage.Clear(this.backGroundColor);

//绘制表格背景线
    //绘制背景横轴线
    for(float i = this.picCurveShow.Height;i>=0;i=i-this.gridHeight)
    {
     System.Drawing.PointF pointFBegin = new PointF(0F,i);
     System.Drawing.PointF pointFEnd = new PointF(this.picCurveShow.Width,i);
     backGroundImage.DrawLine(gridPen,pointFBegin,pointFEnd);
    }

//绘制背景纵轴线
    for(float i = this.picCurveShow.Width; i>=0; i=i-this.gridWidth)
    {
     System.Drawing.PointF pointFBegin ;
     System.Drawing.PointF pointFEnd ;

if(i-gridRemoveX >=0)
     {
      pointFBegin = new PointF(i-gridRemoveX ,0F);
      pointFEnd = new PointF(i-gridRemoveX ,this.picCurveShow.Height);
      backGroundImage.DrawLine(gridPen,pointFBegin,pointFEnd);
     }
    }

//绘制分隔线。
    backGroundImage.DrawLine(gridCompartPen,0,0,0,this.picCurveShow.Height);

//绘制正常值上限,下限
    //绘制分隔线刻度文字
    System.Drawing.Font backGroundFont = new Font("Arial",this.gridFontSize);
    float fontHight = backGroundFont.GetHeight();
    System.Drawing.SolidBrush brush = new SolidBrush(this.gridForeColor);
    //判断上下线值是否有效(非零)
    System.Drawing.Pen upperAndLowerPen = new Pen(this.yUpperAndLowerColor,this.yUpperAndLowerPenWidth);
    upperAndLowerPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;

if(this.yLower > 0)
    {
     float yHeight = (float)this.picCurveShow.Height - (this.yLower /(this.yMaxValue - this.yMinValue)) * (float)this.picCurveShow.Height;
     backGroundImage.DrawLine(upperAndLowerPen,0,yHeight,this.picCurveShow.Width,yHeight);
     //绘制下限文字
     backGroundImage.DrawString(this.yLowerString,backGroundFont,brush,-this.coordinate,yHeight - fontHight/2);
    }

if(this.yUpper > 0)
    {
     float yHeight = (float)this.picCurveShow.Height - (this.yUpper /(this.yMaxValue - this.yMinValue)) * (float)this.picCurveShow.Height;
     backGroundImage.DrawLine(upperAndLowerPen,0,yHeight,this.picCurveShow.Width,yHeight);
     //绘制下限文字
     backGroundImage.DrawString(this.yUpperString,backGroundFont,brush,-this.coordinate,yHeight - fontHight/2);
    }
   
    //绘制最大值文字
    backGroundImage.DrawString(this.yMaxString,backGroundFont,brush,-this.coordinate,0);
    //绘制最小值文字
    backGroundImage.DrawString(this.yMinString,backGroundFont,brush,-this.coordinate,(float)this.picCurveShow.Height - fontHight);

//绘制曲线窗体标题
    brush = new SolidBrush(this.titleColor);
    backGroundImage.DrawString(this.title,backGroundFont,brush,(this.picCurveShow.Width / 2 - this.title.Length * this.gridFontSize),0);

//绘制系统时间
    if(this.showTime)
    {
     brush = new SolidBrush(this.showTimeColor);
     backGroundImage.DrawString(System.DateTime.Now.ToString("T"),backGroundFont,brush,(this.picCurveShow.Width - 105),this.picCurveShow.Height - fontHight);
    }
    return bitmap;
   }

/// <summary>
   /// 刷新背景网格线,并返回背景图片(背景判断是否滚动)
   /// </summary>
   /// <returns>返回背景图片</returns>
   private System.Drawing.Bitmap RefAndRemoveBackground()
   {
    //判断是否需要移动纵轴线
    if(this.removeGrid)
    {
     if(this.gridRemoveX >= this.gridWidth)
     {
      this.gridRemoveX = 1;
     }
     else
     {
      this.gridRemoveX = this.gridRemoveX + curveRemove;
     }
    }
    return this.RefBackground();
   }
   #endregion

/// <summary>
   /// 刷新背景网格线,显示曲线
   /// </summary>
   public void ShowCurve()
   {
    //窗体高度发生变化,先刷新数组Y坐标值
    if((this.picCurveShow.Height != this.lastTimeSystemWindowHeight)||(this.picCurveShow.Width != this.lastTimeSystemWindowWidth))
    {
     this.RefurbishArray();
    }

System.Drawing.Bitmap bitmap = this.RefAndRemoveBackground();
    System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(bitmap);
    //绘制曲线
    //判断数组中是否有两个以上的数值

//绘制直线
    if(this.noteNow > 1)
    {
     //声明绘制曲线的Point数组
     System.Drawing.Point[] pointsTemp = new Point[this.noteNow];
     System.Drawing.Point[] points;
     //数组下标;
     int pointI = 0;
     for(int i=0;i<=this.noteNow-1;i++)
     {
      if(this.noteMessages[i].X >= this.coordinate)
      {
       pointsTemp[pointI].X = this.noteMessages[i].X;
       pointsTemp[pointI].Y = this.noteMessages[i].Y;
       pointI ++;
      }
     }
     points = new Point[pointI];
     Array.Copy(pointsTemp,0,points,0,pointI);
     graphics.DrawLines(new Pen(this.curveColor,this.curvePenWidth),points);
    }

//绘制曲线
//    if(this.noteNow >=2)
//    {
//     graphics.DrawCurve(new Pen(this.curveColor,this.curvePenWidth),points);
//    }
    this.picCurveShow.Image = bitmap;
   }

/// <summary>
   /// 刷新背景网格线,显示曲线,自动添加即时数值
   /// </summary>
   /// <param name="Value">即时数值</param>
   public void ShowCurve(float Value)
   {
    this.AddNewValue(Value);
    this.ShowCurve();
   }

#endregion

#region 自动将最新采样数值添加到数组
   /// <summary>
   /// 自动将最新采样数值添加到数组
   /// </summary>
   /// <param name="newValue">最新采样数值</param>
   private void AddNewValue(float newValue)
   {
    //先判断数组下标
    if(this.noteNow >= this.maxNote -1)
    {
     //数组已经存满数值
     for(int i = 0;i< this.noteNow;i++)
     {
      this.noteMessages[i] = this.noteMessages[i+1];
      this.noteMessages[i].X = this.noteMessages[i].X - curveRemove;
     }
     this.noteMessages[this.noteNow].Value = newValue;
     this.noteMessages[this.noteNow].time = System.DateTime.Now;
     this.noteMessages[this.noteNow].X = this.picCurveShow.Width;
     this.noteMessages[this.noteNow].Y = (int)(this.picCurveShow.Height - (newValue /(this.yMaxValue - this.yMinValue)) * this.picCurveShow.Height);

}
    else
    {
     //数组未存满数值
     for(int i = 0;i< this.noteNow;i++)
     {
      this.noteMessages[i].X = this.noteMessages[i].X - curveRemove;
     }
     this.noteMessages[this.noteNow].Value = newValue;
     this.noteMessages[this.noteNow].time = System.DateTime.Now;
     this.noteMessages[this.noteNow].X = this.picCurveShow.Width;
     System.Random r= new Random();
     this.noteMessages[this.noteNow].Y = (int)(this.picCurveShow.Height - (newValue /(this.yMaxValue - this.yMinValue)) * this.picCurveShow.Height);

this.noteNow ++;
    }
   }
   #endregion

#region 窗体大小变化,自动刷新窗体Y轴值
   /// <summary>
   /// 窗体大小变化,自动刷新窗体Y轴值
   /// </summary>
   private void RefurbishArray()
   {
    if(this.noteNow <= 0)
     return;

for(int i= 0;i <= this.noteNow;i++)
    {
     this.noteMessages[i].X = this.noteMessages[i].X +(this.picCurveShow.Width - this.lastTimeSystemWindowWidth);
     this.noteMessages[i].Y = (int)(this.picCurveShow.Height - (this.noteMessages[i].Value /(this.yMaxValue - this.yMinValue)) * this.picCurveShow.Height);
    }
    //改变窗体大小时自动修改窗体高度临时值
    this.lastTimeSystemWindowHeight = this.picCurveShow.Height;
    this.lastTimeSystemWindowWidth = this.picCurveShow.Width;
   }
   #endregion

#region 显示鼠标当前点坐标值
   /// <summary>
   /// 显示鼠标当前点坐标值
   /// </summary>
   /// <param name="X">鼠标X坐标</param>
   /// <param name="Y">鼠标Y坐标</param>
   private void ShowMouseCoordinateMessage(int X,int Y)
   {
    float x = (int)X;
    float y = (int)Y;

//鼠标位置在偏移量右侧时发生
    if(x >= this.coordinate)
    {
     foreach(CoordinatesValue valueTemp in this.noteMessages)
     {
      if(((valueTemp.X <= (x + this.xYPrecision))&&(valueTemp.X >= (x - this.xYPrecision)))&&((valueTemp.Y >= (y - this.xYPrecision))&&(valueTemp.Y <= (y + this.xYPrecision))))
      {
       this.labShowView.Text ="Time:" + valueTemp.time.ToString("T") + "    Value:" +   valueTemp.Value.ToString() ;
      
       int labX;
       int labY;

if(Y <= this.labShowView.Height )
       {
        labY = Y + this.labShowView.Height + 5;
       }
       else
       {
        labY = Y-this.labShowView.Height;
       }

if(X >= this.picCurveShow.Width - this.labShowView.Width)
       {
        labX = X - this.labShowView.Width;
       }
       else
       {
        labX = X+5;
       }

this.labShowView.Top = labY;
       this.labShowView.Left = labX;
       this.labShowView.BringToFront();
       this.labShowView.Visible = true;

return;
      }
     }
    }

this.labShowView.Visible = false;
   }
   #endregion

private void picCurveShow_DoubleClick(object sender, System.EventArgs e)
   {
    //双击最大化及其正常缩略显示切换
    if(this.Dock == System.Windows.Forms.DockStyle.Fill)
    {
     this.Dock = System.Windows.Forms.DockStyle.None;
    }
    else
    {
     this.BringToFront();
     this.Dock = System.Windows.Forms.DockStyle.Fill;
    }
   }

private void picCurveShow_Resize(object sender, System.EventArgs e)
   {
    //改变窗体大小时自动重绘表格
    this.ShowCurve();
   }

private void CurveControl_Load(object sender, System.EventArgs e)
   {
    //控件加载时

//鼠标X,Y信息数组初始化
    this.noteMessages = new CoordinatesValue[this.maxNote];
    //初始化窗体高度值
    this.lastTimeSystemWindowHeight = this.picCurveShow.Height;
    this.lastTimeSystemWindowWidth = this.picCurveShow.Width;
   }

private void picCurveShow_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
   {
    //移动鼠标
    this.ShowMouseCoordinateMessage(e.X,e.Y);
   }

private void picCurveShow_MouseLeave(object sender, System.EventArgs e)
   {
    //鼠标离开曲线控件
    this.labShowView.Visible = false;
   }
}

#region 定义鼠标X,Y 坐标值,及该点坐标记录值、记录时间
/// <summary>
/// 定义鼠标X,Y 坐标值,及该点坐标记录值、记录时间
/// </summary>
struct CoordinatesValue
{
   public int X;
   public int Y;
   public float Value;
   public System.DateTime time;
}
#endregion
}

转载于:https://www.cnblogs.com/liuling2010/articles/1913417.html

转帖 .Net(C#)纯GDI+绘制实时动态曲线图之二(曲线控件全部源码)相关推荐

  1. C# Winform 使用GDI+ 绘制实时曲线图、面积曲线图

    问题来源 最近为了公司界面的美化,想将原来的单纯曲线图绘制变成曲线面积图. 功能需求 1.通过一系列的点,绘制出曲线面积图或者曲线图. 2.能够实现实时界面刷新. 3.曲线图里面的很多属性都能自定义. ...

  2. 基于GDI+用C#编写的.NET流程图控件开发周记(2011-08-05)

    花了差不多一个月的业余时间,新编写了一个流程图控件(用于.NET和C#),这个控件现在终于有了一个原型.控件可以用在主界面的导航画面,也可以代替Visio来绘制流程图,最重要的是可以用于日后的工作流功 ...

  3. 【python】利用python的tkinter-canvas函数绘制哆啦A梦过程详解(附源码)

    1 引 言 绘制哆啦A梦的过程,其实是对哆啦A梦进行拆解的过程,得先构思出他的头部.眼睛.鼻子.嘴巴.胡须.身体.铃铛.口袋.手以及脚等(如下图所示),才能进行下一步的绘画工作.心中有丘壑,方能水到渠 ...

  4. css怎样使弹跳的小球旋转,如何使用纯CSS实现小球跳跃台阶的动画效果(附源码)...

    本篇文章给大家带来的内容是关于如何使用纯CSS实现小球跳跃台阶的动画效果(附源码) ,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 效果预览 源代码下载 https://github ...

  5. python绘制散点图的函数_Python用PyQt5绘制多彩随机散点图,基本控件之QPainter使用详解...

    前面内容,我们详细介绍了PyQt5中弹出式对话框. 回顾下精彩内容 Python用PyQt5制作颜色对话框,PyQt图形界面编程之QColorDialog Qt图形界面编程之QFileDialog类, ...

  6. c/c++编程日记:纯C实现登录注册和忘记密码功能(附源码)

    这是一个用纯C语言和文件操作实现的系统的登录.注册和忘记密码功能.可以用于c语言大作业的登录系统.下面分享一下具体的代码. 首先定义一个结构体来存放用户的注册信息,账号密码等. typedefstru ...

  7. java绘制点阵数字(LED数字显示),转载源码

    看到一个扫雷例子的源码,学习了下绘制LED数字显示的方法,感觉挺好,做笔记记录下 import java.awt.Color; import java.awt.Component; import ja ...

  8. matplotlib 绘制实时动态曲线图

    import numpy as np import matplotlib.pyplot as plt %matplotlib qt5 from IPython import display impor ...

  9. 基于GDI+用C#编写的.NET流程图控件开发周记(2011-08-28)

    自从上次发布之后,本月几乎一直都在忙于处理工作上的事情,使得这段时间疏于更新流程图控件,所以这一次只作了小范围的功能更新: 1.增加了代表数据库图形 2.实现了对图形进行操作后的撤销(Ctrl+Z)与 ...

最新文章

  1. JavaScript arguments对象
  2. Java集合类原理详解
  3. mysql en dump_mysqldump 命令总结
  4. 20190226-SecureCRT连接linux显示中文乱码
  5. 如何走技术路线的研究生论文?
  6. 使用 Django 的日志模块,同时发送错误邮件到163邮箱
  7. 拓端tecdat|R语言ggsurvplot绘制生存曲线报错 : object of type ‘symbol‘ is not subsettable
  8. 福州万宝产业园的远程预付费电能管理系统
  9. MAC M1系统下的几种截图工具
  10. 微分几何笔记(1)——参数曲线、内积、外积
  11. [USACO题库]1.2.3 Name That Number命名那个数字
  12. 面临裁员潮,更快找到新工作的秘诀
  13. 谈谈我的学习工作经历,自学linux去中兴上班
  14. 10月更新!又一波新功能上线,升级后的EasyOps®简直神了!
  15. Android ScrollView、NestedScrollView、Horizo​​ntalScrollView 等
  16. 一篇文章看懂MySQL的多表连接(包含左/右/全外连接)
  17. 7-20 表达式转换 (25 分)
  18. C++开源游戏推荐,reshade游戏画质增强工具
  19. fluid 如何获取特定层的参数
  20. 前端学习随笔 css篇

热门文章

  1. JavaScript,JS如何控制input输入字符限制
  2. EWS 通过SubscribeToPullNotifications订阅Exchange新邮件提醒
  3. 比利牛斯獒犬 flask web
  4. 三星samsung手机ROM制作教程-另外一篇
  5. Linux用户环境变量
  6. Sharepoint 2007 定制Feature和卸载Feature
  7. ns 25的IKE模式ipsec ***配置
  8. mongoDB 文档操作_改
  9. 精读《React PowerPlug 源码》
  10. Keep Moving blog改版