diff --git a/Cardiopulmonarybypasssystems/Converters/TrendLastPointCoordinateConverter.cs b/Cardiopulmonarybypasssystems/Converters/TrendLastPointCoordinateConverter.cs new file mode 100644 index 0000000..10dc13c --- /dev/null +++ b/Cardiopulmonarybypasssystems/Converters/TrendLastPointCoordinateConverter.cs @@ -0,0 +1,45 @@ +using System.Collections; +using System.Globalization; +using System.Windows.Data; + +namespace Cardiopulmonarybypasssystems.Converters; + +public sealed class TrendLastPointCoordinateConverter : IMultiValueConverter +{ + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + if (values.Length < 4 + || values[0] is not IEnumerable enumerable + || values[1] is not double width + || values[2] is not double height + || values[3] is not double maxValue + || width <= 0 + || height <= 0 + || maxValue <= 0) + { + return -100d; + } + + var samples = enumerable.Cast() + .Select(item => item is double value ? value : System.Convert.ToDouble(item, culture)) + .ToList(); + + if (samples.Count == 0) + { + return -100d; + } + + var lastIndex = samples.Count - 1; + var xStep = samples.Count > 1 ? width / Math.Max(samples.Count - 1, 1) : 0d; + var x = xStep * lastIndex; + var yRatio = Math.Clamp(samples[lastIndex] / maxValue, 0d, 1d); + var y = height - yRatio * height; + + return string.Equals(parameter as string, "y", StringComparison.OrdinalIgnoreCase) + ? y - 4d + : x - 4d; + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) => + throw new NotSupportedException(); +} diff --git a/Cardiopulmonarybypasssystems/MainWindow.xaml b/Cardiopulmonarybypasssystems/MainWindow.xaml index 8625b57..86531ec 100644 --- a/Cardiopulmonarybypasssystems/MainWindow.xaml +++ b/Cardiopulmonarybypasssystems/MainWindow.xaml @@ -13,6 +13,7 @@ WindowStartupLocation="CenterScreen"> + @@ -593,21 +594,133 @@ - + + + + + + - - - - + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -668,43 +781,175 @@ - + + + + + + - - - - + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Cardiopulmonarybypasssystems/ViewModels/MainViewModel.cs b/Cardiopulmonarybypasssystems/ViewModels/MainViewModel.cs index bea6666..bcd49bf 100644 --- a/Cardiopulmonarybypasssystems/ViewModels/MainViewModel.cs +++ b/Cardiopulmonarybypasssystems/ViewModels/MainViewModel.cs @@ -435,6 +435,10 @@ public partial class MainViewModel : ObservableObject, IDisposable }; public double PressureTrendMax => MaxTrendValue([ProximalPressureTrendValues, DistalPressureTrendValues, DeltaPressureTrendValues], 40d); public double FlowTrendMax => MaxTrendValue([ActiveFlowTrendPrimaryValues, ActiveFlowTrendSecondaryValues, ActiveFlowTrendTertiaryValues], Math.Max(RatedMaxFlow, 1d)); + public string PressureTrendTopScaleDisplay => $"{PressureTrendMax:F0}"; + public string PressureTrendMidScaleDisplay => $"{PressureTrendMax / 2d:F0}"; + public string FlowTrendTopScaleDisplay => $"{FlowTrendMax:F1}"; + public string FlowTrendMidScaleDisplay => $"{FlowTrendMax / 2d:F1}"; public string ProximalPressureDisplay => PressureDisplay("近端压力", _proximalPressureRawKpa); public string DistalPressureDisplay => PressureDisplay("远端压力", _distalPressureRawKpa); public string FlowImbalanceDisplay => HasChannelTelemetry("主泵流量", "动脉回输流量") ? $"{Math.Abs(PumpFlow - ReturnFlow):F2} L/min" : "--"; @@ -1468,6 +1472,10 @@ public partial class MainViewModel : ObservableObject, IDisposable OnPropertyChanged(nameof(ActiveFlowTrendTertiaryValues)); OnPropertyChanged(nameof(PressureTrendMax)); OnPropertyChanged(nameof(FlowTrendMax)); + OnPropertyChanged(nameof(PressureTrendTopScaleDisplay)); + OnPropertyChanged(nameof(PressureTrendMidScaleDisplay)); + OnPropertyChanged(nameof(FlowTrendTopScaleDisplay)); + OnPropertyChanged(nameof(FlowTrendMidScaleDisplay)); OnPropertyChanged(nameof(PressureTrendCurrentSummary)); OnPropertyChanged(nameof(FlowTrendCurrentSummary)); }