using FLY.Thick.Blowing.IService; using GalaSoft.MvvmLight.Command; using LiveCharts; using LiveCharts.Configurations; using LiveCharts.Wpf; using Microsoft.Win32; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FLY.Thick.Blowing.UI.Fix.Client { public class PgBlowingExtVm : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; #region 曲线 /// /// 画在图上的 限位信号 /// [PropertyChanged.DoNotCheckEquality] public List LimitValues { get; private set; } /// /// 画在图上的 速度曲线,限制最多100个数据 /// public ChartValues VelocityValues { get; } = new ChartValues(); /// /// 画在图上的 厚度曲线,限制最多100个数据 /// public ChartValues ThicknessValues { get; } = new ChartValues(); /// /// 画在图上的 膜距离增量曲线,限制最多100个数据 /// public ChartValues FilmLength3DValues { get; } = new ChartValues(); /// /// 画在图上的 当前应用的膜距离增量曲线,不用限制,本来就只有100个 /// public ChartValues CurrFilmLength3D { get; } = new ChartValues(); /// /// 画在图上的 计算出来的膜距离增量曲线,不用限制,本来就只有100个 /// public ChartValues NewFilmLength3D { get; } = new ChartValues(); /// /// 转换为分区号单位的 每幅图 /// public SeriesCollection FrameSeries { get; } = new SeriesCollection(); #endregion #region 参数 /// /// 需要 膜距离增量曲线 /// public bool Is3D { get; set; } /// /// 膜距离 /// public double FilmLength { get; set; } /// /// 获取数据分钟数 min /// public int GetDataMinute { get; set; } /// /// 膜距离查找范围 m /// public int FLRange { get; set; } = 5; /// /// 速度滤波 s /// public int VelocityFilter { get; set; } /// /// 牵引1速度 /// public double Velocity1 { get; set; } #endregion #region 状态 public double VAvg { get; private set; } public double VMax { get; private set; } public double VMin { get; private set; } public double FAvg { get; private set; } public double FMax { get; private set; } public double FMin { get; private set; } #endregion #region 界面 /// /// y轴格式 /// public Func YFormatter { get; set; } /// /// X轴格式 /// public Func DateTimeFormatter { get; set; } /// /// 分区号X轴格式 /// public Func BoltNoFormatter { get; set; } public CartesianMapper MapperTv { get; set; } #endregion #region Command public RelayCommand GetDataCmd { get; private set; } public RelayCommand UpdateVCmd { get; private set; } public RelayCommand UpdateFilmLength3DCmd { get; private set; } public RelayCommand ApplyFilmLength3DCmd { get; private set; } public RelayCommand UpdateFramesCmd { get; private set; } public RelayCommand CalCmd { get; private set; } public RelayCommand ApplyFilmLengthCmd { get; private set; } public RelayCommand SaveCmd { get; private set; } public RelayCommand LoadCmd { get; private set; } #endregion public CalFilmLen Cfl { get; private set; } IBlowingFixService blowing; IBlowingDetectService rdetect; public PgBlowingExtVm() { InitCmd(); } public void Init(IBlowingFixService blowing, IBlowingDetectService rdetect) { this.rdetect = rdetect; this.blowing = blowing; Cfl = new CalFilmLen(); Cfl.Init(blowing, rdetect); Misc.BindingOperations.SetBinding(rdetect, "Is3D", this, "Is3D"); Misc.BindingOperations.SetBinding(Cfl, "FilmLength", this, "FilmLength"); Misc.BindingOperations.SetBinding(Cfl, "VelocityFilter", this, "VelocityFilter"); Misc.BindingOperations.SetBinding(Cfl, "Velocity1", this, "Velocity1"); Misc.BindingOperations.SetBinding(Cfl, new string[] { "DataMaxMinute", "DataMinMinute", "DataBestMinute" }, () => { if (GetDataMinute < Cfl.DataMinMinute) GetDataMinute = Cfl.DataBestMinute; else if (GetDataMinute > Cfl.DataMaxMinute) GetDataMinute = Cfl.DataBestMinute; }); Init1(); Cfl.PropertyChanged += CalFilmLen_PropertyChanged; } public void InitCmd() { GetDataCmd = new RelayCommand(GetData); UpdateVCmd = new RelayCommand(UpdateVelocity); UpdateFilmLength3DCmd = new RelayCommand(UpdateFilmLength3D); ApplyFilmLength3DCmd = new RelayCommand(ApplyFilmLength3D); UpdateFramesCmd = new RelayCommand(UpdateFrames); CalCmd = new RelayCommand(Cal); ApplyFilmLengthCmd = new RelayCommand(ApplyFilmLength); SaveCmd = new RelayCommand(Save); LoadCmd = new RelayCommand(Load); } private void CalFilmLen_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == "LimitValues") { LimitValues = Cfl.LimitValues; } else if (e.PropertyName == "VelocityValues") { VelocityValues.Clear(); var vList = Cfl.VelocityValues; for (int i = 0; i < 100; i++) { int idx = vList.Count() * i / 100; if (idx >= vList.Count()) idx = vList.Count() - 1; VelocityValues.Add(vList[idx]); } VAvg = vList.Average(tv => tv.Value); VMax = vList.Max(tv => tv.Value); VMin = vList.Min(tv => tv.Value); } else if (e.PropertyName == "ThicknessValues") { ThicknessValues.Clear(); var tList = Cfl.ThicknessValues; for (int i = 0; i < 100; i++) { int idx = tList.Count() * i / 100; if (idx >= tList.Count()) idx = tList.Count() - 1; ThicknessValues.Add(tList[idx]); } } else if (e.PropertyName == "FilmLength3DValues") { FilmLength3DValues.Clear(); var tList = Cfl.FilmLength3DValues; for (int i = 0; i < 100; i++) { int idx = tList.Count() * i / 100; if (idx >= tList.Count()) idx = tList.Count() - 1; FilmLength3DValues.Add(tList[idx]); } FAvg = tList.Average(tv => tv.Value); FMax = tList.Max(tv => tv.Value); FMin = tList.Min(tv => tv.Value); } else if (e.PropertyName == "CurrFilmLength3D") { CurrFilmLength3D.Clear(); foreach (var d in Cfl.CurrFilmLength3D) CurrFilmLength3D.Add(d); } else if (e.PropertyName == "NewFilmLength3D") { NewFilmLength3D.Clear(); foreach (var d in Cfl.NewFilmLength3D) NewFilmLength3D.Add(d); } else if (e.PropertyName == "Frames") { FrameSeries.Clear(); for (int i = 0; i < Cfl.Frames.Count(); i++) { var frame = Cfl.Frames[i]; string title = $"{((frame.Direction == Misc.DIRECTION.FORWARD) ? "正" : "反")}" + $" [{frame.RotationCnt}]"; if (frame.IsVaild) title += $" R={frame.R:F3}"; FrameSeries.Add( new LineSeries() { Title = title, Values = new ChartValues(frame.Thicks), LineSmoothness = 1, StrokeThickness = 3, PointGeometrySize = 0 }); } } } void Init1() { #region 界面配置 MapperTv = Mappers.Xy() .X(value => value.Time.Ticks) .Y(value => value.Value); DateTimeFormatter = value => new DateTime((long)value).ToString("HH:mm:ss"); BoltNoFormatter = value => (value + 1).ToString(); YFormatter = value => value.ToString("F1"); #endregion } public void GetData() { Cfl.DownloadData(GetDataMinute); } public void UpdateVelocity() { Cfl.UpdateVelocityValues(VelocityFilter); } public void UpdateFilmLength3D() { Cfl.UpdateFilmLength3D(Velocity1); } public void ApplyFilmLength3D() { Cfl.SetFilmLength3D(); } public void UpdateFrames() { Cfl.SetFilmLength(FilmLength); } public void Cal() { Cfl.Cal(FilmLength - FLRange, FilmLength + FLRange); } public void ApplyFilmLength() { rdetect.FilmLength = FilmLength; rdetect.Apply(); FLY.ControlLibrary.Window_Tip.Show( "应用成功", $"膜距离 设置为{FilmLength:F1}m", TimeSpan.FromSeconds(2)); } public void Save() { SaveFileDialog sfd = new SaveFileDialog(); sfd.FileName = $"{DateTime.Now:yyyyMMdd_HHmmss}.json"; if (sfd.ShowDialog() == true) { Cfl.Save(sfd.FileName); FLY.ControlLibrary.Window_Tip.Show( "保存成功", $"保存到{sfd.FileName}", TimeSpan.FromSeconds(2)); } } public void Load() { OpenFileDialog ofd = new OpenFileDialog(); ofd.DefaultExt = ".json"; if (ofd.ShowDialog() == true) { Cfl.Load(ofd.FileName); FLY.ControlLibrary.Window_Tip.Show( "加载成功", $"读取 {ofd.FileName}", TimeSpan.FromSeconds(2)); } //calFilmLen.Test(); } } public class TimeValue : INotifyPropertyChanged { public DateTime Time { get; set; } public double Value { get; set; } public event PropertyChangedEventHandler PropertyChanged; } }