using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Windows.Threading; using LiveCharts; using LiveCharts.Configurations; using LiveCharts.Helpers; using LiveCharts.Wpf; using Misc; namespace FLY.Thick.Base.UI.UiModule { /// <summary> /// Page_FixAnalyze.xaml 的交互逻辑 /// </summary> public partial class PgFixAnalyze : Page { PgFixAnalyzeVm viewModel; public PgFixAnalyze() { InitializeComponent(); } public void Init(double intervalms, List<double> datas) { viewModel = new PgFixAnalyzeVm(); viewModel.Init(intervalms, datas); this.DataContext = viewModel; } private void UIElement_OnMouseMove(object sender, MouseEventArgs e) { var vm = viewModel; var chart = (LiveCharts.Wpf.CartesianChart)sender; //lets get where the mouse is at our chart var mouseCoordinate = e.GetPosition(chart); //now that we know where the mouse is, lets use //ConverToChartValues extension //it takes a point in pixes and scales it to our chart current scale/values var p = chart.ConvertToChartValues(mouseCoordinate); //in the Y section, lets use the raw value vm.YPointer = p.Y; vm.XPointer = p.X; } private void ButtonTestClick(object sender, RoutedEventArgs e) { viewModel.Test(); } private void UIElement_OnMouseDown(object sender, MouseButtonEventArgs e) { var vm = viewModel; var chart = (LiveCharts.Wpf.CartesianChart)sender; //lets get where the mouse is at our chart var mouseCoordinate = e.GetPosition(chart); //now that we know where the mouse is, lets use //ConverToChartValues extension //it takes a point in pixes and scales it to our chart current scale/values var p = chart.ConvertToChartValues(mouseCoordinate); //in the Y section, lets use the raw value vm.YPointer = p.Y; vm.XPointer = p.X; } } public class PgFixAnalyzeVm : INotifyPropertyChanged { /// <summary> /// X轴拖拉条 最大值 /// </summary> public double XRangeSliderMax { get; set; } = 10000; /// <summary> /// X轴拖拉条 最小值 /// </summary> public double XRangeSliderMin { get; set; } = 0; /// <summary> /// X轴 最大值 /// </summary> public double XMax { get; set; } = 1000; /// <summary> /// X轴 最小值 /// </summary> public double XMin { get; set; } public double LowerValue { get; set; } public double UpperValue { get; set; } public double YMax { get; set; } = double.NaN; public double YMin { get; set; } = double.NaN; public double YPointer { get; set; } = 3; public double XPointer { get; set; } = 3; public ChartValues<double> Values { get; private set; } = new ChartValues<double>(); public Func<double, string> XFormatter { get; private set; } DispatcherTimer timer; public void Test() { List<double> datas = new List<double>(); double intervalms = 1.28; for (int i = 0; i < 10000; i++) { double sum = 0; sum += getd(20, intervalms, i); sum += getd(100, intervalms, i); sum += getd(50, intervalms, i); datas.Add(sum); } Init(intervalms, datas); } double getd(double hz, double ms, int i) { double cnt = 1000 / ms / hz; return Math.Sin(Math.PI * 2 * i / cnt); } public PgFixAnalyzeVm() { timer = new DispatcherTimer(); timer.Interval = TimeSpan.FromSeconds(1); timer.Tick += Timer_Tick; this.PropertyChanged += PgFixAnalyzeVm_PropertyChanged; } private void PgFixAnalyzeVm_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == nameof(UpperValue) || e.PropertyName == nameof(LowerValue)) { if (!timer.IsEnabled) timer.Start(); } } private void Timer_Tick(object sender, EventArgs e) { timer.Stop(); if (LowerValue < UpperValue) { XMax = UpperValue; XMin = LowerValue; } } List<double> Magnitudes = new List<double>(); public double MinFs { get; private set; } = 0.1; public void Init(double intervalms, List<double> datas) { MinFs = (1000 / intervalms) / datas.Count(); XFormatter = (d) => { int n = (int)d; return ((n) * MinFs).ToString("F2"); }; Values.Clear(); // System.Numerics.Complex[] complexs = new System.Numerics.Complex[datas.Count()]; for (int i = 0; i < datas.Count(); i++) { complexs[i] = new System.Numerics.Complex(datas[i], 0); } MathNet.Numerics.IntegralTransforms.Fourier.Forward(complexs); complexs[0] = new System.Numerics.Complex(0, 0); Magnitudes.Clear(); Magnitudes.AddRange(complexs.Take(complexs.Count() / 2).Select(c=>c.Magnitude)); Values.AddRange(Magnitudes); XRangeSliderMax = Values.Count(); XRangeSliderMin = 0; UpperValue = XRangeSliderMax; LowerValue = 0; } public event PropertyChangedEventHandler PropertyChanged; protected void ToPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } }