using CommunityToolkit.Mvvm.Input; using FLY.Thick.Base.Common; using FLY.Thick.Base.IService; using FLY.Thick.Base.Server; using Misc; using System; using System.ComponentModel; using System.Drawing; using System.Windows.Controls; using System.Windows.Forms.DataVisualization.Charting; using Unity; namespace FLY.Thick.Base.UI { /// /// Page_BorderSearch.xaml 的交互逻辑 /// public partial class PgBorderSearch : Page { PgBorderSearchVm viewModel; IUnityContainer container; public PgBorderSearch() { InitializeComponent(); InitializeChart(); } void InitializeChart() { System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea(); System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend(); System.Windows.Forms.DataVisualization.Charting.Series series_datas = new System.Windows.Forms.DataVisualization.Charting.Series(); System.Windows.Forms.DataVisualization.Charting.Series series_border = new System.Windows.Forms.DataVisualization.Charting.Series(); // // chart1 // //this.chart1.BackColor = System.Drawing.Color.FromArgb(((System.Byte)(211)), ((System.Byte)(223)), ((System.Byte)(240))); //this.chart1.BackSecondaryColor = System.Drawing.Color.White; //this.chart1.BackGradientStyle = System.Windows.Forms.DataVisualization.Charting.GradientStyle.TopBottom; //this.chart1.BorderlineColor = System.Drawing.Color.FromArgb(((System.Byte)(26)), ((System.Byte)(59)), ((System.Byte)(105))); //this.chart1.BorderlineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid; //this.chart1.BorderlineWidth = 2; //this.chart1.BorderSkin.SkinStyle = System.Windows.Forms.DataVisualization.Charting.BorderSkinStyle.Emboss; #region chartArea #region chartArea1 chartArea1.Name = "chartArea1"; chartArea1.AxisX.IsLabelAutoFit = false; chartArea1.AxisX.LabelStyle.Font = new System.Drawing.Font("Trebuchet MS", 8.25F, System.Drawing.FontStyle.Bold); //chartArea1.AxisX.LabelStyle.IsEndLabelVisible = false; chartArea1.AxisX.LineColor = System.Drawing.Color.FromArgb(((System.Byte)(64)), ((System.Byte)(64)), ((System.Byte)(64)), ((System.Byte)(64))); chartArea1.AxisX.MajorGrid.LineColor = System.Drawing.Color.FromArgb(((System.Byte)(64)), ((System.Byte)(64)), ((System.Byte)(64)), ((System.Byte)(64))); chartArea1.AxisX.Title = "位置(脉冲)"; chartArea1.AxisY.IsLabelAutoFit = false; chartArea1.AxisY.LabelStyle.Font = new System.Drawing.Font("Trebuchet MS", 8.25F, System.Drawing.FontStyle.Bold); chartArea1.AxisY.LineColor = System.Drawing.Color.FromArgb(((System.Byte)(64)), ((System.Byte)(64)), ((System.Byte)(64)), ((System.Byte)(64))); chartArea1.AxisY.MajorGrid.LineColor = System.Drawing.Color.FromArgb(((System.Byte)(64)), ((System.Byte)(64)), ((System.Byte)(64)), ((System.Byte)(64))); chartArea1.AxisY.Title = "AD值"; //chartArea1.AxisY.IsStartedFromZero = false; chartArea1.BackColor = System.Drawing.Color.FromArgb(((System.Byte)(64)), ((System.Byte)(165)), ((System.Byte)(191)), ((System.Byte)(228))); chartArea1.BackSecondaryColor = System.Drawing.Color.White; chartArea1.BackGradientStyle = System.Windows.Forms.DataVisualization.Charting.GradientStyle.TopBottom; chartArea1.BorderColor = System.Drawing.Color.FromArgb(((System.Byte)(64)), ((System.Byte)(64)), ((System.Byte)(64)), ((System.Byte)(64))); chartArea1.BorderDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid; chartArea1.CursorX.IsUserEnabled = true; chartArea1.CursorX.IsUserSelectionEnabled = true; chartArea1.CursorX.SelectionColor = System.Drawing.SystemColors.Highlight; chartArea1.CursorY.IsUserEnabled = true; chartArea1.CursorY.IsUserSelectionEnabled = true; chartArea1.CursorY.SelectionColor = System.Drawing.SystemColors.Highlight; chartArea1.Position.Auto = true; chartArea1.ShadowColor = System.Drawing.Color.Transparent; #endregion this.chart1.ChartAreas.Add(chartArea1); #endregion #region legend legend1.Name = "legend1"; legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Right; legend1.Alignment = System.Drawing.StringAlignment.Far; legend1.LegendStyle = LegendStyle.Column; legend1.IsDockedInsideChartArea = true; legend1.DockedToChartArea = chartArea1.Name; legend1.IsTextAutoFit = false; legend1.BackColor = System.Drawing.Color.Transparent; legend1.Font = new System.Drawing.Font("Trebuchet MS", 8.25F, System.Drawing.FontStyle.Bold); legend1.Position.Auto = true; chart1.Legends.Add(legend1); #endregion #region series series_datas.Name = "series_datas"; series_datas.BorderColor = System.Drawing.Color.FromArgb(((System.Byte)(180)), ((System.Byte)(26)), ((System.Byte)(59)), ((System.Byte)(105))); series_datas.BorderWidth = 2; series_datas.ChartArea = chartArea1.Name; series_datas.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line; series_datas.Color = System.Drawing.Color.FromArgb(((int)(((byte)(220)))), ((int)(((byte)(65)))), ((int)(((byte)(140)))), ((int)(((byte)(240))))); series_datas.LegendText = "AD数据"; series_datas.IsVisibleInLegend = true; series_datas.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Int32; series_datas.YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Int32; series_datas.ShadowColor = System.Drawing.Color.Black; series_datas.ShadowOffset = 2; series_border.Name = "series_border"; series_border.LegendText = "边界点"; series_border.ChartArea = chartArea1.Name; series_border.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Point; series_border.Color = System.Drawing.Color.Violet; series_border.BorderColor = System.Drawing.Color.DarkViolet; series_border.BorderWidth = 3; series_border.MarkerSize = 6; series_border.MarkerStyle = System.Windows.Forms.DataVisualization.Charting.MarkerStyle.Circle; series_border.MarkerBorderColor = System.Drawing.Color.DarkViolet; series_border.MarkerColor = System.Drawing.Color.Violet; series_border.ShadowColor = System.Drawing.Color.Black; series_border.ShadowOffset = 2; chart1.Series.Add(series_datas); chart1.Series.Add(series_border); #endregion chart1.Name = "chart1"; chart1.Palette = System.Windows.Forms.DataVisualization.Charting.ChartColorPalette.BrightPastel; //chart1.Location = new System.Drawing.Point(0, 0); //chart1.PrePaint += Chart1_PrePaint; } [InjectionMethod] public void Init( IUnityContainer container, IBorderSearchService borderSearchService, IInitParamService initParamService, ITDGageService gageService) { this.container = container; container.BuildUp(mircoGage); viewModel = new PgBorderSearchVm(); viewModel.Init(borderSearchService, initParamService, gageService, chart1); this.DataContext = viewModel; } } public class PgBorderSearchVm : INotifyPropertyChanged { #region 延时推送 MARKNO const int MARKNO_UPDATE_BORDER = 0; const int MARKNO_UPDATE_DATAS = 1; #endregion public event PropertyChangedEventHandler PropertyChanged; #region 参数 /// /// 启动与否 /// public bool Enable { get; set; } /// /// 单一材料 /// public bool IsOneMaterial { get; set; } /// /// 边界拐点检测,找到的边界更加精确 /// public bool IsBreakDetect { get; set; } /// /// 有限范围 /// public Range Valid { get; set; } /// /// 手动设置温修AD值 /// public bool TempADBySet { set; get; } /// /// 温修AD值 /// public int TempAD { get; set; } /// /// AD超过了范围, 就认为开始找到边界 /// public int TempRange { get; set; } /// /// 温修范围是温修的百分比 /// public bool IsTempRangeByPercent { get; set; } /// /// 温修范围百分比 /// public double TempRangePercent { get; set; } /// /// 有滤波器,只有非空的连续N个pos以上,才开始算边界开始 /// public int N { get; set; } /// /// 探头直径,单位脉冲, 膜宽 = 边界范围 - 探头直径 /// public int SensorWidth { get; set; } /// /// 找到边界后,边界 + 探头半径 + N2个脉冲。 这个是数据有效的开始 /// public int N2 { get; set; } /// /// 记录两个边界以后扫描,以它们再外扩N3个脉冲,作为扫描范围 /// public int N3 { get; set; } #endregion #region Command public RelayCommand ApplyCmd { get; private set; } #endregion public Misc.DIRECTION Direction { get; private set; } = DIRECTION.FIX; public IBorderSearchService BorderSearchService { get; private set; } public IInitParamService InitParamService { get; private set; } DynArea dynArea; BorderSearchGetViewReponse getViewReponse; System.Windows.Forms.DataVisualization.Charting.Chart chart1; public PgBorderSearchVm() { ApplyCmd = new RelayCommand(Apply); } public void Init( IBorderSearchService borderSearchService, IInitParamService initParamService, ITDGageService gageService, System.Windows.Forms.DataVisualization.Charting.Chart chart) { BorderSearchService = borderSearchService; InitParamService = initParamService; dynArea = gageService.DynArea; chart1 = chart; Misc.BindingOperations.SetBinding(BorderSearchService, nameof(BorderSearchService.Enable), this, nameof(Enable)); Misc.BindingOperations.SetBinding(BorderSearchService, nameof(BorderSearchService.IsOneMaterial), this, nameof(IsOneMaterial)); Misc.BindingOperations.SetBinding(BorderSearchService, nameof(BorderSearchService.IsBreakDetect), this, nameof(IsBreakDetect)); Misc.BindingOperations.SetBinding(BorderSearchService, nameof(BorderSearchService.Valid), () => { Valid = new Range(BorderSearchService.Valid); }); Misc.BindingOperations.SetBinding(BorderSearchService, nameof(BorderSearchService.TempADBySet), this, nameof(TempADBySet)); Misc.BindingOperations.SetBinding(BorderSearchService, nameof(BorderSearchService.TempAD), this, nameof(TempAD)); Misc.BindingOperations.SetBinding(BorderSearchService, nameof(BorderSearchService.TempRange), this, nameof(TempRange)); Misc.BindingOperations.SetBinding(BorderSearchService, nameof(BorderSearchService.IsTempRangeByPercent), this, nameof(IsTempRangeByPercent)); Misc.BindingOperations.SetBinding(BorderSearchService, nameof(BorderSearchService.TempRangePercent), this, nameof(TempRangePercent)); Misc.BindingOperations.SetBinding(BorderSearchService, nameof(BorderSearchService.N), this, nameof(N)); Misc.BindingOperations.SetBinding(BorderSearchService, nameof(BorderSearchService.SensorWidth), this, nameof(SensorWidth)); Misc.BindingOperations.SetBinding(BorderSearchService, nameof(BorderSearchService.N2), this, nameof(N2)); Misc.BindingOperations.SetBinding(BorderSearchService, nameof(BorderSearchService.N3), this, nameof(N3)); BorderSearchService.PropertyChanged += MBorderSearchService_PropertyChanged; InitParamService.PropertyChanged += MInitParamService_PropertyChanged; UpdateX(); chart1.PrePaint += Chart1_PrePaint; getView(); } private void MInitParamService_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { if (e.PropertyName == nameof(InitParamService.PosLength)) { UpdateX(); } } private void MBorderSearchService_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { if (e.PropertyName == nameof(BorderSearch.UpdateTime)) { getView(); } else if ((e.PropertyName == nameof(BorderSearch.TempAD)) || (e.PropertyName == nameof(BorderSearch.TempRange))) { chart1.Invalidate(); } } void getView() { BorderSearchService.GetView((asyncContext, retData) => { this.getViewReponse = retData as BorderSearchGetViewReponse; UpdateDatas(); UpdateBorder(); UpdateSensorWidth(); }, this); } private void Chart1_PrePaint(object sender, ChartPaintEventArgs e) { if (e.ChartElement is ChartArea) { ChartArea area = (ChartArea)e.ChartElement; if (Double.IsNaN(area.AxisY.Minimum)) return; //阀值线 System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.Red, 2); int threshold = BorderSearchService.TempAD - BorderSearchService.TempRange; DrawYGridTick(e.ChartGraphics, pen, threshold); threshold = BorderSearchService.TempAD + BorderSearchService.TempRange; DrawYGridTick(e.ChartGraphics, pen, threshold); } } private void Apply() { if (!WdPassword.Authorize("BorderSearch")) return; BorderSearchService.Enable = Enable; BorderSearchService.IsOneMaterial = IsOneMaterial; BorderSearchService.IsBreakDetect = IsBreakDetect; BorderSearchService.Valid = Valid.ToStruct(); BorderSearchService.TempADBySet = TempADBySet; BorderSearchService.TempAD = TempAD; BorderSearchService.TempRange = TempRange; BorderSearchService.IsTempRangeByPercent = IsTempRangeByPercent; BorderSearchService.TempRangePercent = TempRangePercent; BorderSearchService.N = N; BorderSearchService.SensorWidth = SensorWidth; BorderSearchService.N2 = N2; BorderSearchService.N3 = N3; BorderSearchService.Apply(); FLY.ControlLibrary.Window_Tip.Show("应用成功", null, TimeSpan.FromSeconds(2)); } void DrawYGridTick(ChartGraphics cg, System.Drawing.Pen pen, double y) { ChartArea area = chart1.ChartAreas[0]; if (y > area.AxisY.Maximum || y < area.AxisY.Minimum) return; // Take Graphics object from chart Graphics graph = cg.Graphics; // Convert X and Y values to screen position double py = cg.GetPositionFromAxis(area.Name, AxisName.Y, y); double XMin = cg.GetPositionFromAxis(area.Name, AxisName.X, area.AxisX.Minimum); double XMax = cg.GetPositionFromAxis(area.Name, AxisName.X, area.AxisX.Maximum); System.Drawing.PointF[] points = new System.Drawing.PointF[2]; points[0].X = (float)XMin; points[1].X = (float)XMax; points[0].Y = points[1].Y = (float)py; // Convert relative coordinates to absolute coordinates. points[0] = cg.GetAbsolutePoint(points[0]); points[1] = cg.GetAbsolutePoint(points[1]); graph.DrawLine(pen, points[0], points[1]); } void UpdateY() { if (getViewReponse == null) return; int[] grid = getViewReponse.dat; if (grid == null) return; int max = Misc.MyMath.Max(grid); int min = Misc.MyMath.Min(grid); if (Misc.MyBase.ISVALIDATA(max)) { if (max != min) { chart1.ChartAreas[0].AxisY.Maximum = max + (max - min) * 0.1; chart1.ChartAreas[0].AxisY.Minimum = min - (max - min) * 0.1; if (chart1.ChartAreas[0].AxisY.Minimum < 0) chart1.ChartAreas[0].AxisY.Minimum = 0; } else { chart1.ChartAreas[0].AxisY.Minimum = 0; chart1.ChartAreas[0].AxisY.Maximum = dynArea.ADMax; } } else { chart1.ChartAreas[0].AxisY.Minimum = 0; chart1.ChartAreas[0].AxisY.Maximum = dynArea.ADMax; } if (chart1.ChartAreas[0].AxisY.Minimum == chart1.ChartAreas[0].AxisY.Maximum) { chart1.ChartAreas[0].AxisY.Minimum -= 1000; chart1.ChartAreas[0].AxisY.Maximum += 1000; } } void UpdateX() { chart1.ChartAreas[0].AxisX.Minimum = 0; chart1.ChartAreas[0].AxisX.Maximum = InitParamService.PosLength; } void UpdateDatas() { System.Windows.Forms.DataVisualization.Charting.Series series = chart1.Series["series_datas"]; series.Points.Clear(); if (getViewReponse == null) return; this.Direction = getViewReponse.direction; int[] grid = getViewReponse.dat; if (grid == null) return; int posOfGrid = getViewReponse.posOfGrid; for (int i = 0; i < grid.Length; i++) { series.Points.AddXY((i + getViewReponse.gridBegin) * posOfGrid, grid[i]); if (!Misc.MyBase.ISVALIDATA(grid[i])) { series.Points[i].IsEmpty = true; } } UpdateY(); } #region 更新边界 bool UpdateBorder_pos( System.Windows.Forms.DataVisualization.Charting.Series series, int pos) { if (getViewReponse == null) return false; int[] grid = getViewReponse.dat; if (grid == null) return false; int posOfGrid = getViewReponse.posOfGrid; int grid_idx = pos / posOfGrid - getViewReponse.gridBegin; if (grid_idx < 0) return false; if (grid_idx >= grid.Length) return false; int d = grid[grid_idx]; if (!Misc.MyBase.ISVALIDATA(d)) return false; series.Points.AddXY(pos, d); return true; } void UpdateBorder() { System.Windows.Forms.DataVisualization.Charting.Series series = chart1.Series["series_border"]; series.Points.Clear(); if (getViewReponse == null) return; Misc.Range border = getViewReponse.border; if (border == null) return; if (!border.IsValid) return; if (!UpdateBorder_pos(series, border.Begin)) return; if (!UpdateBorder_pos(series, border.End)) return; } void UpdateSensorWidth() { StripLinesCollection stripLines = chart1.ChartAreas[0].AxisX.StripLines; stripLines.Clear(); if (getViewReponse == null) return; Misc.Range border = getViewReponse.border; if (border == null) return; if (!border.IsValid) return; StripLine stripline = new StripLine(); stripline.BackColor = System.Drawing.Color.FromArgb(64, System.Drawing.Color.Green); stripline.Interval = 0; stripline.IntervalOffset = border.Begin - BorderSearchService.SensorWidth / 2; stripline.StripWidth = BorderSearchService.SensorWidth; stripLines.Add(stripline); stripline = new StripLine(); stripline.BackColor = System.Drawing.Color.FromArgb(64, System.Drawing.Color.Green); stripline.Interval = 0; stripline.IntervalOffset = border.End - BorderSearchService.SensorWidth / 2; stripline.StripWidth = BorderSearchService.SensorWidth; stripLines.Add(stripline); } #endregion } }