using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Log; using Aitex.Core.UI.ControlDataContext; using ControlzEx.Standard; using LiveCharts.Wpf; using MECF.Framework.Common.CommonData; using MECF.Framework.Common.ControlDataContext; using MECF.Framework.Common.DataCenter; using Newtonsoft.Json; using OpenSEMI.ClientBase; using Prism.Commands; using Prism.Mvvm; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Forms; using System.Windows.Input; using System.Windows.Media; using System.Windows.Threading; using System.Xml; using CyberX8_MainPages.Unity; using CyberX8_MainPages.Views; using WPF.Themes.UserControls; using Xceed.Wpf.DataGrid; namespace CyberX8_MainPages.ViewModels { public class DataHistoryViewModel : BindableBase { #region 私有字段 private DataHistoryView DataHistoryView; private ObservableCollection _ParameterNodes; RealtimeProvider _provider = new RealtimeProvider(); private object _lockSelection = new object(); ConcurrentBag _lstTokenTimeData = new ConcurrentBag(); ObservableCollection m_Keys=new ObservableCollection (); ObservableCollection m_KeyDataObservableCollection = new ObservableCollection(); DispatcherTimer timer = new DispatcherTimer(); public List solidColorBrushes = new List (); DateTime currentTime; private bool firstFlag = true; private DateTime startTime=DateTime.Now; #endregion #region 属性 public ObservableCollection OldKeyDataCollection { get; set; } public ObservableCollection ParameterNodes { get { return _ParameterNodes; } set { SetProperty(ref _ParameterNodes, value); } } public ObservableCollection Keys { get { return m_Keys; } set { SetProperty(ref m_Keys, value); } } public ObservableCollection KeyDataObservableCollection { get { return m_KeyDataObservableCollection; } set { SetProperty(ref m_KeyDataObservableCollection, value); } } #endregion #region 命令 private DelegateCommand _LoadCommand; public DelegateCommand LoadCommand => _LoadCommand ?? (_LoadCommand = new DelegateCommand(OnLoad)); private DelegateCommand _UnLoadCommand; public DelegateCommand UnLoadCommand => _UnLoadCommand ?? (_UnLoadCommand = new DelegateCommand(OnUnLoad)); private DelegateCommand _ParameterCheckCommand; public DelegateCommand ParameterCheckCommand => _ParameterCheckCommand ?? (_ParameterCheckCommand = new DelegateCommand(OnParameterCheck)); private DelegateCommand _StartCommand; public DelegateCommand StartCommand => _StartCommand ?? (_StartCommand = new DelegateCommand(OnStart)); private DelegateCommand _ClearCommand; public DelegateCommand ClearCommand => _ClearCommand ?? (_ClearCommand = new DelegateCommand(OnClear)); private DelegateCommand _StartRealTimeCommand; public DelegateCommand StartRealTimeCommand => _StartRealTimeCommand ?? (_StartRealTimeCommand = new DelegateCommand(OnStartRealTime)); private DelegateCommand _StopRealTimeCommand; public DelegateCommand StopRealTimeCommand => _StopRealTimeCommand ?? (_StopRealTimeCommand = new DelegateCommand(OnStopRealTime)); #endregion #region 构造函数 public DataHistoryViewModel() { OldKeyDataCollection = new ObservableCollection(); ParameterNodes = _provider.GetParameters(); timer.Interval = TimeSpan.FromSeconds(1); timer.Tick += Timer_Tick; solidColorBrushes.Add(new SolidColorBrush (Colors.Green)); solidColorBrushes.Add(new SolidColorBrush(Colors.Red)); solidColorBrushes.Add(new SolidColorBrush(Colors.Blue)); solidColorBrushes.Add(new SolidColorBrush(Colors.Orange)); solidColorBrushes.Add(new SolidColorBrush(Colors.Yellow)); solidColorBrushes.Add(new SolidColorBrush(Colors.YellowGreen)); solidColorBrushes.Add(new SolidColorBrush(Colors.AliceBlue)); solidColorBrushes.Add(new SolidColorBrush(Colors.Chocolate)); solidColorBrushes.Add(new SolidColorBrush(Colors.Cyan)); solidColorBrushes.Add(new SolidColorBrush(Colors.DarkGreen)); } #endregion #region 命令方法 private void OnLoad(Object eventView) { if (firstFlag) { this.DataHistoryView = (DataHistoryView)eventView; this.DataHistoryView.wfTimeFrom.Value = DateTime.Today; this.DataHistoryView.wfTimeTo.Value = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, 23, 59, 59, 999); //this.DataHistoryView.MyDrawGraphicsControl.PointCollections=new PointCollection(new Point[] {}) } } private void OnUnLoad() { GC.Collect(); // This should pick up the control removed at a previous MouseDown GC.WaitForPendingFinalizers(); // Doesn't help either GC.Collect(); GC.WaitForPendingFinalizers(); // Doesn't help either } private void OnParameterCheck(object obj) { startTime= DateTime.Now; ParameterNode node = obj as ParameterNode; if (!RefreshTreeStatusToChild(node)) { node.Selected = !node.Selected; } else { RefreshTreeStatusToParent(node); } Keys.Clear(); for (int i = 0; i < ParameterNodes.Count; i++) { CalKeys(ParameterNodes[i]); } OldKeyDataCollection.Clear(); OldKeyDataCollection = DeepCopyJson(KeyDataObservableCollection); KeyDataObservableCollection.Clear(); for (int i = 0; i < Keys.Count; i++) { if (i == 10) { break; } KeyDataObservableCollection.Add(new KeyData() { Key = Keys[i], Color = solidColorBrushes[i],UniqueId=i }); } Compare(OldKeyDataCollection, KeyDataObservableCollection); KeyDataObservableCollection = DeepCopyJson(OldKeyDataCollection); } public void Compare(ObservableCollection olddata, ObservableCollection newdata) { if (newdata != null) { for (int i = 0; i < newdata.Count; i++) { var lists = olddata.ToList().Find(t => t.Key == newdata[i].Key); if (lists == null) { olddata.Add(new KeyData() { Key = newdata[i].Key, Color = solidColorBrushes[i], UniqueId = olddata.Count + 1 }); } } for (int i = 0; i < olddata.Count; i++) { var lists = newdata.ToList().Find(t => t.Key == olddata[i].Key); if (lists == null) { olddata.Remove(olddata[i]); } } } } public static T DeepCopyJson(T obj) { // 序列化 string json = JsonConvert.SerializeObject(obj); // 反序列化 return JsonConvert.DeserializeObject(json); } private void OnStartRealTime(object obj) { if (Keys.Count > 10) { ((System.Windows.Controls.CheckBox)obj).IsChecked= false; timer.Stop(); WPFMessageBox.ShowWarning("最多显示10个数据"); return; } currentTime = DateTime.Now; timer.Start(); } private void OnStopRealTime() { timer.Stop(); } public void OnStart() { if (Keys.Count > 10) { WPFMessageBox.ShowWarning("最多显示10个数据"); return; } this.DataHistoryView.MyDrawGraphicsControl.ClearPlotPoints(); var result = GetData(Keys.Distinct().ToList(), this.DataHistoryView.wfTimeFrom.Value, this.DataHistoryView.wfTimeTo.Value); if (result == null) { return; } List cls = new List(); for (int i = 0; i < Keys.Count; i++) { PointCollection points = new PointCollection(); int k = 1; result[Keys[i]].ForEach(point => { points.Add(new Point() { X = point.dateTime.ToOADate(), Y = point.value }); k += 1; }); cls.Add(points); } for (int i = 0; i < KeyDataObservableCollection.Count(); i++) { var _color = KeyDataObservableCollection[i].Color.Color; this.DataHistoryView.MyDrawGraphicsControl.m_PenCollencteions[i] = new System.Drawing.Pen(System.Drawing.Color.FromArgb(_color.A, _color.R, _color.G, _color.B), 2); } this.DataHistoryView.MyDrawGraphicsControl.PointCollections = cls; this.DataHistoryView.MyDrawGraphicsControl.FitControl(); this.DataHistoryView.MyDrawGraphicsControl.YPoints.Clear(); var item = QueryDataClient.Instance.Service.GetHistorySteps(this.DataHistoryView.wfTimeFrom.Value, this.DataHistoryView.wfTimeTo.Value); if (item != null) { item.ForEach(x => { this.DataHistoryView.MyDrawGraphicsControl.YPoints.Add(new CyberX8_Core.StepItem() { StartValue = x.StartTime.ToOADate(), Information = $"{x.RecipeId}:{x.StepNo}" }); }); } } private void CloseAll(ObservableCollection parameterNodes) { foreach (var item in parameterNodes) { item.Selected = false; if (item.ChildNodes.Count > 0) { CloseAll(item.ChildNodes); } } } private void OnClear() { this.DataHistoryView.MyDrawGraphicsControl.ClearPlotPoints(); this.DataHistoryView.MyDrawGraphicsControl.YPoints = new List(); KeyDataObservableCollection.Clear(); CloseAll(ParameterNodes); } #endregion #region 私有方法 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 //{ // if (node.Selected == true) // { // keys.Add(node.Name); // } // else // { // keys.Remove(node.Name); // } //} return true; } 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); } } private Dictionary> GetData(List keys, DateTime from, DateTime to) { string sql = "select time AS InternalTimeStamp"; foreach (var dataId in keys) { sql += "," + string.Format("\"{0}\"", dataId); } sql += string.Format(" from \"{0}\" where time > {1} and time <= {2} order by time asc", from.ToString("yyyyMMdd") + "." + "Data", from.Ticks, to.Ticks); DataTable dataTable = QueryDataClient.Instance.Service.QueryData(sql); Dictionary> historyData = new Dictionary>(); if (dataTable == null || dataTable.Rows.Count == 0) return null; DateTime dt = new DateTime(); Dictionary colName = new Dictionary(); for (int colNo = 0; colNo < dataTable.Columns.Count; colNo++) { colName.Add(colNo, dataTable.Columns[colNo].ColumnName); historyData[dataTable.Columns[colNo].ColumnName] = new List(); } for (int rowNo = 0; rowNo < dataTable.Rows.Count; rowNo++) { PointCollection points = new PointCollection(); var row = dataTable.Rows[rowNo]; for (int i = 0; i < dataTable.Columns.Count; i++) { HistoryDataItem data = new HistoryDataItem(); if (i == 0) { long ticks = (long)row[i]; dt = new DateTime(ticks); continue; } else { string dataId = colName[i]; if (row[i] is DBNull || row[i] == null) { data.dateTime = dt; data.dbName = colName[i]; data.value = 0; } else if (row[i] is bool) { data.dateTime = dt; data.dbName = colName[i]; data.value = (bool)row[i] ? 1 : 0; } else { data.dateTime = dt; data.dbName = colName[i]; data.value = float.Parse(row[i].ToString()); } } historyData[data.dbName].Add(data); } } foreach (var item in historyData) { item.Value.Sort((x, y) => DateTime.Compare(x.dateTime, y.dateTime)); } return historyData; } private void CalKeys(ParameterNode parameterNode) { if (parameterNode.ChildNodes.Count > 0) { foreach (var item in parameterNode.ChildNodes) { CalKeys(item); } } else { if (parameterNode.Selected == true) { Keys.Add(parameterNode.Name); } } } private void Timer_Tick(object sender, EventArgs e) { if (Keys.Count > 10) { WPFMessageBox.ShowWarning("最多显示10个数据"); timer.Stop(); return; } this.DataHistoryView.MyDrawGraphicsControl.ClearPlotPoints(); var result = GetData(Keys.Distinct().ToList(), currentTime.AddMinutes(-1), DateTime.Now); if (result == null) { return; } List cls = new List(); for (int i = 0; i < Keys.Count; i++) { PointCollection points = new PointCollection(); int k = 1; result[Keys[i]].ForEach(point => { points.Add(new Point() { X = point.dateTime.ToOADate(), Y = point.value }); k += 1; }); cls.Add(points); } this.DataHistoryView.MyDrawGraphicsControl.PointCollections = cls; //if (this.DataHistoryView.MyDrawGraphicsControl.IsHorizontalNavigationEnabled == false && this.DataHistoryView.MyDrawGraphicsControl.IsVerticalNavigationEnabled == false) //{ // this.DataHistoryView.MyDrawGraphicsControl.FitControlWithoutDrawing(); //} //DateTime dateTimeNow = DateTime.Now; this.DataHistoryView.MyDrawGraphicsControl.YPoints.Clear(); var item = QueryDataClient.Instance.Service.GetHistorySteps(startTime, DateTime.Now); if (item.Count > 0) { item.ForEach(x => { this.DataHistoryView.MyDrawGraphicsControl.YPoints.Add(new CyberX8_Core.StepItem() { StartValue = x.StartTime.ToOADate(),Information=$"{x.RecipeId}:{x.StepNo}" }); }); } } #endregion } public class QueryIndexer { public DateTime TimeToken { get; set; } public List DataList { get; set; } public string Module { get; set; } } public class KeyData:BindableBase { public string Key { get; set; } public SolidColorBrush _Color; public SolidColorBrush Color { get { return _Color; } set { SetProperty(ref _Color, value); } } public int UniqueId { get; set; } } }