diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs index cc297bd..13a0f25 100644 --- a/MainWindow.xaml.cs +++ b/MainWindow.xaml.cs @@ -4,442 +4,296 @@ using LiveCharts.Wpf; using SqlSugar; using System.Windows; using System.Windows.Controls; +using System.Windows.Media; using System.Windows.Navigation; using WpfApp.src.components; +using WpfApp.src.config; using WpfApp.src.view; +using WpfApp.Utils; -namespace WpfApp +namespace WpfApp; + +/// +/// Interaction logic for MainWindow.xaml +/// +public partial class MainWindow : Window { - /// - /// Interaction logic for MainWindow.xaml - /// - public partial class MainWindow : Window + private readonly LogService log; + private readonly DatabaseService db; + private readonly EventService even; + + public MainWindow(LogService logService, DatabaseService databaseService, EventService eventService) { - private readonly LogService log; - private readonly DatabaseService db; - private readonly EventService even; + InitializeComponent(); - public MainWindow(LogService logService, DatabaseService databaseService, EventService eventService) + log = logService; + db = databaseService; + even = eventService; + + // 记录窗口初始化日志 + log.Info("MainWindow", "主窗口已通过依赖注入初始化"); + log.Info("窗体启动"); + even.AddEventHandler("GeneralEvent", (m, d) => { - InitializeComponent(); + log.Info($"接收到事件:{d.Data}"); + }); + SetWindowTitle("FMSDGAUGE"); - log = logService; - db = databaseService; - even = eventService; + var labels = new[] { "13:27 23", "13:27 45", "13:27 49", "13:27 50", "13:27 55" }; - // 记录窗口初始化日志 - log.Info("MainWindow", "主窗口已通过依赖注入初始化"); - log.Info("窗体启动"); - even.AddEventHandler("GeneralEvent", (m, d) => - { - log.Info($"接收到事件:{d.Data}"); - }); - - #region 曲线测试数据 - SetWindowTitle("FMSDGAUGE"); - - // 传感器1 - // 初始化Series - myChart.Series = new SeriesCollection - { - // 柱状图 - new ColumnSeries - { - Title = "柱状数据", - Values = new ChartValues { 20, 10, 12, 5, 9 } - }, - // 标准1 - new LineSeries - { - Title = "标准1", - Values = new ChartValues { 5, 5, 5, 5, 5 }, - DataLabels = true, - LabelPoint = value => value.Y.ToString("0.##") + " Hz", - StrokeThickness = 2, - Fill = System.Windows.Media.Brushes.Transparent - }, - // 标准2 - new LineSeries - { - Title = "标准2", - Values = new ChartValues { 10, 10, 10, 10, 10 }, - DataLabels = true, - LabelPoint = value => value.Y.ToString("0.##") + " Hz", - //Foreground = System.Windows.Media.Brushes.Blue,// 标签颜色 - //FontSize = 14,// 字体大小 - // StrokeThickness = 2, // 线条粗细 - StrokeThickness = 2, - Stroke = System.Windows.Media.Brushes.Green, - Fill = System.Windows.Media.Brushes.Transparent - }, - // 标准3 - new LineSeries - { - Title = "标准3", - Values = new ChartValues { 30, 30, 30, 30, 30 }, - DataLabels = true, - LabelPoint = value => value.Y.ToString("0.##") + " Hz", - StrokeThickness = 2, - Stroke = System.Windows.Media.Brushes.Red, - Fill = System.Windows.Media.Brushes.Transparent - } - }; - - // 设置X轴标签 - myChart.AxisX.Add(new Axis - { - Title = "", - Labels = new[] { "13:27 23", "13:27 45", "13:27 49", "13:27 50", "13:27 55" } - }); - - // 设置Y轴 - myChart.AxisY.Add(new Axis - { - Title = "" - }); - - // 传感器2 - // 初始化Series - myChart1.Series = new SeriesCollection - { - // 柱状图 - new ColumnSeries - { - Title = "柱状数据", - Values = new ChartValues { 20, 10, 12, 5, 9 } - }, - // 标准1 - new LineSeries - { - Title = "标准1", - Values = new ChartValues { 5, 5, 5, 5, 5 }, - StrokeThickness = 2, - Fill = System.Windows.Media.Brushes.Transparent - }, - // 标准2 - new LineSeries - { - Title = "标准2", - Values = new ChartValues { 10, 10, 10, 10, 10 }, - StrokeThickness = 2, - Stroke = System.Windows.Media.Brushes.Green, - Fill = System.Windows.Media.Brushes.Transparent - }, - // 标准3 - new LineSeries - { - Title = "标准3", - Values = new ChartValues { 30, 30, 30, 30, 30 }, - StrokeThickness = 2, - Stroke = System.Windows.Media.Brushes.Red, - Fill = System.Windows.Media.Brushes.Transparent - } - }; - - // 设置X轴标签 - myChart1.AxisX.Add(new Axis - { - Title = "", - Labels = new[] { "13:27 23", "13:27 45", "13:27 49", "13:27 50", "13:27 55" } - }); - - // 设置Y轴 - myChart1.AxisY.Add(new Axis - { - Title = "" - }); - - // 传感器3 - // 初始化Series - myChart2.Series = new SeriesCollection - { - // 柱状图 - new ColumnSeries - { - Title = "柱状数据", - Values = new ChartValues { 20, 10, 12, 5, 9 } - }, - // 标准1 - new LineSeries - { - Title = "标准1", - Values = new ChartValues { 5, 5, 5, 5, 5 }, - StrokeThickness = 2, - Fill = System.Windows.Media.Brushes.Transparent - }, - // 标准2 - new LineSeries - { - Title = "标准2", - Values = new ChartValues { 10, 10, 10, 10, 10 }, - StrokeThickness = 2, - Stroke = System.Windows.Media.Brushes.Green, - Fill = System.Windows.Media.Brushes.Transparent - }, - // 标准3 - new LineSeries - { - Title = "标准3", - Values = new ChartValues { 30, 30, 30, 30, 30 }, - StrokeThickness = 2, - Stroke = System.Windows.Media.Brushes.Red, - Fill = System.Windows.Media.Brushes.Transparent - } - }; - - // 设置X轴标签 - myChart2.AxisX.Add(new Axis - { - Title = "", - Labels = new[] { "13:27 23", "13:27 45", "13:27 49", "13:27 50", "13:27 55" } - }); - - // 设置Y轴 - myChart2.AxisY.Add(new Axis - { - Title = "" - }); - - #endregion - } - - private void Button_Click(object sender, RoutedEventArgs e) + var config1 = new ChartConfig { - SqlSugarScope scope = db.GetScope("LocalData"); - scope.guokeCheckToCreate();//检查并创建表 - even.TriggerEvent("GeneralEvent", this, new GeneralEventArgs("测试", 1)); - } - public class aaa : BaseTableModel + ColumnData = new List { 20, 10, 12, 5, 9 }, + Labels = new List(labels), + LineConfigs = new List { - + new LineConfig { Title = "标准1", Values = new List { 5,5,5,5,5 }, Stroke = Brushes.Blue }, + new LineConfig { Title = "标准2", Values = new List { 10,10,10,10,10 }, Stroke = Brushes.Green }, + new LineConfig { Title = "标准3", Values = new List { 30,30,30,30,30 }, Stroke = Brushes.Red, Unit = "A" } } - /// - /// 设置窗体标题的函数 - /// - /// - public void SetWindowTitle(string newTitle) - { - this.Title = newTitle; - } - - - - - #region 菜单点击按钮 - // 在 MainWindow 内部 - /// - /// 按钮点击触发文件页面 - /// - /// - /// - private void OnFilePageButtonClick(object sender, RoutedEventArgs e) - { - FilePage filePage = new FilePage(); - NavigationWindow navWin = new NavigationWindow(); - - navWin.Width = 810; - navWin.Height = 600; - navWin.ResizeMode = ResizeMode.NoResize; - navWin.Content = filePage; - navWin.ShowsNavigationUI = false; - navWin.Title = "记录列表"; - - - // ✅ 新增:设定父窗口、样式与居中弹出 - navWin.Owner = Application.Current.MainWindow; // 绑定主窗口 - navWin.WindowStartupLocation = WindowStartupLocation.CenterOwner; // 居中弹出 - navWin.WindowStyle = WindowStyle.ToolWindow; - - // ✅ 改这里:Show() 改为 ShowDialog() 实现模态窗口 - navWin.ShowDialog(); - } - - - /// - /// 按钮点击触发配置页面 - /// - /// - /// - private void OnConfigPageButtonClick(object sender, RoutedEventArgs e) - { - ConfigPage configPage = new ConfigPage(); - NavigationWindow navWin = new NavigationWindow(); - navWin.Content = configPage; - navWin.ShowsNavigationUI = false; - navWin.Width = 972; - navWin.Height = 648; - navWin.Title = "配置"; - navWin.ResizeMode = ResizeMode.NoResize; - - - - // ✅ 新增:设定父窗口、样式与居中弹出 - navWin.Owner = Application.Current.MainWindow; // 绑定主窗口 - navWin.WindowStartupLocation = WindowStartupLocation.CenterOwner; // 居中弹出 - navWin.WindowStyle = WindowStyle.ToolWindow; - - // ✅ 改这里:Show() 改为 ShowDialog() 实现模态窗口 - navWin.ShowDialog(); - } - - /// - /// 按钮点击触发标准基准页面 - /// - /// - /// - private void OnStandardPageButtonClick(object sender, RoutedEventArgs e) - { - StandardPage standardPage = new StandardPage(); - NavigationWindow navWin = new NavigationWindow(); - navWin.Width = 972; - navWin.Height = 648; - //navWin.ResizeMode = ResizeMode.NoResize; - navWin.Content = standardPage; - navWin.ShowsNavigationUI = false; - navWin.Title = "主标定"; - - - // ✅ 新增:设定父窗口、样式与居中弹出 - navWin.Owner = Application.Current.MainWindow; // 绑定主窗口 - navWin.WindowStartupLocation = WindowStartupLocation.CenterOwner; // 居中弹出 - navWin.WindowStyle = WindowStyle.ToolWindow; - - // ✅ 改这里:Show() 改为 ShowDialog() 实现模态窗口 - navWin.ShowDialog(); - } - - /// - /// 按钮点击触发Gauge页面 - /// - /// - /// - private void OnGaugePageButtonClick(object sender, RoutedEventArgs e) - { - GaugePage gaugePage = new GaugePage(); - NavigationWindow navWin = new NavigationWindow(); - navWin.Content = gaugePage; - navWin.ShowsNavigationUI = false; - navWin.Width = 1080; - navWin.Height = 720; - navWin.Title = "Gauge R&&R"; - - // ✅ 新增:设定父窗口、样式与居中弹出 - navWin.Owner = Application.Current.MainWindow; // 绑定主窗口 - navWin.WindowStartupLocation = WindowStartupLocation.CenterOwner; // 居中弹出 - navWin.WindowStyle = WindowStyle.ToolWindow; - - // ✅ 改这里:Show() 改为 ShowDialog() 实现模态窗口 - navWin.ShowDialog(); - } - - - /// - /// 按钮点击触发CgCgk页面 - /// - /// - /// - private void OnCgCgkPageButtonClick(object sender, RoutedEventArgs e) - { - CgCgkPage cgCgkPage = new CgCgkPage(); - NavigationWindow navWin = new NavigationWindow(); - navWin.Content = cgCgkPage; - navWin.ShowsNavigationUI = false; - navWin.Title = "CgCgk"; - - - // ✅ 新增:设定父窗口、样式与居中弹出 - navWin.Owner = Application.Current.MainWindow; // 绑定主窗口 - navWin.WindowStartupLocation = WindowStartupLocation.CenterOwner; // 居中弹出 - navWin.WindowStyle = WindowStyle.ToolWindow; - - // ✅ 改这里:Show() 改为 ShowDialog() 实现模态窗口 - navWin.ShowDialog(); - } - - - /// - /// 按钮点击触发系统设置页面 - /// - /// - /// - private void OnSysSetPageButtonClick(object sender, RoutedEventArgs e) - { - SysSetPage sysSetPage = new SysSetPage(); - NavigationWindow navWin = new NavigationWindow(); - navWin.Width = 810; - navWin.Height = 600; - navWin.ResizeMode = ResizeMode.NoResize; - navWin.Content = sysSetPage; - navWin.ShowsNavigationUI = false; - navWin.Title = "系统设置"; - - - // ✅ 新增:设定父窗口、样式与居中弹出 - navWin.Owner = Application.Current.MainWindow; // 绑定主窗口 - navWin.WindowStartupLocation = WindowStartupLocation.CenterOwner; // 居中弹出 - navWin.WindowStyle = WindowStyle.ToolWindow; - - // ✅ 改这里:Show() 改为 ShowDialog() 实现模态窗口 - navWin.ShowDialog(); - } - - #endregion - - #region 关闭和测试按钮 - /// - /// 按钮点击触发关闭页面 - /// - /// - /// - private void OnCloseMainWindowButtonClick(object sender, RoutedEventArgs e) - { - this.Close(); - - } - - - /// - /// 测试按钮 - /// - /// - /// - private void OnDemoButtonClick(object sender, RoutedEventArgs e) - { - //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 + }; + InitChart.InitCartesianChart(myChart, config1); + InitChart.InitCartesianChart(myChart1, config1); + InitChart.InitCartesianChart(myChart2, config1); + } + + private void Button_Click(object sender, RoutedEventArgs e) + { + SqlSugarScope scope = db.GetScope("LocalData"); + scope.guokeCheckToCreate();//检查并创建表 + even.TriggerEvent("GeneralEvent", this, new GeneralEventArgs("测试", 1)); + } + public class aaa : BaseTableModel + { + + } + /// + /// 设置窗体标题的函数 + /// + /// + public void SetWindowTitle(string newTitle) + { + this.Title = newTitle; + } + + + + + #region 菜单点击按钮 + // 在 MainWindow 内部 + /// + /// 按钮点击触发文件页面 + /// + /// + /// + private void OnFilePageButtonClick(object sender, RoutedEventArgs e) + { + FilePage filePage = new FilePage(); + NavigationWindow navWin = new NavigationWindow(); + + navWin.Width = 810; + navWin.Height = 600; + navWin.ResizeMode = ResizeMode.NoResize; + navWin.Content = filePage; + navWin.ShowsNavigationUI = false; + navWin.Title = "记录列表"; + + + // ✅ 新增:设定父窗口、样式与居中弹出 + navWin.Owner = Application.Current.MainWindow; // 绑定主窗口 + navWin.WindowStartupLocation = WindowStartupLocation.CenterOwner; // 居中弹出 + navWin.WindowStyle = WindowStyle.ToolWindow; + + // ✅ 改这里:Show() 改为 ShowDialog() 实现模态窗口 + navWin.ShowDialog(); + } + + + /// + /// 按钮点击触发配置页面 + /// + /// + /// + private void OnConfigPageButtonClick(object sender, RoutedEventArgs e) + { + ConfigPage configPage = new ConfigPage(); + NavigationWindow navWin = new NavigationWindow(); + navWin.Content = configPage; + navWin.ShowsNavigationUI = false; + navWin.Width = 972; + navWin.Height = 648; + navWin.Title = "配置"; + navWin.ResizeMode = ResizeMode.NoResize; + + + + // ✅ 新增:设定父窗口、样式与居中弹出 + navWin.Owner = Application.Current.MainWindow; // 绑定主窗口 + navWin.WindowStartupLocation = WindowStartupLocation.CenterOwner; // 居中弹出 + navWin.WindowStyle = WindowStyle.ToolWindow; + + // ✅ 改这里:Show() 改为 ShowDialog() 实现模态窗口 + navWin.ShowDialog(); + } + + /// + /// 按钮点击触发标准基准页面 + /// + /// + /// + private void OnStandardPageButtonClick(object sender, RoutedEventArgs e) + { + StandardPage standardPage = new StandardPage(); + NavigationWindow navWin = new NavigationWindow(); + navWin.Width = 972; + navWin.Height = 648; + //navWin.ResizeMode = ResizeMode.NoResize; + navWin.Content = standardPage; + navWin.ShowsNavigationUI = false; + navWin.Title = "主标定"; + + + // ✅ 新增:设定父窗口、样式与居中弹出 + navWin.Owner = Application.Current.MainWindow; // 绑定主窗口 + navWin.WindowStartupLocation = WindowStartupLocation.CenterOwner; // 居中弹出 + navWin.WindowStyle = WindowStyle.ToolWindow; + + // ✅ 改这里:Show() 改为 ShowDialog() 实现模态窗口 + navWin.ShowDialog(); + } + + /// + /// 按钮点击触发Gauge页面 + /// + /// + /// + private void OnGaugePageButtonClick(object sender, RoutedEventArgs e) + { + GaugePage gaugePage = new GaugePage(); + NavigationWindow navWin = new NavigationWindow(); + navWin.Content = gaugePage; + navWin.ShowsNavigationUI = false; + navWin.Width = 1080; + navWin.Height = 720; + navWin.Title = "Gauge R&&R"; + + // ✅ 新增:设定父窗口、样式与居中弹出 + navWin.Owner = Application.Current.MainWindow; // 绑定主窗口 + navWin.WindowStartupLocation = WindowStartupLocation.CenterOwner; // 居中弹出 + navWin.WindowStyle = WindowStyle.ToolWindow; + + // ✅ 改这里:Show() 改为 ShowDialog() 实现模态窗口 + navWin.ShowDialog(); + } + + + /// + /// 按钮点击触发CgCgk页面 + /// + /// + /// + private void OnCgCgkPageButtonClick(object sender, RoutedEventArgs e) + { + CgCgkPage cgCgkPage = new CgCgkPage(); + NavigationWindow navWin = new NavigationWindow(); + navWin.Content = cgCgkPage; + navWin.ShowsNavigationUI = false; + navWin.Title = "CgCgk"; + + + // ✅ 新增:设定父窗口、样式与居中弹出 + navWin.Owner = Application.Current.MainWindow; // 绑定主窗口 + navWin.WindowStartupLocation = WindowStartupLocation.CenterOwner; // 居中弹出 + navWin.WindowStyle = WindowStyle.ToolWindow; + + // ✅ 改这里:Show() 改为 ShowDialog() 实现模态窗口 + navWin.ShowDialog(); + } + + + /// + /// 按钮点击触发系统设置页面 + /// + /// + /// + private void OnSysSetPageButtonClick(object sender, RoutedEventArgs e) + { + SysSetPage sysSetPage = new SysSetPage(); + NavigationWindow navWin = new NavigationWindow(); + navWin.Width = 810; + navWin.Height = 600; + navWin.ResizeMode = ResizeMode.NoResize; + navWin.Content = sysSetPage; + navWin.ShowsNavigationUI = false; + navWin.Title = "系统设置"; + + + // ✅ 新增:设定父窗口、样式与居中弹出 + navWin.Owner = Application.Current.MainWindow; // 绑定主窗口 + navWin.WindowStartupLocation = WindowStartupLocation.CenterOwner; // 居中弹出 + navWin.WindowStyle = WindowStyle.ToolWindow; + + // ✅ 改这里:Show() 改为 ShowDialog() 实现模态窗口 + navWin.ShowDialog(); + } + + #endregion + + #region 关闭和测试按钮 + /// + /// 按钮点击触发关闭页面 + /// + /// + /// + private void OnCloseMainWindowButtonClick(object sender, RoutedEventArgs e) + { + this.Close(); + + } + + + /// + /// 测试按钮 + /// + /// + /// + private void OnDemoButtonClick(object sender, RoutedEventArgs e) + { + //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/Utils/InitChart.cs b/Utils/InitChart.cs new file mode 100644 index 0000000..5cc0d12 --- /dev/null +++ b/Utils/InitChart.cs @@ -0,0 +1,58 @@ +using LiveCharts; +using LiveCharts.Wpf; +using System.Windows.Media; +using WpfApp.src.config; + +namespace WpfApp.Utils; + +public static class InitChart +{ + public static void InitCartesianChart(CartesianChart chart, ChartConfig config) + { + chart.Series = new SeriesCollection(); + + // 柱状图 + if (config.ColumnData != null && config.ColumnData.Count > 0) + { + chart.Series.Add(new ColumnSeries + { + Title = "柱状数据", + Values = new ChartValues(config.ColumnData) + }); + } + + // 标准线条 + foreach (var line in config.LineConfigs) + { + var lineSeries = new LineSeries + { + Title = line.Title, + Values = new ChartValues(line.Values), + Stroke = line.Stroke ?? Brushes.Black, + StrokeThickness = 2, + Fill = Brushes.Transparent, + DataLabels = line.ShowLabel, + }; + + if (line.ShowLabel) + lineSeries.LabelPoint = value => $"{value.Y:0.##} {line.Unit}"; + + chart.Series.Add(lineSeries); + } + + // X轴 + chart.AxisX.Clear(); + chart.AxisX.Add(new Axis + { + Title = config.XTitle ?? "", + Labels = config.Labels + }); + + // Y轴 + chart.AxisY.Clear(); + chart.AxisY.Add(new Axis + { + Title = config.YTitle ?? "" + }); + } +} diff --git a/src/components/SensorChart.xaml.cs b/src/components/SensorChart.xaml.cs index 955e878..e579c6c 100644 --- a/src/components/SensorChart.xaml.cs +++ b/src/components/SensorChart.xaml.cs @@ -1,402 +1,409 @@ -using System; -using System.Collections.Generic; using System.ComponentModel; using System.Windows; using System.Windows.Controls; using System.Windows.Media; -namespace WpfApp.src.components +namespace WpfApp.src.components; + +/// +/// 刻度线数据结构 +/// +public class ScaleLine { - /// - /// 刻度线数据结构 - /// - 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 的交互逻辑 +/// +public partial class SensorChart : UserControl, INotifyPropertyChanged +{ + public SensorChart() { - 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; } + InitializeComponent(); + DataContext = this; + + // 设置默认值 + SensorName = "传感器"; + HeaderBackground = new SolidColorBrush(Color.FromRgb(230, 243, 255)); // #E6F3FF + Value = 0; + RedLineValues = new List(); + Level = SensorLevel.Medium; // 默认中等 + + // 生成初始刻度 + GenerateScaleLines(); + } + + public event PropertyChangedEventHandler PropertyChanged; + + protected virtual void OnPropertyChanged(string propertyName) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + #region 依赖属性 + + // 传感器名称 + public static readonly DependencyProperty SensorNameProperty = + DependencyProperty.Register("SensorName", typeof(string), typeof(SensorChart), + new PropertyMetadata("传感器", OnSensorNameChanged)); + + public string SensorName + { + get { return (string)GetValue(SensorNameProperty); } + set { SetValue(SensorNameProperty, value); } + } + + private static void OnSensorNameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var control = d as SensorChart; + control?.OnPropertyChanged(nameof(SensorName)); + } + + // 标题背景色 + public static readonly DependencyProperty HeaderBackgroundProperty = + DependencyProperty.Register("HeaderBackground", typeof(Brush), typeof(SensorChart), + new PropertyMetadata(new SolidColorBrush(Color.FromRgb(230, 243, 255)), OnHeaderBackgroundChanged)); + + public Brush HeaderBackground + { + get { return (Brush)GetValue(HeaderBackgroundProperty); } + set { SetValue(HeaderBackgroundProperty, value); } + } + + private static void OnHeaderBackgroundChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var control = d as SensorChart; + control?.OnPropertyChanged(nameof(HeaderBackground)); + } + + // 数值 + public static readonly DependencyProperty ValueProperty = + DependencyProperty.Register("Value", typeof(double), typeof(SensorChart), + new PropertyMetadata(0.0, OnValueChanged)); + + public double Value + { + get { return (double)GetValue(ValueProperty); } + set { SetValue(ValueProperty, value); } + } + + private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var control = d as SensorChart; + control?.UpdateBarPosition(); + } + + // 红线数值列表 + public static readonly DependencyProperty RedLineValuesProperty = + DependencyProperty.Register("RedLineValues", typeof(List), typeof(SensorChart), + new PropertyMetadata(new List(), OnRedLineValuesChanged)); + + public List RedLineValues + { + get { return (List)GetValue(RedLineValuesProperty); } + set { SetValue(RedLineValuesProperty, value); } + } + + private static void OnRedLineValuesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var control = d as SensorChart; + 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 计算属性 + + private double _barTop; + public double BarTop + { + get { return _barTop; } + private set + { + _barTop = value; + OnPropertyChanged(nameof(BarTop)); + } + } + + private double _barHeight; + public double BarHeight + { + get { return _barHeight; } + private set + { + _barHeight = value; + OnPropertyChanged(nameof(BarHeight)); + } + } + + private List _redLinePositions = new List(); + public List RedLinePositions + { + get { return _redLinePositions; } + private set + { + _redLinePositions = value; + OnPropertyChanged(nameof(RedLinePositions)); + } + } + + 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(); } /// - /// SensorChart.xaml 的交互逻辑 + /// 生成刻度线 /// - public partial class SensorChart : UserControl, INotifyPropertyChanged + private void GenerateScaleLines() { - public SensorChart() + 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++) { - InitializeComponent(); - DataContext = this; + double value = maxVal - i * mainInterval; + double y = ValueToY(value); - // 设置默认值 - SensorName = "传感器"; - HeaderBackground = new SolidColorBrush(Color.FromRgb(230, 243, 255)); // #E6F3FF - Value = 0; - RedLineValues = new List(); - Level = SensorLevel.Medium; // 默认中等 + 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 + }); - // 生成初始刻度 - GenerateScaleLines(); - } - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void OnPropertyChanged(string propertyName) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - #region 依赖属性 - - // 传感器名称 - public static readonly DependencyProperty SensorNameProperty = - DependencyProperty.Register("SensorName", typeof(string), typeof(SensorChart), - new PropertyMetadata("传感器", OnSensorNameChanged)); - - public string SensorName - { - get { return (string)GetValue(SensorNameProperty); } - set { SetValue(SensorNameProperty, value); } - } - - private static void OnSensorNameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - var control = d as SensorChart; - control?.OnPropertyChanged(nameof(SensorName)); - } - - // 标题背景色 - public static readonly DependencyProperty HeaderBackgroundProperty = - DependencyProperty.Register("HeaderBackground", typeof(Brush), typeof(SensorChart), - new PropertyMetadata(new SolidColorBrush(Color.FromRgb(230, 243, 255)), OnHeaderBackgroundChanged)); - - public Brush HeaderBackground - { - get { return (Brush)GetValue(HeaderBackgroundProperty); } - set { SetValue(HeaderBackgroundProperty, value); } - } - - private static void OnHeaderBackgroundChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - var control = d as SensorChart; - control?.OnPropertyChanged(nameof(HeaderBackground)); - } - - // 数值 - public static readonly DependencyProperty ValueProperty = - DependencyProperty.Register("Value", typeof(double), typeof(SensorChart), - new PropertyMetadata(0.0, OnValueChanged)); - - public double Value - { - get { return (double)GetValue(ValueProperty); } - set { SetValue(ValueProperty, value); } - } - - private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - var control = d as SensorChart; - control?.UpdateBarPosition(); - } - - // 红线数值列表 - public static readonly DependencyProperty RedLineValuesProperty = - DependencyProperty.Register("RedLineValues", typeof(List), typeof(SensorChart), - new PropertyMetadata(new List(), OnRedLineValuesChanged)); - - public List RedLineValues - { - get { return (List)GetValue(RedLineValuesProperty); } - set { SetValue(RedLineValuesProperty, value); } - } - - private static void OnRedLineValuesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - var control = d as SensorChart; - 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 计算属性 - - private double _barTop; - public double BarTop - { - get { return _barTop; } - private set + // 生成小刻度线(除了最后一个主刻度) + if (i < 8) { - _barTop = value; - OnPropertyChanged(nameof(BarTop)); - } - } - - private double _barHeight; - public double BarHeight - { - get { return _barHeight; } - private set - { - _barHeight = value; - OnPropertyChanged(nameof(BarHeight)); - } - } - - private List _redLinePositions = new List(); - public List RedLinePositions - { - get { return _redLinePositions; } - private set - { - _redLinePositions = value; - OnPropertyChanged(nameof(RedLinePositions)); - } - } - - private List _scaleLines = new List(); - public List ScaleLines - { - get { return _scaleLines; } - private set - { - _scaleLines = value; - OnPropertyChanged(nameof(ScaleLines)); - } - } - - // 当前等级的最小值 - public double MinValue - { - get - { - switch (Level) + for (int j = 1; j < 4; j++) { - 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 { - 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 - }); - } + X1 = 40, + Y1 = subY, + X2 = 125, + Y2 = subY, + StrokeThickness = 0.5, + Label = "", + LabelX = 0, + LabelY = 0, + IsMainScale = false + }); } } - - ScaleLines = lines; } - - /// - /// 将数值转换为Y坐标位置 - /// 根据当前等级动态计算刻度范围 - /// - /// 数值 - /// Y坐标 - private double ValueToY(double value) - { - double minVal = MinValue; - double maxVal = MaxValue; - - // 限制数值范围 - 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; - } - - /// - /// 更新柱状图位置 - /// - private void UpdateBarPosition() - { - if (Value >= 0) - { - // 正值:从0线向上 - BarTop = ValueToY(Value); - BarHeight = ValueToY(0) - ValueToY(Value); - } - else - { - // 负值:从0线向下 - BarTop = ValueToY(0); - BarHeight = ValueToY(Value) - ValueToY(0); - } - } - - /// - /// 更新红线位置 - /// - private void UpdateRedLinePositions() - { - var positions = new List(); - if (RedLineValues != null) - { - foreach (var value in RedLineValues) - { - positions.Add(ValueToY(value)); - } - } - RedLinePositions = positions; - } - - #endregion - - #region 公共方法 - - /// - /// 设置传感器数据 - /// - /// 传感器名称 - /// 数值 - /// 红线数值列表 - /// 标题背景色 - /// 传感器等级 - public void SetSensorData(string name, double value, List redLines = null, Color? headerColor = null, SensorLevel? level = null) - { - SensorName = name; - Value = value; - - if (redLines != null) - { - RedLineValues = new List(redLines); - } - - if (headerColor.HasValue) - { - HeaderBackground = new SolidColorBrush(headerColor.Value); - } - - if (level.HasValue) - { - Level = level.Value; - } - } - - /// - /// 添加红线 - /// - /// 红线数值 - public void AddRedLine(double value) - { - var lines = new List(RedLineValues) { value }; - RedLineValues = lines; - } - - /// - /// 清除所有红线 - /// - public void ClearRedLines() - { - RedLineValues = new List(); - } - - #endregion + + ScaleLines = lines; } + + /// + /// 将数值转换为Y坐标位置 + /// 根据当前等级动态计算刻度范围 + /// + /// 数值 + /// Y坐标 + private double ValueToY(double value) + { + double minVal = MinValue; + double maxVal = MaxValue; + + // 限制数值范围 + 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; + } + + /// + /// 更新柱状图位置 + /// + private void UpdateBarPosition() + { + if (Value >= 0) + { + // 正值:从0线向上 + BarTop = ValueToY(Value); + BarHeight = ValueToY(0) - ValueToY(Value); + } + else + { + // 负值:从0线向下 + BarTop = ValueToY(0); + BarHeight = ValueToY(Value) - ValueToY(0); + } + } + + /// + /// 更新红线位置 + /// + private void UpdateRedLinePositions() + { + var positions = new List(); + if (RedLineValues != null) + { + foreach (var value in RedLineValues) + { + positions.Add(ValueToY(value)); + } + } + RedLinePositions = positions; + } + + #endregion + + #region 公共方法 + + /// + /// 设置传感器数据 + /// + /// 传感器名称 + /// 数值 + /// 红线数值列表 + /// 标题背景色 + /// 传感器等级 + public void SetSensorData(string name, double value, List redLines = null, Color? headerColor = null, SensorLevel? level = null) + { + SensorName = name; + Value = value; + + if (redLines != null) + { + RedLineValues = new List(redLines); + } + + if (headerColor.HasValue) + { + HeaderBackground = new SolidColorBrush(headerColor.Value); + } + + if (level.HasValue) + { + Level = level.Value; + } + } + + /// + /// 添加红线 + /// + /// 红线数值 + public void AddRedLine(double value) + { + var lines = new List(RedLineValues) { value }; + RedLineValues = lines; + } + + /// + /// 清除所有红线 + /// + public void ClearRedLines() + { + RedLineValues = new List(); + } + + #endregion +} + +/// +/// 传感器等级枚举 +/// +public enum SensorLevel +{ + Low, // 低等:-20到20 + Medium, // 中等:-40到40 + High // 高等:-60到60 } \ No newline at end of file diff --git a/src/components/SensorLevel.cs b/src/components/SensorLevel.cs deleted file mode 100644 index 9028d11..0000000 --- a/src/components/SensorLevel.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace WpfApp.src.components -{ - /// - /// 传感器等级枚举 - /// - public enum SensorLevel - { - Low, // 低等:-20到20 - Medium, // 中等:-40到40 - High // 高等:-60到60 - } -} \ No newline at end of file diff --git a/src/config/ChartConfig.cs b/src/config/ChartConfig.cs new file mode 100644 index 0000000..46ff05c --- /dev/null +++ b/src/config/ChartConfig.cs @@ -0,0 +1,36 @@ +using System.Windows.Media; + +namespace WpfApp.src.config; + +public class ChartConfig +{ + public List ColumnData { get; set; } = new(); + public List LineConfigs { get; set; } = new(); + public List Labels { get; set; } = new(); + public string XTitle { get; set; } + public string YTitle { get; set; } +} + +public class LineConfig +{ + /// + /// 曲线标题 + /// + public string Title { get; set; } + /// + /// 曲线的值 + /// + public List Values { get; set; } + /// + /// 曲线颜色 + /// + public Brush Stroke { get; set; } = Brushes.Black; + /// + /// 是否显示数据点上的标签 + /// + public bool ShowLabel { get; set; } = true; + /// + /// 单位 + /// + public string Unit { get; set; } = "Hz"; +}