341 lines
11 KiB
C#
341 lines
11 KiB
C#
using DevExpress.ClipboardSource.SpreadsheetML;
|
||
using DevExpress.Xpf.Charts;
|
||
using DevExpress.Xpf.Core;
|
||
using NModbus;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Net.Sockets;
|
||
using System.Text;
|
||
using System.Windows;
|
||
using System.Windows.Controls;
|
||
using System.Windows.Data;
|
||
using System.Windows.Documents;
|
||
using System.Windows.Input;
|
||
using System.Windows.Media;
|
||
using System.Windows.Media.Imaging;
|
||
using System.Windows.Shapes;
|
||
using 建材不燃性试验炉.Data; // 这是关键
|
||
|
||
|
||
namespace jiancaiburanxing
|
||
{
|
||
/// <summary>
|
||
/// Interaction logic for TemperatureChartWindow.xaml
|
||
/// </summary>
|
||
public partial class TemperatureChartWindow : ThemedWindow
|
||
{
|
||
|
||
|
||
// 存储温度数据
|
||
private List<Tuple<double, double>> temperatureData = new List<Tuple<double, double>>();
|
||
|
||
public TemperatureChartWindow()
|
||
{
|
||
InitializeComponent();
|
||
Loaded += TemperatureChartWindow_Loaded;
|
||
}
|
||
|
||
private void TemperatureChartWindow_Loaded(object sender, RoutedEventArgs e)
|
||
{
|
||
try
|
||
{
|
||
InitializeChart();
|
||
GenerateSampleData();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show($"初始化图表时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||
}
|
||
}
|
||
|
||
private void InitializeChart()
|
||
{
|
||
try
|
||
{
|
||
// 初始化图表配置
|
||
if (temperatureChart.Diagram is XYDiagram2D diagram)
|
||
{
|
||
// 设置X轴
|
||
if (diagram.AxisX is AxisX2D axisX)
|
||
{
|
||
// 设置标题
|
||
if (axisX.Title == null)
|
||
{
|
||
axisX.Title = new AxisTitle();
|
||
}
|
||
axisX.Title.Content = "时间 (分钟)";
|
||
|
||
// 设置范围
|
||
axisX.WholeRange = new DevExpress.Xpf.Charts.Range
|
||
{
|
||
MinValue = 0,
|
||
MaxValue = 60
|
||
};
|
||
|
||
// 设置网格线
|
||
axisX.GridLinesVisible = true;
|
||
axisX.GridLinesMinorVisible = false;
|
||
}
|
||
|
||
// 设置Y轴
|
||
if (diagram.AxisY is AxisY2D axisY)
|
||
{
|
||
// 设置标题
|
||
if (axisY.Title == null)
|
||
{
|
||
axisY.Title = new AxisTitle();
|
||
}
|
||
axisY.Title.Content = "温度 (°C)";
|
||
|
||
// 设置范围
|
||
axisY.WholeRange = new DevExpress.Xpf.Charts.Range
|
||
{
|
||
MinValue = 0,
|
||
MaxValue = 800
|
||
};
|
||
|
||
// 设置网格线
|
||
axisY.GridLinesVisible = true;
|
||
axisY.GridLinesMinorVisible = false;
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show($"配置图表时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||
}
|
||
}
|
||
|
||
private void GenerateSampleData()
|
||
{
|
||
try
|
||
{
|
||
// 清空现有数据
|
||
temperatureData.Clear();
|
||
|
||
// 必须重新创建Points集合,因为不能直接赋值给只读属性
|
||
// 先清除现有数据点
|
||
ClearSeriesPoints(temperatureSeries);
|
||
ClearSeriesPoints(targetSeries);
|
||
|
||
// 生成模拟温度数据 - 典型的升温曲线
|
||
// 0-6分钟:快速升温到750°C
|
||
// 6-10分钟:保持750°C
|
||
|
||
// 温度曲线数据
|
||
AddDataPoint(temperatureSeries, 0, 25); // 起始温度
|
||
AddDataPoint(temperatureSeries, 1, 200); // 快速升温
|
||
AddDataPoint(temperatureSeries, 2, 400);
|
||
AddDataPoint(temperatureSeries, 3, 600);
|
||
AddDataPoint(temperatureSeries, 4, 720); // 接近目标
|
||
AddDataPoint(temperatureSeries, 5, 750); // 达到目标
|
||
AddDataPoint(temperatureSeries, 6, 750); // 保持
|
||
AddDataPoint(temperatureSeries, 7, 750);
|
||
AddDataPoint(temperatureSeries, 8, 750);
|
||
AddDataPoint(temperatureSeries, 9, 750);
|
||
AddDataPoint(temperatureSeries, 10, 750); // 保持
|
||
|
||
// 将数据也保存到List中用于统计计算
|
||
for (int i = 0; i <= 10; i++)
|
||
{
|
||
double temp;
|
||
if (i <= 5)
|
||
temp = 25 + (725 * i / 5.0);
|
||
else
|
||
temp = 750;
|
||
|
||
temperatureData.Add(new Tuple<double, double>(i, temp));
|
||
}
|
||
|
||
// 设置温度曲线样式
|
||
if (temperatureSeries != null)
|
||
{
|
||
temperatureSeries.Brush = new SolidColorBrush(Color.FromRgb(52, 152, 219)); // 蓝色
|
||
if (temperatureSeries.LineStyle != null)
|
||
{
|
||
temperatureSeries.LineStyle.Thickness = 2;
|
||
}
|
||
}
|
||
|
||
// 目标温度线数据 (750°C水平线)
|
||
AddDataPoint(targetSeries, 0, 750);
|
||
AddDataPoint(targetSeries, 10, 750);
|
||
|
||
// 设置目标温度线样式
|
||
if (targetSeries != null)
|
||
{
|
||
targetSeries.Brush = new SolidColorBrush(Color.FromRgb(231, 76, 60)); // 红色
|
||
if (targetSeries.LineStyle != null)
|
||
{
|
||
targetSeries.LineStyle.Thickness = 2;
|
||
targetSeries.LineStyle.DashStyle = new DashStyle(new double[] { 4, 2 }, 0);
|
||
}
|
||
}
|
||
|
||
// 更新统计信息
|
||
UpdateStatistics();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show($"生成数据时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||
}
|
||
}
|
||
|
||
private void ClearSeriesPoints(LineSeries2D series)
|
||
{
|
||
try
|
||
{
|
||
if (series != null && series.Points != null)
|
||
{
|
||
// Points是只读的,但我们可以清除其中的数据
|
||
series.Points.Clear();
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show($"清除数据点时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||
}
|
||
}
|
||
|
||
private void AddDataPoint(LineSeries2D series, double time, double temperature)
|
||
{
|
||
try
|
||
{
|
||
if (series == null) return;
|
||
|
||
// 确保Points集合存在
|
||
if (series.Points == null)
|
||
{
|
||
// 不能直接设置Points,但可以在XAML中初始化
|
||
// 这里我们假设Points已经在XAML中初始化
|
||
return;
|
||
}
|
||
|
||
// 直接添加数据点到现有的Points集合
|
||
series.Points.Add(new SeriesPoint(time, temperature));
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show($"添加数据点时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||
}
|
||
}
|
||
|
||
private void UpdateStatistics()
|
||
{
|
||
try
|
||
{
|
||
if (temperatureData == null || temperatureData.Count == 0)
|
||
{
|
||
txtMaxTemp.Text = "0°C";
|
||
txtAvgTemp.Text = "0°C";
|
||
txtDataPoints.Text = "0";
|
||
return;
|
||
}
|
||
|
||
double maxTemp = 0;
|
||
double sumTemp = 0;
|
||
int validPoints = 0;
|
||
|
||
foreach (var point in temperatureData)
|
||
{
|
||
try
|
||
{
|
||
double temp = point.Item2;
|
||
if (temp > maxTemp) maxTemp = temp;
|
||
sumTemp += temp;
|
||
validPoints++;
|
||
}
|
||
catch
|
||
{
|
||
// 忽略错误的数据点
|
||
}
|
||
}
|
||
|
||
if (validPoints > 0)
|
||
{
|
||
double avgTemp = sumTemp / validPoints;
|
||
|
||
txtMaxTemp.Text = $"{maxTemp:F1}°C";
|
||
txtAvgTemp.Text = $"{avgTemp:F1}°C";
|
||
txtDataPoints.Text = validPoints.ToString();
|
||
}
|
||
else
|
||
{
|
||
txtMaxTemp.Text = "0°C";
|
||
txtAvgTemp.Text = "0°C";
|
||
txtDataPoints.Text = "0";
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show($"更新统计信息时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||
}
|
||
}
|
||
|
||
private void btnGenerateData_Click(object sender, RoutedEventArgs e)
|
||
{
|
||
try
|
||
{
|
||
GenerateSampleData();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show($"重新生成数据时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||
}
|
||
}
|
||
|
||
private void btnClearData_Click(object sender, RoutedEventArgs e)
|
||
{
|
||
try
|
||
{
|
||
// 清空数据
|
||
temperatureData.Clear();
|
||
ClearSeriesPoints(temperatureSeries);
|
||
ClearSeriesPoints(targetSeries);
|
||
|
||
// 重置统计信息
|
||
txtMaxTemp.Text = "0°C";
|
||
txtAvgTemp.Text = "0°C";
|
||
txtDataPoints.Text = "0";
|
||
|
||
MessageBox.Show("数据已清空", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show($"清空数据时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||
}
|
||
}
|
||
|
||
private void btnClose_Click(object sender, RoutedEventArgs e)
|
||
{
|
||
try
|
||
{
|
||
this.Close();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show($"关闭窗口时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||
}
|
||
}
|
||
|
||
// 窗口关闭时清理资源
|
||
protected override void OnClosed(EventArgs e)
|
||
{
|
||
try
|
||
{
|
||
temperatureData.Clear();
|
||
|
||
// 不再尝试清空Points,因为可能会出错
|
||
}
|
||
catch
|
||
{
|
||
// 忽略清理时的错误
|
||
}
|
||
|
||
base.OnClosed(e);
|
||
}
|
||
}
|
||
|
||
}
|