using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; using DevExpress.XtraEditors; using System.IO; using System.Reflection; using DevExpress.XtraEditors.Controls; namespace Uninpho.Railway.Waveform { public partial class DrawCrl : DevExpress.XtraEditors.XtraUserControl { #region 变量 public static int boardkey = 0;//键盘key bool ishover = false;//鼠标是否在控件内 WaveInput waveinput = new WaveInput(); Bitmap bmp; Graphics g; Bitmap bmpsc; Graphics gg; List labelTitle = new List(); public Dictionary labelList = new Dictionary();//label集合 MathTools MT;//计算工具 int pianyi = 0;//对比的图的偏移量 int step = 25;//纵轴平移步长 int stepX = 10;//横轴方向显示步长 double blc = 0.5;//波形图显示高与实际bitmap的比值 double blcx = 0.5;//波形图显示高与实际bitmap的比值 int maxW = 0;//滚动条最大宽度,按照输入参数中坐标的数量确定 int nowX = 0;//滚动条当前位置的x值 #endregion public DrawCrl() { InitializeComponent(); } #region !!!初始化信息 !!! /// /// 初始化加载项 /// public void YXCLoadEvnet(WaveInput waveinput_,bool showJGT) { waveinput = waveinput_; if (waveinput_.InputType.Split('_')[0] == "jh") { TitlleCrl.Text = " 几 何 波 形"; } else if (waveinput_.InputType.Split('_')[0] == "lgl") { TitlleCrl.Text = " 轮 轨 力 波 形"; } else { TitlleCrl.Text = ""; } TitlleCrl.BackColor = Color.White; MT = new MathTools(waveinput.InputType); //1.加载结构图(判断是否有,有则加载) YXCjiegoutuLoad(showJGT); //2.加载需要绘制的数据 YXCDrawDataLoad(); //3.加载相关组件 YXCComponentsLoad(); //4.绘制 DrawMainBox_PaintFun(); } /// /// 初始化加载结构图 /// private void YXCjiegoutuLoad(bool showJGT) { if (showJGT && File.Exists(waveinput.jgtPath)) { JGTpictureBox.Image = Image.FromFile(waveinput.jgtPath); //JGTpictureBox.ImageLocation } else { MytableLayoutPanel.RowStyles[0].Height = 0; } } /// /// 初始化加载绘制数据 /// private void YXCDrawDataLoad() { //1.修正pictureBox宽度 maxW = waveinput.waveData.ElementAt(0).Value.CoorList.Count; int sho = maxW / 10; if (sho >= 10) { maxW = (sho * 10 + 10) / 10; } //2.初始化画布等参数 bmp = new Bitmap(2000, 2000);//初始化bitmap宽高 bmpsc = new Bitmap(2000, 90); blc = Convert.ToDouble(DrawMainBox.Height) / Convert.ToDouble(bmp.Height);//采集bmp的拉伸比例,用来修正右侧label位置,可以理解为label控件坐标系统和波形图坐标系统转换的一个参数 blcx = Convert.ToDouble(DrawMainBox.Width) / Convert.ToDouble(bmp.Width);//采集bmp的拉伸比例,用来修正右侧label位置,可以理解为label控件坐标系统和波形图坐标系统转换的一个参数 //DrawMainBox.Location = new Point(0, 0); g = Graphics.FromImage(bmp); gg = Graphics.FromImage(bmpsc); DrawFunClass.Trans(g, 0, bmp.Height); DrawFunClass.Trans(gg, 0, bmpsc.Height); } /// /// 初始化组件 /// private void YXCComponentsLoad() { //图片互操作激活 JGTpictureBox.MouseWheel += pictureBox1_MouseWheel; DrawMainBox.MouseWheel += DrawMainBox_MouseWheel; //初始化checkedcombobox for (int i = 0; i < waveinput.waveData.Count; i++) { iniSetClass.updataPZflash1(waveinput.waveData.ElementAt(i).Value);//只要选择框出现的字段都在配置文件中添加一次 BXCheckedComboBox.Properties.Items.Add(new CheckedListBoxItem() { CheckState = waveinput.waveData.ElementAt(i).Value.Visible == true ? CheckState.Checked : CheckState.Unchecked, Description = waveinput.waveData.ElementAt(i).Value.ListName, Value = waveinput.waveData.ElementAt(i).Value.ListId, }); } initLabelFun();//初始化波形图右侧的label控件 checkedDataWithCCB(); showLabelFun(); } #endregion #region 事件 #region 绘制 List xarr = new List(); /// /// 画图 /// public void DrawMainBox_PaintFun() { string temp = string.Empty; blc = Convert.ToDouble(DrawMainBox.Height) / Convert.ToDouble(bmp.Height);//采集bmp的拉伸比例,用来修正右侧label位置,可以理解为label控件坐标系统和波形图坐标系统转换的一个参数 blcx = Convert.ToDouble(DrawMainBox.Width) / Convert.ToDouble(bmp.Width);//采集bmp的拉伸比例,用来修正右侧label位置,可以理解为label控件坐标系统和波形图坐标系统转换的一个参数 g.Clear(Color.White); for (int i = 0; i < labelTitle.Count; i++) { CoorListClass c = waveinput.waveData[(string)labelTitle[i].Value]; if (c.Visible == false) { continue; } int offset = MT.PYLJZ(c.Offset, c.AxisY, bmp.Height, step); if (c.CoorListOld != null) { MT.MathLoad(c.CoorListOld, maxW);//为了提高渲染效率,把计算范围的过程提出来了 PointF[] points1 = MT.getDrawPointsOld(c.CoorListOld, bmp.Width, (int)(300 / c.Scale), nowX, offset, pianyi); DrawFunClass.DrawLinesFun(g, points1, Color.Black, c.Width); } MT.MathLoad(c.CoorList, maxW);//为了提高渲染效率,把计算范围的过程提出来了 PointF[] points = MT.getDrawPoints(c.CoorList, bmp.Width, (int)(300 / c.Scale), nowX, offset, ref temp); DrawFunClass.DrawLinesFun(g, points, Color.FromArgb(c.RGBA[3], c.RGBA[0], c.RGBA[1], c.RGBA[2]), c.Width); if (waveinput.InputType == "qsfx_all") { if (xarr.Count == 0) { for (int j = 0; j < points.Length; j++) { xarr.Add(points[j].X); } } } //************************ //画横坐标轴 Pen p = new Pen(Color.Black, 2); p.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom; p.DashPattern = new float[] { stepX, stepX }; g.DrawLine(p, new PointF(0 - nowX * 2, offset), new PointF(bmp.Width, offset)); labelList[c.ListId].changeLabelValue(temp); } PaintZZ(MT.xAxis, MT.xAxisF);//画纵坐标轴 ScalePanel_PaintFun(); DrawMainBox.Image = bmp; } /// /// 画比例尺图 /// public void ScalePanel_PaintFun() { gg.Clear(Color.White); DrawFunClass.DrawScaleLine(gg, new PointF(0, bmpsc.Height / 8), new PointF(bmpsc.Width, bmpsc.Height / 8), Color.Red, bmpsc.Height / 4); if (waveinput.InputType == "qsfx_all") { for (int i = 0; i < xarr.Count; i++) { PointF p1 = new PointF(xarr[i], 0); PointF p2 = new PointF(xarr[i], bmpsc.Height / 2); DrawFunClass.DrawScaleLine(gg, p1, p2, Color.Red, 10); DrawFunClass.DrawScaleString(gg, p2, Color.Red, 30, waveinput.waveData.ElementAt(0).Value.qsfxXstring[i], 125); } } else { for (int i = 0; i < MT.xAxis.Count; i++) { PointF p1 = new PointF(MT.xAxis[i], 0); PointF p2 = new PointF(MT.xAxis[i], bmpsc.Height / 2); DrawFunClass.DrawScaleLine(gg, p1, p2, Color.Red, 10); DrawFunClass.DrawScaleString(gg, p2, Color.Red, 30, MT.AxisValue[i],25); } for (int i = 0; i < MT.xAxisF.Count; i++) { PointF p1 = new PointF(MT.xAxisF[i], 0); PointF p2 = new PointF(MT.xAxisF[i], bmpsc.Height / 2); DrawFunClass.DrawScaleLine(gg, p1, p2, Color.Red, 5); } } ScalePanel.Image = bmpsc; } /// /// 画纵轴 /// private void PaintZZ(List xAxis, List xAxisF) { for (int j = 0; j < xAxis.Count; j++) { float x = xAxis[j]; Pen ps = new Pen(Color.Black, 1); g.DrawLine(ps, new PointF(x, 0), new PointF(x, bmp.Height)); for (int i = 0; i < bmp.Height; i = i + step) { g.DrawLine(ps, new PointF(x - 5, i), new PointF(x + 5, i)); } } for (int j = 0; j < xAxisF.Count; j++) { float x = xAxisF[j]; Pen ps = new Pen(Color.Black, 1); //g.DrawLine(ps, new PointF(x, 0), new PointF(x, bmp.Height)); for (int i = 0; i < bmp.Height; i = i + step) { g.DrawLine(ps, new PointF(x - 5, i), new PointF(x + 5, i)); } } } #endregion /// /// 重选通道、重新绘制 /// /// /// private void BXCheckedComboBox_Closed(object sender, ClosedEventArgs e) { checkedDataWithCCB(); showLabelFun(); DrawMainBox_PaintFun(); } /// /// 使用Resize方法修正label坐标 /// private void LabelPanel_Resize(object sender, EventArgs e) { if (bmp != null) { DrawMainBox_PaintFun(); } correctLabelLocation(); } #region 键盘鼠标交互 private void DrawMainBox_MouseEnter(object sender, EventArgs e) { ishover = true; } private void DrawMainBox_MouseLeave(object sender, EventArgs e) { ishover = false; } private void DrawMainBox_MouseWheel(object sender, MouseEventArgs e) { if (ishover) { if (e.Delta > 0) { if (boardkey == 18) { //历史数据对比 //仅限波形分析使用 //历史波形向右移动 alt pianyi = pianyi + 5; } else if (boardkey == 17) { //缩放 放大 ctrl } else { //平移 向右 nowX = nowX < 0 ? 0 : nowX - 1; BitMapHScroll.Value = nowX; } } else { if (boardkey == 18) { //历史数据对比 //仅限波形分析使用 //还原 pianyi = pianyi - 5; } else if (boardkey == 17) { //缩放 缩小 } else { //平移 向左 nowX = nowX > BitMapHScroll.Maximum ? BitMapHScroll.Maximum : nowX + 1; BitMapHScroll.Value = nowX; } } DrawMainBox_PaintFun(); } } #endregion #endregion #region Tools public void updataWaveInput(CoorListClass newlist) { waveinput.waveData[newlist.ListId] = newlist; iniSetClass.updataPZflash(newlist); iniSetClass.savePZFun(); DrawMainBox_PaintFun(); } #region 鼠标点击上下移动波形图 int ay; int y; PanelControl rc; private void panel1_MouseDown(object sender, MouseEventArgs e) { rc = (PanelControl)sender; ay = e.Y; //y = DeepCopyByReflect(labelList[rc.Name].Location.Y); y = labelList[rc.Name].Location.Y; } private void panel1_MouseMove(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { int yy = labelList[rc.Name].Location.Y; //int offset = (int)((e.Y - ay) / (step * blc)) * (int)(step * blc); int offset = (int)Math.Round((int)((e.Y - ay) / (step * blc)) * (step * blc), 0); labelList[rc.Name].Location = new Point(5, yy + offset); //DataBus.coorslist[DataBus.dictindex][rc.Name].Offset += (double)offset / (double)LabelPanel.Height; //DrawMainBox_PaintFun(); } } private void panel1_MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { waveinput.waveData[rc.Name].Offset += (double)(labelList[rc.Name].Location.Y - y) / (double)LabelPanel.Height; DrawMainBox_PaintFun(); } } #endregion #region 初始化右侧可移动的label标签 /// /// 新建一个RightLabelControl /// private void createLabelCtrl(Point location, CoorListClass coor) { RightLabelControl rlc = new RightLabelControl(coor, this); rlc.Name = coor.ListId + "_RLC"; rlc.Parent = LabelPanel; rlc.Visible = false; rlc.move_Panel.Name = coor.ListId; rlc.move_Panel.MouseDown += panel1_MouseDown; rlc.move_Panel.MouseMove += panel1_MouseMove; rlc.move_Panel.MouseUp += panel1_MouseUp; labelList.Add(coor.ListId, rlc); } /// /// 初始化波形图右侧的label控件 /// private void initLabelFun() { for (int i = 0; i < waveinput.waveData.Count; i++) { createLabelCtrl(new Point(0, 0), waveinput.waveData.ElementAt(i).Value); } } /// /// 选择勾选的通道进行显示 /// private void checkedDataWithCCB() { labelTitle.Clear(); labelTitle = BXCheckedComboBox.Properties.Items.Where(c => { return c.CheckState == CheckState.Checked; }).ToList(); double rows = 1.0 / (labelTitle.Count + 1.0); foreach (var item in waveinput.waveData) { item.Value.Visible = false; } for (int i = 0; i < labelTitle.Count; i++) { waveinput.waveData[(string)labelTitle[i].Value].Visible = true; waveinput.waveData[(string)labelTitle[i].Value].AxisY = rows * (i + 1); iniSetClass.updataPZflash(waveinput.waveData[(string)labelTitle[i].Value]); } iniSetClass.savePZFun(); } /// /// 控制波形图右侧的label控件显隐 /// private void showLabelFun() { for (int i = 0; i < waveinput.waveData.Count; i++) { CoorListClass c = waveinput.waveData.ElementAt(i).Value; labelList[c.ListId].Visible = c.Visible; } correctLabelLocation(); } /// /// 修正label坐标 /// private void correctLabelLocation() { for (int i = 0; i < labelTitle.Count; i++) { CoorListClass c = waveinput.waveData[(string)labelTitle[i].Value]; //int offset = (int)(c.AxisY * DrawMainBox.Height); int offset = (int)((c.Offset + c.AxisY) * DrawMainBox.Height); labelList[c.ListId].Location = new Point(5, offset - labelList[c.ListId].Height); } } #endregion /// /// Scroll左右滑动波形图 /// private void BitMapHScroll_Scroll(object sender, ScrollEventArgs e) { //DrawMainBox.Left = -BitMapHScroll.Value; nowX = (int)BitMapHScroll.Value; DrawMainBox_PaintFun(); } /// /// 深拷贝 /// /// /// /// public static T DeepCopyByReflect(T obj) { //如果是字符串或值类型则直接返回 if (obj is string || obj.GetType().IsValueType) return obj; object retval = Activator.CreateInstance(obj.GetType()); FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static); foreach (FieldInfo field in fields) { try { field.SetValue(retval, DeepCopyByReflect(field.GetValue(obj))); } catch { } } return (T)retval; } #endregion #region 测试用的,结构图移动 private void pictureBox1_MouseClick(object sender, MouseEventArgs e) { JGTpictureBox.Focus(); if (isMove) { int x, y; int moveX, moveY; moveX = Cursor.Position.X - mouseDownPoint.X; moveY = Cursor.Position.Y - mouseDownPoint.Y; x = JGTpictureBox.Location.X + moveX; y = JGTpictureBox.Location.Y + moveY; JGTpictureBox.Location = new Point(x, y); mouseDownPoint.X = Cursor.Position.X; mouseDownPoint.Y = Cursor.Position.Y; } } Point mouseDownPoint = new Point(); bool isMove; private void pictureBox1_MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { isMove = false; } } private void pictureBox1_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { mouseDownPoint.X = Cursor.Position.X; mouseDownPoint.Y = Cursor.Position.Y; isMove = true; JGTpictureBox.Focus(); } } int zoomStep = 20; private void pictureBox1_MouseWheel(object sender, MouseEventArgs e) { int x = e.Location.X; int y = e.Location.Y; int ow = JGTpictureBox.Width; int oh = JGTpictureBox.Height; int vx, vy; if (e.Delta > 0) //放大 { //1、 JGTpictureBox.Width += zoomStep + 10; JGTpictureBox.Height += zoomStep + 10; //2、 PropertyInfo pInfo = JGTpictureBox.GetType().GetProperty("ImageRectangle", BindingFlags.Instance | BindingFlags.NonPublic); Rectangle rect = (Rectangle)pInfo.GetValue(JGTpictureBox);//()里可以含两个参数,index[]为null //3、 JGTpictureBox.Width = rect.Width; JGTpictureBox.Height = rect.Height; } if (e.Delta < 0)//缩小 { //防止缩小成负 if (JGTpictureBox.Width < zoomStep) { return; } JGTpictureBox.Width -= zoomStep; JGTpictureBox.Height -= zoomStep; PropertyInfo pInfo = JGTpictureBox.GetType().GetProperty("ImageRectangle", BindingFlags.Instance | BindingFlags.NonPublic); Rectangle rect = (Rectangle)pInfo.GetValue(JGTpictureBox); JGTpictureBox.Width = rect.Width; JGTpictureBox.Height = rect.Height; } //4、 vx = (int)((double)x * (ow - JGTpictureBox.Width) / ow); vy = (int)((double)y * (oh - JGTpictureBox.Height) / oh); JGTpictureBox.Location = new Point(JGTpictureBox.Location.X + vx, JGTpictureBox.Location.Y + vy); } #endregion } }