using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Windows; using Aitex.Core.RT.Log; using Aitex.Core.Util; using MECF.Framework.Common.ControlDataContext; using MECF.Framework.Common.DataCenter; using MECF.Framework.Common.Utilities; using OpenSEMI.ClientBase; using SciChart.Charting.Visuals.Axes; using SciChart.Charting.Visuals.RenderableSeries; using VirgoUI.Client.Models.History.ProcessHistory; using VirgoUI.Client.Models.Sys; namespace VirgoUI.Client.Models.Operate.RealTime { public class RealTimeViewModel : UiViewModelBase { #region Property private const int MAX_PARAMETERS = 20; private int MenuPermission; private ObservableCollection _ParameterNodes; public ObservableCollection ParameterNodes { get { return _ParameterNodes; } set { _ParameterNodes = value; NotifyOfPropertyChange("ParameterNodes"); } } public ObservableCollection SelectedData { get; set; } object _lockSelection = new object(); public AutoRange ChartAutoRange { get { return EnableAutoZoom ? AutoRange.Always : AutoRange.Never; } } private bool _enableAutoZoom = true; public bool EnableAutoZoom { get { return _enableAutoZoom; } set { _enableAutoZoom = value; NotifyOfPropertyChange(nameof(EnableAutoZoom)); NotifyOfPropertyChange(nameof(ChartAutoRange)); } } RealtimeProvider _provider = new RealtimeProvider(); private PeriodicJob _thread; #endregion #region Function public RealTimeViewModel() { MenuPermission = ClientApp.Instance.GetPermission("DataCharting"); DisplayName = "RealTime"; SelectedData = new ObservableCollection(); ParameterNodes = _provider.GetParameters(); _thread = new PeriodicJob(100, MonitorData, "RealTime", true); } protected override void OnActivate() { base.OnActivate(); } protected bool MonitorData() { try { Dictionary data = null; if (SelectedData.Count > 0) { data = QueryDataClient.Instance.Service.PollData(Array.ConvertAll(SelectedData.ToArray(), x => (x as ChartDataLine).DataName)); } Application.Current.Dispatcher.Invoke(new Action(() => { ParameterNodes = _provider.GetParameters(); AppendData(data); })); } catch (Exception ex) { LOG.Error(ex.Message); } return true; } public void AppendData(Dictionary data) { if (data == null) return; DateTime dt = DateTime.Now; foreach (var item in SelectedData) { var seriesItem = item as ChartDataLine; if (!data.ContainsKey(seriesItem.DataName)) continue; seriesItem.Append(dt, Convert.ToDouble(data[seriesItem.DataName])); } } public void Preset() { } public void Clear() { } public void Apply() { } public void ParameterCheck(ParameterNode node) { bool result = RefreshTreeStatusToChild(node); if (!result) node.Selected = !node.Selected; else RefreshTreeStatusToParent(node); } /// /// Refresh tree node status from current to children, and add data to SelectedData /// private bool RefreshTreeStatusToChild(ParameterNode node) { if (node.ChildNodes.Count > 0) { for (int i = 0; i < node.ChildNodes.Count; i++) { ParameterNode n = node.ChildNodes[i]; n.Selected = node.Selected; if (!RefreshTreeStatusToChild(n)) { //uncheck left node for (int j = i; j < node.ChildNodes.Count; j++) { node.ChildNodes[j].Selected = !node.Selected; } node.Selected = !node.Selected; return false; } } } else //leaf node { lock (_lockSelection) { bool isExist = SelectedData.FirstOrDefault(x => (x as ChartDataLine).DataName == node.Name) != null; if (node.Selected && !isExist) { if (SelectedData.Count < MAX_PARAMETERS) { var line = new ChartDataLine(node.Name); line.Tag = node; SelectedData.Add(line); } else { DialogBox.ShowWarning($"The max number of parameters is {MAX_PARAMETERS}."); return false; } } else if (!node.Selected && isExist) { //SelectedParameters.Remove(node.Name); var data = SelectedData.FirstOrDefault(d => (d as ChartDataLine).DataName == node.Name); SelectedData.Remove(data); } } } return true; } /// /// Refresh tree node status from current to parent /// /// /// private void RefreshTreeStatusToParent(ParameterNode node) { if (node.ParentNode != null) { if (node.Selected) { bool flag = true; for (int i = 0; i < node.ParentNode.ChildNodes.Count; i++) { if (!node.ParentNode.ChildNodes[i].Selected) { flag = false; //as least one child is unselected break; } } if (flag) node.ParentNode.Selected = true; } else { node.ParentNode.Selected = false; } RefreshTreeStatusToParent(node.ParentNode); } } #region Parameter Grid Control public void DeleteAll() { if (MenuPermission != 3) return; //uncheck all tree nodes foreach (ChartDataLine cp in SelectedData) { (cp.Tag as ParameterNode).Selected = false; RefreshTreeStatusToParent(cp.Tag as ParameterNode); } SelectedData.Clear(); } private void SetParameterNode(ObservableCollection nodes, bool isChecked) { foreach (ParameterNode n in nodes) { n.Selected = isChecked; SetParameterNode(n.ChildNodes, isChecked); } } public void Delete(ChartDataLine cp) { if (MenuPermission != 3) return; if (cp != null && SelectedData.Contains(cp)) { //uncheck tree node (cp.Tag as ParameterNode).Selected = false; RefreshTreeStatusToParent(cp.Tag as ParameterNode); SelectedData.Remove(cp); } } public void ExportAll() { if (MenuPermission != 3) return; try { Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog(); dlg.DefaultExt = ".xlsx"; // Default file extension dlg.Filter = "Excel数据表格文件(*.xlsx)|*.xlsx"; // Filter files by extension dlg.FileName = $"Export_{DateTime.Now:yyyyMMdd_HHmmss}"; Nullable result = dlg.ShowDialog();// Show open file dialog box if (result == true) // Process open file dialog box results { System.Data.DataSet ds = new System.Data.DataSet(); ds.Tables.Add(new System.Data.DataTable($"Export_{DateTime.Now:yyyyMMdd_HHmmss}")); ds.Tables[0].Columns.Add("Time"); ds.Tables[0].Columns[0].DataType = typeof(DateTime); lock (_lockSelection) { Dictionary timeValue = new Dictionary(); for (int i = 0; i < SelectedData.Count; i++) { List> data = (SelectedData[i] as ChartDataLine).Points; foreach (var tuple in data) { if (!timeValue.ContainsKey(tuple.Item1)) timeValue[tuple.Item1] = new double[SelectedData.Count]; timeValue[tuple.Item1][i] = tuple.Item2; } ds.Tables[0].Columns.Add((SelectedData[i] as ChartDataLine).DataName); ds.Tables[0].Columns[i+1].DataType = typeof(double); } foreach (var item in timeValue) { var row = ds.Tables[0].NewRow(); row[0] = item.Key; for (int j = 0; j < item.Value.Length; j++) { row[j+1] = item.Value[j]; } ds.Tables[0].Rows.Add(row); } } if (!ExcelHelper.ExportToExcel(dlg.FileName, ds, out string reason)) { MessageBox.Show($"Export failed, {reason}", "Export", MessageBoxButton.OK, MessageBoxImage.Warning); return; } MessageBox.Show($"Export succeed, file save as {dlg.FileName}", "Export", MessageBoxButton.OK, MessageBoxImage.Information); } } catch (Exception ex) { LOG.Write(ex); MessageBox.Show("Write failed," + ex.Message, "export failed", MessageBoxButton.OK, MessageBoxImage.Warning); } } public void Export(ChartDataLine cp) { if (MenuPermission != 3) return; try { Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog(); dlg.DefaultExt = ".xlsx"; // Default file extension dlg.Filter = "Excel数据表格文件(*.xlsx)|*.xlsx"; // Filter files by extension dlg.FileName = $"{cp.DataName}_{DateTime.Now:yyyyMMdd_HHmmss}"; Nullable result = dlg.ShowDialog();// Show open file dialog box if (result == true) // Process open file dialog box results { System.Data.DataSet ds = new System.Data.DataSet(); ds.Tables.Add(new System.Data.DataTable(cp.DataName)); ds.Tables[0].Columns.Add("Time"); ds.Tables[0].Columns[0].DataType = typeof(DateTime); ds.Tables[0].Columns.Add(cp.DataName); ds.Tables[0].Columns[1].DataType = typeof(double); foreach (var item in cp.Points) { var row = ds.Tables[0].NewRow(); row[0] = item.Item1; row[1] = item.Item2; ds.Tables[0].Rows.Add(row); } if (!ExcelHelper.ExportToExcel(dlg.FileName, ds, out string reason)) { MessageBox.Show($"Export failed, {reason}" , "Export", MessageBoxButton.OK, MessageBoxImage.Warning); return; } MessageBox.Show($"Export succeed, file save as {dlg.FileName}", "Export", MessageBoxButton.OK, MessageBoxImage.Information); } } catch (Exception ex) { LOG.Write(ex); MessageBox.Show("Write failed,"+ex.Message, "export failed", MessageBoxButton.OK, MessageBoxImage.Warning); } } public void SelectColor(ChartDataLine cp) { if (cp == null) return; var dlg = new System.Windows.Forms.ColorDialog(); if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK) { cp.Stroke = new System.Windows.Media.Color() { A = dlg.Color.A, B = dlg.Color.B, G = dlg.Color.G, R = dlg.Color.R }; } } #endregion #endregion } }