
类设计

主程序
using System;using System.Collections.Generic;using System.ComponentModel;using System.Drawing;using System.Data;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;using Microsoft.Extensions.DependencyInjection;using CBB_Saker_Painting_1._0._0.Models;using System.Drawing.Drawing2D;using CBB_Saker_Painting_1._0._0.Global;using saker_Winform.UserControls;using System.IO;using System.Runtime.Serialization;using System.Runtime.Serialization.Formatters.Binary;namespace CBB_Saker_Painting_1._0._0 { public partial class Painting : UserControl { public Painting() { InitializeComponent(); } #region 字段/属性/变量 PaintPara paintPara = new PaintPara(); DataManager dataManager = new DataManager(); List<Data> listWaveDataSeriesCopy = new List<Data>(); #endregion #region 方法:开双缓冲器 /// <summary> /// 复写方法:双缓冲器打开 /// </summary> protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x02000000; return cp; } } #endregion #region 方法:初始化显示 private void Init() { paintPara.Init(this.pictureBox_Wave.Width, this.pictureBox_Wave.Height); this.ucChanLabel_CursorY1.Visible = paintPara.bCursorYShow; this.ucChanLabel_CursorY2.Visible = paintPara.bCursorYShow; this.ucChanLabelVertical_CursorX1.Visible = paintPara.bCursorXShow; this.ucChanLabelVertical_CursorX2.Visible = paintPara.bCursorXShow; this.ucCursorInfo_XY.Visible = paintPara.bCursorXYMesInfo; paintPara.MinValueY = -10; paintPara.MaxValueY = 10; paintPara.MinValueX = 0; paintPara.MaxValueX = 10; } #endregion #region 方法:绘图 private void Drawing(List<Data> listWaveDataSeries) { if ((this.pictureBox_Wave.Width <= 0) || (this.pictureBox_Wave.Height <= 0)) { return; } Bitmap bmpClear = new Bitmap(pictureBox_Wave.Width, pictureBox_Wave.Height); Graphics gClear = Graphics.FromImage(bmpClear); gClear.Clear(System.Drawing.Color.Black); this.pictureBox_Wave.Image = bmpClear; // 先生成一个新的位图 Bitmap bmp = new Bitmap(pictureBox_Wave.Width, pictureBox_Wave.Height); using (Graphics g = Graphics.FromImage(bmp)) { g.Clear(System.Drawing.Color.Black); g.SmoothingMode = SmoothingMode.AntiAlias; Pen pen = new Pen(Color.Gray, 1); pen.DashStyle = DashStyle.Solid;//画笔为实线 Rectangle rectangle = new Rectangle(pictureBox_Wave.ClientRectangle.X, pictureBox_Wave.ClientRectangle.Y, pictureBox_Wave.ClientRectangle.X + pictureBox_Wave.ClientRectangle.Width, pictureBox_Wave.ClientRectangle.Y + pictureBox_Wave.ClientRectangle.Height); g.DrawRectangle(pen, rectangle); pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom; //虚线 pen.DashPattern = new float[] { 2, 2 }; StringFormat strFmt = new System.Drawing.StringFormat(); strFmt.Alignment = StringAlignment.Center; //文本水平居中 strFmt.LineAlignment = StringAlignment.Center; //文本垂直居中 Font axisFont = new Font("微软雅黑", 9, FontStyle.Bold); //绘制顶部位置的纵坐标标示 SizeF sf = g.MeasureString(paintPara.strTopY, axisFont); RectangleF rf = new RectangleF(0, 0, sf.Width, sf.Height); if (paintPara.bYMarking) { //s要绘制的字符串,font文本格式,brush文本的颜色和纹理,x左上角x坐标,y左上角y坐标,format文本对齐方式 g.DrawString(paintPara.strTopY, axisFont, new SolidBrush(Color.White), rf, strFmt); } //绘制底部位置的纵坐标标示 sf = g.MeasureString(paintPara.strBottomY, axisFont); rf = new RectangleF(0, this.pictureBox_Wave.Height - sf.Height, sf.Width, sf.Height); if (paintPara.bYMarking) { g.DrawString(paintPara.strBottomY, axisFont, new SolidBrush(Color.White), rf, strFmt); } //绘制Y轴刻度线 for (int i = 1; i < paintPara.BisectrixY; i++) { float div = (float)this.pictureBox_Wave.ClientRectangle.Height / paintPara.BisectrixY; string strVertScale = PaintPara.Voltage2String(paintPara.MaxValueY - paintPara.VertScale / paintPara.BisectrixY * i); sf = g.MeasureString(strVertScale, axisFont); rf = new RectangleF(0, div * i - sf.Height / 2, sf.Width, sf.Height); //绘制纵坐标标示 if (paintPara.bYMarking) { g.DrawString(strVertScale, axisFont, new SolidBrush(Color.White), rf, strFmt); } if (i == paintPara.BisectrixY / 2) { pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid; //实线 if (paintPara.bDrawGridLineY) { //Pen线条样式,x1,y1,x2,y2 g.DrawLine(pen, 0, div * i, pictureBox_Wave.ClientRectangle.Width, div * i); } } else { pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom; //虚线 pen.DashPattern = new float[] { 2, 2 }; if (paintPara.bDrawGridLineY) { g.DrawLine(pen, 0, div * i, pictureBox_Wave.ClientRectangle.Width, div * i); } } } //绘制最右侧水平坐标标示 sf = g.MeasureString(paintPara.HorizRight, axisFont); rf = new RectangleF(this.pictureBox_Wave.Width - sf.Width, 0, sf.Width, sf.Height); if (paintPara.bXMarking) { g.DrawString(paintPara.HorizRight, axisFont, new SolidBrush(Color.Orange), rf, strFmt); } //绘制X轴刻度线条 for (int i = 1; i < paintPara.BisectrixX; i++) { float div = (float)this.pictureBox_Wave.ClientRectangle.Width / paintPara.BisectrixX; string strHoriScale = PaintPara.Time2String(paintPara.MinValueX + paintPara.HoriScale / paintPara.BisectrixX * i); sf = g.MeasureString(strHoriScale, axisFont); rf = new RectangleF(div * i - sf.Width / 2, 0, sf.Width, sf.Height); //绘制横坐标标示 if (paintPara.bXMarking) { g.DrawString(strHoriScale, axisFont, new SolidBrush(Color.Orange), rf, strFmt); } if (i == paintPara.BisectrixX / 2) { pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid; //实线 if (paintPara.bDrawGridLineX) { //Pen线条样式,x1,y1,x2,y2 g.DrawLine(pen, div * i, 0, div * i, pictureBox_Wave.ClientRectangle.Width); } } else { pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom; //虚线 pen.DashPattern = new float[] { 2, 2 }; if (paintPara.bDrawGridLineY) { g.DrawLine(pen, div * i, 0, div * i, pictureBox_Wave.ClientRectangle.Width); } } } //多图层绘制图层链表 for (int i = 0; i < listWaveDataSeries.Count; i++) { Bitmap bitmap = new Bitmap(this.pictureBox_Wave.Width, this.pictureBox_Wave.Height); paintPara.listImages.Add(bitmap); } if(paintPara.IndexXFinish - paintPara.IndexXStart < 2) { return; } //并发绘制 Parallel.For(0, listWaveDataSeries.Count, item => { Graphics graphics = Graphics.FromImage(paintPara.listImages[item]); graphics.SmoothingMode = SmoothingMode.AntiAlias; //paintPara.XScaleCount = listWaveDataSeries[item].listWaveData.Count; paintPara.XScaleCount = paintPara.IndexXFinish - paintPara.IndexXStart; //计算0值的坐标 int tempv = (int)(-paintPara.MinValueY / paintPara.IntervalValueY);//得到0到最小值的间隔距离; float zeroY = paintPara.EndPosition.Y - tempv * paintPara.VerticalBetween;//值为0点Y抽坐标; if (listWaveDataSeries[item].listWaveData.Count > 1) { int dataIndex = 0; //PointF[] arrDataPoint = new PointF[listWaveDataSeries[item].listWaveData.Count]; PointF[] arrDataPoint = new PointF[paintPara.IndexXFinish- paintPara.IndexXStart]; int index = 0; int j = 0; foreach (PointF pf in listWaveDataSeries[item].listWaveData) { if(index>=paintPara.IndexXStart && index <= (paintPara.IndexXFinish-1)) { PointF temp = new PointF(); temp.X = paintPara.StartPosition.X + paintPara.HorizontalBetween * j; temp.Y = zeroY - paintPara.VerticalBetween * pf.Y / paintPara.IntervalValueY; arrDataPoint[dataIndex++] = temp; j++; } index++; } //均值圆滑一下 graphics.DrawCurve(new Pen(new SolidBrush(listWaveDataSeries[item].LineColor), 1F), arrDataPoint); } graphics.Dispose(); }); //清零计数 foreach (Bitmap item in paintPara.listImages) { g.DrawImage(item, new Rectangle(0, 0, pictureBox_Wave.Width, pictureBox_Wave.Height)); } g.Dispose(); paintPara.listImages.Clear(); } pictureBox_Wave.Image = bmp; } #endregion #region 方法:添加/刷新/移除Tag控件到PanelLeft中 private void AddTagControl(List<Data> listWaveDataSeries) { foreach (var item in listWaveDataSeries) { //添加左侧Tag UCChanLabel uCChanLabel = new UCChanLabel(); this.panel_Left.Controls.Add(uCChanLabel); uCChanLabel.setLabel(item.TagName, item.LineColor); uCChanLabel.Location = new Point(uCChanLabel.Location.X, (int)((paintPara.MaxValueY - item.listWaveData[0].Y) / paintPara.VertScale * this.panel_Left.Height - this.ucChanLabel_CursorY1.Height / 2)); uCChanLabel.MouseDown += UCChanLabel_MouseDown; uCChanLabel.MouseMove += UCChanLabel_MouseMove; uCChanLabel.MouseUp += UCChanLabel_MouseUp; } } private void RefreshControl(List<Data> listWaveDataSeries) { foreach (UCChanLabel item in this.panel_Left.Controls) { if (!item.m_strChanID.Contains("Y")) { int index = listWaveDataSeries.FindIndex(i => i.TagName == item.m_strChanID); if (index != -1) { item.Location = new Point(item.Location.X, (int)((paintPara.MaxValueY - listWaveDataSeries[index].listWaveData[paintPara.IndexXStart].Y) / paintPara.VertScale * this.panel_Left.Height - this.ucChanLabel_CursorY1.Height / 2)); item.CurrentCursorLocation = item.Location.Y / (panel_Left.Height * 1.0); } } } this.panel_Left.Refresh(); } //用for循环替代foreach中ControlCollection会变化的问题 private void RemoveControl(List<Data> listWaveDataSeries) { int k = 0; for (int i = 0; i < (listWaveDataSeriesCopy.Count+2); i++) { var item =(UCChanLabel)panel_Left.Controls[k]; if (!item.m_strChanID.Contains("Y")) { int index = listWaveDataSeries.FindIndex(j => j.TagName == item.m_strChanID); if (index != -1) { this.panel_Left.Controls.Remove(item); } else { k++; } } else { k++; } } this.panel_Left.Refresh(); } #endregion #region 事件:Load事件 private void Painting_Load(object sender, EventArgs e) { Init(); listWaveDataSeriesCopy = dataManager.listWaveDataSeries; Drawing(listWaveDataSeriesCopy); // 设置光标显示的内容 ucChanLabel_CursorY1.setLabel(" Y1", Color.GreenYellow); ucChanLabel_CursorY2.setLabel(" Y2", Color.GreenYellow); ucChanLabelVertical_CursorX1.setLabel("X1", Color.GreenYellow); ucChanLabelVertical_CursorX2.setLabel("X2", Color.GreenYellow); this.ucCursorInfo_XY.Parent = this.pictureBox_DrawRect;//父容器设置为顶层pictureBox this.pictureBox_DrawRect.Parent = this.pictureBox_Wave;//父容器设置为底层pictureBox } #endregion #region 事件:Tag移动 private void UCChanLabel_MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { var uCChanLabel = (UCChanLabel)sender; uCChanLabel.IsChanLabelMouseDown = false; float ampPrePoint = paintPara.VertScale / this.panel_Left.Height; int index = listWaveDataSeriesCopy.FindIndex(item => item.TagName == uCChanLabel.m_strChanID); if (index != -1) { float offsetAmp = paintPara.MaxValueY - ampPrePoint * (uCChanLabel.Location.Y + uCChanLabel.Height / 2) - listWaveDataSeriesCopy[index].listWaveData[paintPara.IndexXStart].Y; /*更新显示的偏移值*/ for (int i = 0; i < listWaveDataSeriesCopy[index].listWaveData.Count; i++) { listWaveDataSeriesCopy[index].listWaveData[i] = new System.Drawing.PointF(listWaveDataSeriesCopy[index].listWaveData[i].X, listWaveDataSeriesCopy[index].listWaveData[i].Y + offsetAmp); } } uCChanLabel.CurrentCursorLocation = ucChanLabel_CursorY2.Location.Y / (panel_Left.Height * 1.0); Drawing(listWaveDataSeriesCopy); } } private void UCChanLabel_MouseMove(object sender, MouseEventArgs e) { var uCChanLabel = (UCChanLabel)sender; if (uCChanLabel.IsChanLabelMouseDown) { uCChanLabel.Location = new Point(uCChanLabel.Location.X, uCChanLabel.Location.Y + (e.Y - uCChanLabel.AyChanLabel)); if (uCChanLabel.Location.Y <= 0) { uCChanLabel.Location = new Point(uCChanLabel.Location.X, 0); } if (uCChanLabel.Location.Y >= this.panel_Left.Height - uCChanLabel.Height) { uCChanLabel.Location = new Point(uCChanLabel.Location.X, this.panel_Left.Height - uCChanLabel.Height); } } } private void UCChanLabel_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { var ucChanLabel = (UCChanLabel)sender; ucChanLabel.IsChanLabelMouseDown = true; ucChanLabel.AxChanLable = e.X; ucChanLabel.AyChanLabel = e.Y; } } #endregion #region 事件:Mark显示 /// <summary> /// 显示X轴光标 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void iconMenuItem_XCursor_Click(object sender, EventArgs e) { paintPara.bCursorXShow = !paintPara.bCursorXShow; this.ucChanLabelVertical_CursorX1.Visible = paintPara.bCursorXShow; this.ucChanLabelVertical_CursorX2.Visible = paintPara.bCursorXShow; this.pictureBox_DrawRect.Refresh();//触发pictureBox_DrawRect的Painting事件 } /// <summary> /// 显示XY轴测量信息 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void iconMenuItem_MesInfoXY_Click(object sender, EventArgs e) { paintPara.bCursorXYMesInfo = !paintPara.bCursorXYMesInfo; this.ucCursorInfo_XY.Visible = paintPara.bCursorXYMesInfo; } /// <summary> /// 显示Y轴光标 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void iconMenuItem_YCursor_Click(object sender, EventArgs e) { paintPara.bCursorYShow = !paintPara.bCursorYShow; this.ucChanLabel_CursorY1.Visible = paintPara.bCursorYShow; this.ucChanLabel_CursorY2.Visible = paintPara.bCursorYShow; this.pictureBox_DrawRect.Refresh();//触发pictureBox_DrawRect的Painting事件 } #endregion #region 事件:顶层PictureBox绘制 /// <summary> /// 顶层pictureBox绘制事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void pictureBox_DrawRect_Paint(object sender, PaintEventArgs e) { if (paintPara.bDrawStart & paintPara.bEnlagerClick) { Pen pen = new Pen(Color.White, 1f); pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash; //实时的画矩形 int w = paintPara.PointContinue.X - paintPara.PointStart.X; int h = paintPara.PointContinue.Y - paintPara.PointStart.Y; Rectangle rect = new Rectangle(paintPara.PointStart, new Size(w, h)); e.Graphics.DrawRectangle(pen, rect); pen.Dispose(); } Pen penCursor = new Pen(Color.GreenYellow, 1f); penCursor.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom; //虚线 penCursor.DashPattern = new float[] { 2, 2 }; if (paintPara.bCursorYShow) { e.Graphics.DrawLine(penCursor, 0, ucChanLabel_CursorY1.Location.Y + ucChanLabel_CursorY1.Height / 2, pictureBox_DrawRect.ClientRectangle.Width, ucChanLabel_CursorY1.Location.Y + ucChanLabel_CursorY1.Height / 2); e.Graphics.DrawLine(penCursor, 0, ucChanLabel_CursorY2.Location.Y + ucChanLabel_CursorY2.Height / 2, pictureBox_DrawRect.ClientRectangle.Width, ucChanLabel_CursorY2.Location.Y + ucChanLabel_CursorY2.Height / 2); } if (paintPara.bCursorXShow) { e.Graphics.DrawLine(penCursor, ucChanLabelVertical_CursorX1.Location.X + ucChanLabelVertical_CursorX1.Width / 2, 0, ucChanLabelVertical_CursorX1.Location.X + ucChanLabelVertical_CursorX1.Width / 2, pictureBox_DrawRect.ClientRectangle.Height); e.Graphics.DrawLine(penCursor, ucChanLabelVertical_CursorX2.Location.X + ucChanLabelVertical_CursorX2.Width / 2, 0, ucChanLabelVertical_CursorX2.Location.X + ucChanLabelVertical_CursorX2.Width / 2, pictureBox_DrawRect.ClientRectangle.Height); } penCursor.Dispose(); } /// <summary> /// pictureBox_DrawRect鼠标点击事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void pictureBox_DrawRect_MouseDown(object sender, MouseEventArgs e) { if (paintPara.bEnlagerClick && e.Button == MouseButtons.Left) { paintPara.bDrawStart = true; paintPara.PointStart = e.Location; } } /// <summary> /// pictureBox_DrawRect鼠标移动事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void pictureBox_DrawRect_MouseMove(object sender, MouseEventArgs e) { if (paintPara.bDrawStart) { paintPara.PointContinue = e.Location; pictureBox_DrawRect.Invalidate(); } } private void pictureBox_DrawRect_MouseUp(object sender, MouseEventArgs e) { paintPara.bDrawStart = false; this.pictureBox_DrawRect.Invalidate(); /*重新构建显示的数据*/ int width = pictureBox_Wave.Width; int height = pictureBox_Wave.Height; int w = paintPara.PointContinue.X - paintPara.PointStart.X; if ((w <= 1) || (width < w)) { paintPara.PointStart = Point.Empty; paintPara.PointContinue = Point.Empty; return; } int h = paintPara.PointContinue.Y - paintPara.PointStart.Y; if ((height < h) || (h <= 0)) { paintPara.PointStart = Point.Empty; paintPara.PointContinue = Point.Empty; return; } if (dataManager.listWaveDataSeries.Count == 0) { return; } float factorStart = (float)paintPara.PointStart.X / (float)width; float factorContinue = (float)paintPara.PointContinue.X / (float)width; paintPara.MinValueX = factorStart * (paintPara.MaxValueX - paintPara.MinValueX); paintPara.MaxValueX = factorContinue * (paintPara.MaxValueX - paintPara.MinValueX); int PaintingScreen = paintPara.IndexXFinish - paintPara.IndexXStart; paintPara.IndexXStart = (int)(factorStart * PaintingScreen); paintPara.IndexXFinish = (int)(factorContinue * PaintingScreen); if(paintPara.IndexXFinish>paintPara.IndexXStart) { Drawing(listWaveDataSeriesCopy); RefreshControl(listWaveDataSeriesCopy); } paintPara.PointStart = Point.Empty; paintPara.PointContinue = Point.Empty; } /// <summary> /// 点击放大框 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void iconToolStripButton_Enlager_Click(object sender, EventArgs e) { if (paintPara.bEnlagerClick == false) { paintPara.bEnlagerClick = true; iconToolStripButton_Enlager.IconColor = Color.Red; this.pictureBox_Wave.Cursor = Cursors.Hand; } else { paintPara.bEnlagerClick = false; iconToolStripButton_Enlager.IconColor = Color.White; this.pictureBox_Wave.Cursor = Cursors.Default; } } #region 事件:双击pictureBox还原波形 private void pictureBox_DrawRect_MouseDoubleClick(object sender, MouseEventArgs e) { paintPara.IndexXStart = 0; paintPara.IndexXFinish = listWaveDataSeriesCopy[0].listWaveData.Count; paintPara.MinValueX = paintPara.MinValueXOrig; paintPara.MaxValueX = paintPara.MaxValueXOrig; if (paintPara.IndexXFinish > paintPara.IndexXStart) { Drawing(listWaveDataSeriesCopy); RefreshControl(listWaveDataSeriesCopy); } } #endregion #endregion #region 事件:XY光标移动事件 /// <summary> /// 光标Y1移动操作 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ucChanLabel_CursorY1_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { this.ucChanLabel_CursorY1.IsChanLabelMouseDown = true; this.ucChanLabel_CursorY1.AxChanLable = e.X; this.ucChanLabel_CursorY1.AyChanLabel = e.Y; } } private void ucChanLabel_CursorY1_MouseMove(object sender, MouseEventArgs e) { if (this.ucChanLabel_CursorY1.IsChanLabelMouseDown) { ucChanLabel_CursorY1.Location = new Point(ucChanLabel_CursorY1.Location.X, ucChanLabel_CursorY1.Location.Y + (e.Y - this.ucChanLabel_CursorY1.AyChanLabel)); if (ucChanLabel_CursorY1.Location.Y <= 0) { ucChanLabel_CursorY1.Location = new Point(ucChanLabel_CursorY1.Location.X, 0); } if (ucChanLabel_CursorY1.Location.Y >= this.panel_Left.Height - ucChanLabel_CursorY1.Height) { ucChanLabel_CursorY1.Location = new Point(ucChanLabel_CursorY1.Location.X, this.panel_Left.Height - ucChanLabel_CursorY1.Height); } pictureBox_DrawRect.Invalidate(); // 更新光标显示 double y1 = paintPara.VertScale - ((ucChanLabel_CursorY1.Location.Y + ucChanLabel_CursorY1.Height / 2) / (panel_Left.Height * 1.0)) * paintPara.VertScale + paintPara.MinValueY; double y2 = paintPara.VertScale - ((ucChanLabel_CursorY2.Location.Y + ucChanLabel_CursorY2.Height / 2) / (panel_Left.Height * 1.0)) * paintPara.VertScale + paintPara.MinValueY; double x1 = ((ucChanLabelVertical_CursorX1.Location.X + ucChanLabelVertical_CursorX1.Width / 2) / (this.panel_Bottom.Width * 1.0)) * paintPara.VertScale + paintPara.MinValueX; double x2 = ((ucChanLabelVertical_CursorX2.Location.X + ucChanLabelVertical_CursorX2.Width / 2) / (this.panel_Bottom.Width * 1.0)) * paintPara.VertScale + paintPara.MinValueX; ucCursorInfo_XY.update_CursorResult(x1, x2, y1, y2); } } private void ucChanLabel_CursorY1_MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { this.ucChanLabel_CursorY1.IsChanLabelMouseDown = false; this.ucChanLabel_CursorY1.CurrentCursorLocation = ucChanLabel_CursorY1.Location.Y / (panel_Left.Height * 1.0); } } private void ucChanLabel_CursorY2_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { this.ucChanLabel_CursorY2.IsChanLabelMouseDown = true; this.ucChanLabel_CursorY2.AxChanLable = e.X; this.ucChanLabel_CursorY2.AyChanLabel = e.Y; } } private void ucChanLabel_CursorY2_MouseMove(object sender, MouseEventArgs e) { if (this.ucChanLabel_CursorY2.IsChanLabelMouseDown) { ucChanLabel_CursorY2.Location = new Point(ucChanLabel_CursorY2.Location.X, ucChanLabel_CursorY2.Location.Y + (e.Y - this.ucChanLabel_CursorY2.AyChanLabel)); if (ucChanLabel_CursorY2.Location.Y <= 0) { ucChanLabel_CursorY2.Location = new Point(ucChanLabel_CursorY2.Location.X, 0); } if (ucChanLabel_CursorY2.Location.Y >= this.panel_Left.Height - ucChanLabel_CursorY2.Height) { ucChanLabel_CursorY2.Location = new Point(ucChanLabel_CursorY2.Location.X, this.panel_Left.Height - ucChanLabel_CursorY2.Height); } pictureBox_DrawRect.Invalidate(); // 更新光标显示 double y1 = paintPara.VertScale - ((ucChanLabel_CursorY1.Location.Y + ucChanLabel_CursorY1.Height / 2) / (panel_Left.Height * 1.0)) * paintPara.VertScale + paintPara.MinValueY; double y2 = paintPara.VertScale - ((ucChanLabel_CursorY2.Location.Y + ucChanLabel_CursorY2.Height / 2) / (panel_Left.Height * 1.0)) * paintPara.VertScale + paintPara.MinValueY; double x1 = ((ucChanLabelVertical_CursorX1.Location.X + ucChanLabelVertical_CursorX1.Width / 2) / (this.panel_Bottom.Width * 1.0)) * paintPara.HoriScale + paintPara.MinValueX; double x2 = ((ucChanLabelVertical_CursorX2.Location.X + ucChanLabelVertical_CursorX2.Width / 2) / (this.panel_Bottom.Width * 1.0)) * paintPara.HoriScale + paintPara.MinValueX; ucCursorInfo_XY.update_CursorResult(x1, x2, y1, y2); } } private void ucChanLabel_CursorY2_MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { this.ucChanLabel_CursorY2.IsChanLabelMouseDown = false; this.ucChanLabel_CursorY2.CurrentCursorLocation = ucChanLabel_CursorY2.Location.Y / (panel_Left.Height * 1.0); } } private void ucChanLabelVertical_CursorX1_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { this.ucChanLabelVertical_CursorX1.IsChanLabelMouseDown = true; this.ucChanLabelVertical_CursorX1.AxChanLable = e.X; this.ucChanLabelVertical_CursorX1.AyChanLabel = e.Y; } } private void ucChanLabelVertical_CursorX1_MouseMove(object sender, MouseEventArgs e) { if (this.ucChanLabelVertical_CursorX1.IsChanLabelMouseDown) { ucChanLabelVertical_CursorX1.Location = new Point(ucChanLabelVertical_CursorX1.Location.X + (e.X - this.ucChanLabelVertical_CursorX1.AxChanLable), ucChanLabelVertical_CursorX1.Location.Y); if (ucChanLabelVertical_CursorX1.Location.X <= 0) { ucChanLabelVertical_CursorX1.Location = new Point(0, ucChanLabelVertical_CursorX1.Location.Y); } if (ucChanLabelVertical_CursorX1.Location.X >= this.panel_Bottom.Width - ucChanLabelVertical_CursorX1.Width) { ucChanLabelVertical_CursorX1.Location = new Point(this.panel_Bottom.Width - ucChanLabelVertical_CursorX1.Width, ucChanLabelVertical_CursorX1.Location.Y); } pictureBox_DrawRect.Invalidate(); // 更新光标显示 double y1 = paintPara.VertScale - ((ucChanLabel_CursorY1.Location.Y + ucChanLabel_CursorY1.Height / 2) / (panel_Left.Height * 1.0)) * paintPara.VertScale + paintPara.MinValueY; double y2 = paintPara.VertScale - ((ucChanLabel_CursorY2.Location.Y + ucChanLabel_CursorY2.Height / 2) / (panel_Left.Height * 1.0)) * paintPara.VertScale + paintPara.MinValueY; double x1 = ((ucChanLabelVertical_CursorX1.Location.X + ucChanLabelVertical_CursorX1.Width / 2) / (this.panel_Bottom.Width * 1.0)) * paintPara.HoriScale + paintPara.MinValueX; double x2 = ((ucChanLabelVertical_CursorX2.Location.X + ucChanLabelVertical_CursorX2.Width / 2) / (this.panel_Bottom.Width * 1.0)) * paintPara.HoriScale + paintPara.MinValueX; ucCursorInfo_XY.update_CursorResult(x1, x2, y1, y2); } } private void ucChanLabelVertical_CursorX1_MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { this.ucChanLabelVertical_CursorX1.IsChanLabelMouseDown = false; this.ucChanLabelVertical_CursorX1.CurrentCursorLocation = ucChanLabelVertical_CursorX1.Location.X / (panel_Bottom.Width * 1.0); } } private void ucChanLabelVertical_CursorX2_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { this.ucChanLabelVertical_CursorX2.IsChanLabelMouseDown = true; this.ucChanLabelVertical_CursorX2.AxChanLable = e.X; this.ucChanLabelVertical_CursorX2.AyChanLabel = e.Y; } } private void ucChanLabelVertical_CursorX2_MouseMove(object sender, MouseEventArgs e) { if (this.ucChanLabelVertical_CursorX2.IsChanLabelMouseDown) { ucChanLabelVertical_CursorX2.Location = new Point(ucChanLabelVertical_CursorX2.Location.X + (e.X - this.ucChanLabelVertical_CursorX2.AxChanLable), ucChanLabelVertical_CursorX2.Location.Y); if (ucChanLabelVertical_CursorX2.Location.X <= 0) { ucChanLabelVertical_CursorX2.Location = new Point(0, ucChanLabelVertical_CursorX2.Location.Y); } if (ucChanLabelVertical_CursorX2.Location.X >= this.panel_Bottom.Width - ucChanLabelVertical_CursorX2.Width) { ucChanLabelVertical_CursorX2.Location = new Point(this.panel_Bottom.Width - ucChanLabelVertical_CursorX2.Width, ucChanLabelVertical_CursorX2.Location.Y); } pictureBox_DrawRect.Invalidate(); // 更新光标显示 double y1 = paintPara.VertScale - ((ucChanLabel_CursorY1.Location.Y + ucChanLabel_CursorY1.Height / 2) / (panel_Left.Height * 1.0)) * paintPara.VertScale + paintPara.MinValueY; double y2 = paintPara.VertScale - ((ucChanLabel_CursorY2.Location.Y + ucChanLabel_CursorY2.Height / 2) / (panel_Left.Height * 1.0)) * paintPara.VertScale + paintPara.MinValueY; double x1 = ((ucChanLabelVertical_CursorX1.Location.X + ucChanLabelVertical_CursorX1.Width / 2) / (this.panel_Bottom.Width * 1.0)) * paintPara.HoriScale + paintPara.MinValueX; double x2 = ((ucChanLabelVertical_CursorX2.Location.X + ucChanLabelVertical_CursorX2.Width / 2) / (this.panel_Bottom.Width * 1.0)) * paintPara.HoriScale + paintPara.MinValueX; ucCursorInfo_XY.update_CursorResult(x1, x2, y1, y2); } } private void ucChanLabelVertical_CursorX2_MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { this.ucChanLabelVertical_CursorX2.IsChanLabelMouseDown = false; this.ucChanLabelVertical_CursorX2.CurrentCursorLocation = ucChanLabelVertical_CursorX2.Location.X / (panel_Bottom.Width * 1.0); } } private void ucCursorInfo_XY_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { this.ucCursorInfo_XY.IsCursorResultMouseDown = true; this.ucCursorInfo_XY.AxCursorResult = e.X; this.ucCursorInfo_XY.AyCursorResult = e.Y; } } private void ucCursorInfo_XY_MouseMove(object sender, MouseEventArgs e) { if (this.ucCursorInfo_XY.IsCursorResultMouseDown) { ucCursorInfo_XY.Location = new Point(ucCursorInfo_XY.Location.X + (e.X - this.ucCursorInfo_XY.AxCursorResult), ucCursorInfo_XY.Location.Y + (e.Y - this.ucCursorInfo_XY.AxCursorResult)); if (ucCursorInfo_XY.Location.X <= 0) { ucCursorInfo_XY.Location = new Point(0, ucCursorInfo_XY.Location.Y); } if (ucCursorInfo_XY.Location.X >= this.pictureBox_DrawRect.Width - ucCursorInfo_XY.Width) { ucCursorInfo_XY.Location = new Point(this.pictureBox_DrawRect.Width - ucCursorInfo_XY.Width, ucCursorInfo_XY.Location.Y); } if (ucCursorInfo_XY.Location.Y <= 0) { ucCursorInfo_XY.Location = new Point(ucCursorInfo_XY.Location.X, 0); } if (ucCursorInfo_XY.Location.Y >= this.pictureBox_DrawRect.Height - ucCursorInfo_XY.Height) { ucCursorInfo_XY.Location = new Point(ucCursorInfo_XY.Location.X, this.pictureBox_DrawRect.Height - ucCursorInfo_XY.Height); } } } private void ucCursorInfo_XY_MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { this.ucCursorInfo_XY.IsCursorResultMouseDown = false; } } #endregion #region 事件:波形复原,根据偏移值算点 private void iconMenuItem_All_Click(object sender, EventArgs e) { /*更新显示的偏移值*/ foreach (var item in listWaveDataSeriesCopy) { int index = 0; if (item.listWaveData[0].Y != item.offSetOrig[0].Y) { float pos = item.listWaveData[0].Y - item.offSetOrig[0].Y; for (int i = 0; i < item.listWaveData.Count; i++) { item.listWaveData[i] = new System.Drawing.PointF(item.listWaveData[i].X, item.listWaveData[i].Y-pos); } } index++; } RefreshControl(listWaveDataSeriesCopy); Drawing(listWaveDataSeriesCopy); } //类可序列化[Serializable] public static T Clone<T>(T RealObject) { using (Stream objectStream = new MemoryStream()) { //利用 System.Runtime.Serialization序列化与反序列化完成引用对象的复制 IFormatter formatter = new BinaryFormatter(); formatter.Serialize(objectStream, RealObject); objectStream.Seek(0, SeekOrigin.Begin); return (T)formatter.Deserialize(objectStream); } } #endregion #region 事件:加载波形数据(需实现dataManager.ReadData()方法 private void iconToolStripButton_Load_Click(object sender, EventArgs e) { //清空显示 RemoveControl(listWaveDataSeriesCopy); //读取数据 listWaveDataSeriesCopy.Clear(); //初始化 Init(); dataManager.ReadData(); listWaveDataSeriesCopy = dataManager.listWaveDataSeries; paintPara.IndexXStart = 0; paintPara.IndexXFinish = listWaveDataSeriesCopy[0].listWaveData.Count; Drawing(listWaveDataSeriesCopy); AddTagControl(listWaveDataSeriesCopy); } #endregion #region 事件:半峰高对齐 private void iconToolStripButton_Align_Click(object sender, EventArgs e) { } #endregion #region 事件:归一化显示 private void iconToolStripButton_Normalization_Click(object sender, EventArgs e) { } #endregion }}
波形参数
using CBB_Saker_Painting_1._0._0.Global;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
namespace CBB_Saker_Painting_1._0._0 {
public class PaintPara {
#region 绘图属性
private float maxValueY;
public float MaxValueY {
get { return maxValueY; }
set { maxValueY = value; }
}
private float minValueY;
public float MinValueY {
get { return minValueY; }
set { minValueY = value; }
}
private double minValueX;
public double MinValueX {
get { return minValueX; }
set { minValueX = value; }
}
private double maxValueX;
public double MaxValueX {
get { return maxValueX; }
set { maxValueX = value; }
}
/// <summary>
/// 垂直范围
/// </summary>
private float vertScale;
public float VertScale {
get { return (MaxValueY - MinValueY); }
set { vertScale = value; }
}
/// <summary>
/// 水平范围
/// </summary>
private double horiScale;
public double HoriScale {
get { return (MaxValueX - MinValueX); }
set { horiScale = value; }
}
/// <summary>
/// Y顶部
/// </summary>
private string strtopY;
public string strTopY {
get { return Voltage2String(MaxValueY); }
set { strtopY = value; }
}
/// <summary>
/// Y底部
/// </summary>
private string strbottomY;
public string strBottomY {
get { return Voltage2String(MinValueY); }
set { strbottomY = value; }
}
/// <summary>
/// X轴最右侧
/// </summary>
private string horizRight;
public string HorizRight {
get { return Time2String(MaxValueX); }
set { horizRight = value; }
}
/// <summary>
/// 线条颜色
/// </summary>
private Color lineColor;
public Color LineColor {
get { return lineColor; }
set { lineColor = value; }
}
/// <summary>
/// 纵轴等分数量
/// </summary>
private float bisectrixY;
public float BisectrixY {
get { return bisectrixY; }
set { bisectrixY = value; }
}
/// <summary>
/// 横轴等分数量
/// </summary>
private float bisectrixX;
public float BisectrixX {
get { return bisectrixX; }
set { bisectrixX = value; }
}
/// <summary>
/// X轴点的个数
/// </summary>
private int xScaleCount;
public int XScaleCount {
get { return xScaleCount; }
set { xScaleCount = value; }
}
/// <summary>
/// Y轴点的个数
/// </summary>
private int yScaleCount =256;
public int YScaleCount {
get { return yScaleCount; }
set { yScaleCount = value; }
}
/// <summary>
/// 垂直间距像素
/// </summary>
private float verticalBetween;
public float VerticalBetween {
get { return CharHeight/YScaleCount; }
set { verticalBetween = value; }
}
/// <summary>
/// 水平间距像素
/// </summary>
private float horizontalBetween;
public float HorizontalBetween {
get { return CharWidth / XScaleCount; }
set { horizontalBetween = value; }
}
/// <summary>
/// 图表区域宽度
/// </summary>
private float charWidth;
public float CharWidth {
get { return charWidth; }
set { charWidth = value; }
}
/// <summary>
/// 图表区域高度
/// </summary>
private float charHeight;
public float CharHeight {
get { return charHeight; }
set { charHeight = value; }
}
/// <summary>
/// Y轴每个间隔值
/// </summary>
private float intervalValueY;
public float IntervalValueY {
get { return VertScale/YScaleCount; }
set { intervalValueY = value; }
}
/// <summary>
/// 画图区域起点
/// </summary>
private PointF startPosition;
public PointF StartPosition {
get { return new PointF(0,0); }
set { startPosition = value; }
}
/// <summary>
/// 画图区域终点
/// </summary>
private PointF endPosition;
public PointF EndPosition {
get { return new PointF(CharWidth, CharHeight); }
set { endPosition = value; }
}
public bool bYMarking { get; set; }//是否显示Y轴标志
public bool bDrawGridLineY { get; set; }// 是否绘制Y轴的刻度线
public bool bXMarking { get; set; }//是否显示X轴标志
public bool bDrawGridLineX { get; set; }//是否绘制X轴的刻度线
public List<Bitmap> listImages = new List<Bitmap>();//图层链表
#endregion
#region 波形放大相关参数
/// <summary>
/// 波形放大标志
/// </summary>
private bool benlagerClick;
public bool bEnlagerClick {
get { return benlagerClick; }
set { benlagerClick = value; }
}
/// <summary>
/// 开始绘制
/// </summary>
private bool bdrawStart;
public bool bDrawStart {
get { return bdrawStart; }
set { bdrawStart = value; }
}
public Point PointStart { get; set; }
public Point PointContinue { get; set; }
#endregion
#region XY光标参数
public bool bCursorXShow { get; set; } //显示X轴光标
public bool bCursorYShow { get; set; }//显示Y轴光标
public bool bCursorXYMesInfo { get; set; }//XY轴光标测量信息
#endregion
#region 方法:处理横纵轴坐标
public static string Voltage2String(double value) {
string str = "";
if (Math.Abs(value) >= 1.0) {
if (Math.Abs(value) / 1000000.0 >= 1.0) {
str = Math.Round(value / 1000000.0, 2).ToString() + CGlobalString.STR_VOLTAGE_M_V;
}
else if (Math.Abs(value) / 1000.0 >= 1.0) {
str = Math.Round(value / 1000.0, 2).ToString() + CGlobalString.STR_VOLTAGE_KV;
}
else {
str = Math.Round(value, 2).ToString() + CGlobalString.STR_VOLTAGE_V;
}
}
else if (Math.Abs(value) * 1000 >= 1.0) {
if (Math.Abs(value) * 1000 >= 100) {
str = Math.Round(value * 1000, 0).ToString() + CGlobalString.STR_VOLTAGE_MV;
}
else if (Math.Abs(value) * 1000 >= 10) {
str = Math.Round(value * 1000, 1).ToString() + CGlobalString.STR_VOLTAGE_MV;
}
else {
str = Math.Round(value * 1000, 2).ToString() + CGlobalString.STR_VOLTAGE_MV;
}
}
else if (Math.Abs(value) * 1000000 >= 1.0) {
if (Math.Abs(value) * 1000000 >= 100) {
str = Math.Round(value * 1000, 0).ToString() + CGlobalString.STR_VOLTAGE_UV;
}
else if (Math.Abs(value) * 1000000 >= 10) {
str = Math.Round(value * 1000, 1).ToString() + CGlobalString.STR_VOLTAGE_UV;
}
else {
str = Math.Round(value * 1000, 2).ToString() + CGlobalString.STR_VOLTAGE_UV;
}
}
else {
str = "0.00" + CGlobalString.STR_VOLTAGE_V;
}
return str;
}
public static string Time2String(double value) {
string strTime = "";
if (Math.Abs(value) >= 1.0) {
strTime = Math.Round(value, 2).ToString() + CGlobalString.STR_TIME_S;
}
else if (Math.Abs(value) * 1000 >= 1.0) {
if (Math.Abs(value) * 1000 >= 100) {
strTime = Math.Round(value * 1000, 0).ToString() + CGlobalString.STR_TIME_MS;
}
else if (Math.Abs(value) * 1000 >= 10) {
strTime = Math.Round(value * 1000, 1).ToString() + CGlobalString.STR_TIME_MS;
}
else {
strTime = Math.Round(value * 1000, 2).ToString() + CGlobalString.STR_TIME_MS;
}
}
else if (Math.Abs(value) * 1000000 >= 1.0) {
if (Math.Abs(value) * 1000000 >= 100) {
strTime = Math.Round(value * 1000000, 6).ToString() + CGlobalString.STR_TIME_US;
}
else if (Math.Abs(value) * 1000000 >= 10) {
strTime = Math.Round(value * 1000000, 6).ToString() + CGlobalString.STR_TIME_US;
}
else {
strTime = Math.Round(value * 1000000, 6).ToString() + CGlobalString.STR_TIME_US;
}
}
else if (Math.Abs(value) * 1000000000 >= 1.0) {
if (Math.Abs(value) * 1000000000 >= 100) {
strTime = Math.Round(value * 1000000000, 3).ToString() + CGlobalString.STR_TIME_NS;
}
else if (Math.Abs(value) * 1000000000 >= 10) {
strTime = Math.Round(value * 1000000000, 3).ToString() + CGlobalString.STR_TIME_NS;
}
else {
strTime = Math.Round(value * 1000000000, 3).ToString() + CGlobalString.STR_TIME_NS;
}
}
else if (Math.Abs(value) * 1000000000000 >= 1.0) {
if (Math.Abs(value) * 1000000000000 >= 100) {
strTime = Math.Round(value * 1000000000000, 0).ToString() + CGlobalString.STR_TIME_PS;
}
else if (Math.Abs(value) * 1000000000000 >= 10) {
strTime = Math.Round(value * 1000000000000, 1).ToString() + CGlobalString.STR_TIME_PS;
}
else {
strTime = Math.Round(value * 1000000000000, 2).ToString() + CGlobalString.STR_TIME_PS;
}
}
else {
strTime = "0.00s";
}
return strTime;
}
public void Init(float pictureWidth, float pictureHeight) {
this.MinValueY = -10;
this.MaxValueY = 10;
this.MinValueX = 0;
this.MaxValueX = 10;
this.BisectrixY = 8.0f;//分为8份
this.bisectrixX = 10.0f;//分为10份
this.bYMarking = true;//显示Y轴标志
this.bXMarking = true;//显示X轴标志
this.bDrawGridLineX = true;//绘制X轴的刻度线
this.bDrawGridLineY = true;//绘制Y轴的刻度线
this.bCursorXShow = true;//X光标默认显示
this.bCursorYShow = true;//Y光标默认显示
this.bCursorXYMesInfo = true;//XY轴测量信息
this.CharHeight = pictureHeight;//绘图区域
this.CharWidth = pictureWidth;//绘图区域
}
#endregion
}
}
