using FLY.Thick.Base.Client;
using FLY.Thick.Base.Common;
using FLY.Thick.Base.IService;
using GalaSoft.MvvmLight.Command;
using LiveCharts;
using LiveCharts.Wpf;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Media;
using Unity;
namespace FLY.Thick.Base.UI
{
class PgGridVm : IPgGridVm
{
public event PropertyChangedEventHandler PropertyChanged;
#region IPgGridVm Property
///
/// 调试速度 单位:脉冲/秒
///
public UInt32 VJog { get; set; }
///
/// 调试速度 单位:m/min
///
public double VJogMm => VJog* Mmpp * Speed1Scale / 1000 * 60;
///
/// 目标位置 单位:脉冲
///
public int TargetPos { get; set; }
///
/// 目标位置 单位:mm
///
public double TargetMm => TargetPos * Mmpp;
///
/// AD值模式
///
public bool IsADMode { get; set; }
///
/// 最多6条曲线
///
public ObservableCollection SeriesInfos { get; } = new ObservableCollection();
#region 曲线
public Func XFormatter { get; private set; }
public Func YFormatter { get; private set; }
public double XUpper { get; set; } = 1024;
public double XLower { get; set; } = 0;
public double YUpper { get; set; } = double.NaN;
public double YLower { get; set; } = double.NaN;
public double XMax { get; private set; } = 1024;
public double XMin { get; private set; } = 0;
public double YMax { get; private set; } = double.NaN;
public double YMin { get; private set; } = double.NaN;
public double SectionValue => MeasureValuePos / PosOfGrid;
public double SectionWidth => MeasureWidthPos / PosOfGrid;
public SeriesCollection Series { get; } = new SeriesCollection();
#endregion
#region 测量
///
/// 测量开始位置 单位:脉冲
///
public int MeasureValuePos { get; set; }
///
/// 测量开始位置 单位:mm
///
public double MeasureValueMm => MeasureValuePos * Mmpp;
///
/// 测量宽度 单位:脉冲
///
public int MeasureWidthPos { get; set; }
///
/// 测量宽度 单位:mm
///
public double MeasureWidthMm => MeasureWidthPos * Mmpp;
#endregion
#endregion
#region IPgGridVm Command
public RelayCommand RunToCmd { get; private set; }
public RelayCommand GetFDataCmd { get; private set; }
public RelayCommand GetBDataCmd { get; private set; }
public RelayCommand ClearCmd { get; private set; }
public RelayCommand MeasureCmd { get; private set; }
public RelayCommand SaveCmd { get; private set; }
public RelayCommand SelectCmd { get; private set; }
#endregion
public int PosOfGrid { get; set; } = 10;
public double Mmpp { get; set; } = 0.1;
public double Speed1Scale { get; set; } = 4;
ITDGageService gageService;
IFlyADService flyAdService;
IInitParamService initParam;
public PgGridVm()
{
#region 与数据无关界面参数
XFormatter = (x) =>
{
int index = (int)x;
int pos = index * PosOfGrid;
int mm = (int)(pos * Mmpp);
return $"{pos}\n{mm}mm";
};
YFormatter = (y) =>
{
if (IsADMode)
{
return $"{y}";
}
else
{
return $"{y:F1}";
}
};
for (int i = 0; i < 6; i++)
{
SeriesInfo info = new SeriesInfo()
{
Title = $"{i}",
Fill = FLY.ControlLibrary.Themes.Styles.GetForeground(i),
};
LineSeries lineSeries = new LineSeries
{
StrokeThickness = 2,
Fill = new SolidColorBrush(System.Windows.Media.Colors.Transparent),
PointGeometry = null
};
lineSeries.SetBinding(LineSeries.StrokeProperty, "Fill");
lineSeries.DataContext = info;
Series.Add(lineSeries);
info.Series = lineSeries;
SeriesInfos.Add(info);
}
SeriesInfos[0].IsSelected = true;
UpdateADMode();
#endregion
InitCmd();
this.PropertyChanged += PgGridVm_PropertyChanged;
}
public void Init(
IInitParamService initParam,
ITDGageService gageService,
IFlyADService flyADService
)
{
this.initParam = initParam;
this.gageService = gageService;
this.flyAdService = flyADService;
Misc.BindingOperations.SetBinding(this.initParam, nameof(initParam.Encoder1_mmpp), this, nameof(Mmpp));
Misc.BindingOperations.SetBinding(this.initParam, nameof(initParam.PosOfGrid), this, nameof(PosOfGrid));
Misc.BindingOperations.SetBinding(this.initParam, nameof(initParam.Speed1Scale), this, nameof(Speed1Scale));
Misc.BindingOperations.SetBinding(this.initParam, nameof(initParam.VJOG), this, nameof(VJog));
}
private void PgGridVm_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(IsADMode))
{
UpdateADMode();
UpdateRange(true);
}
}
void InitCmd()
{
RunToCmd = new RelayCommand(() =>
{
if (VJog != initParam.VJOG) {
initParam.VJOG = VJog;
initParam.Apply();
}
gageService.StartP2(STARTP2_MODE.RUNTO, TargetPos);
});
GetFDataCmd = new RelayCommand(() =>
{
flyAdService.GetGrid(Misc.DIRECTION.FORWARD, GetGridCB, null);
});
GetBDataCmd = new RelayCommand(() =>
{
flyAdService.GetGrid(Misc.DIRECTION.BACKWARD, GetGridCB, null);
});
ClearCmd = new RelayCommand(() => {
var series = SeriesInfos.First(s => s.IsSelected);
series.Clear();
});
MeasureCmd = new RelayCommand(() =>
{
UpdateMeasure();
});
SaveCmd = new RelayCommand(() => {
Save();
});
SelectCmd = new RelayCommand((info) =>
{
if (info.IsSelected)
return;
foreach (var i in SeriesInfos)
i.IsSelected = (i == info);
});
}
void GetGridCB(object asyncState, object retData)
{
GridInfo gridinfo = retData as GridInfo;
var series = SeriesInfos.First(s => s.IsSelected);
series.IsBackw = gridinfo.direction == Misc.DIRECTION.BACKWARD;
series.ADs.Clear();
series.Thicks.Clear();
var ads = gridinfo.data.Select(ad =>
{
if (Misc.MyBase.ISVALIDATA(ad))
{
return ad;
}
else
{
return double.NaN;
}
});
series.ADs.AddRange(ads);
series.Thicks.AddRange(gridinfo.thick);
UpdateRange();
}
void UpdateADMode()
{
if (IsADMode)
{
foreach (var info in SeriesInfos)
info.Series.SetBinding(LineSeries.ValuesProperty, nameof(SeriesInfo.ADs));
}
else
{
foreach (var info in SeriesInfos)
info.Series.SetBinding(LineSeries.ValuesProperty, nameof(SeriesInfo.Thicks));
}
}
void UpdateMeasure()
{
int begin_grid = MeasureValuePos / PosOfGrid;
int end_grid = (MeasureValuePos + MeasureWidthPos) / PosOfGrid;
foreach (var info in SeriesInfos)
{
if (IsADMode)
{
double sum = 0;
int cnt = 0;
for (int i = begin_grid; i <= end_grid && i < info.ADs.Count() && i >= 0; i++)
{
sum += info.ADs[i];
cnt++;
}
if (cnt == 0)
info.Avg = double.NaN;
else
info.Avg = sum / cnt;
}
else
{
double sum = 0;
int cnt = 0;
for (int i = begin_grid; i <= end_grid && i < info.Thicks.Count() && i >= 0; i++)
{
sum += info.Thicks[i];
cnt++;
}
if (cnt == 0)
info.Avg = double.NaN;
else
info.Avg = sum / cnt;
}
}
}
void UpdateRange()
{
UpdateRange(false);
}
void UpdateRange(bool isReset)
{
List vlist = new List();
foreach (var info in SeriesInfos)
{
IEnumerable values = (IsADMode) ? info.ADs : info.Thicks;
if (values.Count()==0)
continue;
var values2 = values.Where(v => !double.IsNaN(v));
if (values2.Count() == 0)
continue;
vlist.AddRange(values2);
}
if (vlist.Count() == 0)
{
//没有任何数据
return;
}
else
{
bool isYMaxAuto = (YMax == YUpper) || double.IsNaN(YUpper);
bool isYMinAuto = (YMin == YLower) || double.IsNaN(YLower);
if (IsADMode)
{
YMax = 65535;
YMin = 0;
}
else
{
double max = vlist.Max();
double min = vlist.Min();
double range = max - min;
if (range < 10)
range = 10;
YMax = Math.Round(max + range / 10);
YMin = Math.Round(min - range / 10);
}
if (isReset)
{
YUpper = YMax;
YLower = YMin;
}
else
{
if (isYMaxAuto)
YUpper = YMax;
if (isYMinAuto)
YLower = YMin;
}
}
}
void Save()
{
string strDesktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
string filename = $"Grid数据_{DateTime.Now:yyyyMMddHHmmss}.xlsx";
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "xlsx files (*.xlsx)|*.xlsx";
sfd.InitialDirectory = strDesktopPath;
sfd.FileName = filename;
if (sfd.ShowDialog() == DialogResult.OK)
{
PgGridOutput ouput = new PgGridOutput();
ouput.Init(this);
ouput.SaveToXlsx(sfd.FileName);
}
////完成
//FLY.ControlLibrary.Window_Tip.Show("成功", "保存到路径 " + filepath, TimeSpan.FromSeconds(2));
//return;
}
}
}