2026-07-03 10:47:27 +08:00
|
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
2026-07-06 13:37:48 +08:00
|
|
|
using CommunityToolkit.Mvvm.Input;
|
|
|
|
|
using CommunityToolkit.Mvvm.Messaging;
|
2026-07-03 10:47:27 +08:00
|
|
|
using LiveChartsCore;
|
|
|
|
|
using LiveChartsCore.SkiaSharpView;
|
2026-07-06 10:23:41 +08:00
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
using WCTDataMiner.Core.Services;
|
2026-07-06 13:37:48 +08:00
|
|
|
using WCTDataMiner.Wpf.Messages;
|
2026-07-03 10:47:27 +08:00
|
|
|
|
|
|
|
|
namespace WCTDataMiner.Wpf.ViewModels;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Ploss 折线图 ViewModel
|
|
|
|
|
/// </summary>
|
|
|
|
|
public partial class PlossChartViewModel : ObservableObject
|
|
|
|
|
{
|
2026-07-06 10:23:41 +08:00
|
|
|
private readonly ScenarioService _scenarioService;
|
|
|
|
|
private readonly ILogger<PlossChartViewModel> _logger;
|
|
|
|
|
|
2026-07-03 10:47:27 +08:00
|
|
|
[ObservableProperty]
|
2026-07-06 10:23:41 +08:00
|
|
|
private Guid _scenarioId;
|
2026-07-03 10:47:27 +08:00
|
|
|
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
private ISeries[] _series;
|
|
|
|
|
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
private Axis[] _xAxes;
|
|
|
|
|
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
private Axis[] _yAxes;
|
|
|
|
|
|
2026-07-06 13:37:48 +08:00
|
|
|
[ObservableProperty]
|
|
|
|
|
private bool _isLoading;
|
|
|
|
|
|
|
|
|
|
[ObservableProperty]
|
|
|
|
|
private string _loadingMessage = "";
|
|
|
|
|
|
2026-07-06 10:23:41 +08:00
|
|
|
public PlossChartViewModel(
|
|
|
|
|
ScenarioService scenarioService,
|
|
|
|
|
ILogger<PlossChartViewModel> logger)
|
2026-07-03 10:47:27 +08:00
|
|
|
{
|
2026-07-06 10:23:41 +08:00
|
|
|
_scenarioService = scenarioService;
|
|
|
|
|
_logger = logger;
|
|
|
|
|
|
2026-07-03 10:47:27 +08:00
|
|
|
// 初始化图表配置
|
|
|
|
|
Series = Array.Empty<ISeries>();
|
|
|
|
|
XAxes = new Axis[] { new Axis { Name = "Trigger Count" } };
|
|
|
|
|
YAxes = new Axis[] { new Axis { Name = "Power Loss (mW)" } };
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-06 13:37:48 +08:00
|
|
|
/// <summary>
|
|
|
|
|
/// ScenarioId 属性变更时自动触发数据加载
|
|
|
|
|
/// </summary>
|
|
|
|
|
partial void OnScenarioIdChanged(Guid value)
|
|
|
|
|
{
|
|
|
|
|
if (value != Guid.Empty)
|
|
|
|
|
{
|
|
|
|
|
_ = LoadDataAsync().ContinueWith(t =>
|
|
|
|
|
{
|
|
|
|
|
if (t.Exception != null)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError(t.Exception, "LoadDataAsync 失败: ScenarioId={ScenarioId}", value);
|
|
|
|
|
}
|
|
|
|
|
}, TaskContinuationOptions.OnlyOnFaulted);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[RelayCommand]
|
|
|
|
|
private void SwitchToTable()
|
|
|
|
|
{
|
|
|
|
|
WeakReferenceMessenger.Default.Send(new NavigateToPlossTableMessage(ScenarioId));
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-03 10:47:27 +08:00
|
|
|
public async Task LoadDataAsync()
|
|
|
|
|
{
|
2026-07-06 13:37:48 +08:00
|
|
|
if (IsLoading) return; // 防并发
|
|
|
|
|
|
|
|
|
|
IsLoading = true;
|
|
|
|
|
LoadingMessage = "正在加载数据...";
|
|
|
|
|
|
2026-07-06 10:23:41 +08:00
|
|
|
try
|
2026-07-03 10:47:27 +08:00
|
|
|
{
|
2026-07-06 13:37:48 +08:00
|
|
|
var records = await _scenarioService.GetPlossRecordsByScenarioIdAsync(ScenarioId);
|
|
|
|
|
|
|
|
|
|
if (records.Count == 0)
|
|
|
|
|
{
|
|
|
|
|
Series = Array.Empty<ISeries>();
|
|
|
|
|
_logger.LogWarning("未找到 Ploss 数据: ScenarioId={ScenarioId}", ScenarioId);
|
|
|
|
|
LoadingMessage = "无数据";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 构建 Ploss 曲线 (Field7) 和 Threshold 阈值线 (Field8)
|
|
|
|
|
var plossValues = records.Select(r => (double)r.Field7).ToArray();
|
|
|
|
|
var thresholdValues = records.Select(r => (double)r.Field8).ToArray();
|
|
|
|
|
var triggerLabels = records.Select(r => r.Field9.ToString()).ToArray();
|
|
|
|
|
|
2026-07-06 10:23:41 +08:00
|
|
|
Series = new ISeries[]
|
2026-07-03 10:47:27 +08:00
|
|
|
{
|
2026-07-06 10:23:41 +08:00
|
|
|
new LineSeries<double>
|
|
|
|
|
{
|
|
|
|
|
Name = "Ploss",
|
2026-07-06 13:37:48 +08:00
|
|
|
Values = plossValues,
|
|
|
|
|
Fill = null,
|
|
|
|
|
GeometrySize = 5
|
2026-07-06 10:23:41 +08:00
|
|
|
},
|
|
|
|
|
new LineSeries<double>
|
|
|
|
|
{
|
|
|
|
|
Name = "Threshold",
|
2026-07-06 13:37:48 +08:00
|
|
|
Values = thresholdValues,
|
|
|
|
|
Fill = null,
|
|
|
|
|
GeometrySize = 0,
|
|
|
|
|
LineSmoothness = 0 // 直线
|
2026-07-06 10:23:41 +08:00
|
|
|
}
|
|
|
|
|
};
|
2026-07-06 13:37:48 +08:00
|
|
|
|
|
|
|
|
// 更新 X 轴标签
|
|
|
|
|
XAxes = new Axis[]
|
|
|
|
|
{
|
|
|
|
|
new Axis
|
|
|
|
|
{
|
|
|
|
|
Name = "Trigger Count",
|
|
|
|
|
Labels = triggerLabels
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation("加载 Ploss 图表数据成功: ScenarioId={ScenarioId}, 记录数={Count}", ScenarioId, records.Count);
|
|
|
|
|
LoadingMessage = "";
|
2026-07-06 10:23:41 +08:00
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError(ex, "加载 Ploss 图表数据失败: ScenarioId={ScenarioId}", ScenarioId);
|
2026-07-06 13:37:48 +08:00
|
|
|
LoadingMessage = $"加载失败: {ex.Message}";
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
IsLoading = false;
|
2026-07-06 10:23:41 +08:00
|
|
|
}
|
2026-07-03 10:47:27 +08:00
|
|
|
}
|
2026-07-06 13:37:48 +08:00
|
|
|
}
|