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);
}
}
}