
类设计

主程序
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
}
}
