RandomMainPageViewModel.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. using Avalonia;
  2. using Avalonia.Collections;
  3. using Avalonia.Controls;
  4. using Avalonia.Controls.ApplicationLifetimes;
  5. using OxyPlot;
  6. using OxyPlot.Series;
  7. using ParquetSharp;
  8. using Shaker.Models;
  9. using ShakerApp.Tools;
  10. using ShakerApp.Views;
  11. using System;
  12. using System.Collections;
  13. using System.Collections.Generic;
  14. using System.Linq;
  15. using System.Text;
  16. using System.Threading.Tasks;
  17. namespace ShakerApp.ViewModels
  18. {
  19. internal class RandomMainPageViewModel:BaseMainPageViewModel<RandomDataModel>
  20. {
  21. [PropertyAssociation(nameof(RandomDataModel.CurrentIdentifyDisplacement))]
  22. public double CurrentIdentifyDisplacement => Model.CurrentIdentifyDisplacement;
  23. [PropertyAssociation(nameof(RandomDataModel.CurrentIdentifyRms))]
  24. public double CurrentIdentifyRms => Model.CurrentIdentifyRms;
  25. [PropertyAssociation(nameof(RandomDataModel.IdentifyIndex))]
  26. public double IdentifyIndex => Model.IdentifyIndex;
  27. [PropertyAssociation(nameof(RandomDataModel.RandomStatus))]
  28. public RandomStatus RandomStatus => Model.RandomStatus;
  29. [PropertyAssociation(nameof(RandomDataModel.TimeDomainRMS))]
  30. public double TimeDomainRMS => Model.TimeDomainRMS;
  31. [PropertyAssociation(nameof(RandomDataModel.RandomTestStep))]
  32. public RandomTestStep RandomTestStep => Model.RandomTestStep;
  33. [PropertyAssociation(nameof(RandomDataModel.RandomTestStep))]
  34. public string RandomTestStepKey => RandomTestStep.Description();
  35. [PropertyAssociation(nameof(RandomDataModel.CurrentTestLevel))]
  36. public double CurrentTestLevel => Model.CurrentTestLevel;
  37. [PropertyAssociation(nameof(RandomDataModel.CurrentTestTime))]
  38. public uint CurrentTestTime => Model.CurrentTestTime;
  39. [PropertyAssociation(nameof(RandomDataModel.CurrentLevelTestMaxTime))]
  40. public uint CurrentLevelTestMaxTime => Model.CurrentLevelTestMaxTime;
  41. public AvaloniaList<LineSeries> LineSeries { get; } = new AvaloniaList<LineSeries>();
  42. List<OxyColor> oxyColors = new List<OxyColor>() {OxyColors.Blue, OxyColors.Black, OxyColors.Green, OxyColors.Red, OxyColors.Red, OxyColors.Yellow, OxyColors.Yellow };
  43. List<LineStyle> lineStyles = new List<LineStyle>() { LineStyle.Solid, LineStyle.Solid, LineStyle.Solid, LineStyle.Solid, LineStyle.Solid, LineStyle.LongDashDotDot, LineStyle.LongDashDotDot };
  44. List<string> properties = new List<string>() {nameof(RandomData.Driver), nameof(RandomData.Acceleration), nameof(RandomData.TargetAcceleration), nameof(RandomData.UpStopAcceleration), nameof(RandomData.DownStopAcceleration), nameof(RandomData.UpWarnAcceleration), nameof(RandomData.DownWarnAcceleration) };
  45. List<RandomData> datas = new List<RandomData>();
  46. private RandomMainPageViewModel()
  47. {
  48. Content = typeof(Views.RandomMainPage);
  49. #region 加速度谱曲线
  50. PlotModel.Axes.Add(new OxyPlot.Axes.LogarithmicAxis()
  51. {
  52. MaximumPadding = 0,
  53. MinimumPadding = 0,
  54. Title = App.Current?.FindResource(ShakerConstant.FrequencyKey) + "",
  55. Unit = "Hz",
  56. MajorGridlineStyle = LineStyle.Solid,
  57. Position = OxyPlot.Axes.AxisPosition.Bottom,
  58. Key = "Freq"
  59. });
  60. PlotModel.Axes.Add(new OxyPlot.Axes.LogarithmicAxis()
  61. {
  62. Key = "Ampt",
  63. Title = App.Current?.FindResource(ShakerConstant.AmptAxisTitleKey) + "",
  64. Unit = App.Current?.FindResource("RandomValueUnit")?.ToString() ?? string.Empty,
  65. MajorGridlineStyle = LineStyle.Solid,
  66. Position = OxyPlot.Axes.AxisPosition.Left,
  67. });
  68. PlotModel.Title = App.Current?.FindResource(MainPageType.RandomPage.Description()) + "";
  69. for (int i = 0; i < oxyColors.Count; i++)
  70. {
  71. LineSeries line = new LineSeries();
  72. line.Title = App.Current?.FindResource(ShakerConstant.ShowRandomAccelerationSpectrumNames[i]) + "";
  73. line.Color = oxyColors[i];
  74. line.StrokeThickness = 1;
  75. line.DataFieldX = nameof(SweepData.Frequency);
  76. line.DataFieldY = properties[i];
  77. line.LineStyle = lineStyles[i];
  78. line.XAxisKey = "Freq";
  79. line.YAxisKey = "Ampt";
  80. LineSeries.Add(line);
  81. PlotModel.Series.Add(line);
  82. }
  83. PlotModel.Legends.Add(new OxyPlot.Legends.Legend()
  84. {
  85. ShowInvisibleSeries = true,
  86. });
  87. PlotModel.Title = App.Current?.FindResource(MainPageType.RandomPage.Description()) + "";
  88. #endregion
  89. GetEvent(ShakerSettingViewModel.LANGUAGECHANGEDEVENT).Subscrip((_, _) =>
  90. {
  91. PlotModel.InvalidatePlot(false);
  92. PlotModel.Title = App.Current?.FindResource(MainPageType.RandomPage.Description()) + "";
  93. PlotModel.Axes[0].Title = App.Current?.FindResource("Frequency") + "";
  94. PlotModel.Axes[1].Title = Title = App.Current?.FindResource("Ampt") + "";
  95. PlotModel.InvalidatePlot(true);
  96. });
  97. GetEvent<AllConfig>().Subscrip((_, _) =>
  98. {
  99. CommunicationViewModel.Instance.LocalCommunication?.GetEvent<RandomDataModel>()?.Subscrip((_, args) =>
  100. {
  101. UpdateData(new List<IResultDataModel>() { args.Data });
  102. CommunicationViewModel.Instance.ServiceCommunication?.GetEvent<RandomDataModel>()?.Publish(this, args.Data);
  103. });
  104. CommunicationViewModel.Instance.LocalCommunication?.GetEvent(nameof(RandomDataModel.TransferFunction))?.Subscrip((sender, args) =>
  105. {
  106. if (args.Data.Length > 0 && args.Data[0] is double[] func)
  107. {
  108. Tools.DispatherInovke.Inovke(()=> ShowTransferFunction(func));
  109. CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(nameof(RandomDataModel.TransferFunction))?.Publish(this, null, func);
  110. }
  111. });
  112. });
  113. }
  114. private async void ShowTransferFunction(double[] data)
  115. {
  116. if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
  117. {
  118. RandomTransferFunctionViewModel.Instance.InitData();
  119. RandomTransferFunctionViewModel.Instance.InitTransferFunctionData(data);
  120. RandomTransferFunctionViewModel.Instance.Title = "TransferFunction";
  121. BaseDialogWindow window = new BaseDialogWindow();
  122. window.DataContext = RandomTransferFunctionViewModel.Instance;
  123. bool isclose = false;
  124. RandomTransferFunctionViewModel.Instance.CloseWindowAction = () =>
  125. {
  126. if (isclose) return;
  127. isclose = true;
  128. window?.Close();
  129. };
  130. await window.ShowDialog(desktop.MainWindow!);
  131. }
  132. }
  133. static RandomMainPageViewModel()
  134. {
  135. }
  136. public override void SaveTdmsConfig(Dictionary<string, string> config)
  137. {
  138. base.SaveTdmsConfig(config);
  139. typeof(RandomConfigViewModel).GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)
  140. .Select(x => (x, x.GetValue(RandomConfigViewModel.Instance.Model)))
  141. .ToList()
  142. .ForEach(x =>
  143. {
  144. if (x.Item2 == null)
  145. {
  146. return;
  147. }
  148. if (x.x.FieldType.IsAssignableTo(typeof(IList)) || x.x.FieldType.IsArray)
  149. {
  150. config[$"{nameof(RandomConfigViewModel)}_{x.x.Name}"] = string.Join("", x.Item2.GetBytes().Select(x => $"{x:X2}"));
  151. }
  152. else
  153. {
  154. config[$"{nameof(RandomConfigViewModel)}_{x.x.Name}"] = x.Item2?.ToString() ?? string.Empty;
  155. }
  156. });
  157. }
  158. public override void UpdataColnumInfo()
  159. {
  160. /*
  161. * 保存时域信号和各加速度通道psd数据、加速度合成PSD数据和驱动PSD数据
  162. */
  163. columns = new Column[ShakerConfigViewModel.Instance.ChannelCount + ShakerConfigViewModel.Instance.AccelerationSensorCount + 2];
  164. for(int i=0;i<columns.Length;i++)
  165. {
  166. if(i<ShakerConfigViewModel.Instance.ChannelCount)
  167. {
  168. columns[i] = new Column<double>($"{ShakerConfigViewModel.Instance.Model.AnalogSignalConfigs[i].Name}_{ShakerConfigViewModel.Instance.Model.AnalogSignalConfigs[i].Unit}_{ShakerConfigViewModel.Instance.Model.AnalogSignalConfigs[i].AnalogType}_{Models.DataAxisType.Linear}");
  169. }
  170. else
  171. {
  172. columns[i] = new Column<double>($"{ShakerConfigViewModel.Instance.Model.AnalogSignalConfigs[i].Name}_{App.Current?.FindResource("RandomValueUnit")}_{""}_{Models.DataAxisType.Logarithm}");
  173. }
  174. }
  175. }
  176. public override void SaveTestData(ParquetFileWriter file)
  177. {
  178. base.SaveTestData(file);
  179. if (lastdata == null) return;
  180. var writer = file.AppendBufferedRowGroup();
  181. for(int i=0;i<ShakerConfigViewModel.Instance.AccelerationSensorCount;i++)
  182. {
  183. writer.Column(ShakerConfigViewModel.Instance.AnalogSignals.Count + i).LogicalWriter<double>().WriteBatch(lastdata.CurrentAccelerationPSD[i]);
  184. }
  185. writer.Column(ShakerConfigViewModel.Instance.AccelerationSensorCount + ShakerConfigViewModel.Instance.AnalogSignals.Count).LogicalWriter<double>().WriteBatch(lastdata.CurrentAccelerationSynthesisPSD);
  186. writer.Column(ShakerConfigViewModel.Instance.AccelerationSensorCount + ShakerConfigViewModel.Instance.Accelerations.Count + 1).LogicalWriter<double>().WriteBatch(lastdata.DriverPSD);
  187. }
  188. public override void Start()
  189. {
  190. SetRefSpectrum(RandomConfigViewModel.Instance.RefSpectrum);
  191. }
  192. public override void Stop()
  193. {
  194. }
  195. private RandomDataModel lastdata;
  196. public override void UpDateModel(RandomDataModel model)
  197. {
  198. lastdata = model;
  199. base.UpDateModel(model);
  200. int startindex = (int)(RandomConfigViewModel.Instance.MinFrequency / RandomConfigViewModel.Instance.FrequencyResolution);
  201. for(int i=0;i<datas.Count;i++)
  202. {
  203. datas[i].SetAcceleration(model.CurrentAccelerationSynthesisPSD[i + startindex]);
  204. datas[i].SetDriver(model.DriverPSD[i + startindex]);
  205. }
  206. PlotModel.InvalidatePlot(false);
  207. for(int i=0;i<LineSeries.Count;i++)
  208. {
  209. LineSeries[i].ItemsSource = datas;
  210. }
  211. PlotModel.InvalidatePlot(true);
  212. }
  213. public override void UpdateData(List<IResultDataModel> model)
  214. {
  215. if(model !=null &&model.Count >0 && model.First() is RandomDataModel randomdata)
  216. {
  217. UpDateModel(randomdata);
  218. }
  219. }
  220. public void SetRefSpectrum(List<RandomData> data)
  221. {
  222. datas.Clear();
  223. datas.AddRange(data);
  224. PlotModel.InvalidatePlot(false);
  225. for (int i = 0; i < LineSeries.Count; i++)
  226. {
  227. LineSeries[i].ItemsSource = datas;
  228. }
  229. PlotModel.InvalidatePlot(true);
  230. }
  231. public override MainPageType PageType => MainPageType.RandomPage;
  232. public OxyPlot.PlotModel PlotModel { get; private set; } = new OxyPlot.PlotModel();
  233. public static RandomMainPageViewModel Instance { get; } = new RandomMainPageViewModel();
  234. }
  235. }