BaseDataReviewItemViewModel.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. using Avalonia.Controls;
  2. using Shaker.Models;
  3. using ShakerApp.Tools;
  4. using System;
  5. using System.Collections;
  6. using System.Collections.Generic;
  7. using System.Data;
  8. using System.Diagnostics;
  9. using System.Diagnostics.CodeAnalysis;
  10. using System.Linq;
  11. using System.Text;
  12. namespace ShakerApp.ViewModels
  13. {
  14. public abstract class BaseDataReviewItemViewModel:DisplayViewModelBase<IModel>,IDataReviewItem
  15. {
  16. public BaseDataReviewItemViewModel()
  17. {
  18. TimeDomainReview = new TimeDomainReviewViewModel(this);
  19. }
  20. private protected ShakerConfigModel ShakerConfig = new ShakerConfigModel();
  21. private protected ShakerControlModel ShakerControl = new ShakerControlModel();
  22. private protected DeviceInfoModel DeviceInfo = new DeviceInfoModel();
  23. private protected bool isopen = false;
  24. public bool IsOpen => isopen;
  25. public abstract MainPageType PageType { get; }
  26. public string File { get; } = string.Empty;
  27. [AllowNull]
  28. private protected TDMS.ITDMSFile tdmsfile;
  29. [AllowNull]
  30. public TimeDomainReviewViewModel TimeDomainReview { get; }
  31. public virtual void OpenFile(string path)
  32. {
  33. tdmsfile?.Close();
  34. tdmsfile?.Dispose();
  35. tdmsfile = TDMS.TDMSDataBuilder.OpenExisting(path);
  36. isopen = true;
  37. InitConfig();
  38. }
  39. public virtual void InitData(TDMS.ITDMSFile file)
  40. {
  41. tdmsfile?.Close();
  42. tdmsfile?.Dispose();
  43. tdmsfile = file;
  44. isopen = true;
  45. InitConfig();
  46. }
  47. private protected virtual void InitConfig()
  48. {
  49. if (tdmsfile == null) return;
  50. var group = tdmsfile.Contains(nameof(ShakerConfigModel)) ? tdmsfile[nameof(ShakerConfigModel)] : null;
  51. if (group == null) return;
  52. GetConfig(ShakerConfig, group!);
  53. group = tdmsfile.Contains(nameof(ShakerControlModel)) ? tdmsfile[nameof(ShakerControlModel)] : null;
  54. if (group == null) return;
  55. GetConfig(ShakerControl, group!);
  56. group = tdmsfile.Contains(nameof(DeviceInfoModel)) ? tdmsfile[nameof(DeviceInfoModel)] : null;
  57. if (group == null) return;
  58. GetConfig(DeviceInfo, group!);
  59. TimeDomainReview.InitData();
  60. }
  61. private protected void GetConfig<T>(T config,TDMS.ITDMSChannelGroup group)
  62. {
  63. typeof(T).GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public)
  64. .ToList()
  65. .ForEach(x =>
  66. {
  67. if (x.FieldType.IsAssignableTo(typeof(IList)) || x.FieldType.IsArray)
  68. {
  69. if (group.TryGetProperty<string>(x.Name, out var val) && !string.IsNullOrEmpty(val))
  70. {
  71. byte[] bytes = new byte[val.Length / 2];
  72. for (int i = 0; i < bytes.Length; i++)
  73. {
  74. bytes[i] = System.Convert.ToByte(val.Substring(i * 2, 2), 16);
  75. }
  76. x.SetValue(config,ShakerApp.Tools.Tools.Deserialize(x.FieldType, bytes));
  77. }
  78. else
  79. {
  80. x.SetValue(config,Activator.CreateInstance(x.FieldType));
  81. }
  82. }
  83. else if(x.FieldType == typeof(string))
  84. {
  85. if (group.TryGetProperty<string>(x.Name, out var val) && !string.IsNullOrEmpty(val))
  86. {
  87. x.SetValue(config,val);
  88. }
  89. else
  90. {
  91. x.SetValue(config,string.Empty);
  92. }
  93. }
  94. else if (x.FieldType.IsEnum)
  95. {
  96. if (group.TryGetProperty<string>(x.Name, out var val) && !string.IsNullOrEmpty(val))
  97. {
  98. x.SetValue(config,Enum.Parse(x.FieldType, val));
  99. }
  100. else
  101. {
  102. x.SetValue(config,Enum.GetValues(x.FieldType));
  103. }
  104. }
  105. else if (x.FieldType == typeof(byte))
  106. {
  107. if (group.TryGetProperty<string>(x.Name, out var val) && !string.IsNullOrEmpty(val) && byte.TryParse(val, out var b))
  108. {
  109. x.SetValue(config,b);
  110. }
  111. else
  112. {
  113. x.SetValue(config,(byte)0);
  114. }
  115. }
  116. else if (x.FieldType == typeof(sbyte))
  117. {
  118. if (group.TryGetProperty<string>(x.Name, out var val) && !string.IsNullOrEmpty(val) && sbyte.TryParse(val, out var b))
  119. {
  120. x.SetValue(config,b);
  121. }
  122. else
  123. {
  124. x.SetValue(config,(sbyte)0);
  125. }
  126. }
  127. else if (x.FieldType == typeof(short))
  128. {
  129. if (group.TryGetProperty<string>(x.Name, out var val) && !string.IsNullOrEmpty(val) && short.TryParse(val, out var b))
  130. {
  131. x.SetValue(config,b);
  132. }
  133. else
  134. {
  135. x.SetValue(config,(short)0);
  136. }
  137. }
  138. else if (x.FieldType == typeof(ushort))
  139. {
  140. if (group.TryGetProperty<string>(x.Name, out var val) && !string.IsNullOrEmpty(val) && ushort.TryParse(val, out var b))
  141. {
  142. x.SetValue(config,b);
  143. }
  144. else
  145. {
  146. x.SetValue(config,(ushort)0);
  147. }
  148. }
  149. else if (x.FieldType == typeof(int))
  150. {
  151. if (group.TryGetProperty<string>(x.Name, out var val) && !string.IsNullOrEmpty(val) && int.TryParse(val, out var b))
  152. {
  153. x.SetValue(config,b);
  154. }
  155. else
  156. {
  157. x.SetValue(config,(int)0);
  158. }
  159. }
  160. else if (x.FieldType == typeof(uint))
  161. {
  162. if (group.TryGetProperty<string>(x.Name, out var val) && !string.IsNullOrEmpty(val) && uint.TryParse(val, out var b))
  163. {
  164. x.SetValue(config,b);
  165. }
  166. else
  167. {
  168. x.SetValue(config,(uint)0);
  169. }
  170. }
  171. else if (x.FieldType == typeof(long))
  172. {
  173. if (group.TryGetProperty<string>(x.Name, out var val) && !string.IsNullOrEmpty(val) && long.TryParse(val, out var b))
  174. {
  175. x.SetValue(config,b);
  176. }
  177. else
  178. {
  179. x.SetValue(config,(long)0);
  180. }
  181. }
  182. else if (x.FieldType == typeof(ulong))
  183. {
  184. if (group.TryGetProperty<string>(x.Name, out var val) && !string.IsNullOrEmpty(val) && ulong.TryParse(val, out var b))
  185. {
  186. x.SetValue(config,b);
  187. }
  188. else
  189. {
  190. x.SetValue(config,(ulong)0);
  191. }
  192. }
  193. else if (x.FieldType == typeof(float))
  194. {
  195. if (group.TryGetProperty<string>(x.Name, out var val) && !string.IsNullOrEmpty(val) && float.TryParse(val, out var b))
  196. {
  197. x.SetValue(config,b);
  198. }
  199. else
  200. {
  201. x.SetValue(config,(float)0);
  202. }
  203. }
  204. else if (x.FieldType == typeof(double))
  205. {
  206. if (group.TryGetProperty<string>(x.Name, out var val) && !string.IsNullOrEmpty(val) && double.TryParse(val, out var b))
  207. {
  208. x.SetValue(config,b);
  209. }
  210. else
  211. {
  212. x.SetValue(config,(double)0);
  213. }
  214. }
  215. else if (x.FieldType == typeof(bool))
  216. {
  217. if (group.TryGetProperty<string>(x.Name, out var val) && !string.IsNullOrEmpty(val) && bool.TryParse(val, out var b))
  218. {
  219. x.SetValue(config,b);
  220. }
  221. else
  222. {
  223. x.SetValue(config,false);
  224. }
  225. }
  226. });
  227. }
  228. public virtual void CloseFile()
  229. {
  230. tdmsfile?.Close();
  231. tdmsfile?.Dispose();
  232. tdmsfile = null;
  233. }
  234. public class TimeDomainReviewViewModel : DisplayViewModelBase<IModel>
  235. {
  236. private bool isinint = false;
  237. List<OxyPlot.Series.LineSeries> _LineSeries = new List<OxyPlot.Series.LineSeries>();
  238. public OxyPlot.PlotModel PlotModel { get; } = new OxyPlot.PlotModel();
  239. private BaseDataReviewItemViewModel _Parent;
  240. public uint SampleRate { get => sampleRate; set =>SetProperty(ref sampleRate , value); }
  241. public uint TotalPages
  242. {
  243. get => Math.Clamp(totalPages, 1, uint.MaxValue);
  244. set
  245. {
  246. SetProperty(ref totalPages, value);
  247. OnPropertyChanged(nameof(MaxPageIndex));
  248. OnPropertyChanged(nameof(MaxReadPages));
  249. OnPropertyChanged(nameof(PageIndex));
  250. OnPropertyChanged(nameof(ReadPages));
  251. }
  252. }
  253. public uint PageIndex
  254. {
  255. get =>Math.Clamp(pageIndex,MinPageIndex,MaxPageIndex);
  256. set
  257. {
  258. SetProperty(ref pageIndex, value);
  259. OnPropertyChanged(nameof(MaxReadPages));
  260. OnPropertyChanged(nameof(ReadPages));
  261. LoadData();
  262. }
  263. }
  264. public uint MinPageIndex => 1;
  265. public uint MaxPageIndex => TotalPages;
  266. public uint ReadPages
  267. {
  268. get =>Math.Clamp(readPages,MinReadPages,MaxReadPages);
  269. set
  270. {
  271. SetProperty(ref readPages, value);
  272. LoadData();
  273. }
  274. }
  275. public uint MinReadPages => 1;
  276. public uint MaxReadPages => Math.Clamp(TotalPages - PageIndex + 1, 1, 10000);
  277. public TimeDomainReviewViewModel(BaseDataReviewItemViewModel parent)
  278. {
  279. _Parent = parent;
  280. PlotModel.Axes.Add(new OxyPlot.Axes.LinearAxis()
  281. {
  282. Position = OxyPlot.Axes.AxisPosition.Bottom,
  283. Key = "X",
  284. Title = App.Current?.FindResource("Time") +"",
  285. Unit = "s",
  286. MinimumPadding = 0,
  287. MaximumPadding = 0,
  288. });
  289. PlotModel.Axes.Add(new OxyPlot.Axes.LinearAxis()
  290. {
  291. Position = OxyPlot.Axes.AxisPosition.Left,
  292. Key = "Y",
  293. Title = App.Current?.FindResource("")+"",
  294. MinimumPadding = 0,
  295. MaximumPadding = 0,
  296. });
  297. PlotModel.Legends.Add(new OxyPlot.Legends.Legend()
  298. {
  299. IsLegendVisible = true,
  300. });
  301. }
  302. private TDMS.ITDMSChannelGroup? _DataGroup;
  303. private List<TDMS.ITDMSChannel> _Channels = new List<TDMS.ITDMSChannel>();
  304. private uint readPages;
  305. private uint pageIndex;
  306. private uint totalPages;
  307. private uint sampleRate;
  308. public override void InitData()
  309. {
  310. isinint = false;
  311. base.InitData();
  312. _DataGroup = _Parent.tdmsfile.Contains(BaseMainPageViewModel<IModel>.TimeDomainData) ? _Parent.tdmsfile[BaseMainPageViewModel<IModel>.TimeDomainData] : null;
  313. if (_DataGroup == null)
  314. {
  315. DataReviewViewModel.Instance.ShowError(App.Current?.FindResource("TestFileReadError")+"");
  316. return;
  317. }
  318. _Channels.Clear();
  319. _LineSeries.Clear();
  320. PlotModel.Series.Clear();
  321. if(_DataGroup.ChildCount ==0)
  322. {
  323. DataReviewViewModel.Instance.ShowError(App.Current?.FindResource("TestFileReadError") + "");
  324. return;
  325. }
  326. PlotModel.InvalidatePlot(false);
  327. for(ulong i=0;i<_DataGroup.ChildCount;i++)
  328. {
  329. _Channels.Add(_DataGroup[(int)i]!);
  330. _LineSeries.Add(new OxyPlot.Series.LineSeries()
  331. {
  332. XAxisKey = "X",
  333. YAxisKey = "Y",
  334. DataFieldX = nameof(OxyPlot.DataPoint.X),
  335. DataFieldY = nameof(OxyPlot.DataPoint.Y),
  336. Title = App.Current?.FindResource(_Channels[^1].Name)+"",
  337. Tag = _Channels[^1].Unit,
  338. });
  339. PlotModel.Series.Add(_LineSeries[^1]);
  340. }
  341. PlotModel.InvalidatePlot(true);
  342. SampleRate = _Parent.ShakerConfig.SampleRate;
  343. TotalPages = (uint)Math.Ceiling(_Channels[0].ChildCount / (double)SampleRate);
  344. ReadPages = 1;
  345. PageIndex = 1;
  346. isinint = true;
  347. LoadData();
  348. }
  349. private void LoadData()
  350. {
  351. if (!isinint) return;
  352. uint start = (PageIndex - 1) * SampleRate;
  353. uint len = ReadPages * SampleRate;
  354. len = (uint)Math.Clamp(len, len, _Channels[^1].ChildCount - start);
  355. double pro = 1d / SampleRate;
  356. //var datas = Enumerable.Repeat(new OxyPlot.DataPoint(), 1000_000).ToList();
  357. PlotModel.InvalidatePlot(false);
  358. for(int i=0;i<_Channels.Count;i++)
  359. {
  360. uint index = 0;
  361. _LineSeries[i].ItemsSource = _Channels[i].GetDataValues<double>(start, len).Select(x =>
  362. {
  363. return new OxyPlot.DataPoint((index++) * pro, x);
  364. }).ToList();
  365. // _LineSeries[i].ItemsSource = datas;
  366. }
  367. PlotModel.InvalidatePlot(true);
  368. }
  369. }
  370. }
  371. }