更新曲线图

This commit is contained in:
GukSang.Jin
2026-02-04 17:01:05 +08:00
parent e52782f16e
commit 719ad88388
3 changed files with 175 additions and 109 deletions

View File

@@ -1,9 +1,11 @@
using LiveCharts; using OxyPlot;
using LiveCharts.Wpf; using OxyPlot.Axes;
using OxyPlot.Series;
using OxyPlot.WindowsForms;
using System; using System;
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
using System.Windows.Forms.Integration;
namespace namespace
{ {
@@ -14,12 +16,14 @@ namespace 全自动水压检测仪
/// </summary> /// </summary>
public class ChartManager public class ChartManager
{ {
private ElementHost _chartHost; private PlotView _plotView;
private LiveCharts.Wpf.CartesianChart _chart; private PlotModel _plotModel;
private ChartValues<double> _pressureValues; // 实时压力值地址3130 private LineSeries _pressureSeries; // 实时压力值地址3130
private ChartValues<double> _pressureSetValues; // 压力设定值地址2400 private LineSeries _pressureSetSeries; // 压力设定值地址2400
private ChartValues<string> _timeLabels; private List<DataPoint> _pressureData;
private List<DataPoint> _pressureSetData;
private const int MAX_DATA_POINTS = 60; // 最多显示60个数据点 private const int MAX_DATA_POINTS = 60; // 最多显示60个数据点
private int _dataPointIndex = 0;
/// <summary> /// <summary>
/// 初始化图表并添加到指定面板 /// 初始化图表并添加到指定面板
@@ -33,92 +37,112 @@ namespace 全自动水压检测仪
targetPanel.Text = null; targetPanel.Text = null;
// 初始化数据集合 // 初始化数据集合
_pressureValues = new ChartValues<double>(); // 实时压力 _pressureData = new List<DataPoint>();
_pressureSetValues = new ChartValues<double>(); // 压力设定值 _pressureSetData = new List<DataPoint>();
_timeLabels = new ChartValues<string>();
// 创建WPF图表控件 // 创建PlotModel
_chart = new LiveCharts.Wpf.CartesianChart _plotModel = new PlotModel
{ {
Background = System.Windows.Media.Brushes.White, Title = "",
DisableAnimations = false, Background = OxyColors.White,
Hoverable = true, PlotAreaBorderColor = OxyColors.Gray
DataTooltip = null,
LegendLocation = LegendLocation.Top
}; };
// 配置X轴时间轴 // 配置图例
_chart.AxisX.Add(new Axis _plotModel.Legends.Add(new OxyPlot.Legends.Legend
{ {
LegendPosition = OxyPlot.Legends.LegendPosition.TopCenter,
LegendOrientation = OxyPlot.Legends.LegendOrientation.Horizontal
});
// 配置X轴时间轴 - 使用数据点索引)
var xAxis = new LinearAxis
{
Position = AxisPosition.Bottom,
Title = "时间", Title = "时间",
Labels = _timeLabels, TitleFontSize = 12,
FontSize = 12, FontSize = 10,
Foreground = System.Windows.Media.Brushes.Black, MajorGridlineStyle = LineStyle.Solid,
Separator = new LiveCharts.Wpf.Separator MajorGridlineColor = OxyColor.FromRgb(230, 230, 230),
{ MinorGridlineStyle = LineStyle.Dot,
Step = 5, MinorGridlineColor = OxyColor.FromRgb(240, 240, 240),
IsEnabled = true StringFormat = "0",
} Minimum = 0,
}); Maximum = MAX_DATA_POINTS
};
_plotModel.Axes.Add(xAxis);
// 配置Y轴压力 // 配置Y轴实时压力)
_chart.AxisY.Add(new Axis var yAxisLeft = new LinearAxis
{ {
Title = "压力 (MPa)", Position = AxisPosition.Left,
FontSize = 12, Title = "压力 (PSI)",
Foreground = System.Windows.Media.Brushes.Blue, TitleFontSize = 12,
LabelFormatter = value => value.ToString("F2"), FontSize = 10,
MinValue = 0 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);
// 配置第二Y轴压力设定值 // 配置Y轴压力设定值
_chart.AxisY.Add(new Axis var yAxisRight = new LinearAxis
{ {
Title = "压力设定值 (MPa)", Position = AxisPosition.Right,
FontSize = 12, Title = "压力设定值 (PSI)",
Foreground = System.Windows.Media.Brushes.Red, TitleFontSize = 12,
LabelFormatter = value => value.ToString("F2"), FontSize = 10,
Position = AxisPosition.RightTop, TitleColor = OxyColors.Red,
MinValue = 0 TextColor = OxyColors.Red,
}); MajorGridlineStyle = LineStyle.None,
StringFormat = "F2",
Minimum = 0,
Key = "RightAxis"
};
_plotModel.Axes.Add(yAxisRight);
// 添加压力曲线 // 添加实时压力曲线
_chart.Series.Add(new LineSeries _pressureSeries = new LineSeries
{ {
Title = "实时压力", Title = "实时压力",
Values = _pressureValues, Color = OxyColors.Blue,
Stroke = System.Windows.Media.Brushes.Blue,
Fill = System.Windows.Media.Brushes.Transparent,
PointGeometry = DefaultGeometries.Circle,
PointGeometrySize = 5,
StrokeThickness = 2, StrokeThickness = 2,
LineSmoothness = 0.3, MarkerType = MarkerType.Circle,
ScalesYAt = 0 MarkerSize = 4,
}); MarkerFill = OxyColors.Blue,
YAxisKey = "LeftAxis"
};
_plotModel.Series.Add(_pressureSeries);
// 添加压力设定值曲线来自地址2400对应"压力设置(PSI)" // 添加压力设定值曲线
_chart.Series.Add(new LineSeries _pressureSetSeries = new LineSeries
{ {
Title = "压力设定值", Title = "压力设定值",
Values = _pressureSetValues, Color = OxyColors.Red,
Stroke = System.Windows.Media.Brushes.Red,
Fill = System.Windows.Media.Brushes.Transparent,
PointGeometry = DefaultGeometries.Diamond,
PointGeometrySize = 5,
StrokeThickness = 2, StrokeThickness = 2,
LineSmoothness = 0.3, MarkerType = MarkerType.Diamond,
ScalesYAt = 1 MarkerSize = 4,
}); MarkerFill = OxyColors.Red,
YAxisKey = "RightAxis"
};
_plotModel.Series.Add(_pressureSetSeries);
// 创建ElementHost以承载WPF控件 // 创建PlotView控件
_chartHost = new ElementHost _plotView = new PlotView
{ {
Model = _plotModel,
Dock = DockStyle.Fill, Dock = DockStyle.Fill,
Child = _chart BackColor = System.Drawing.Color.White
}; };
// 添加到目标面板 // 添加到目标面板
targetPanel.Controls.Add(_chartHost); targetPanel.Controls.Add(_plotView);
} }
/// <summary> /// <summary>
@@ -129,25 +153,38 @@ namespace 全自动水压检测仪
/// <param name="time">时间标签(可选,默认使用当前时间)</param> /// <param name="time">时间标签(可选,默认使用当前时间)</param>
public void AddDataPoint(double pressure, double pressureSetValue, string time = null) public void AddDataPoint(double pressure, double pressureSetValue, string time = null)
{ {
if (_pressureValues == null || _pressureSetValues == null || _timeLabels == null) if (_pressureSeries == null || _pressureSetSeries == null || _plotModel == null)
return; return;
// 使用当前时间作为默认标签 // 添加数据点使用索引作为X轴值
if (string.IsNullOrEmpty(time)) _pressureData.Add(new DataPoint(_dataPointIndex, pressure));
time = DateTime.Now.ToString("HH:mm:ss"); _pressureSetData.Add(new DataPoint(_dataPointIndex, pressureSetValue));
_dataPointIndex++;
// 添加数据点
_pressureValues.Add(pressure);
_pressureSetValues.Add(pressureSetValue);
_timeLabels.Add(time);
// 限制数据点数量,保持图表流畅 // 限制数据点数量,保持图表流畅
if (_pressureValues.Count > MAX_DATA_POINTS) if (_pressureData.Count > MAX_DATA_POINTS)
{ {
_pressureValues.RemoveAt(0); _pressureData.RemoveAt(0);
_pressureSetValues.RemoveAt(0); _pressureSetData.RemoveAt(0);
_timeLabels.RemoveAt(0);
// 重新索引数据点
for (int i = 0; i < _pressureData.Count; i++)
{
_pressureData[i] = new DataPoint(i, _pressureData[i].Y);
_pressureSetData[i] = new DataPoint(i, _pressureSetData[i].Y);
}
_dataPointIndex = _pressureData.Count;
} }
// 更新系列数据
_pressureSeries.Points.Clear();
_pressureSeries.Points.AddRange(_pressureData);
_pressureSetSeries.Points.Clear();
_pressureSetSeries.Points.AddRange(_pressureSetData);
// 刷新图表
_plotModel.InvalidatePlot(true);
} }
/// <summary> /// <summary>
@@ -155,9 +192,21 @@ namespace 全自动水压检测仪
/// </summary> /// </summary>
public void ClearData() public void ClearData()
{ {
_pressureValues?.Clear(); _pressureData?.Clear();
_pressureSetValues?.Clear(); _pressureSetData?.Clear();
_timeLabels?.Clear(); _dataPointIndex = 0;
if (_pressureSeries != null)
{
_pressureSeries.Points.Clear();
}
if (_pressureSetSeries != null)
{
_pressureSetSeries.Points.Clear();
}
_plotModel?.InvalidatePlot(true);
} }
/// <summary> /// <summary>
@@ -166,21 +215,26 @@ namespace 全自动水压检测仪
/// <param name="isHighTemperatureMode">是否为高温模式</param> /// <param name="isHighTemperatureMode">是否为高温模式</param>
public void UpdateChartMode(bool isHighTemperatureMode) public void UpdateChartMode(bool isHighTemperatureMode)
{ {
if (_chart == null || _chart.Series.Count < 2) if (_plotModel == null || _plotModel.Series.Count < 2)
return; return;
// 压力设定值曲线标题保持不变 // 压力设定值曲线标题保持不变
var pressureSetSeries = _chart.Series[1] as LineSeries; if (_pressureSetSeries != null)
if (pressureSetSeries != null)
{ {
pressureSetSeries.Title = "压力设定值"; _pressureSetSeries.Title = "压力设定值";
} }
// 可以根据模式调整Y轴范围压力设定值范围 // 可以根据模式调整Y轴范围压力设定值范围
if (_chart.AxisY.Count > 1) foreach (var axis in _plotModel.Axes)
{ {
_chart.AxisY[1].MaxValue = 10; // 压力设定值通常不超过10MPa if (axis.Key == "RightAxis")
{
axis.Maximum = 10; // 压力设定值通常不超过10MPa
break;
}
} }
_plotModel.InvalidatePlot(true);
} }
/// <summary> /// <summary>
@@ -188,11 +242,12 @@ namespace 全自动水压检测仪
/// </summary> /// </summary>
public void Dispose() public void Dispose()
{ {
_chartHost?.Dispose(); _plotView?.Dispose();
_chart = null; _plotModel = null;
_pressureValues = null; _pressureSeries = null;
_pressureSetValues = null; _pressureSetSeries = null;
_timeLabels = null; _pressureData = null;
_pressureSetData = null;
} }
} }
} }

View File

@@ -7,11 +7,14 @@
<package id="K4os.Compression.LZ4" version="1.3.8" targetFramework="net472" /> <package id="K4os.Compression.LZ4" version="1.3.8" targetFramework="net472" />
<package id="K4os.Compression.LZ4.Streams" version="1.3.8" targetFramework="net472" /> <package id="K4os.Compression.LZ4.Streams" version="1.3.8" targetFramework="net472" />
<package id="K4os.Hash.xxHash" version="1.0.8" targetFramework="net472" /> <package id="K4os.Hash.xxHash" version="1.0.8" targetFramework="net472" />
<package id="LiveCharts" version="0.9.7" targetFramework="net472" /> <package id="OxyPlot.Core" version="2.2.0" targetFramework="net472" />
<package id="LiveCharts.Wpf" version="0.9.7" targetFramework="net472" /> <package id="OxyPlot.WindowsForms" version="2.2.0" targetFramework="net472" />
<package id="Microsoft.Bcl.AsyncInterfaces" version="9.0.1" targetFramework="net472" /> <package id="Microsoft.Bcl.AsyncInterfaces" version="9.0.1" targetFramework="net472" />
<package id="Microsoft.NETFramework.ReferenceAssemblies" version="1.0.2" targetFramework="net472" developmentDependency="true" />
<package id="Microsoft.NETFramework.ReferenceAssemblies.net472" version="1.0.2" targetFramework="net472" developmentDependency="true" />
<package id="MySql.Data" version="9.5.0" targetFramework="net472" /> <package id="MySql.Data" version="9.5.0" targetFramework="net472" />
<package id="NModbus4" version="2.1.0" targetFramework="net472" /> <package id="NModbus4" version="2.1.0" targetFramework="net472" />
<package id="OxyPlot.Core" version="2.2.0" targetFramework="net472" />
<package id="SunnyUI" version="3.9.1" targetFramework="net472" /> <package id="SunnyUI" version="3.9.1" targetFramework="net472" />
<package id="SunnyUI.Common" version="3.9.1" targetFramework="net472" /> <package id="SunnyUI.Common" version="3.9.1" targetFramework="net472" />
<package id="System.Buffers" version="4.5.1" targetFramework="net472" /> <package id="System.Buffers" version="4.5.1" targetFramework="net472" />

View File

@@ -12,6 +12,8 @@
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic> <Deterministic>true</Deterministic>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
@@ -59,11 +61,15 @@
<Reference Include="K4os.Hash.xxHash, Version=1.0.8.0, Culture=neutral, PublicKeyToken=32cd54395057cec3, processorArchitecture=MSIL"> <Reference Include="K4os.Hash.xxHash, Version=1.0.8.0, Culture=neutral, PublicKeyToken=32cd54395057cec3, processorArchitecture=MSIL">
<HintPath>..\packages\K4os.Hash.xxHash.1.0.8\lib\net462\K4os.Hash.xxHash.dll</HintPath> <HintPath>..\packages\K4os.Hash.xxHash.1.0.8\lib\net462\K4os.Hash.xxHash.dll</HintPath>
</Reference> </Reference>
<Reference Include="LiveCharts, Version=0.9.7.0, Culture=neutral, PublicKeyToken=0bc1f845d1ebb8df, processorArchitecture=MSIL"> <Reference Include="OxyPlot, Version=2.2.0.0, Culture=neutral, PublicKeyToken=638079a8f0bd61e9, processorArchitecture=MSIL">
<HintPath>..\packages\LiveCharts.0.9.7\lib\net45\LiveCharts.dll</HintPath> <HintPath>..\packages\OxyPlot.Core.2.2.0\lib\net462\OxyPlot.dll</HintPath>
<Private>True</Private>
<SpecificVersion>True</SpecificVersion>
</Reference> </Reference>
<Reference Include="LiveCharts.Wpf, Version=0.9.7.0, Culture=neutral, PublicKeyToken=0bc1f845d1ebb8df, processorArchitecture=MSIL"> <Reference Include="OxyPlot.WindowsForms, Version=2.2.0.0, Culture=neutral, PublicKeyToken=245eacd6b5d2d338, processorArchitecture=MSIL">
<HintPath>..\packages\LiveCharts.Wpf.0.9.7\lib\net45\LiveCharts.Wpf.dll</HintPath> <HintPath>..\packages\OxyPlot.WindowsForms.2.2.0\lib\net462\OxyPlot.WindowsForms.dll</HintPath>
<Private>True</Private>
<SpecificVersion>False</SpecificVersion>
</Reference> </Reference>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=9.0.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> <Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=9.0.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.9.0.1\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath> <HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.9.0.1\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
@@ -74,8 +80,6 @@
<Reference Include="NModbus4, Version=2.1.0.0, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="NModbus4, Version=2.1.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\NModbus4.2.1.0\lib\net40\NModbus4.dll</HintPath> <HintPath>..\packages\NModbus4.2.1.0\lib\net40\NModbus4.dll</HintPath>
</Reference> </Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="SunnyUI, Version=3.9.1.0, Culture=neutral, PublicKeyToken=3f4ebed4237db5e1, processorArchitecture=MSIL"> <Reference Include="SunnyUI, Version=3.9.1.0, Culture=neutral, PublicKeyToken=3f4ebed4237db5e1, processorArchitecture=MSIL">
<HintPath>..\packages\SunnyUI.3.9.1\lib\net472\SunnyUI.dll</HintPath> <HintPath>..\packages\SunnyUI.3.9.1\lib\net472\SunnyUI.dll</HintPath>
</Reference> </Reference>
@@ -121,9 +125,6 @@
<Reference Include="System.Net.Http" /> <Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" /> <Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
<Reference Include="System.Xaml" />
<Reference Include="WindowsBase" />
<Reference Include="WindowsFormsIntegration" />
<Reference Include="ZstdSharp, Version=0.8.6.0, Culture=neutral, PublicKeyToken=8d151af33a4ad5cf, processorArchitecture=MSIL"> <Reference Include="ZstdSharp, Version=0.8.6.0, Culture=neutral, PublicKeyToken=8d151af33a4ad5cf, processorArchitecture=MSIL">
<HintPath>..\packages\ZstdSharp.Port.0.8.6\lib\net462\ZstdSharp.dll</HintPath> <HintPath>..\packages\ZstdSharp.Port.0.8.6\lib\net462\ZstdSharp.dll</HintPath>
</Reference> </Reference>
@@ -284,4 +285,11 @@
<WCFMetadata Include="Connected Services\" /> <WCFMetadata Include="Connected Services\" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Microsoft.NETFramework.ReferenceAssemblies.net472.1.0.2\build\Microsoft.NETFramework.ReferenceAssemblies.net472.targets" Condition="Exists('..\packages\Microsoft.NETFramework.ReferenceAssemblies.net472.1.0.2\build\Microsoft.NETFramework.ReferenceAssemblies.net472.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.NETFramework.ReferenceAssemblies.net472.1.0.2\build\Microsoft.NETFramework.ReferenceAssemblies.net472.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.NETFramework.ReferenceAssemblies.net472.1.0.2\build\Microsoft.NETFramework.ReferenceAssemblies.net472.targets'))" />
</Target>
</Project> </Project>