失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 转帖 .Net(C#)纯GDI+绘制实时动态曲线图之二(曲线控件全部源码)

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

时间:2020-01-07 22:23:24

相关推荐

转帖 .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

}

如果觉得《转帖 .Net(C#)纯GDI+绘制实时动态曲线图之二(曲线控件全部源码)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。