Files
FullAutoWaterCheck/全自动水压检测仪/ChartManager.cs

275 lines
9.3 KiB
C#
Raw Normal View History

2026-02-04 17:01:05 +08:00
using OxyPlot;
using OxyPlot.Axes;
using OxyPlot.Series;
using OxyPlot.WindowsForms;
2026-02-03 17:47:32 +08:00
using System;
2026-02-04 17:01:05 +08:00
using System.Collections.Generic;
2026-02-03 17:47:32 +08:00
using System.Drawing;
2026-02-04 17:18:47 +08:00
using System.Linq;
2026-02-03 17:47:32 +08:00
using System.Windows.Forms;
namespace
{
/// <summary>
/// 图表管理器 - 负责实时曲线图的创建和数据更新
2026-02-04 15:38:42 +08:00
/// 第一Y轴实时压力地址3130
/// 第二Y轴压力设定值地址2400对应"压力设置(PSI)"
2026-02-03 17:47:32 +08:00
/// </summary>
public class ChartManager
{
2026-02-04 17:01:05 +08:00
private PlotView _plotView;
private PlotModel _plotModel;
private LineSeries _pressureSeries; // 实时压力值地址3130
private LineSeries _pressureSetSeries; // 压力设定值地址2400
private List<DataPoint> _pressureData;
private List<DataPoint> _pressureSetData;
2026-02-03 17:47:32 +08:00
private const int MAX_DATA_POINTS = 60; // 最多显示60个数据点
/// <summary>
/// 初始化图表并添加到指定面板
/// </summary>
public void InitializeChart(Control targetPanel)
{
2026-02-04 17:19:49 +08:00
targetPanel.Invoke(new Action(() =>
{
if (targetPanel == null)
throw new ArgumentNullException(nameof(targetPanel));
2026-02-03 17:47:32 +08:00
2026-02-04 17:19:49 +08:00
// 清除占位文字
targetPanel.Text = null;
2026-02-03 17:47:32 +08:00
// 初始化数据集合
2026-02-04 17:01:05 +08:00
_pressureData = new List<DataPoint>();
_pressureSetData = new List<DataPoint>();
2026-02-04 17:19:49 +08:00
2026-02-04 17:01:05 +08:00
// 创建PlotModel
_plotModel = new PlotModel
2026-02-03 17:47:32 +08:00
{
2026-02-04 17:01:05 +08:00
Title = "",
Background = OxyColors.White,
PlotAreaBorderColor = OxyColors.Gray
2026-02-03 17:47:32 +08:00
};
2026-02-04 17:01:05 +08:00
// 配置图例
_plotModel.Legends.Add(new OxyPlot.Legends.Legend
{
LegendPosition = OxyPlot.Legends.LegendPosition.TopCenter,
LegendOrientation = OxyPlot.Legends.LegendOrientation.Horizontal
});
2026-02-04 17:19:49 +08:00
2026-02-04 17:18:47 +08:00
// 配置X轴时间轴 - 使用测试时间总秒数)
2026-02-04 17:01:05 +08:00
var xAxis = new LinearAxis
2026-02-03 17:47:32 +08:00
{
2026-02-04 17:01:05 +08:00
Position = AxisPosition.Bottom,
2026-02-04 17:18:47 +08:00
Title = "测试时间",
2026-02-04 17:01:05 +08:00
TitleFontSize = 12,
FontSize = 10,
MajorGridlineStyle = LineStyle.Solid,
MajorGridlineColor = OxyColor.FromRgb(230, 230, 230),
MinorGridlineStyle = LineStyle.Dot,
MinorGridlineColor = OxyColor.FromRgb(240, 240, 240),
Minimum = 0,
2026-02-04 17:18:47 +08:00
Maximum = 60,
// 格式化X轴标签为HH:MM:SS格式
LabelFormatter = value =>
2026-02-03 17:47:32 +08:00
{
2026-02-04 17:18:47 +08:00
int totalSec = (int)value;
int h = totalSec / 3600;
int m = (totalSec % 3600) / 60;
int s = totalSec % 60;
return $"{h:D2}:{m:D2}:{s:D2}";
}
2026-02-04 17:01:05 +08:00
};
_plotModel.Axes.Add(xAxis);
2026-02-04 17:19:49 +08:00
2026-02-04 17:01:05 +08:00
// 配置左Y轴实时压力
var yAxisLeft = new LinearAxis
2026-02-03 17:47:32 +08:00
{
2026-02-04 17:01:05 +08:00
Position = AxisPosition.Left,
Title = "压力 (PSI)",
TitleFontSize = 12,
FontSize = 10,
TitleColor = OxyColors.Blue,
TextColor = OxyColors.Blue,
MajorGridlineStyle = LineStyle.Solid,
MajorGridlineColor = OxyColor.FromRgb(230, 230, 230),
MinorGridlineStyle = LineStyle.Dot,
MinorGridlineColor = OxyColor.FromRgb(240, 240, 240),
StringFormat = "F2",
Minimum = 0,
Key = "LeftAxis"
};
_plotModel.Axes.Add(yAxisLeft);
2026-02-04 17:19:49 +08:00
2026-02-04 17:01:05 +08:00
// 配置右Y轴压力设定值
var yAxisRight = new LinearAxis
2026-02-03 17:47:32 +08:00
{
2026-02-04 17:01:05 +08:00
Position = AxisPosition.Right,
Title = "压力设定值 (PSI)",
TitleFontSize = 12,
FontSize = 10,
TitleColor = OxyColors.Red,
TextColor = OxyColors.Red,
MajorGridlineStyle = LineStyle.None,
StringFormat = "F2",
Minimum = 0,
Key = "RightAxis"
};
_plotModel.Axes.Add(yAxisRight);
2026-02-04 17:19:49 +08:00
2026-02-04 17:01:05 +08:00
// 添加实时压力曲线
_pressureSeries = new LineSeries
2026-02-03 17:47:32 +08:00
{
Title = "实时压力",
2026-02-04 17:01:05 +08:00
Color = OxyColors.Blue,
2026-02-03 17:47:32 +08:00
StrokeThickness = 2,
2026-02-04 17:01:05 +08:00
MarkerType = MarkerType.Circle,
MarkerSize = 4,
MarkerFill = OxyColors.Blue,
YAxisKey = "LeftAxis"
};
_plotModel.Series.Add(_pressureSeries);
2026-02-04 17:19:49 +08:00
2026-02-04 17:01:05 +08:00
// 添加压力设定值曲线
_pressureSetSeries = new LineSeries
2026-02-03 17:47:32 +08:00
{
2026-02-04 12:00:13 +08:00
Title = "压力设定值",
2026-02-04 17:01:05 +08:00
Color = OxyColors.Red,
2026-02-03 17:47:32 +08:00
StrokeThickness = 2,
2026-02-04 17:01:05 +08:00
MarkerType = MarkerType.Diamond,
MarkerSize = 4,
MarkerFill = OxyColors.Red,
YAxisKey = "RightAxis"
};
_plotModel.Series.Add(_pressureSetSeries);
2026-02-03 17:47:32 +08:00
2026-02-04 17:01:05 +08:00
// 创建PlotView控件
_plotView = new PlotView
2026-02-03 17:47:32 +08:00
{
2026-02-04 17:01:05 +08:00
Model = _plotModel,
2026-02-03 17:47:32 +08:00
Dock = DockStyle.Fill,
2026-02-04 17:01:05 +08:00
BackColor = System.Drawing.Color.White
2026-02-03 17:47:32 +08:00
};
// 添加到目标面板
2026-02-04 17:01:05 +08:00
targetPanel.Controls.Add(_plotView);
2026-02-03 17:47:32 +08:00
}
/// <summary>
/// 添加新的数据点
/// </summary>
2026-02-04 12:00:13 +08:00
/// <param name="pressure">实时压力值</param>
2026-02-04 15:38:42 +08:00
/// <param name="pressureSetValue">压力设定值(来自"压力设置(PSI)"地址2400</param>
2026-02-04 17:18:47 +08:00
/// <param name="totalSeconds">测试时间(总秒数)</param>
public void AddDataPoint(double pressure, double pressureSetValue, int totalSeconds)
2026-02-03 17:47:32 +08:00
{
2026-02-04 17:01:05 +08:00
if (_pressureSeries == null || _pressureSetSeries == null || _plotModel == null)
2026-02-03 17:47:32 +08:00
return;
2026-02-04 17:18:47 +08:00
// 添加数据点使用测试时间总秒数作为X轴值
_pressureData.Add(new DataPoint(totalSeconds, pressure));
_pressureSetData.Add(new DataPoint(totalSeconds, pressureSetValue));
2026-02-03 17:47:32 +08:00
// 限制数据点数量,保持图表流畅
2026-02-04 17:01:05 +08:00
if (_pressureData.Count > MAX_DATA_POINTS)
2026-02-03 17:47:32 +08:00
{
2026-02-04 17:01:05 +08:00
_pressureData.RemoveAt(0);
_pressureSetData.RemoveAt(0);
2026-02-03 17:47:32 +08:00
}
2026-02-04 17:01:05 +08:00
// 更新系列数据
_pressureSeries.Points.Clear();
_pressureSeries.Points.AddRange(_pressureData);
_pressureSetSeries.Points.Clear();
_pressureSetSeries.Points.AddRange(_pressureSetData);
2026-02-04 17:18:47 +08:00
// 动态调整X轴范围
if (_pressureData.Count > 0)
{
var xAxis = _plotModel.Axes.FirstOrDefault(a => a.Position == AxisPosition.Bottom);
if (xAxis != null)
{
double minX = _pressureData.Min(p => p.X);
double maxX = _pressureData.Max(p => p.X);
xAxis.Minimum = minX;
xAxis.Maximum = maxX + 5; // 留一点余量
}
}
2026-02-04 17:01:05 +08:00
// 刷新图表
_plotModel.InvalidatePlot(true);
2026-02-03 17:47:32 +08:00
}
/// <summary>
/// 清除所有数据
/// </summary>
public void ClearData()
{
2026-02-04 17:01:05 +08:00
_pressureData?.Clear();
_pressureSetData?.Clear();
if (_pressureSeries != null)
{
_pressureSeries.Points.Clear();
}
if (_pressureSetSeries != null)
{
_pressureSetSeries.Points.Clear();
}
2026-02-04 17:18:47 +08:00
// 重置X轴范围
var xAxis = _plotModel?.Axes.FirstOrDefault(a => a.Position == AxisPosition.Bottom);
if (xAxis != null)
{
xAxis.Minimum = 0;
xAxis.Maximum = 60;
}
2026-02-04 17:01:05 +08:00
_plotModel?.InvalidatePlot(true);
2026-02-03 17:47:32 +08:00
}
/// <summary>
/// 更新图表配置(例如切换温度模式时)
/// </summary>
/// <param name="isHighTemperatureMode">是否为高温模式</param>
public void UpdateChartMode(bool isHighTemperatureMode)
{
2026-02-04 17:01:05 +08:00
if (_plotModel == null || _plotModel.Series.Count < 2)
2026-02-03 17:47:32 +08:00
return;
2026-02-04 12:00:13 +08:00
// 压力设定值曲线标题保持不变
2026-02-04 17:01:05 +08:00
if (_pressureSetSeries != null)
2026-02-03 17:47:32 +08:00
{
2026-02-04 17:01:05 +08:00
_pressureSetSeries.Title = "压力设定值";
2026-02-03 17:47:32 +08:00
}
2026-02-04 12:00:13 +08:00
// 可以根据模式调整Y轴范围压力设定值范围
2026-02-04 17:01:05 +08:00
foreach (var axis in _plotModel.Axes)
2026-02-03 17:47:32 +08:00
{
2026-02-04 17:01:05 +08:00
if (axis.Key == "RightAxis")
{
axis.Maximum = 10; // 压力设定值通常不超过10MPa
break;
}
2026-02-03 17:47:32 +08:00
}
2026-02-04 17:01:05 +08:00
_plotModel.InvalidatePlot(true);
2026-02-03 17:47:32 +08:00
}
/// <summary>
/// 释放资源
/// </summary>
public void Dispose()
{
2026-02-04 17:01:05 +08:00
_plotView?.Dispose();
_plotModel = null;
_pressureSeries = null;
_pressureSetSeries = null;
_pressureData = null;
_pressureSetData = null;
2026-02-03 17:47:32 +08:00
}
}
}