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

#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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/549071.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL Server语句

SQL简介&#xff1a; 结构化查询语言&#xff0c;全拼 Structured Query Language 主要用于对数据库的操作&#xff0c;大多数据库遵循sql原则 SQL server使用的是sql的扩展集T-SQL 全拼 Transact-SQL SQL组成&#xff1a; SQL由四部分组成分别为DML DDL DQL DCL DML:数据表操…

渗透测试岗位面试题(重点:渗透测试思路)

转载自公众号&#xff1a;alisrc 本文主要是讲解遇到问题的各思路解决方法&#xff0c;不仅可做为面试题查看&#xff0c;在实操中收到思绪的阻碍也可作为参考. 1、拿到一个待检测的站&#xff0c;你觉得应该先做什么&#xff1f;1)信息收集1&#xff0c;获取域名的whois信息,获…

Mysql5.1.36 autoinstall.sh

以下脚本由杨良伟同学一手编写&#xff0c;我只是为了其他文章方便转载才放进自己的文章&#xff0c;以下有附件可以下载&#xff0c;将txt改成sh&#xff0c;赋予执行位&#xff0c;即可执行自动安装&#xff0c;忘转载者标明出处&#xff0c;谢谢。 杨良伟同学blog链接: http…

春晓JAVA的横排和竖排输出

public class ChunXiao {public static void main(String[] args) {String a[][] { { "春", "眠", "不", "觉", "晓", "&#xff0c;" }, { "处", "处", "闻", "啼", &…

Android BroadcastReceiver应用

1. 创建Receiver&#xff0c;两种方式&#xff0c;动态和静态&#xff1a; &#xff08;1&#xff09;静态注册&#xff1a; 首先自定义个Receiver&#xff0c; publicclassMyReceiver extendsBroadcastReceiver { Override publicvoidonReceive(Context context, Intent…

JAVA “百鸡问题”:鸡翁一,值钱五,鸡母一,值钱三,鸡雏三,值钱一。百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?

public class BaiYuanBaiJi {public static void main(String[] args) {int x 0, y 0, z 0;//各种鸡的数量 xyz100(只) 5x3yz/3100(元)for (x 0; x < 20; x) {//全部买公鸡&#xff0c;最大是20只for (y 0; y < 33; y) {//全部买母鸡&#xff0c;最大是33只z 100…

mssql 2008恢复xp_cmdshell

EXEC sp_configure show advanced options, 1;RECONFIGURE;EXEC sp_configure xp_cmdshell, 1;RECONFIGURE; 关闭一样.只是将上面的后面的那个"1"改成"0"就可以了. EXEC sp_configure show advanced options, 1;RECONFIGURE;EXEC sp_configure xp_cmdshell…

用数组保存每个月份的天数,输出每个月有多少天。输入一个年份,输出该年份每个月的天数(提醒:闰年二月份多一天)

2、用数组保存每个月份的天数&#xff0c;输出每个月有多少天。 输入一个年份&#xff0c;输出该年份每个月的天数&#xff08;提醒&#xff1a;闰年二月份多一天&#xff09; import java.util.Scanner;public class TianShu {public static void main(String[] args) {int a[…

使用Symantec Altiris 来监控 Dell 服务器 的 硬件

最近一直在折腾DMC 监控 Dell 服务器&#xff0c; Altiris 6 对Dell的监控策略会丰富很多 &#xff0c;到了 7 严重缩水&#xff0c;6的策略又不能转化成7 ~~比较郁闷~~ 唯有自己去写不过最算给我写完了大部分常用的~~ 主要是 电源、电压、风扇、温度、处理器、内存、电池 等等…

从键盘输入四个数保存在数组中,找出最大、最小值 java

import java.util.Scanner;public class ZuiDaZuiXiao {public static void main(String[] args) {int a[] new int[4];Scanner s new Scanner(System.in);System.out.println("请输入4个数");//赋值数组for (int i 0; i < a.length; i) {a[i] s.nextInt();}/…

Technical Tcode List

Basis 需要知道的 SAP R/3 Technical Transaction Code List CCMS MENU (Transaction SRZL) Control Monitoring ------------------ RZ02 System Monitor AL01 SAP Alert Monitor RZ01 Job Scheduling Monitor RZ20 CCMS Alert Monitor (v4) RZ03 Presentation, Control SAP …

AD+DNS安装步骤详解

一.安装ADDNS准备工作&#xff08;虚拟机使用VPC&#xff09; 1.准备一台纯净版的Windows Server2003&#xff0c;并且设置只有一块网卡其属性为Local only。 2.配置网卡IP地址&#xff0c;一定要设置DNS服务器地址。若是第一台域控制器&#xff08;AD&#xff09;&#xff0c;…

使用网络进行项目托管

转载于:https://blog.51cto.com/quietheart/470873

2010年终人生的思考

我也不知道是什么时候&#xff0c;自己开始逐渐意识到人会老&#xff0c;人会死。应该是在高中的时候吧&#xff0c;某个哥们发神经似地问“人活着是为了什么”&#xff0c;当时居然都答不上来&#xff0c;他发神经就算了&#xff0c;还搞得我也跟着发起了一阵的神经。后来由于…

第一个Android工程HelloAndroid

2019独角兽企业重金招聘Python工程师标准>>> 从这一节我们将正式进入Android编程世界,希望大家多多给我留言以及提些建议.首先我们打开Eclipse选择左上方的菜单[File->New->Project->Android Project]双击后会出现新建Android工程对话框,如下图所示:如果你…

IP地址 子网掩码 网关

A类、B类、C类IP地址区别 IP地址&#xff08;其实这个是IPV4&#xff09;是一个32位的二进制数&#xff0c;由四个八位字段组成。每个IP地址包括两部分&#xff1a;一部分为网络标识&#xff0c;一部分为主机标识。 A类地址前8位为网络标识。后24位为主机标识 B类地址前16位为网…

[转]自定义SqlMembershipProvider方法

asp 2.0自带了许多方法&#xff0c;很多东西都给我们封装好了&#xff0c;但是这样就导致了我们自定义的空间越来越小。忙碌了两个星期&#xff0c;一直想重写System.Web.Security.SqlMembershipProvider&#xff0c;但是没有找到方法&#xff0c;昨天在asp.net这个晚上上找到了…

用FileZilla Server搭建ftp服务器

用FileZilla Server搭建ftp服务器 1.先在浏览器搜索 filezilla server 2.点开FileZilla软件的官网&#xff0c;下载该软件 3.下载完成后&#xff0c;按照操作流程一步步完成安装 4.打开filezilla Server软件&#xff0c;运行该软件&#xff0c;使FTP Server运行起来 5.…

不使用Vmware easy install 安装

进行了多次ubuntu的安装&#xff0c;始终发现ubuntu很多命令都没有安装到&#xff0c;用起来十分不方便&#xff0c;连最基本的init等命令都不具备&#xff0c;开始怀疑是版本的问题&#xff0c;尝试了多次&#xff0c;依旧无法解决。后来重新安装虚拟机的时候发现 选择Instal…

IP地址的分类 十进制与二进制的转换

liuweifei 1.IP地址的分类&#xff1a; ​ A类IP地址 A类IP地址就由1字节的网络地址和3字节主机地址组成&#xff0c;网络地址的最高位必须 是“0”。地址范围从1.0.0.1到127.255.255.254 &#xff08;二进制表示为&#xff1a;00000001 00000000 00000000 00000001 - 011111…