using Avalonia.Collections; using Avalonia.Controls; using IViewModel.Models; using IViewModel.Tools; using IViewModel.ViewModels; using OxyPlot; using OxyPlot.Axes; using OxyPlot.Series; using Shaker.Model; using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Dynamicloadsimulationdevice.ViewModels { internal sealed class AnalogSignalPreviewViewModel:DisplayViewModelBase,IDataPreview { public string AttachTitle { get => attachTitle; set { if (attachTitle == value) return; attachTitle = value; UpdatePlotTitle(SelectedAnalog); } } List lineSeries = new List(); private object locker = new object(); public AvaloniaList Statistics { get; } = new AvaloniaList(); private ResultChannelType selectedAnalog; private bool canChangedAnalog = true; public bool StatisticsVisibily { get => statisticsVisibily; set =>SetProperty(ref statisticsVisibily , value); } public AnalogSignalPreviewViewModel(bool createcontrol = false):base() { Content = typeof(Views.AnalogSignalPreviewView); if(createcontrol) { Control = (Control)Activator.CreateInstance(Content)!; } PlotModel.Axes.Add(new OxyPlot.Axes.LinearAxis() { MaximumPadding = 0, MinimumPadding = 0, Title = LanguageValueViewModel.Instance.Time, Unit = "s", Key = "X", MajorGridlineStyle = OxyPlot.LineStyle.Solid, Position = OxyPlot.Axes.AxisPosition.Bottom }); PlotModel.Axes.Add(new OxyPlot.Axes.LinearAxis() { Title = LanguageValueViewModel.Instance.Ampt, Unit = "V", Key = "Y", MajorGridlineStyle = OxyPlot.LineStyle.Solid, Position = OxyPlot.Axes.AxisPosition.Left, }); UpdatePlotTitle(lasttype); PlotModel.Legends.Add(new OxyPlot.Legends.Legend() { ShowInvisibleSeries = true, }); PlotController.BindMouseWheel(OxyMouseWheelCommand); GetEvent(Topic.DATA).Subscrip((_, _) => { if (!UpSignalData) return; lock(locker) { var data = ShakerDataViewModel.Instance.GetAnalogData(SelectedAnalog); PlotModel.InvalidatePlot(false); for(int i=0;i { lock(locker) { Menu.Clear(); ShakerChannelViewModel.Instance.ResultChannels .DistinctBy(x=>x.Value.ChannelType) .ToList() .ForEach(x => { Menu.Add(new TimeDomainMenuViewModel() { IsChecked = false, IsEnabled = true, AnalogType = x.Value.ChannelType, Unit = x.Value.Unit, }); }); if (CanChangedAnalog) { int index = Menu.ToList().FindIndex(x => x.AnalogType == lasttype); if (index == -1) { SelectedAnalog = Menu.First().AnalogType; } else { SelectedAnalog = lasttype; } } else { SelectedAnalog = lasttype; } } }); GetEvent(IViewModel.ViewModels.LanguageViewModel.LANGUAGECHANGEDEVENT).Subscrip((_, _) => { PlotModel.InvalidatePlot(false); PlotModel.Axes[0].Title = LanguageValueViewModel.Instance.Time; PlotModel.Axes[1].Title = LanguageValueViewModel.Instance.Ampt; UpdatePlotTitle(SelectedAnalog); var config = ShakerChannelViewModel.Instance.ResultChannels.FirstOrDefault(x => x.Value.ChannelType == SelectedAnalog); if (config == null) return; for(int i=0;i Menu { get; } = new AvaloniaList(); public AnalogSignalPreviewViewModel(ResultChannelType analogType,bool createcontrol = false):this(createcontrol) { lasttype = analogType; } public ResultChannelType SelectedAnalog { get => selectedAnalog; set { SetProperty(ref selectedAnalog, value); ChangeAnalogType(value); } } public bool UpSignalData { get; set; } = true; private void ChangeAnalogType(ResultChannelType type) { lock (locker) { lineSeries.Clear(); PlotModel.Series.Clear(); Statistics.Clear(); for (int i = 0; i < Menu.Count; i++) { Menu[i].IsChecked = Menu[i].AnalogType == type; } if (ShakerChannelViewModel.Instance.ResultChannels.Count == 0) return; var config = ShakerChannelViewModel.Instance.ResultChannels.FirstOrDefault(x => x.Value.ChannelType == type); if (config == null) return; PlotModel.Axes[1].Unit = config.Value.Unit; var allconfig = ShakerChannelViewModel.Instance.ResultChannels.Where(x => x.Value.ChannelType == type).ToList(); for (int i = 0; i < allconfig.Count; i++) { LineSeries series = new LineSeries(); series.Title = LanguageValueViewModel.Instance[allconfig[i].Value.Name]; series.XAxisKey = "X"; series.YAxisKey = "Y"; series.Tag = allconfig[i].Value.Unit; series.DataFieldX = nameof(DataPoint.X); series.DataFieldY = nameof(DataPoint.Y); Statistics.Add(new StatisticsViewModel(new StatisticsModel() { Name = allconfig[i].Value.Name, })); lineSeries.Add(series); } PlotModel.InvalidatePlot(false); UpdatePlotTitle(type); lineSeries.ForEach(x => PlotModel.Series.Add(x)); PlotModel.InvalidatePlot(true); } } public bool CanChangedAnalog { get => canChangedAnalog; set =>SetProperty(ref canChangedAnalog , value); } public OxyPlot.PlotModel PlotModel { get; } = new OxyPlot.PlotModel(); public OxyPlot.PlotController PlotController { get; } = new OxyPlot.PlotController(); public IViewCommand OxyMouseWheelCommand => new DelegatePlotCommand(OnOxyMouseWheel); private void OnOxyMouseWheel(IPlotView view, IController controller, OxyMouseWheelEventArgs args) { HandleZoomByWheel(view, args); if (view.ActualModel is PlotModel plotModel && plotModel.Axes.Count >= 1 && plotModel.Axes[0] is LinearAxis axis) { axis.MajorStep = (axis.Maximum - axis.Minimum) / 10; } } private void HandleZoomByWheel(IPlotView view, OxyMouseWheelEventArgs args, double factor = 1) { var m = new ZoomStepManipulator(view) { AxisPreference = AxisPreference.X, Step = args.Delta * 0.001 * factor, FineControl = args.IsControlDown, }; m.Started(args); } } }