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