using Avalonia.Collections; using Avalonia.Controls; using OxyPlot; using OxyPlot.Axes; using Shaker.Models; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using ShakerApp.Tools; using OxyPlot.Series; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; namespace ShakerApp.ViewModels { public class AnalogSignalPreviewViewModel:ViewModelBase,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 AnalogType 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 = App.Current?.FindResource("Time") + "", Unit = "s", Key = "X", MajorGridlineStyle = OxyPlot.LineStyle.Solid, Position = OxyPlot.Axes.AxisPosition.Bottom }); PlotModel.Axes.Add(new OxyPlot.Axes.LinearAxis() { Title = App.Current?.FindResource("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) { if(SelectedAnalog == AnalogType.Driver) { } var data = ShakerDataViewModel.Instance.GetAnalogData(SelectedAnalog); PlotModel.InvalidatePlot(false); for(int i=0;i { lock(locker) { Menu.Clear(); ShakerConfigViewModel.Instance.AnalogSignals .DistinctBy(x=>x.Value.AnalogType) .ToList() .ForEach(x => { Menu.Add(new TimeDomainMenuViewModel() { IsChecked = false, IsEnabled = true, AnalogType = x.Value.AnalogType, 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(ViewModels.ShakerSettingViewModel.LANGUAGECHANGEDEVENT).Subscrip((_, _) => { PlotModel.InvalidatePlot(false); PlotModel.Axes[0].Title = App.Current?.FindResource("Time") + ""; PlotModel.Axes[1].Title = App.Current?.FindResource("Ampt") + ""; UpdatePlotTitle(SelectedAnalog); var config = ShakerConfigViewModel.Instance.Model.AnalogSignalConfigs.First(x => x.AnalogType == SelectedAnalog); for(int i=0;i Menu { get; } = new AvaloniaList(); public AnalogSignalPreviewViewModel(Shaker.Models.AnalogType analogType,bool createcontrol = false):this(createcontrol) { lasttype = analogType; } public AnalogType SelectedAnalog { get => selectedAnalog; set { SetProperty(ref selectedAnalog, value); ChangeAnalogType(value); } } public bool UpSignalData { get; set; } = true; private void ChangeAnalogType(AnalogType type) { lock (locker) { lineSeries.Clear(); PlotModel.Series.Clear(); Statistics.Clear(); for(int i=0;i x.AnalogType == type); PlotModel.Axes[1].Unit = config.Unit; var allconfig = ShakerConfigViewModel.Instance.Model.AnalogSignalConfigs.Where(x => x.AnalogType == type).ToList(); for (int i = 0; i < allconfig.Count; i++) { LineSeries series = new LineSeries(); series.Title = App.Current?.FindResource(allconfig[i].Name) + ""; series.XAxisKey = "X"; series.YAxisKey = "Y"; series.DataFieldX = nameof(DataPoint.X); series.DataFieldY = nameof(DataPoint.Y); Statistics.Add(new StatisticsViewModel(new Models.StatisticsModel() { Name = allconfig[i].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); } } }