From c4d6a58bf4c929b65d18472b8e432e95f9544559 Mon Sep 17 00:00:00 2001 From: "GukSang.Jin" Date: Sun, 5 Apr 2026 16:46:26 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TrendLastPointCoordinateConverter.cs | 45 +++ Cardiopulmonarybypasssystems/MainWindow.xaml | 341 +++++++++++++++--- .../ViewModels/MainViewModel.cs | 8 + 3 files changed, 346 insertions(+), 48 deletions(-) create mode 100644 Cardiopulmonarybypasssystems/Converters/TrendLastPointCoordinateConverter.cs 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)); }