AnalogSignalPreviewViewModel.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. using Avalonia.Collections;
  2. using Avalonia.Controls;
  3. using OxyPlot;
  4. using OxyPlot.Axes;
  5. using Shaker.Models;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Text;
  10. using System.Threading.Tasks;
  11. using ShakerApp.Tools;
  12. using OxyPlot.Series;
  13. namespace ShakerApp.ViewModels
  14. {
  15. public class AnalogSignalPreviewViewModel:ViewModelBase<IModel>,IDataPreview
  16. {
  17. List<OxyPlot.Series.LineSeries> lineSeries = new List<OxyPlot.Series.LineSeries>();
  18. private object locker = new object();
  19. public AvaloniaList<KeyValuePair<string, AnalogType>> AllAnalogTypes { get; } = new AvaloniaList<KeyValuePair<string, AnalogType>>();
  20. public AvaloniaList<ViewModels.StatisticsViewModel> Statistics { get; } = new AvaloniaList<StatisticsViewModel>();
  21. private AnalogType selectedAnalog;
  22. private bool canChangedAnalog = true;
  23. public bool StatisticsVisibily { get => statisticsVisibily; set =>SetProperty(ref statisticsVisibily , value); }
  24. public AnalogSignalPreviewViewModel():base()
  25. {
  26. Content = typeof(Views.AnalogSignalPreviewView);
  27. PlotModel.Axes.Add(new OxyPlot.Axes.LinearAxis()
  28. {
  29. MaximumPadding = 0,
  30. MinimumPadding = 0,
  31. Title = App.Current?.FindResource("Time") + "",
  32. Unit = "s",
  33. Key = "X",
  34. MajorGridlineStyle = OxyPlot.LineStyle.Solid,
  35. Position = OxyPlot.Axes.AxisPosition.Bottom
  36. });
  37. PlotModel.Axes.Add(new OxyPlot.Axes.LinearAxis()
  38. {
  39. Title = App.Current?.FindResource("Ampt") + "",
  40. Unit = "V",
  41. Key = "Y",
  42. MajorGridlineStyle = OxyPlot.LineStyle.Solid,
  43. Position = OxyPlot.Axes.AxisPosition.Left,
  44. });
  45. PlotModel.Title = App.Current?.FindResource("ValveDriveSignal") + "";
  46. PlotModel.Legends.Add(new OxyPlot.Legends.Legend()
  47. {
  48. ShowInvisibleSeries = true,
  49. });
  50. PlotController.BindMouseWheel(OxyMouseWheelCommand);
  51. GetEvent(Topic.DATA).Subscrip((_, _) =>
  52. {
  53. if (!UpSignalData) return;
  54. lock(locker)
  55. {
  56. if(SelectedAnalog == AnalogType.Driver)
  57. {
  58. }
  59. var data = ShakerDataViewModel.Instance.GetAnalogData(SelectedAnalog);
  60. PlotModel.InvalidatePlot(false);
  61. for(int i=0;i<data.Count;i++)
  62. {
  63. lineSeries[i].ItemsSource = data[i].Item1;
  64. Statistics[i].UpDateModel(data[i].Item2);
  65. }
  66. PlotModel.InvalidatePlot(true);
  67. }
  68. });
  69. GetEvent(Models.Topic.InitSeries).Subscrip((_, _) =>
  70. {
  71. lock(locker)
  72. {
  73. AllAnalogTypes.Clear();
  74. ShakerConfigViewModel.Instance.AnalogSignals.ToList()
  75. .ForEach(x =>
  76. {
  77. AllAnalogTypes.Add(new KeyValuePair<string, AnalogType>(x.Value.AnalogType.Description(), x.Value.AnalogType));
  78. });
  79. if (CanChangedAnalog)
  80. {
  81. int index = AllAnalogTypes.ToList().FindIndex(x => x.Value == lasttype);
  82. if (index == -1)
  83. {
  84. SelectedAnalog = AllAnalogTypes.First().Value;
  85. }
  86. else
  87. {
  88. SelectedAnalog = lasttype;
  89. }
  90. }
  91. else
  92. {
  93. SelectedAnalog = lasttype;
  94. }
  95. }
  96. });
  97. }
  98. private AnalogType lasttype = AnalogType.Displacement;
  99. private bool statisticsVisibily = true;
  100. public AnalogSignalPreviewViewModel(Shaker.Models.AnalogType analogType):this()
  101. {
  102. lasttype = analogType;
  103. }
  104. public AnalogType SelectedAnalog
  105. {
  106. get => selectedAnalog;
  107. set
  108. {
  109. SetProperty(ref selectedAnalog, value);
  110. ChangeAnalogType(value);
  111. }
  112. }
  113. public bool UpSignalData { get; set; } = true;
  114. private void ChangeAnalogType(AnalogType type)
  115. {
  116. lock(locker)
  117. {
  118. lineSeries.Clear();
  119. PlotModel.Series.Clear();
  120. Statistics.Clear();
  121. var config = ShakerConfigViewModel.Instance.Model.AnalogSignalConfigs.First(x => x.AnalogType == type);
  122. PlotModel.Axes[1].Unit = config.Unit;
  123. int count = ShakerConfigViewModel.Instance.Model.AnalogSignalConfigs.Count(x => x.AnalogType == type);
  124. var data = ShakerDataViewModel.Instance.GetAnalogData(type);
  125. for(int i=0;i<count;i++)
  126. {
  127. LineSeries series = new LineSeries();
  128. series.Title = App.Current?.FindResource(config.Name) + "";
  129. series.XAxisKey = "X";
  130. series.YAxisKey = "Y";
  131. series.DataFieldX = nameof(DataPoint.X);
  132. series.DataFieldY = nameof(DataPoint.Y);
  133. if(data.Count==count)
  134. {
  135. Statistics.Add(new StatisticsViewModel(data[i].Item2));
  136. series.ItemsSource = data[i].Item1;
  137. }
  138. else
  139. {
  140. Statistics.Add(new StatisticsViewModel());
  141. }
  142. lineSeries.Add(series);
  143. }
  144. PlotModel.InvalidatePlot(false);
  145. PlotModel.Title = App.Current?.FindResource(type.Description()) + "";
  146. lineSeries.ForEach(x => PlotModel.Series.Add(x));
  147. PlotModel.InvalidatePlot(true);
  148. }
  149. }
  150. public bool CanChangedAnalog
  151. {
  152. get => canChangedAnalog;
  153. set =>SetProperty(ref canChangedAnalog , value);
  154. }
  155. public OxyPlot.PlotModel PlotModel { get; } = new OxyPlot.PlotModel();
  156. public OxyPlot.PlotController PlotController { get; } = new OxyPlot.PlotController();
  157. public IViewCommand<OxyMouseWheelEventArgs> OxyMouseWheelCommand => new DelegatePlotCommand<OxyMouseWheelEventArgs>(OnOxyMouseWheel);
  158. private void OnOxyMouseWheel(IPlotView view, IController controller, OxyMouseWheelEventArgs args)
  159. {
  160. HandleZoomByWheel(view, args);
  161. if (view.ActualModel is PlotModel plotModel && plotModel.Axes.Count >= 1 && plotModel.Axes[0] is LinearAxis axis)
  162. {
  163. axis.MajorStep = (axis.Maximum - axis.Minimum) / 10;
  164. }
  165. }
  166. private void HandleZoomByWheel(IPlotView view, OxyMouseWheelEventArgs args, double factor = 1)
  167. {
  168. var m = new ZoomStepManipulator(view)
  169. {
  170. AxisPreference = AxisPreference.X,
  171. Step = args.Delta * 0.001 * factor,
  172. FineControl = args.IsControlDown,
  173. };
  174. m.Started(args);
  175. }
  176. }
  177. }