using Avalonia.Collections; using Avalonia.Controls; using OxyPlot; using OxyPlot.Series; using Shaker.Models; using Shaker.Models.Tools; using ShakerApp.Tools; using ShakerApp.Views; using System; using System.Collections.Generic; using System.Linq; using System.Net.Http.Headers; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; namespace ShakerApp.ViewModels { internal class SineMainPageViewModel : ViewModelBase, IMainPageViewModel { List oxyColors = new List() {OxyColors.Black, OxyColors.Green, OxyColors.Red, OxyColors.Red, OxyColors.Yellow, OxyColors.Yellow }; List lineStyles = new List() {LineStyle.Solid, LineStyle.Solid, LineStyle.Solid, LineStyle.Solid, LineStyle.LongDashDotDot, LineStyle.LongDashDotDot }; List properties = new List() {nameof(SweepData.Acceleration), nameof(SweepData.TargetAcceleration), nameof(SweepData.UpStopAcceleration), nameof(SweepData.DownStopAcceleration), nameof(SweepData.UpWarnAcceleration), nameof(SweepData.DownWarnAcceleration) }; List datas = new List(); DateTime dateTime = DateTime.Now; OxyPlot.Annotations.ArrowAnnotation arrowAnnotation = new OxyPlot.Annotations.ArrowAnnotation(); public AvaloniaList LineSeries { get; } = new AvaloniaList(); private SineMainPageViewModel() { #region 加速度谱曲线 PlotModel.Axes.Add(new OxyPlot.Axes.LogarithmicAxis() { MaximumPadding = 0, MinimumPadding = 0, Title = App.Current?.FindResource(ShakerConstant.FrequencyKey) + "", Unit = "Hz", MajorGridlineStyle = LineStyle.Solid, Position = OxyPlot.Axes.AxisPosition.Bottom, Key = "Freq" }); PlotModel.Axes.Add(new OxyPlot.Axes.LogarithmicAxis() { Key = "Ampt", Title = App.Current?.FindResource(ShakerConstant.AmptAxisTitleKey) + "", Unit = "g", MajorGridlineStyle = LineStyle.Solid, Position = OxyPlot.Axes.AxisPosition.Left, }); PlotModel.Title = App.Current?.FindResource(ShakerConstant.AccelerationSpectrumKey) + ""; for (int i = 0; i < oxyColors.Count; i++) { LineSeries line = new LineSeries(); line.Title = App.Current?.FindResource(ShakerConstant.ShowSweepAccelerationSpectrumNames[i]) + ""; line.Color = oxyColors[i]; line.StrokeThickness = 1; line.DataFieldX = nameof(SweepData.Frequency); line.DataFieldY = properties[i]; line.LineStyle = lineStyles[i]; line.XAxisKey = "Freq"; line.YAxisKey = "Ampt"; LineSeries.Add(line); PlotModel.Series.Add(line); } PlotModel.Annotations.Add(arrowAnnotation); arrowAnnotation.Selectable = false; arrowAnnotation.SelectionMode = OxyPlot.SelectionMode.Single; arrowAnnotation.Text = "Test"; arrowAnnotation.TextColor = OxyColors.Transparent; arrowAnnotation.StartPoint = new DataPoint(8, 4); arrowAnnotation.EndPoint = new DataPoint(); arrowAnnotation.Color = OxyColors.Transparent; PlotModel.Legends.Add(new OxyPlot.Legends.Legend() { ShowInvisibleSeries = true, }); PlotModel.Title = App.Current?.FindResource(MainPageType.SinePage.Description()) + ""; #endregion GetEvent(ShakerSettingViewModel.LANGUAGECHANGEDEVENT).Subscrip((_, _) => { PlotModel.InvalidatePlot(false); PlotModel.Title = App.Current?.FindResource(MainPageType.SinePage.Description()) + ""; PlotModel.Axes[0].Title = App.Current?.FindResource("Frequency") + ""; PlotModel.Axes[1].Title = Title = App.Current?.FindResource("Ampt") + ""; for(int i=0;i().Subscrip((_, _) => { CommunicationViewModel.Instance.LocalCommunication?.GetEvent>()?.Subscrip((_, args) => { UpdateData(args.Data.Cast().ToList()); CommunicationViewModel.Instance.ServiceCommunication?.GetEvent>()?.Publish(this, args.Data); }); }); } static SineMainPageViewModel() { } public void SetRefSpectrum(List data) { datas.Clear(); datas.AddRange(data); PlotModel.InvalidatePlot(false); for(int i=0;i model) { if (model.Last() is SineDataModel sine) { if (sine.SweepDirection != Model.SweepDirection && sine.SweepStep != Shaker.Models.SweepStep.Stop) { SetRefSpectrum(SweepConfigViewModel.Instance.RefSpectrum); } UpDataModels(model.Cast().ToList()); UpDateModel(sine); UpPlot(); } } private void UpDataModels(List models) { models.ForEach(sine => { double currentacc = Shaker.Models.Tools.Tools.VoltageToQuantities(sine.CurrentAcceleration, ShakerConfigViewModel.Instance.AccelerationSensitivity); uint currentfreq = (uint)(sine.CurrentFrequency * 1000_000); int index = -1; for (int i = 0; i < datas.Count; i++) { uint tempfreq = (uint)(datas[i].Frequency * 1000_000); if (tempfreq == currentfreq) { index = i; datas[i].SetAcceleration(currentacc); if (sine.SweepDirection == Shaker.Models.SweepDirection.Up) { for (int j = i - 1; j >= 0; j--) { if (datas[j].Frequency > SweepConfigViewModel.Instance.EndFrequency) break; if (double.IsNaN(datas[j].Acceleration)) { datas[j].SetAcceleration(currentacc); } else break; } } else { for (int j = i + 1; j < datas.Count; j++) { if (datas[j].Frequency < SweepConfigViewModel.Instance.StartFrequency) break; if (double.IsNaN(datas[j].Acceleration)) { datas[j].SetAcceleration(currentacc); } else break; } } return; } else if (tempfreq > currentfreq) { if (i > 0) { index = i - 1; } else index = 0; break; } } if (index == -1) index = datas.Count - 1; if (sine.SweepDirection == Shaker.Models.SweepDirection.Up) { for (int j = index; j >= 0; j--) { if (datas[j].Frequency > SweepConfigViewModel.Instance.EndFrequency) break; if (double.IsNaN(datas[j].Acceleration)) { datas[j].SetAcceleration(currentacc); } else break; } } else { for (int j = index + 1; j < datas.Count; j++) { if (datas[j].Frequency < SweepConfigViewModel.Instance.StartFrequency) break; if (double.IsNaN(datas[j].Acceleration)) { datas[j].SetAcceleration(currentacc); } else break; } } double value = 0; double upstop = 0; double upwarn = 0; double downstop = 0; double downwarn = 0; SweepConfigViewModel.Instance.Model.CalcAmpt(sine.CurrentFrequency, ref value, ref upstop, ref upwarn, ref downstop, ref downwarn); datas.Insert(index + 1, new SweepData(sine.CurrentFrequency,currentacc, value, upstop, downstop, upwarn, downwarn)); }); } private void UpPlot() { PlotModel.InvalidatePlot(false); if (Model.SweepStep == Shaker.Models.SweepStep.Stop) { arrowAnnotation.TextColor = OxyColors.Transparent; arrowAnnotation.Color = OxyColors.Transparent; } else { arrowAnnotation.TextColor = OxyColors.Black; arrowAnnotation.Color = OxyColors.Green; arrowAnnotation.EndPoint = new DataPoint(CurrentFrequency, CurrentAcceleration); arrowAnnotation.StartPoint = new DataPoint(CurrentFrequency, 1E-30); arrowAnnotation.Text = $"{App.Current?.FindResource("Frequency")}:{CurrentFrequency:F2}Hz\r\n{App.Current?.FindResource("Acceleration")}:{CurrentAcceleration:F3}g"; arrowAnnotation.TextPosition = arrowAnnotation.EndPoint; arrowAnnotation.TextHorizontalAlignment = HorizontalAlignment.Left; arrowAnnotation.TextVerticalAlignment = VerticalAlignment.Top; } for(int i=0;i Model.TotalTime; set => SetProperty(ref Model.TotalTime, value); } [PropertyAssociation(nameof(SineDataModel.RunTime))] public double RunTime { get => Model.RunTime; set => SetProperty(ref Model.RunTime, value); } [PropertyAssociation(nameof(SineDataModel.CurrentFrequency))] public double CurrentFrequency { get => Model.CurrentFrequency; set => SetProperty(ref Model.CurrentFrequency, value); } [PropertyAssociation(nameof(SineDataModel.CurrentAcceleration))] public double CurrentAcceleration { get => Shaker.Models.Tools.Tools.VoltageToQuantities(Model.CurrentAcceleration, ShakerConfigViewModel.Instance.AccelerationSensitivity); set => SetProperty(ref Model.CurrentAcceleration, value); } [PropertyAssociation(nameof(SineDataModel.SweepDirection))] public string SweepDirection { get => Model.SweepDirection.Description(); } [PropertyAssociation(nameof(SineDataModel.SweepStep))] public string SweepStep { get => Model.SweepStep.Description(); } [PropertyAssociation(nameof(SineDataModel.SweepIndex))] public uint SweepIndex { get => Model.SweepIndex; set => SetProperty(ref Model.SweepIndex, value); } [PropertyAssociation(nameof(SineDataModel.MainPageType))] public MainPageType PageType => Model.MainPageType; public OxyPlot.PlotModel PlotModel { get; private set; } = new OxyPlot.PlotModel(); public static SineMainPageViewModel Instance { get; } = new SineMainPageViewModel(); public OxyPlot.PlotModel DriverModel { get; private set; } = new PlotModel(); } }