diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs index 8b0e00b..60317f5 100644 --- a/MainWindow.xaml.cs +++ b/MainWindow.xaml.cs @@ -93,7 +93,6 @@ public partial class MainWindow : Window // 清空之前图表数据 chartManager.ClearAllCharts(); sensorManager.Start(); - //chartManager.Start(); // 启动图表刷新 BtnSensorControl.Content = "检测确定"; isDetecting = true; } @@ -101,7 +100,6 @@ public partial class MainWindow : Window { // 停止检测 sensorManager.Stop(); - //chartManager.Stop(); // 停止图表刷新 BtnSensorControl.Content = "检测开始"; isDetecting = false; } diff --git a/Services/ChartManager.cs b/Services/ChartManager.cs index 8769a4e..73b8209 100644 --- a/Services/ChartManager.cs +++ b/Services/ChartManager.cs @@ -1,199 +1,195 @@ using guoke; using LiveCharts; using LiveCharts.Wpf; -using System; -using System.Collections.Generic; using System.Windows.Threading; -using WpfApp.src.config; -namespace WpfApp.Services +namespace WpfApp.Services; + +public class ChartManager { - public class ChartManager + private readonly Dispatcher dispatcher; + private readonly LogService log; + private readonly DatabaseService db; + private readonly EventService even; + + private const string SENSOR_DATA_EVENT = "SensorDataUpdate"; + + // 最大保留点数 + private const int MAX_POINTS = 20; + + // 每个图表的数据封装 + private class ChartData { - private readonly Dispatcher dispatcher; - private readonly LogService log; - private readonly DatabaseService db; - private readonly EventService even; + public ColumnSeries ColumnSeries; + public ChartValues StandardMin = new ChartValues(); + public ChartValues StandardAvg = new ChartValues(); + public ChartValues StandardMax = new ChartValues(); + public List Labels = new List(); + } - private const string SENSOR_DATA_EVENT = "SensorDataUpdate"; + // 管理多个图表 + private Dictionary charts = new Dictionary(); - // 最大保留点数 - private const int MAX_POINTS = 20; + public ChartManager(Dispatcher uiDispatcher, + LogService logService, + DatabaseService databaseService, + EventService eventService) + { + dispatcher = uiDispatcher; + log = logService; + db = databaseService; + even = eventService; - // 每个图表的数据封装 - private class ChartData + SubscribeToSensorDataEvents(); + } + + /// + /// 初始化图表(一次性设置标准线和柱状图) + /// + public void InitChart(CartesianChart chart) + { + dispatcher.Invoke(() => { - public ColumnSeries ColumnSeries; - public ChartValues StandardMin = new ChartValues(); - public ChartValues StandardAvg = new ChartValues(); - public ChartValues StandardMax = new ChartValues(); - public List Labels = new List(); - } + if (chart == null) return; - // 管理多个图表 - private Dictionary charts = new Dictionary(); - - public ChartManager(Dispatcher uiDispatcher, - LogService logService, - DatabaseService databaseService, - EventService eventService) - { - dispatcher = uiDispatcher; - log = logService; - db = databaseService; - even = eventService; - - SubscribeToSensorDataEvents(); - } - - /// - /// 初始化图表(一次性设置标准线和柱状图) - /// - public void InitChart(CartesianChart chart) - { - dispatcher.Invoke(() => + // 如果已经初始化过,先清除 + if (charts.ContainsKey(chart)) { - if (chart == null) return; - - // 如果已经初始化过,先清除 - if (charts.ContainsKey(chart)) - { - charts.Remove(chart); - } - - var data = new ChartData(); - data.ColumnSeries = new ColumnSeries - { - Title = "实时值", - Values = new ChartValues() - }; - - var line1 = new LineSeries { Title = "标准下限", Values = data.StandardMin }; - var line2 = new LineSeries { Title = "标准均值", Values = data.StandardAvg }; - var line3 = new LineSeries { Title = "标准上限", Values = data.StandardMax }; - - chart.Series = new SeriesCollection { data.ColumnSeries, line1, line2, line3 }; - - chart.AxisX.Clear(); - chart.AxisY.Clear(); - - chart.AxisX.Add(new Axis - { - Title = "时间", - Labels = data.Labels - }); - - chart.AxisY.Add(new Axis - { - Title = "数值" - }); - - charts[chart] = data; - }); - } - - /// - /// 接收到传感器实时数据(单点更新) - /// - private void OnSensorDataReceived(object sender, GeneralEventArgs e) - { - if (e is SensorDataEventArgs sensorArgs) - { - string chartTitle = sensorArgs.ChartTitle; // 例如 "myChart1" - double value = sensorArgs.SensorValue; - string timeLabel = DateTime.Now.ToString("HH:mm:ss"); - - // 找到对应图表并更新 - foreach (var chart in charts.Keys) - { - if (chart.Name == chartTitle) - { - UpdateChartPoint(chart, timeLabel, value); - break; - } - } + charts.Remove(chart); } - } - - /// - /// 更新单个图表的数据点(柱状图 + 标准线 + X轴标签) - /// - public void UpdateChartPoint(CartesianChart chart, string label, double value) - { - if (chart == null || !charts.TryGetValue(chart, out var data)) - return; - - dispatcher.Invoke(() => + var data = new ChartData(); + data.ColumnSeries = new ColumnSeries { - // 保留四位小数 - double roundedValue = Math.Round(value, 4); - data.ColumnSeries.Values.Add(roundedValue); - // 对标准线固定值,强制 double - data.StandardMin.Add(Math.Round((double)5, 4)); - data.StandardAvg.Add(Math.Round((double)10, 4)); - data.StandardMax.Add(Math.Round((double)30, 4)); - data.Labels.Add(label); + Title = "实时值", + Values = new ChartValues() + }; - // 超过最大点数时,移除最旧的数据 - if (data.ColumnSeries.Values.Count > MAX_POINTS) - { - data.ColumnSeries.Values.RemoveAt(0); - data.StandardMin.RemoveAt(0); - data.StandardAvg.RemoveAt(0); - data.StandardMax.RemoveAt(0); - data.Labels.RemoveAt(0); - } + var line1 = new LineSeries { Title = "标准下限", Values = data.StandardMin }; + var line2 = new LineSeries { Title = "标准均值", Values = data.StandardAvg }; + var line3 = new LineSeries { Title = "标准上限", Values = data.StandardMax }; - // 刷新 X 轴标签 - chart.AxisX[0].Labels = new List(data.Labels); - }); - } + chart.Series = new SeriesCollection { data.ColumnSeries, line1, line2, line3 }; - /// - /// 手动添加数据到指定图表 - /// - public void AddData(CartesianChart chart, double value, string label) - { - UpdateChartPoint(chart, label, value); - } + chart.AxisX.Clear(); + chart.AxisY.Clear(); - /// - /// 手动清除指定图表的数据 - /// - public void ClearChart(CartesianChart chart) - { - if (chart == null || !charts.TryGetValue(chart, out var data)) - return; - - dispatcher.Invoke(() => + chart.AxisX.Add(new Axis { - data.ColumnSeries.Values.Clear(); - data.StandardMin.Clear(); - data.StandardAvg.Clear(); - data.StandardMax.Clear(); - data.Labels.Clear(); - chart.AxisX[0].Labels.Clear(); + Title = "时间", + Labels = data.Labels }); - } - /// - /// 清除所有图表 - /// - public void ClearAllCharts() + chart.AxisY.Add(new Axis + { + Title = "数值" + }); + + charts[chart] = data; + }); + } + + /// + /// 接收到传感器实时数据(单点更新) + /// + private void OnSensorDataReceived(object sender, GeneralEventArgs e) + { + if (e is SensorDataEventArgs sensorArgs) { + string chartTitle = sensorArgs.ChartTitle; // 例如 "myChart1" + double value = sensorArgs.SensorValue; + string timeLabel = DateTime.Now.ToString("HH:mm:ss"); + + // 找到对应图表并更新 foreach (var chart in charts.Keys) { - ClearChart(chart); + if (chart.Name == chartTitle) + { + UpdateChartPoint(chart, timeLabel, value); + break; + } } } + } - /// - /// 订阅传感器数据事件 - /// - private void SubscribeToSensorDataEvents() + + /// + /// 更新单个图表的数据点(柱状图 + 标准线 + X轴标签) + /// + public void UpdateChartPoint(CartesianChart chart, string label, double value) + { + if (chart == null || !charts.TryGetValue(chart, out var data)) + return; + + dispatcher.Invoke(() => { - even?.AddEventHandler(SENSOR_DATA_EVENT, OnSensorDataReceived); + // 保留四位小数 + double roundedValue = Math.Round(value, 4); + data.ColumnSeries.Values.Add(roundedValue); + // 对标准线固定值,强制 double + data.StandardMin.Add(Math.Round((double)5, 4)); + data.StandardAvg.Add(Math.Round((double)10, 4)); + data.StandardMax.Add(Math.Round((double)30, 4)); + data.Labels.Add(label); + + // 超过最大点数时,移除最旧的数据 + if (data.ColumnSeries.Values.Count > MAX_POINTS) + { + data.ColumnSeries.Values.RemoveAt(0); + data.StandardMin.RemoveAt(0); + data.StandardAvg.RemoveAt(0); + data.StandardMax.RemoveAt(0); + data.Labels.RemoveAt(0); + } + + // 刷新 X 轴标签 + chart.AxisX[0].Labels = new List(data.Labels); + }); + } + + /// + /// 手动添加数据到指定图表 + /// + public void AddData(CartesianChart chart, double value, string label) + { + UpdateChartPoint(chart, label, value); + } + + /// + /// 手动清除指定图表的数据 + /// + public void ClearChart(CartesianChart chart) + { + if (chart == null || !charts.TryGetValue(chart, out var data)) + return; + + dispatcher.Invoke(() => + { + data.ColumnSeries.Values.Clear(); + data.StandardMin.Clear(); + data.StandardAvg.Clear(); + data.StandardMax.Clear(); + data.Labels.Clear(); + chart.AxisX[0].Labels.Clear(); + }); + } + + /// + /// 清除所有图表 + /// + public void ClearAllCharts() + { + foreach (var chart in charts.Keys) + { + ClearChart(chart); } } + + /// + /// 订阅传感器数据事件 + /// + private void SubscribeToSensorDataEvents() + { + even?.AddEventHandler(SENSOR_DATA_EVENT, OnSensorDataReceived); + } } diff --git a/Services/SensorChartManager.cs b/Services/SensorChartManager.cs index baa4e0e..8d8c319 100644 --- a/Services/SensorChartManager.cs +++ b/Services/SensorChartManager.cs @@ -2,95 +2,94 @@ using System.Windows; using WpfApp.src.components; -namespace WpfApp.Services +namespace WpfApp.Services; + +/// +/// SensorChart 管理器 - 负责传感器数据采集和更新 +/// +public class SensorChartManager { - /// - /// SensorChart 管理器 - 负责传感器数据采集和更新 - /// - public class SensorChartManager + private readonly Window dispatcherOwner; + private CancellationTokenSource cts; + private readonly Random rand = new Random(); + private readonly LogService log; + private readonly DatabaseService db; + private readonly EventService even; + + // 事件名称常量 + private const string SENSOR_DATA_EVENT = "SensorDataUpdate"; + + + // 绑定的传感器控件 + public SensorChart Sensor1 { get; set; } + public SensorChart Sensor2 { get; set; } + public SensorChart Sensor3 { get; set; } + + public SensorChartManager(Window owner, LogService logService, DatabaseService databaseService, EventService eventService) { - private readonly Window dispatcherOwner; - private CancellationTokenSource cts; - private readonly Random rand = new Random(); - private readonly LogService log; - private readonly DatabaseService db; - private readonly EventService even; + dispatcherOwner = owner; + log = logService; + db = databaseService; + even = eventService; + } - // 事件名称常量 - private const string SENSOR_DATA_EVENT = "SensorDataUpdate"; + /// + /// 启动模拟数据采集 + /// + public void Start() + { + if (Sensor1 == null || Sensor2 == null || Sensor3 == null) + throw new InvalidOperationException("请先绑定传感器控件"); + cts = new CancellationTokenSource(); - // 绑定的传感器控件 - public SensorChart Sensor1 { get; set; } - public SensorChart Sensor2 { get; set; } - public SensorChart Sensor3 { get; set; } - - public SensorChartManager(Window owner, LogService logService, DatabaseService databaseService, EventService eventService) + Task.Run(async () => { - dispatcherOwner = owner; - log = logService; - db = databaseService; - even = eventService; - } - - /// - /// 启动模拟数据采集 - /// - public void Start() - { - if (Sensor1 == null || Sensor2 == null || Sensor3 == null) - throw new InvalidOperationException("请先绑定传感器控件"); - - cts = new CancellationTokenSource(); - - Task.Run(async () => + while (!cts.Token.IsCancellationRequested) { - while (!cts.Token.IsCancellationRequested) + // 模拟数据 + double s1 = rand.NextDouble() * 100 - 50; + double s2 = rand.NextDouble() * 100 - 50; + double s3 = rand.NextDouble() * 100 - 50; + + // 更新 UI + dispatcherOwner.Dispatcher.Invoke(() => { - // 模拟数据 - double s1 = rand.NextDouble() * 100 - 50; - double s2 = rand.NextDouble() * 100 - 50; - double s3 = rand.NextDouble() * 100 - 50; + Sensor1.SetSensorData("传感器1", s1); + Sensor2.SetSensorData("传感器2", s2); + Sensor3.SetSensorData("传感器3", s3); + + // 通过事件将传感器数据传递到ChartManager + PublishSensorData("传感器1", s1, "myChart1"); + PublishSensorData("传感器2", s2, "myChart2"); + PublishSensorData("传感器3", s3, "myChart3"); + }); - // 更新 UI - dispatcherOwner.Dispatcher.Invoke(() => - { - Sensor1.SetSensorData("传感器1", s1); - Sensor2.SetSensorData("传感器2", s2); - Sensor3.SetSensorData("传感器3", s3); - - // 通过事件将传感器数据传递到ChartManager - PublishSensorData("传感器1", s1, "myChart1"); - PublishSensorData("传感器2", s2, "myChart2"); - PublishSensorData("传感器3", s3, "myChart3"); - }); - - await Task.Delay(1000); // 每1000毫秒采集一次 - } - }, cts.Token); - } - - /// - /// 停止采集 - /// - public void Stop() - { - cts?.Cancel(); - } - - /// - /// 发布传感器数据事件 - /// - /// 传感器标题 - /// 传感器值 - /// 图表标题 - private void PublishSensorData(string sensorTitle, double sensorValue, string chartTitle) - { - if (even != null) - { - var eventArgs = new SensorDataEventArgs(sensorTitle, sensorValue, chartTitle); - even.TriggerEvent(SENSOR_DATA_EVENT, this, eventArgs); + await Task.Delay(1000); // 每1000毫秒采集一次 } + }, cts.Token); + } + + /// + /// 停止采集 + /// + public void Stop() + { + cts?.Cancel(); + } + + /// + /// 发布传感器数据事件 + /// + /// 传感器标题 + /// 传感器值 + /// 图表标题 + private void PublishSensorData(string sensorTitle, double sensorValue, string chartTitle) + { + if (even != null) + { + var eventArgs = new SensorDataEventArgs(sensorTitle, sensorValue, chartTitle); + even.TriggerEvent(SENSOR_DATA_EVENT, this, eventArgs); } } } diff --git a/src/public/Excel/Report_2025_10_13.xlsx b/src/public/Excel/Report_2025_10_13.xlsx index b8f9606..edef71e 100644 Binary files a/src/public/Excel/Report_2025_10_13.xlsx and b/src/public/Excel/Report_2025_10_13.xlsx differ