From 18a63a1c1da201c6015ce4cb4161c68355e7cda0 Mon Sep 17 00:00:00 2001 From: YONGYE Date: Sat, 11 Oct 2025 09:21:00 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=BA=E6=9F=B1=E7=8A=B6=E4=BC=A0=E6=84=9F?= =?UTF-8?q?=E5=99=A8=E5=9B=BE=E6=B7=BB=E5=8A=A0=E7=AD=89=E7=BA=A7=E9=80=89?= =?UTF-8?q?=E6=8B=A9=E5=88=86=E4=B8=BA=E9=AB=98=E4=B8=AD=E4=BD=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MainWindow.xaml | 10 +- MainWindow.xaml.cs | 33 +++++ src/components/SensorChart.xaml | 220 +++++++++-------------------- src/components/SensorChart.xaml.cs | 173 ++++++++++++++++++++++- src/components/SensorLevel.cs | 12 ++ 5 files changed, 285 insertions(+), 163 deletions(-) create mode 100644 src/components/SensorLevel.cs diff --git a/MainWindow.xaml b/MainWindow.xaml index 2cb57de..1ccd66a 100644 --- a/MainWindow.xaml +++ b/MainWindow.xaml @@ -1,4 +1,4 @@ - - - - - + + + + diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs index c0947e7..cc297bd 100644 --- a/MainWindow.xaml.cs +++ b/MainWindow.xaml.cs @@ -3,7 +3,9 @@ using LiveCharts; using LiveCharts.Wpf; using SqlSugar; using System.Windows; +using System.Windows.Controls; using System.Windows.Navigation; +using WpfApp.src.components; using WpfApp.src.view; @@ -407,6 +409,37 @@ namespace WpfApp //LineBarChartDemo lineBarChartDemo = new LineBarChartDemo(); //lineBarChartDemo.Show(); } + + /// + /// 等级选择下拉框变化事件处理 + /// + /// + /// + private void LevelComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (sender is ComboBox comboBox && comboBox.SelectedItem is ComboBoxItem selectedItem) + { + // 根据选择的Tag确定等级 + SensorLevel selectedLevel = SensorLevel.Medium; // 默认值 + switch (selectedItem.Tag?.ToString()) + { + case "Low": + selectedLevel = SensorLevel.Low; + break; + case "Medium": + selectedLevel = SensorLevel.Medium; + break; + case "High": + selectedLevel = SensorLevel.High; + break; + } + + // 更新所有传感器图表的等级 + Sensor1.Level = selectedLevel; + Sensor2.Level = selectedLevel; + Sensor3.Level = selectedLevel; + } + } #endregion } } \ No newline at end of file diff --git a/src/components/SensorChart.xaml b/src/components/SensorChart.xaml index bd07de2..50216a7 100644 --- a/src/components/SensorChart.xaml +++ b/src/components/SensorChart.xaml @@ -3,10 +3,12 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="clr-namespace:WpfApp.src.components" mc:Ignorable="d" d:DesignWidth="200" > + @@ -19,9 +21,33 @@ FontWeight="Bold" Background="{Binding HeaderBackground, RelativeSource={RelativeSource AncestorType=UserControl}}"/> - - + + + + + + + + + + + + + + + + + @@ -32,155 +58,47 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + /// 刻度线数据结构 + /// + public class ScaleLine + { + public double Y1 { get; set; } + public double Y2 { get; set; } + public double X1 { get; set; } + public double X2 { get; set; } + public double StrokeThickness { get; set; } + public string Label { get; set; } + public double LabelX { get; set; } + public double LabelY { get; set; } + public bool IsMainScale { get; set; } + } + /// /// SensorChart.xaml 的交互逻辑 /// @@ -22,6 +38,10 @@ namespace WpfApp.src.components HeaderBackground = new SolidColorBrush(Color.FromRgb(230, 243, 255)); // #E6F3FF Value = 0; RedLineValues = new List(); + Level = SensorLevel.Medium; // 默认中等 + + // 生成初始刻度 + GenerateScaleLines(); } public event PropertyChangedEventHandler PropertyChanged; @@ -101,6 +121,23 @@ namespace WpfApp.src.components control?.UpdateRedLinePositions(); } + // 传感器等级 + public static readonly DependencyProperty LevelProperty = + DependencyProperty.Register("Level", typeof(SensorLevel), typeof(SensorChart), + new PropertyMetadata(SensorLevel.Medium, OnLevelChanged)); + + public SensorLevel Level + { + get { return (SensorLevel)GetValue(LevelProperty); } + set { SetValue(LevelProperty, value); } + } + + private static void OnLevelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var control = d as SensorChart; + control?.OnLevelChanged(); + } + #endregion #region 计算属性 @@ -138,24 +175,140 @@ namespace WpfApp.src.components } } + private List _scaleLines = new List(); + public List ScaleLines + { + get { return _scaleLines; } + private set + { + _scaleLines = value; + OnPropertyChanged(nameof(ScaleLines)); + } + } + + // 当前等级的最小值 + public double MinValue + { + get + { + switch (Level) + { + case SensorLevel.Low: return -20; + case SensorLevel.Medium: return -40; + case SensorLevel.High: return -60; + default: return -40; + } + } + } + + // 当前等级的最大值 + public double MaxValue + { + get + { + switch (Level) + { + case SensorLevel.Low: return 20; + case SensorLevel.Medium: return 40; + case SensorLevel.High: return 60; + default: return 40; + } + } + } + #endregion #region 私有方法 + /// + /// 等级改变时的处理 + /// + private void OnLevelChanged() + { + OnPropertyChanged(nameof(Level)); + OnPropertyChanged(nameof(MinValue)); + OnPropertyChanged(nameof(MaxValue)); + GenerateScaleLines(); + UpdateBarPosition(); + UpdateRedLinePositions(); + } + + /// + /// 生成刻度线 + /// + private void GenerateScaleLines() + { + var lines = new List(); + double minVal = MinValue; + double maxVal = MaxValue; + + // 根据等级确定刻度间隔 + double mainInterval = (maxVal - minVal) / 8; // 8个主刻度间隔 + double subInterval = mainInterval / 4; // 每个主刻度间隔4个小刻度 + + // 生成主刻度线 + for (int i = 0; i <= 8; i++) + { + double value = maxVal - i * mainInterval; + double y = ValueToY(value); + + lines.Add(new ScaleLine + { + X1 = 40, + Y1 = y, + X2 = 130, + Y2 = y, + StrokeThickness = 1, + Label = value.ToString("0"), + LabelX = 135, + LabelY = y - 5, + IsMainScale = true + }); + + // 生成小刻度线(除了最后一个主刻度) + if (i < 8) + { + for (int j = 1; j < 4; j++) + { + double subValue = value - j * subInterval; + double subY = ValueToY(subValue); + + lines.Add(new ScaleLine + { + X1 = 40, + Y1 = subY, + X2 = 125, + Y2 = subY, + StrokeThickness = 0.5, + Label = "", + LabelX = 0, + LabelY = 0, + IsMainScale = false + }); + } + } + } + + ScaleLines = lines; + } + /// /// 将数值转换为Y坐标位置 - /// 刻度范围:40 到 -40,对应Y坐标:20 到 420 + /// 根据当前等级动态计算刻度范围 /// /// 数值 /// Y坐标 private double ValueToY(double value) { - // 限制数值范围 - value = Math.Max(-40, Math.Min(40, value)); + double minVal = MinValue; + double maxVal = MaxValue; - // 线性映射:40对应Y=20,-40对应Y=420 - // Y = 220 - value * 5 - return 220 - value * 5; + // 限制数值范围 + value = Math.Max(minVal, Math.Min(maxVal, value)); + + // 线性映射:maxVal对应Y=20,minVal对应Y=420 + double range = maxVal - minVal; + return 220 - ((value - minVal) / range - 0.5) * 400; } /// @@ -204,7 +357,8 @@ namespace WpfApp.src.components /// 数值 /// 红线数值列表 /// 标题背景色 - public void SetSensorData(string name, double value, List redLines = null, Color? headerColor = null) + /// 传感器等级 + public void SetSensorData(string name, double value, List redLines = null, Color? headerColor = null, SensorLevel? level = null) { SensorName = name; Value = value; @@ -218,6 +372,11 @@ namespace WpfApp.src.components { HeaderBackground = new SolidColorBrush(headerColor.Value); } + + if (level.HasValue) + { + Level = level.Value; + } } /// diff --git a/src/components/SensorLevel.cs b/src/components/SensorLevel.cs new file mode 100644 index 0000000..9028d11 --- /dev/null +++ b/src/components/SensorLevel.cs @@ -0,0 +1,12 @@ +namespace WpfApp.src.components +{ + /// + /// 传感器等级枚举 + /// + public enum SensorLevel + { + Low, // 低等:-20到20 + Medium, // 中等:-40到40 + High // 高等:-60到60 + } +} \ No newline at end of file