using GalaSoft.MvvmLight.Command;
using LiveCharts;
using LiveCharts.Configurations;
using LiveCharts.Wpf;
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 PgBlowingExtVmUt : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
#region 曲线
///
/// 画在图上的 限位信号
///
public List LimitValues { get; } = new List();
///
/// 画在图上的 速度曲线,限制最多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; }
///
/// 速度滤波 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; } = value => value.ToString("F1");
///
/// X轴格式
///
public Func DateTimeFormatter { get; set; } = value => new DateTime((long)value).ToString("HH:mm:ss");
public Func BoltNoFormatter { get; set; } = value => (value + 1).ToString();
public CartesianMapper MapperTv { get; set; }
= Mappers.Xy()
.X(value => value.Time.Ticks)
.Y(value => value.Value);
#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 CalFilmLenUt Cfl { get; set; }
public PgBlowingExtVmUt()
{
Init1();
init_virtualdata();
}
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
}
///
/// 产生虚拟数据
///
void init_virtualdata()
{
#region 虚拟数据
int[] thicks = new int[]{
3518 ,
3484 ,
3634 ,
3620 ,
3579 ,
3625 ,
3635 ,
3638 ,
3635 ,
3606 ,
3611 ,
3603 ,
3590 ,
3631 ,
3646 ,
3647 ,
3710 ,
3705 ,
3607 ,
3720 ,
3680 ,
3637 ,
3659 ,
3703 ,
3860 ,
3720 ,
3615 ,
3810 ,
3772 ,
3666 ,
3614 ,
3627 ,
3618 ,
3502 ,
3575 ,
3583 ,
3615 ,
3680 ,
3730 ,
3840 ,
3927 ,
3946 ,
3923 ,
3841 ,
3797 ,
3865 ,
3810 ,
3711 ,
3754 ,
3705 ,
3723 ,
3699 ,
3723 ,
3801 ,
3786 ,
3798 ,
3907 ,
3945 ,
3828 ,
3860 ,
3846 ,
3903 ,
3871 ,
3844 ,
3759 ,
3816 ,
3886 ,
3815 ,
3789 ,
3876 ,
3942 ,
3854 ,
3842 ,
3921 ,
3846 ,
3835 ,
3886 ,
3881 ,
3820 ,
3787 ,
3730 ,
3617 ,
3650 ,
3610 ,
3536 ,
3545 ,
3564 ,
3584 ,
3580 ,
3572 ,
3571 ,
3579 ,
3620 ,
3634 ,
3484 ,
3518 ,
};
//辊周长 m
double RollPerimeter = 0.314;
//线速度 m/min
double FilmVelocity = 20;
//旋转周期
TimeSpan RInterval = TimeSpan.FromMinutes(6.1);
//速度震荡周期 m
double FV_Range = 2;
TimeSpan DataLen = TimeSpan.FromMinutes(30);
DateTime dt_begin = DateTime.Now;
DateTime dt_end = dt_begin + DataLen;
List vList = new List();
List tList = new List();
List lList = new List();
for (TimeSpan ts = TimeSpan.Zero; ts < DataLen; ts += TimeSpan.FromSeconds(1))
{
DateTime dt = dt_begin + ts;
double min = ts.TotalMinutes;
//速度以1/2旋转周期变化
double v = FilmVelocity + Math.Sin(Math.PI * 2 * min / (RInterval.TotalMinutes / 2)) * FV_Range;
vList.Add(new TimeValue() { Time = dt, Value = v });
int n = ((int)(min / RInterval.TotalMinutes)) % 2;
double m = min % RInterval.TotalMinutes;
int idx = (int)(thicks.Count() * m / RInterval.TotalMinutes);
if (idx < 0) idx = 0;
else if (idx > thicks.Count()) idx = thicks.Count() - 1;
double thick;
if (n == 0)
thick = thicks[idx];
else
thick = thicks[thicks.Count() - 1 - idx];
tList.Add(new TimeValue()
{
Time = dt,
Value = thick / 100.0
});
if (lList.Count() == 0)
{
lList.Add(new TimeValue() { Time = dt_begin + RInterval, Value = n });
}
else if (dt >= lList.Last().Time)
{
lList.Add(new TimeValue() { Time = lList.Last().Time + RInterval, Value = n });
}
}
List fList = new List();
double sum = 0;
double avg = vList.Average(tv => tv.Value);
foreach (var tv in vList)
{
sum += (tv.Value - avg) * TimeSpan.FromSeconds(1).TotalMinutes;
fList.Add(new TimeValue() { Time = tv.Time, Value = sum });
}
{
double min = fList.Min(tv => tv.Value);
foreach (var tv in vList)
{
tv.Value -= min;
}
}
List setFilmLength = new List();
foreach (var tv in fList)
{
if (tv.Time >= lList[0].Time && tv.Time <= lList[1].Time)
{
setFilmLength.Add(tv.Value);
}
else if (tv.Time > lList[1].Time)
{
break;
}
}
Random r = new Random();
List currFilmLength = new List();
foreach (var f in setFilmLength)
{
currFilmLength.Add(f + r.NextDouble() - 0.5);
}
List> frames = new List>();
for (int i = 0; i < lList.Count() - 1; i++)
{
List frame = new List();
frame.AddRange(thicks.Select(t => (t + (r.NextDouble() - 0.5) * t * 2 / 100) / 100.0));
frames.Add(frame);
}
#endregion
foreach (var tv in lList)
{
LimitValues.Add(tv);
}
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("LimitValues"));
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]);
}
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]);
}
for (int i = 0; i < 100; i++)
{
int idx = fList.Count() * i / 100;
if (idx >= fList.Count()) idx = fList.Count() - 1;
FilmLength3DValues.Add(fList[idx]);
}
for (int i = 0; i < 100; i++)
{
int idx = currFilmLength.Count() * i / 100;
if (idx >= currFilmLength.Count()) idx = currFilmLength.Count() - 1;
CurrFilmLength3D.Add(currFilmLength[idx]);
}
for (int i = 0; i < 100; i++)
{
int idx = setFilmLength.Count() * i / 100;
if (idx >= setFilmLength.Count()) idx = setFilmLength.Count() - 1;
NewFilmLength3D.Add(setFilmLength[idx]);
}
for (int i = 0; i < frames.Count(); i++)
{
var frame = frames[i];
FrameSeries.Add(
new LineSeries()
{
Title = i.ToString(),
Values = new ChartValues(frame),
LineSmoothness = 1,
StrokeThickness = 3,
PointGeometrySize = 0
});
}
}
}
public class CalFilmLenUt : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
#region 参数
#endregion
#region 状态
///
/// 信息
///
public string Msg { get; set; }
///
/// 下载中
///
public bool IsDownloading { get; set; }
///
/// 数据准备好了
///
public bool IsDataReady { get; set; }
///
/// 计算中
///
public bool IsCaling { get; set; }
///
/// 有足够的数据,可以下载
///
public bool IsCanDownload { get; set; }
///
/// 当前数据总分钟数 min
///
public int DataMaxMinute { get; set; }
///
/// 必须获取的最少数据量 min
///
public int DataMinMinute { get; set; }
///
/// 最佳获取数据量 min
///
public int DataBestMinute { get; set; }
#endregion
}
}