using CommunityToolkit.Mvvm.Input; using FLY.Thick.Base.IService; using LiveCharts; using LiveCharts.Configurations; using Microsoft.Win32; using Misc; using OfficeOpenXml; using OfficeOpenXml.Table; using System; using System.ComponentModel; using System.Data; using System.IO; using System.Linq; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using Unity; namespace FLY.Thick.Base.UI { /// /// Page_Reject.xaml 的交互逻辑 /// public partial class PgReject : Page { IRejectService rejectService; IInitParamService initParamService; PgRejectVm viewModel; public PgReject() { InitializeComponent(); } [InjectionMethod] public void Init( IUnityContainer container, IRejectService rejectService, IInitParamService initParamService) { container.BuildUp(mircoGage); viewModel = new PgRejectVm(); viewModel.Init(rejectService, initParamService); this.DataContext = this.viewModel; } } public class PgRejectVm : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; #region 曲线 public Func YFormatter { get; private set; } [PropertyChanged.DependsOn(nameof(PosOfGrid), nameof(Mmpp))] public Func XFormatter { get; private set; } public CartesianMapper Mapper { get; set; } /// /// X轴最小范围 /// public double XMin => 0; /// /// X轴最大范围 /// public double XMax => PosLength / PosOfGrid; public ChartValues FilterDatas { get; } = new ChartValues(); public ChartValues RejectDatas { get; } = new ChartValues(); #endregion #region 状态 public double Threshold { get; set; } = double.NaN; public double UpperLimit { get; set; } = double.NaN; public double LowerLimit { get; set; } = double.NaN; #endregion /// /// 使能 /// public bool Enable { get; set; } /// /// 剔除阈值,低于 ThresholdRatio*Target 都要被删除 /// public double ThresholdRatio { get; set; } /// /// 规格范围,Math.Abs(value-Target) > UpperLimitRatio*Target 都要被删除 /// public double LimitRangeRatio { get; set; } /// /// 滤波范围,单位脉冲 /// public int SmoothRange { get; set; } /// /// 当前数据需要剔除,那么它的前后Range2个脉冲的数据都是删除,单位脉冲 /// public int RejectRange { get; set; } /// /// 机架总长,脉冲 /// public int PosLength { get; set; } = 8000; /// /// 1个grid = N个pos /// public int PosOfGrid { get; set; } = 10; /// /// 比例 /// public double Mmpp { get; set; } = 0.1; public DateTime DebugUpdateTime { get; set; } public RelayCommand ApplyCmd { get; } public RelayCommand SaveCmd { get; } IRejectService rejectService; public IInitParamService InitParamService { get; private set; } Page page; public PgRejectVm() { Mapper = Mappers.Xy() .X((value, index) => value.X) .Y(value => value.Y); XFormatter = (x) => { //x 是 grid int pos = (int)(x * PosOfGrid); int mm = (int)(pos * Mmpp); return $"{pos}\n{mm}mm"; }; YFormatter = (y) => { return $"{y:F1}"; }; ApplyCmd = new RelayCommand(Apply); SaveCmd = new RelayCommand(SaveXlsx); } public void Init( IRejectService rejectService, IInitParamService initParamService) { this.rejectService = rejectService; this.InitParamService = initParamService; Misc.BindingOperations.SetBinding(rejectService, nameof(rejectService.Enable), this, nameof(Enable)); Misc.BindingOperations.SetBinding(rejectService, nameof(rejectService.ThresholdRatio), this, nameof(ThresholdRatio)); Misc.BindingOperations.SetBinding(rejectService, nameof(rejectService.LimitRangeRatio), this, nameof(LimitRangeRatio)); Misc.BindingOperations.SetBinding(rejectService, nameof(rejectService.LimitRangeRatio), this, nameof(LimitRangeRatio)); Misc.BindingOperations.SetBinding(rejectService, nameof(rejectService.SmoothRange), this, nameof(SmoothRange)); Misc.BindingOperations.SetBinding(rejectService, nameof(rejectService.RejectRange), this, nameof(RejectRange)); Misc.BindingOperations.SetBinding(rejectService, nameof(rejectService.DebugUpdateTime), this, nameof(DebugUpdateTime)); Misc.BindingOperations.SetBinding(initParamService, nameof(initParamService.Encoder1_mmpp), this, nameof(Mmpp)); Misc.BindingOperations.SetBinding(initParamService, nameof(initParamService.PosLength), this, nameof(PosLength)); Misc.BindingOperations.SetBinding(initParamService, nameof(initParamService.PosOfGrid), this, nameof(PosOfGrid)); this.rejectService.PropertyChanged += new PropertyChangedEventHandler(mRejectService_PropertyChanged); Download(); } private async void SaveXlsx() { //下载数据 string strDesktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); string filename = $"剔除_{DateTime.Now:yyyyMMddHHmmss}.xlsx"; SaveFileDialog sfd = new SaveFileDialog(); sfd.Filter = "xlsx files (*.xlsx)|*.xlsx"; sfd.InitialDirectory = strDesktopPath; sfd.FileName = filename; if (sfd.ShowDialog() == true) { filename = sfd.FileName; await Task.Factory.StartNew(() => { SaveToXlsx(filename); }); string tit = (string)Application.Current.TryFindResource("str.PgReject.OperateSuccessfully"); FLY.ControlLibrary.Window_Tip.Show(tit, filename, TimeSpan.FromSeconds(2)); } } private void SaveToXlsx(string filepath) { if (FilterDatas.Count() == 0) { return; } if (File.Exists(filepath)) { File.Delete(filepath); } using (ExcelPackage p = new ExcelPackage(new FileInfo(filepath))) { ExcelWorksheet sheet = p.Workbook.Worksheets.Add("剔除"); DataTable dataTable = new DataTable("table_reject"); dataTable.Columns.Add(new DataColumn() { ColumnName = "序号", DataType = typeof(double), Caption = "0" }); dataTable.Columns.Add(new DataColumn() { ColumnName = "脉冲", DataType = typeof(double), Caption = "0" }); dataTable.Columns.Add(new DataColumn() { ColumnName = "mm", DataType = typeof(double), Caption = "0.0" }); dataTable.Columns.Add(new DataColumn() { ColumnName = "滤波", DataType = typeof(double), Caption = "0.00" }); dataTable.Columns.Add(new DataColumn() { ColumnName = "剔除后", DataType = typeof(double), Caption = "0.00" }); XY data = FilterDatas.First(); int start_grid = (int)data.X; for (int i = 0; i < start_grid; i++) { try { var dataRow = dataTable.NewRow(); dataRow["序号"] = i; dataRow["脉冲"] = i * PosOfGrid; dataRow["mm"] = i * PosOfGrid * Mmpp; dataTable.Rows.Add(dataRow); } catch { break; } } for (int i = 0; i < FilterDatas.Count() && i < RejectDatas.Count(); i++) { try { var dataRow = dataTable.NewRow(); int index = start_grid + i; dataRow["序号"] = index; dataRow["脉冲"] = index * PosOfGrid; dataRow["mm"] = index * PosOfGrid * Mmpp; dataRow["滤波"] = FilterDatas[i].Y; dataRow["剔除后"] = RejectDatas[i].Y; dataTable.Rows.Add(dataRow); } catch { break; } } ToSheet(sheet, dataTable); p.Save(); } } void ToSheet(ExcelWorksheet sheet, DataTable dataTable) { int from_row = 1; int row = from_row; //添加标题 for (int i = 0; i < dataTable.Columns.Count; i++) { int col = i + 1; sheet.Cells[row, col].Value = dataTable.Columns[i].ColumnName; //格式 sheet.Column(col).Style.Numberformat.Format = dataTable.Columns[i].Caption; } row++; for (int i = 0; i < dataTable.Rows.Count; i++) { for (int j = 0; j < dataTable.Columns.Count; j++) { int col = j + 1; sheet.Cells[row, col].Value = dataTable.Rows[i][j]; } row++; } int colcnt = dataTable.Columns.Count; int rowcnt = dataTable.Rows.Count; var range = sheet.Cells[from_row, 1, from_row + rowcnt, colcnt]; var tbl = sheet.Tables.Add(range, dataTable.TableName); tbl.TableStyle = TableStyles.Medium9; sheet.Cells[sheet.Dimension.Address].AutoFitColumns(); } private void Apply() { if (!WdPassword.Authorize("Reject")) return; rejectService.Enable = this.Enable; rejectService.ThresholdRatio = this.ThresholdRatio; rejectService.LimitRangeRatio = this.LimitRangeRatio; rejectService.SmoothRange = this.SmoothRange; rejectService.RejectRange = this.RejectRange; rejectService.Apply(); string tit = (string)Application.Current.TryFindResource("str.PgReject.ApplySuccessfully"); FLY.ControlLibrary.Window_Tip.Show(tit,null,TimeSpan.FromSeconds(2)); } void mRejectService_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { if (e.PropertyName == nameof(rejectService.DebugUpdateTime)) { //下载 Download(); } else if (e.PropertyName == nameof(FObjBase.FObjServiceClient.IsConnected)) { var client = rejectService as FObjBase.FObjServiceClient; if (client.IsConnected) { Download(); } } } void Download() { rejectService.GetDebugData((asyncContext, retData) => { var reponse = retData as RejectDebugData; FilterDatas.Clear(); RejectDatas.Clear(); if (reponse == null) { //无数据 Threshold = double.NaN; UpperLimit = double.NaN; LowerLimit = double.NaN; return; } if (reponse.filterDatas != null && reponse.filterDatas.Count() > 0) { FilterDatas.AddRange(reponse.filterDatas.Select((d, i) => new XY() { X = reponse.start_grid + i, Y = d })); } if (reponse.rejectDatas != null && reponse.rejectDatas.Count() > 0) { RejectDatas.AddRange(reponse.rejectDatas.Select((d, i) => new XY() { X = reponse.start_grid + i, Y = d })); } Threshold = reponse.target * rejectService.ThresholdRatio; UpperLimit = reponse.target * (1 + rejectService.LimitRangeRatio); LowerLimit = reponse.target * (1 - rejectService.LimitRangeRatio); }, this); } } }