using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Net; using FLY.Thick.Base.Client; using System.Windows.Forms.DataVisualization.Charting; using System.Drawing; using Unity; using FLY.Thick.Base.IService; using System.ComponentModel; using Misc; using GalaSoft.MvvmLight.Command; using FLY.Thick.Base.Server; namespace FLY.Thick.Base.UI { /// <summary> /// Page_BorderSearch.xaml 的交互逻辑 /// </summary> public partial class PgBorderSearch : Page { PgBorderSearchVm viewModel; 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(IBorderSearchService borderSearchService, IInitParamService initParamService,IDynAreaService dynAreaService) { viewModel = new PgBorderSearchVm(); viewModel.Init(borderSearchService, initParamService, dynAreaService, 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 参数 /// <summary> /// 启动与否 /// </summary> public bool Enable { get; set; } /// <summary> /// 边界拐点检测,找到的边界更加精确 /// </summary> public bool IsBreakDetect { get; set; } /// <summary> /// 有限范围 /// </summary> public Range Valid { get; set; } /// <summary> /// 手动设置温修AD值 /// </summary> public bool TempADBySet { set; get; } /// <summary> /// 温修AD值 /// </summary> public int TempAD { get; set; } /// <summary> /// AD超过了范围, 就认为开始找到边界 /// </summary> public int TempRange { get; set; } /// <summary> /// 温修范围是温修的百分比 /// </summary> public bool IsTempRangeByPercent { get; set; } /// <summary> /// 温修范围百分比 /// </summary> public double TempRangePercent { get; set; } /// <summary> /// 有滤波器,只有非空的连续N个pos以上,才开始算边界开始 /// </summary> public int N { get; set; } /// <summary> /// 探头直径,单位脉冲, 膜宽 = 边界范围 - 探头直径 /// </summary> public int SensorWidth { get; set; } /// <summary> /// 找到边界后,边界 + 探头半径 + N2个脉冲。 这个是数据有效的开始 /// </summary> public int N2 { get; set; } /// <summary> /// 记录两个边界以后扫描,以它们再外扩N3个脉冲,作为扫描范围 /// </summary> 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; } IDynAreaService dynAreaService; BorderSearchGetViewReponse getViewReponse; System.Windows.Forms.DataVisualization.Charting.Chart chart1; public PgBorderSearchVm() { ApplyCmd = new RelayCommand(Apply); } public void Init( IBorderSearchService borderSearchService, IInitParamService initParamService, IDynAreaService dynAreaService, System.Windows.Forms.DataVisualization.Charting.Chart chart) { BorderSearchService = borderSearchService; InitParamService = initParamService; this.dynAreaService = dynAreaService; chart1 = chart; Misc.BindingOperations.SetBinding(BorderSearchService, "Enable",this,"Enable"); Misc.BindingOperations.SetBinding(BorderSearchService, "IsBreakDetect",this,"IsBreakDetect"); Misc.BindingOperations.SetBinding(BorderSearchService, "Valid",this,"Valid"); Misc.BindingOperations.SetBinding(BorderSearchService, "TempADBySet",this,"TempADBySet"); Misc.BindingOperations.SetBinding(BorderSearchService, "TempAD",this,"TempAD"); Misc.BindingOperations.SetBinding(BorderSearchService, "TempRange",this,"TempRange"); Misc.BindingOperations.SetBinding(BorderSearchService, "IsTempRangeByPercent",this,"IsTempRangeByPercent"); Misc.BindingOperations.SetBinding(BorderSearchService, "TempRangePercent",this,"TempRangePercent"); Misc.BindingOperations.SetBinding(BorderSearchService, "N",this,"N"); Misc.BindingOperations.SetBinding(BorderSearchService, "SensorWidth",this,"SensorWidth"); Misc.BindingOperations.SetBinding(BorderSearchService, "N2",this,"N2"); Misc.BindingOperations.SetBinding(BorderSearchService, "N3",this,"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 == "PosLength") { UpdateX(); } } private void MBorderSearchService_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { if (e.PropertyName == "UpdateTime") { getView(); } else if ((e.PropertyName == "TempAD") || (e.PropertyName == "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); } } private void Apply() { if (!WdPassword.Authorize("BorderSearch")) return; BorderSearchService.Enable = Enable; BorderSearchService.IsBreakDetect = IsBreakDetect; BorderSearchService.Valid = Valid; 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 = dynAreaService.DynArea.ADMax; } } else { chart1.ChartAreas[0].AxisY.Minimum = 0; chart1.ChartAreas[0].AxisY.Maximum = dynAreaService.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; 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; stripline.StripWidth = BorderSearchService.SensorWidth; stripLines.Add(stripline); } #endregion } }