295 lines
8.8 KiB
C#
295 lines
8.8 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Linq;
|
|||
|
using System.Windows;
|
|||
|
using Aitex.Core.RT.Log;
|
|||
|
using Aitex.Core.Util;
|
|||
|
using Aitex.Core.Utilities;
|
|||
|
using MECF.Framework.Common.DataCenter;
|
|||
|
using MECF.Framework.UI.Client.CenterViews.Core;
|
|||
|
using MECF.Framework.UI.Client.CenterViews.Core.Charting;
|
|||
|
using MECF.Framework.UI.Client.CenterViews.Core.EventArgs;
|
|||
|
using SciChart.Charting.Model.DataSeries;
|
|||
|
using SciChart.Charting.Visuals.Axes;
|
|||
|
using Sicentury.Core.EventArgs;
|
|||
|
using Sicentury.Core.Tree;
|
|||
|
|
|||
|
namespace MECF.Framework.UI.Client.CenterViews.Operations.RealTime
|
|||
|
{
|
|||
|
public class RealtimeViewModel : BusyIndicateableUiViewModelBase
|
|||
|
{
|
|||
|
#region Variables
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 允许监控的最大曲线数量
|
|||
|
/// </summary>
|
|||
|
private const int MAX_PARAMETERS_ALLOWED = 200;
|
|||
|
|
|||
|
private readonly RealtimeProvider _provider = new RealtimeProvider();
|
|||
|
|
|||
|
private bool _enableAutoZoom = true;
|
|||
|
private int _pointCount;
|
|||
|
private readonly PeriodicJob _thread;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Monitor中添加数据点时直接向DataSeries对象添加,已实现跨线程操作。
|
|||
|
/// </summary>
|
|||
|
private readonly List<SicFastLineDataSeries> _dataSeriesList;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 更新报告导出信息。
|
|||
|
/// </summary>
|
|||
|
private readonly IProgress<ProgressUpdatingEventArgs> _exportingProgressReporter;
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Constructors
|
|||
|
|
|||
|
public RealtimeViewModel()
|
|||
|
{
|
|||
|
DisplayName = "Realtime";
|
|||
|
|
|||
|
SelectedData = new ChartingLineSeriesCollection(DisplayName);
|
|||
|
|
|||
|
ParameterNodes = new TreeNode(DisplayName)
|
|||
|
{
|
|||
|
MaxTerminalSelectionAllowed = MAX_PARAMETERS_ALLOWED
|
|||
|
};
|
|||
|
|
|||
|
ParameterNodes.ChildNodes.AddRange(_provider.GetParameters());
|
|||
|
ParameterNodes.TerminalNodeSelectionChanged += OnNodeSelectionChanged;
|
|||
|
|
|||
|
IntervalSaved = true;
|
|||
|
TrendInterval = 500;
|
|||
|
TimeSpanSaved = true;
|
|||
|
TrendTimeSpan = 60 * 5;
|
|||
|
|
|||
|
_thread = new PeriodicJob(TrendInterval, MonitorData, "RealTime", true);
|
|||
|
_pointCount = Math.Max(TrendTimeSpan * 1000 / TrendInterval, 10);
|
|||
|
|
|||
|
_dataSeriesList = new List<SicFastLineDataSeries>();
|
|||
|
|
|||
|
_exportingProgressReporter = new Progress<ProgressUpdatingEventArgs>(e =>
|
|||
|
{
|
|||
|
BusyIndicatorContent = e.Message;
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Properties
|
|||
|
|
|||
|
public bool IsPermission => this.Permission == 3;
|
|||
|
|
|||
|
public TreeNode ParameterNodes { get; }
|
|||
|
|
|||
|
public ChartingLineSeriesCollection SelectedData { get; set; }
|
|||
|
|
|||
|
|
|||
|
public AutoRange ChartAutoRange => EnableAutoZoom ? AutoRange.Always : AutoRange.Never;
|
|||
|
|
|||
|
public bool EnableAutoZoom
|
|||
|
{
|
|||
|
get => _enableAutoZoom;
|
|||
|
|
|||
|
set
|
|||
|
{
|
|||
|
_enableAutoZoom = value;
|
|||
|
NotifyOfPropertyChange(nameof(EnableAutoZoom));
|
|||
|
NotifyOfPropertyChange(nameof(ChartAutoRange));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
[IgnorePropertyChange]
|
|||
|
public int TrendInterval { get; set; }
|
|||
|
|
|||
|
public bool IntervalSaved { get; set; }
|
|||
|
|
|||
|
[IgnorePropertyChange]
|
|||
|
public int TrendTimeSpan { get; set; }
|
|||
|
|
|||
|
public bool TimeSpanSaved { get; set; }
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Methods
|
|||
|
|
|||
|
protected bool MonitorData()
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
Dictionary<string, object> data = null;
|
|||
|
if (SelectedData.Count > 0)
|
|||
|
{
|
|||
|
data = QueryDataClient.Instance.Service.PollData(Array.ConvertAll(SelectedData.ToArray(), x => (x as SicFastLineSeries).DataName));
|
|||
|
}
|
|||
|
|
|||
|
AppendData(data);
|
|||
|
|
|||
|
for (var j = 0; j < ParameterNodes.ChildNodes.Count; j++)
|
|||
|
{
|
|||
|
var par = ParameterNodes.ChildNodes[j];
|
|||
|
par.IsVisibilityParentNode = Visibility.Hidden;
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
LOG.Error(ex.Message);
|
|||
|
}
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
public void AppendData(Dictionary<string, object> data)
|
|||
|
{
|
|||
|
if (data == null)
|
|||
|
return;
|
|||
|
|
|||
|
var dt = DateTime.Now;
|
|||
|
|
|||
|
foreach (var ds in _dataSeriesList)
|
|||
|
{
|
|||
|
if (ds == null || !data.ContainsKey(ds.SeriesName))
|
|||
|
continue;
|
|||
|
|
|||
|
if (data[ds.SeriesName] is bool)
|
|||
|
{
|
|||
|
ds.Append(dt, ((bool)data[ds.SeriesName] ? 1 : 0) * ds.Factor + ds.Offset, new ParameterNodePoint(dt, ((bool)data[ds.SeriesName] ? 1 : 0)));
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
if (!double.TryParse(data[ds.SeriesName].ToString(), out var value))
|
|||
|
continue;
|
|||
|
|
|||
|
ds.Append(dt, value * ds.Factor + ds.Offset, new ParameterNodePoint(dt, value));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void UpdateFifoCapacity(int capacity)
|
|||
|
{
|
|||
|
foreach (var renderableSeries in SelectedData)
|
|||
|
{
|
|||
|
if (renderableSeries is SicFastLineSeries line)
|
|||
|
{
|
|||
|
var ds = line.GetDataSeries();
|
|||
|
var copyMetaData = ds.Metadata.Where(x => x != null && ((ParameterNodePoint)x).Time > DateTime.Now.AddSeconds(-TrendTimeSpan)).ToList();
|
|||
|
|
|||
|
ds.FifoCapacity = capacity;
|
|||
|
foreach (ParameterNodePoint item in copyMetaData)
|
|||
|
{
|
|||
|
ds.Append(item.Time, item.Value);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void SetInterval()
|
|||
|
{
|
|||
|
_thread.ChangeInterval(TrendInterval);
|
|||
|
_pointCount = Math.Max(10, TrendTimeSpan * 1000 / TrendInterval);
|
|||
|
IntervalSaved = true;
|
|||
|
NotifyOfPropertyChange(nameof(IntervalSaved));
|
|||
|
|
|||
|
UpdateFifoCapacity(_pointCount);
|
|||
|
}
|
|||
|
|
|||
|
public void SetTimeSpan()
|
|||
|
{
|
|||
|
_pointCount = Math.Max(10, TrendTimeSpan * 1000 / TrendInterval);
|
|||
|
TimeSpanSaved = true;
|
|||
|
NotifyOfPropertyChange(nameof(TimeSpanSaved));
|
|||
|
|
|||
|
UpdateFifoCapacity(_pointCount);
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Events
|
|||
|
|
|||
|
public void OnNodeSelectionChanged(object sender, TreeNodeSelectionChangedEventArgs e)
|
|||
|
{
|
|||
|
if (e.NewValue == true && SelectedData.Count >= MAX_PARAMETERS_ALLOWED)
|
|||
|
{
|
|||
|
e.Cancel = true;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
var line = SelectedData.Cast<SicFastLineSeries>().FirstOrDefault(x => x.DataName == e.Source.FullName);
|
|||
|
switch (e.NewValue)
|
|||
|
{
|
|||
|
case false:
|
|||
|
{
|
|||
|
if (line != null)
|
|||
|
{
|
|||
|
_dataSeriesList.Remove(line.GetDataSeries());
|
|||
|
SelectedData.Remove(line);
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
case true:
|
|||
|
{
|
|||
|
if (line == null)
|
|||
|
{
|
|||
|
var series = new SicFastLineSeries(e.Source.FullName)
|
|||
|
{
|
|||
|
BackendParameterNode = e.Source
|
|||
|
};
|
|||
|
series.GetDataSeries().FifoCapacity = _pointCount;
|
|||
|
|
|||
|
SelectedData.Add(series);
|
|||
|
_dataSeriesList.Add(series.GetDataSeries());
|
|||
|
SelectedData.ResetColors();
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
default:
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void Deleted(object sender, RenderableSeriesDeletingEventArgs e)
|
|||
|
{
|
|||
|
var list = e.Source.Cast<SicFastLineSeries>().ToList();
|
|||
|
|
|||
|
var total = SelectedData.Count;
|
|||
|
for (var i = total - 1; i >= 0; i--)
|
|||
|
{
|
|||
|
list[i].BackendParameterNode.IsSelected = false;
|
|||
|
}
|
|||
|
|
|||
|
_dataSeriesList.Clear();
|
|||
|
((RealtimeView)View).tvParameterNodes.ClearPresetGroupSelectionOnly();
|
|||
|
}
|
|||
|
|
|||
|
public void Exporting(object sender, EventArgs e)
|
|||
|
{
|
|||
|
BusyIndicatorContent = "Exporting ...";
|
|||
|
IsBusy = true;
|
|||
|
}
|
|||
|
|
|||
|
public void Exported(object sender, EventArgs e)
|
|||
|
{
|
|||
|
IsBusy = false;
|
|||
|
}
|
|||
|
|
|||
|
public void ProgressUpdating(object sender, ProgressUpdatingEventArgs e)
|
|||
|
{
|
|||
|
_exportingProgressReporter.Report(e);
|
|||
|
}
|
|||
|
|
|||
|
public override void Cancel()
|
|||
|
{
|
|||
|
if (View is RealtimeView view)
|
|||
|
{
|
|||
|
view.dataGrid.CancelOperation();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
}
|
|||
|
}
|