| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472 | using Aitex.Core.RT.Log;using Aitex.Core.UI.ControlDataContext;using Aitex.Core.Util;using Caliburn.Micro;using Caliburn.Micro.Core;using MECF.Framework.Common.CommonData;using MECF.Framework.Common.ControlDataContext;using MECF.Framework.Common.DataCenter;using MECF.Framework.Common.Utilities;using MECF.Framework.UI.Client.CenterViews.Configs.SystemConfig;using MECF.Framework.UI.Client.CenterViews.DataLogs.ProcessHistory;using MECF.Framework.UI.Client.CenterViews.Dialogs;using MECF.Framework.UI.Client.ClientBase;using OpenSEMI.ClientBase;using SciChart.Charting.Visuals;using SciChart.Charting.Visuals.Annotations;using SciChart.Charting.Visuals.Axes;using SciChart.Charting.Visuals.RenderableSeries;using SciChart.Data.Model;using System;using System.Collections.Concurrent;using System.Collections.Generic;using System.Collections.ObjectModel;using System.Data;using System.Diagnostics;using System.Drawing;using System.Linq;using System.Threading;using System.Threading.Tasks;using System.Windows;using System.Windows.Controls;using Action = System.Action;using Media = System.Windows.Media;namespace MECF.Framework.UI.Client.CenterViews.DataLogs.ProcessHistory{    public class StepInfo    {        public DateTime StartTime { get; set; }        public DateTime StepEndTime { get; set; }        public DateTime EndTime { get; set; }        public string StepNo { get; set; }        public string StepName { get; set; }        public double StepTime { get; set; }        public bool IsChecked { get; set; } = true;        public string SubRecipeStepNumber { get; set; }        public string SubRecipeStepName { get; set; }        public string SubRecipeStepTime { get; set; }        public string SubRecipeLoopInfo { get; set; }        public string TempCorrection { get; set; }        public string TempPid { get; set; }    }    public class ProcessDetailViewModel<T> : ModuleUiViewModelBase where T : IComparable    {        public class TimeChartDataLine : ChartDataLine<T>        {            public string Module { get; set; }            public DateTime StartTime { get; set; }            public DateTime EndTime { get; set; }            public TimeChartDataLine(string dataName, string module, DateTime startTime, DateTime endTime) : base(dataName)            {                StartTime = startTime;                EndTime = endTime;                Module = module;            }        }        public class QueryIndexer        {            public TimeChartDataLine DataLine { get; set; }            public List<string> DataList { get; set; }            public DateTime TimeToken { get; set; }        }        public bool IsPermission { get => this.Permission == 3; }        private ProcessDetailView view;        /// <summary>        /// 正在导出数据事件。        /// </summary>        private event EventHandler Exporting;        private CancellationTokenSource _cancellationTokenSource;        #region Property        private const int MAX_PARAMETERS = 20;        private Queue<Color> colorQueue = new Queue<Color>(new Color[]{Color.Red,Color.Orange,Color.Yellow,Color.Green,Color.Blue,Color.Pink,Color.Purple,Color.Aqua,Color.Bisque,Color.Brown,Color.BurlyWood,Color.CadetBlue,            Color.CornflowerBlue,Color.DarkBlue,Color.DarkCyan,Color.DarkGray,Color.DarkGreen,Color.DarkKhaki,Color.DarkMagenta,Color.DarkOliveGreen, Color.DarkOrange,            Color.DarkSeaGreen,Color.DarkSlateBlue,Color.DarkSlateGray,Color.DarkViolet,Color.DeepPink,Color.DeepSkyBlue,Color.DimGray, Color.DodgerBlue,Color.ForestGreen, Color.Gold,            Color.Gray,Color.GreenYellow,Color.HotPink,Color.Indigo,Color.Khaki,Color.LightBlue,Color.LightCoral,Color.LightGreen, Color.LightPink,Color.LightSalmon,Color.LightSkyBlue,            Color.LightSlateGray,Color.LightSteelBlue,Color.LimeGreen,Color.MediumOrchid,Color.MediumPurple,Color.MediumSeaGreen,Color.MediumSlateBlue,Color.MediumSpringGreen,            Color.MediumTurquoise,Color.Moccasin,Color.NavajoWhite,Color.Olive,Color.OliveDrab,Color.OrangeRed,Color.Orchid,Color.PaleGoldenrod,Color.PaleGreen,            Color.PeachPuff,Color.Peru,Color.Plum,Color.PowderBlue,Color.RosyBrown,Color.RoyalBlue,Color.SaddleBrown,Color.Salmon,Color.SeaGreen, Color.Sienna,            Color.SkyBlue,Color.SlateBlue,Color.SlateGray,Color.SpringGreen,Color.Teal,Color.Aquamarine,Color.Tomato,Color.Turquoise,Color.Violet,Color.Wheat, Color.YellowGreen});        private ObservableCollection<ParameterNode> _ParameterNodes;        public ObservableCollection<ParameterNode> ParameterNodes        {            get { return _ParameterNodes; }            set { _ParameterNodes = value; NotifyOfPropertyChange("ParameterNodes"); }        }        public ObservableCollection<IRenderableSeries> SelectedData { get; set; }        public List<ProcessHistoryLot> RecipeDatas { get; set; }        private static object _lockSelection = new object();        private AutoRange _autoRange;        public AutoRange ChartAutoRange        {            get { return _autoRange; }            set            {                _autoRange = value;                NotifyOfPropertyChange(nameof(ChartAutoRange));            }        }        private IRange _timeRange;        public IRange VisibleRangeTime        {            get { return _timeRange; }            set            {                _timeRange = value;                NotifyOfPropertyChange(nameof(VisibleRangeTime));            }        }        private IRange _VisibleRangeValue;        public IRange VisibleRangeValue        {            get { return _VisibleRangeValue; }            set { _VisibleRangeValue = value; NotifyOfPropertyChange(nameof(VisibleRangeValue)); }        }        private PeriodicJob _thread;        private ConcurrentBag<QueryIndexer> _lstTokenTimeData = new ConcurrentBag<QueryIndexer>();        private Dictionary<string, string> _processDetailDisplayDic = new Dictionary<string, string>();        private string _resolution;        private AnnotationCollection _annotations;        public AnnotationCollection Annotations        {            get => _annotations;            set            {                _annotations = value;                InvokePropertyChanged(nameof(Annotations));            }        }        //StartTime,EndTime,StepNo,StepName        private List<StepInfo> _stepInfo = new List<StepInfo>();        public List<StepInfo> StepInfo        {            get { return _stepInfo; }            set { _stepInfo = value; this.NotifyOfPropertyChange(nameof(StepInfo)); }        }        public bool IsStepVisiable => RecipeDatas.Count == 1;        public DateTime StepStartTime { get; set; }        public DateTime StepEndTime { get; set; }        private bool _isAdding;        #endregion        #region Function        public ProcessDetailViewModel(List<ProcessHistoryLot> recipes)        {            DisplayName = "Process Detail";            RecipeDatas = recipes;            ParameterNodes = GetParameters();            if (recipes == null || recipes.Count == 0)            {                return;            }            SelectedData = new ObservableCollection<IRenderableSeries>();            var now = DateTime.Now;            VisibleRangeTime = new DateRange(DateTime.Now.AddMinutes(60), DateTime.Now.AddMinutes(-60));            VisibleRangeValue = new DoubleRange(0, 10);            Annotations = new AnnotationCollection();            _thread = new PeriodicJob(200, MonitorData, "ProcessDetail", true);            RecipeDatas.ToList().ForEach(recipe =>            {                QueryStep(recipe.StartTime, recipe.EndTime);            });            if (StepInfo != null && StepInfo.Count > 0)            {                StepStartTime = StepInfo.FirstOrDefault().StartTime;                StepEndTime = StepInfo.LastOrDefault().EndTime;            }        }        protected override void OnViewLoaded(object view)        {            base.OnViewLoaded(view);            this.view = (ProcessDetailView)view;        }        protected override void OnActivate()        {            _resolution = "f1";            if (QueryDataClient.Instance.Service.GetConfig($"System.DataHistoryResolution") != null)                _resolution = $"f{QueryDataClient.Instance.Service.GetConfig($"System.DataHistoryResolution")}";            base.OnActivate();        }        public void QueryStep(DateTime starTime, DateTime endTime)//, string recipeName去掉查询recipeName名称,有嵌套调用        {            starTime = starTime.AddMinutes(-1);            endTime = endTime.AddMinutes(1);            string sql = $"SELECT * FROM \"process_data\" where (\"process_begin_time\" >= '{starTime:yyyy/MM/dd HH:mm:ss.fff}' and \"process_end_time\" <= '{endTime:yyyy/MM/dd HH:mm:ss.fff}') order by \"process_begin_time\" DESC;";            DataTable dbData = QueryDataClient.Instance.Service.QueryData(sql);            if (dbData != null && dbData.Rows.Count > 0)            {                List<ProcessDataLot> ProcessDataLotList = new List<ProcessDataLot>();                for (int i = 0; i < dbData.Rows.Count; i++)                {                    ProcessDataLot item = new ProcessDataLot();                    item.GUID = dbData.Rows[i]["guid"].ToString();                    item.RecipeName = dbData.Rows[i]["recipe_name"].ToString();                    item.ProcessStatus = dbData.Rows[i]["process_status"].ToString();                    item.WaferDataGUID = dbData.Rows[i]["wafer_data_guid"].ToString();                    item.ProcessIn = dbData.Rows[i]["process_in"].ToString();                    if (!dbData.Rows[i]["process_begin_time"].Equals(DBNull.Value))                    {                        item.ProcessBeginTime = (DateTime)dbData.Rows[i]["process_begin_time"];                    }                    if (!dbData.Rows[i]["process_end_time"].Equals(DBNull.Value))                    {                        item.ProcessEndTime = (DateTime)dbData.Rows[i]["process_end_time"];                    }                    ProcessDataLotList.Add(item);                }                Annotations.Add(VerLine(Media.Brushes.Blue, ProcessDataLotList[0].ProcessBeginTime, Media.Brushes.Blue, $"{ProcessDataLotList[0].RecipeName}"));                Annotations.Add(VerLine(Media.Brushes.Blue, ProcessDataLotList[0].ProcessEndTime, Media.Brushes.Blue, $"Recipe End"));                string sql2 = $"SELECT * FROM \"recipe_step_data\" where";                sql2 += $" \"recipe_step_data\".\"process_data_guid\" = '{ProcessDataLotList[0].GUID.ToString()}'";                sql2 += " order by \"step_begin_time\" ASC;";                using (var table = QueryDataClient.Instance.Service.QueryData(sql2))                {                    if (!(table == null || table.Rows.Count == 0))                    {                        for (int i = 0; i < table.Rows.Count; i++)                        {                            var item = table.Rows[i];                            string startStepTime = "";                            string endStepTime = "";                            double stepTime = 0;                            if (!item["step_begin_time"].Equals(DBNull.Value))                                startStepTime = ((DateTime)item["step_begin_time"]).ToString("yyyy/MM/dd HH:mm:ss.fff");                            if (!item["step_end_time"].Equals(DBNull.Value))                                endStepTime = ((DateTime)item["step_end_time"]).ToString("yyyy/MM/dd HH:mm:ss.fff");                            if (!item["step_time"].Equals(DBNull.Value))                            {                                stepTime = (float)item["step_time"];                            }                            string stepNo = item["step_number"].ToString();                            string stepName = item["step_name"].ToString();                            if (DateTime.TryParse(startStepTime, out DateTime StartTime) && DateTime.TryParse(endStepTime, out DateTime EndTime))                            {                                //Annotations.Add(VerLine(Media.Brushes.AliceBlue, StartTime, Media.Brushes.Blue, $"{stepNo}"));                                if (EndTime < StartTime.AddSeconds(stepTime))                                {                                    EndTime = StartTime.AddSeconds(stepTime);                                }                                _stepInfo.Add(new StepInfo() { StartTime = StartTime, EndTime = EndTime, StepName = stepName, StepTime = stepTime, StepNo = stepNo });                            }                        }                    }                }            }        }        public static VerticalLineAnnotation VerLine(Media.Brush stroke, DateTime x, Media.Brush color, string text)        {            var label = new AnnotationLabel()            {                LabelPlacement = LabelPlacement.TopRight,                FontSize = 12,                RotationAngle = 0,                Foreground = color,                Text = text            };            var line = new VerticalLineAnnotation()            {                Stroke = stroke,                StrokeThickness = 1,                X1 = x,                IsEditable = false,                VerticalAlignment = VerticalAlignment.Stretch,                AnnotationLabels = new ObservableCollection<AnnotationLabel>() { label },            };            return line;        }        protected bool MonitorData()        {            try            {                if (_isAdding)                    return true;                bool allUpdated = true;                for (int j = 0; j < ParameterNodes.Count; j++)                {                    ParameterNode par = ParameterNodes[j];                    par.IsVisibilityParentNode = Visibility.Hidden;                }                lock (_lockSelection)                {                    foreach (var item in _lstTokenTimeData)                    {                        DateTime timeFrom = item.TimeToken;                        if (timeFrom >= item.DataLine.EndTime)                            continue;                        allUpdated = false;                        ChartAutoRange = AutoRange.Always;                        DateTime timeTo = timeFrom.AddMinutes(60);                        if (timeTo.DayOfYear > timeFrom.DayOfYear)                            timeTo = new DateTime(timeFrom.Year, timeFrom.Month, timeFrom.Day).AddDays(1);                        if (timeTo > item.DataLine.EndTime)                            timeTo = item.DataLine.EndTime;                        item.TimeToken = timeTo;                        GetData(item.DataList, timeFrom, timeTo, item.DataLine.Module, item.DataLine.DataSource);                        #region Update   VisualMin、VisualMax、DataStatisticsInfo                        Application.Current.Dispatcher.BeginInvoke(new Action(() =>                        {                            double min = ((DoubleRange)VisibleRangeValue).Min;                            double max = ((DoubleRange)VisibleRangeValue).Max;                            int PointCount = 0;                            foreach (var selectedData in SelectedData)                            {                                var seriesItem = selectedData as ChartDataLine<T>;                                if (seriesItem == null)                                    continue;                                double sumValue = 0;                                double minValue = 100000;                                double maxValue = 0;                                double averageValue = 0;                                double stdevValue = 0;                                double sigma3Value = 0;                                var pointValueList = seriesItem.Points.Select(x => x.Item2).ToList();                                for (int i = 0; i < pointValueList.Count; i++)                                {                                    sumValue += pointValueList[i];                                    if (pointValueList[i] < minValue)                                        minValue = pointValueList[i];                                    if (pointValueList[i] > maxValue)                                        maxValue = pointValueList[i];                                }                                averageValue = sumValue / pointValueList.Count;                                for (int i = 0; i < pointValueList.Count; i++)                                {                                    stdevValue += Math.Pow(pointValueList[i] - averageValue, 2);                                }                                stdevValue = stdevValue / pointValueList.Count;                                sigma3Value = Math.Sqrt(stdevValue) * 3;                                (seriesItem.Tag as ParameterNode).AverageValue = averageValue.ToString("F2");                                (seriesItem.Tag as ParameterNode).MinValue = minValue.ToString("F2");                                (seriesItem.Tag as ParameterNode).MaxValue = maxValue.ToString("F2");                                (seriesItem.Tag as ParameterNode).Sigma3Value = sigma3Value.ToString("F2");                                min = minValue;                                max = maxValue;                                PointCount = pointValueList.Count;                            }                            VisibleRangeValue = new DoubleRange(min, max);                        }));                        #endregion                    }                }                if (allUpdated)                {                    lock (_lockSelection)                    {                        while (_lstTokenTimeData.Count > 0)                        {                            _lstTokenTimeData.TryTake(out _);                        }                        ChartAutoRange = AutoRange.Never;                    }                }            }            catch (Exception ex)            {                LOG.Error(ex.Message);            }            return true;        }        public ObservableCollection<ParameterNode> GetParameters()        {            ObservableCollection<ParameterNode> rootNode = new ObservableCollection<ParameterNode>();            try            {                Dictionary<string, string> displayDic = QueryDataClient.Instance.Service.GetData("System.ProcessDetailDisplay") as Dictionary<string, string>;                if (displayDic == null)                    return rootNode;                List<string> dataList = new List<string>();                foreach (var key in displayDic.Keys)                {                    string[] item = key.Split('.');                    if (item != null)                    {                        if (item.Length == 2)                        {                            _processDetailDisplayDic.Add($"{item[1]}", displayDic[key]);                            dataList.Add($"{item[0]}.{item[1]}");                        }                        else if (item.Length == 3)                        {                            _processDetailDisplayDic.Add($"{item[1]} {item[2]}", displayDic[key]);                            dataList.Add($"{item[0]}.{item[1]}.{item[2]}");                        }                        //if (item[0] == "MFC") // MFC.MFCN1.Set                        //{                        //    if (item.Length > 2)                        //    {                        //        _processDetailDisplayDic.Add($"{item[1]} {item[2]}", displayDic[key]);                        //        dataList.Add($"{item[0]}.{item[1]}.{item[2]}");                        //    }                        //}                        //else if (item[0] == "MFM") // MFM.MFMH2.Actual                        //{                        //    if (item.Length > 2)                        //    {                        //        _processDetailDisplayDic.Add($"{item[1]} {item[2]}", displayDic[key]);                        //        dataList.Add($"{item[0]}.{item[1]}.{item[2]}");                        //    }                        //}                        //else if (item[0] == "Heater") // Heater.Paddle Set.TopZone                        //{                        //    if (item.Length > 2)                        //    {                        //        _processDetailDisplayDic.Add($"{item[1]} {item[2]}", displayDic[key]);                        //        dataList.Add($"{item[0]}.{item[1]}.{item[2]}");                        //    }                        //}                        //else // APC.Position Actual                        //{                        //    if (item.Length == 2)                        //    {                        //        _processDetailDisplayDic.Add($"{item[1]}", displayDic[key]);                        //        dataList.Add($"{item[0]}.{item[1]}");                        //    }                        //    else if (item.Length == 3)                        //    {                        //        _processDetailDisplayDic.Add($"{item[1]}.{item[2]}", displayDic[key]);                        //        dataList.Add($"{item[0]}.{item[1]}.{item[2]}");                        //    }                        //}                    }                }                //_keyValuePairs.Add("ChamberPressure", "PM1.ChamberPressure");                //_keyValuePairs.Add("Position.Set", "PM1.APC.PositionSetPoint");                //_keyValuePairs.Add("Position.Actual", "PM1.APC.PositionFeedback");                //_keyValuePairs.Add("Pressure.Set", "PM1.APC.PressureSetPoint");                //_keyValuePairs.Add("Pressure.Actual", "PM1.APC.PressureFeedback");                //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCD1.GasName")}.Set");                //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCD1.GasName")}.Actual");                //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCJ1.GasName")}.Set");                //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCJ1.GasName")}.Actual");                //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCM1.GasName")}.Set");                //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCM1.GasName")}.Actual");                //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCM2.GasName")}.Set");                //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCM2.GasName")}.Actual");                //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCN1.GasName")}.Set");                //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCN1.GasName")}.Actual");                //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCN2.GasName")}.Set");                //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCN2.GasName")}.Actual");                //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCN3.GasName")}.Set");                //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCN3.GasName")}.Actual");                //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCNR.GasName")}.Set");                //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCNR.GasName")}.Actual");                //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCNX.GasName")}.Set");                //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCNX.GasName")}.Actual");                //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCNY.GasName")}.Set");                //dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCNY.GasName")}.Actual");                //dataList.Add($"MFM.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFM.MfmD1.Name")}.Set");                //dataList.Add($"MFM.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFM.MfmD1.Name")}.Actual");                //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCD1.GasName")}.Set", "PM1.MfcD1.SetPoint");                //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCD1.GasName")}.Actual", "PM1.MfcD1.Feedback");                //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCJ1.GasName")}.Set", "PM1.MfcJ1.SetPoint");                //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCJ1.GasName")}.Actual", "PM1.MfcJ1.Feedback");                //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCM1.GasName")}.Set", "PM1.MfcM1.SetPoint");                //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCM1.GasName")}.Actual", "PM1.MfcM1.Feedback");                //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCM2.GasName")}.Set", "PM1.MfcM2.SetPoint");                //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCM2.GasName")}.Actual", "PM1.MfcM2.Feedback");                //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCN1.GasName")}.Set", "PM1.MfcN1.SetPoint");                //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCN1.GasName")}.Actual", "PM1.MfcN1.Feedback");                //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCN2.GasName")}.Set", "PM1.MfcN2.SetPoint");                //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCN2.GasName")}.Actual", "PM1.MfcN2.Feedback");                //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCN3.GasName")}.Set", "PM1.MfcN3.SetPoint");                //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCN3.GasName")}.Actual", "PM1.MfcN3.Feedback");                //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCNR.GasName")}.Set", "PM1.MfcNR.SetPoint");                //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCNR.GasName")}.Actual", "PM1.MfcNR.Feedback");                //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCNX.GasName")}.Set", "PM1.MfcNX.SetPoint");                //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCNX.GasName")}.Actual", "PM1.MfcNX.Feedback");                //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCNY.GasName")}.Set", "PM1.MfcNY.SetPoint");                //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFCNY.GasName")}.Actual", "PM1.MfcNY.Feedback");                //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFM.MfmD1.Name")}.Set", "PM1.MfmD1._setpoint");                //_keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFM.MfmD1.Name")}.Actual", "PM1.MfmD1.Feedback");                //for (int i = 11; i <= 16; i++)                //{                //    dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFC{i}.GasName")}.Set");                //    dataList.Add($"MFC.{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFC{i}.GasName")}.Actual");                //    _keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFC{i}.GasName")}.Set", $"PM1.Mfc{i}.SetPoint");                //    _keyValuePairs.Add($"{SystemConfigProvider.Instance.GetValueByName($"PM1.MFC.MFC{i}.GasName")}.Actual", $"PM1.Mfc{i}.Feedback");                //}                //for (int i = 1; i < 10; i += 2)                //{                //    dataList.Add($"Heater.Inner {SystemConfigProvider.Instance.GetValueByName($"PM1.Heater.Heater{i}.DisplayName")}.Set");                //    dataList.Add($"Heater.Inner {SystemConfigProvider.Instance.GetValueByName($"PM1.Heater.Heater{i}.DisplayName")}.Actual");                //    _keyValuePairs.Add($"Inner {SystemConfigProvider.Instance.GetValueByName($"PM1.Heater.Heater{i}.DisplayName")}.Set", $"PM1.Heater{i}.TempSetPoint");                //    _keyValuePairs.Add($"Inner {SystemConfigProvider.Instance.GetValueByName($"PM1.Heater.Heater{i}.DisplayName")}.Actual", $"PM1.Heater{i}.TempFeedback");                //}                //for (int i = 2; i <= 10; i += 2)                //{                //    dataList.Add($"Heater.Outer {SystemConfigProvider.Instance.GetValueByName($"PM1.Heater.Heater{i}.DisplayName")}.Set");                //    dataList.Add($"Heater.Outer {SystemConfigProvider.Instance.GetValueByName($"PM1.Heater.Heater{i}.DisplayName")}.Actual");                //    _keyValuePairs.Add($"Outer {SystemConfigProvider.Instance.GetValueByName($"PM1.Heater.Heater{i}.DisplayName")}.Set", $"PM1.Heater{i}.TempSetPoint");                //    _keyValuePairs.Add($"Outer {SystemConfigProvider.Instance.GetValueByName($"PM1.Heater.Heater{i}.DisplayName")}.Actual", $"PM1.Heater{i}.TempFeedback");                //}                Dictionary<string, ParameterNode> indexer = new Dictionary<string, ParameterNode>();                foreach (string dataName in dataList)                {                    string[] nodeName = dataName.Split('.');                    ParameterNode parentNode = null;                    string pathName = "";                    for (int i = 0; i < nodeName.Length; i++)                    {                        pathName = (i == 0 || i == 1) ? nodeName[i] : (pathName + " " + nodeName[i]);                        if (!indexer.ContainsKey(pathName))                        {                            indexer[pathName] = new ParameterNode() { Name = pathName, ChildNodes = new ObservableCollection<ParameterNode>(), ParentNode = parentNode };                            if (parentNode == null)                            {                                rootNode.Add(indexer[pathName]);                            }                            else                            {                                parentNode.ChildNodes.Add(indexer[pathName]);                            }                        }                        parentNode = indexer[pathName];                    }                }            }            catch (Exception ex)            {                LOG.Write(ex);            }            return rootNode;        }        private void GetData(List<string> keys, DateTime from, DateTime to, string module, string dataSource)        {            string sql = "select time AS InternalTimeStamp";            foreach (var dataKey in keys)            {                var dataId = _processDetailDisplayDic.ContainsKey(dataKey) ? _processDetailDisplayDic[dataKey] : dataKey;                sql += "," + string.Format("\"{0}\"", dataId);            }            sql += string.Format(" from \"{0}\" where time > {1} and time <= {2} order by time asc",                from.ToString("yyyyMMdd") + "." + module, from.Ticks, to.Ticks);            DataTable dataTable = QueryDataClient.Instance.Service.QueryData(sql);            Dictionary<string, List<HistoryDataItem>> historyData = new Dictionary<string, List<HistoryDataItem>>();            if (dataTable == null || dataTable.Rows.Count == 0)                return;            DateTime dt = new DateTime();            Dictionary<int, string> colName = new Dictionary<int, string>();            for (int colNo = 0; colNo < dataTable.Columns.Count; colNo++)            {                colName.Add(colNo, dataTable.Columns[colNo].ColumnName);                historyData[dataTable.Columns[colNo].ColumnName] = new List<HistoryDataItem>();            }            for (int rowNo = 0; rowNo < dataTable.Rows.Count; rowNo++)            {                var row = dataTable.Rows[rowNo];                for (int i = 0; i < dataTable.Columns.Count; i++)                {                    HistoryDataItem data = new HistoryDataItem();                    if (i == 0)                    {                        dt = new DateTime((long)row[i]);                        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];                            var value = float.Parse(row[i].ToString()).ToString(_resolution);                            data.value = float.Parse(value);                        }                    }                    historyData[data.dbName].Add(data);                }            }            foreach (var item in historyData)            {                item.Value.Sort((x, y) => DateTime.Compare(x.dateTime, y.dateTime));            }            Application.Current.Dispatcher.BeginInvoke(new Action(() =>            {                try                {                    var items = SelectedData.Where(x => (x as ChartDataLine<T>).DataSource == dataSource).ToList();                    foreach (var item in items)                    {                        var seriesItem = item as ChartDataLine<T>;                        if (seriesItem == null)                            continue;                        foreach (var data in historyData)                        {                            var dataKey = _processDetailDisplayDic.ContainsKey(seriesItem.DataName) ? _processDetailDisplayDic[seriesItem.DataName] : seriesItem.DataName;                            if (data.Key != dataKey)                                continue;                            seriesItem.Capacity += data.Value.Count;                            DateTime beginTime = StepStartTime;                            for (int i = 0; i < data.Value.Count; i++)                            {                                var historyDataItem = data.Value[i];                                if (typeof(T) == typeof(double))                                {                                    double xData;                                    xData = Math.Round((historyDataItem.dateTime - beginTime).TotalMilliseconds / 1000, 0, MidpointRounding.AwayFromZero);                                    seriesItem.Append((T)Convert.ChangeType(xData, typeof(T)), historyDataItem.value);                                }                                else                                    seriesItem.Append((T)Convert.ChangeType(historyDataItem.dateTime, typeof(T)), historyDataItem.value);                            }                        }                    }                    RefresCharView();                }                catch (Exception ex)                {                    LOG.Write(ex);                }            }));        }        private void SelectedDataChanged()        {            foreach (var item in SelectedData)            {                if (item.Stroke.Equals(System.Windows.Media.Color.FromArgb(255, 0, 0, 255)))                {                    Color drawingColor = colorQueue.Peek();                    item.Stroke = System.Windows.Media.Color.FromRgb(drawingColor.R, drawingColor.G, drawingColor.B);                    colorQueue.Enqueue(colorQueue.Dequeue());                }            }        }        public void TxtMouseLeftButtonDown(ParameterNode node)        {            node.Selected = !node.Selected;            ParameterCheck(node);        }        public void ParameterCheck(ParameterNode node)        {            bool result = RefreshTreeStatusToChild(node);            if (!result)            {                node.Selected = !node.Selected;                DialogBox.ShowWarning($"The max number of parameters is {MAX_PARAMETERS}.");            }            else            {                RefreshTreeStatusToParent(node);            }        }        /// <summary>        /// Refresh tree node status from current to children, and add data to SelectedData        /// </summary>        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;                        }                        return false;                    }                }            }            else //leaf node            {                bool lockTaken = false;                try                {                    Monitor.TryEnter(_lockSelection, 1000, ref lockTaken);                    if (lockTaken)                    //lock (_lockSelection)                    {                        var item = SelectedData.FirstOrDefault(x => (x as ChartDataLine<T>).DataName == node.Name);                        bool isExist = item != null;                        if (isExist && !node.Selected)//删除                        {                            SelectedData = new ObservableCollection<IRenderableSeries>(SelectedData.Where(d => (d as ChartDataLine<T>).DataName != node.Name));                        }                        else                        {                            if (node.Selected)                            {                                if (SelectedData.Count >= MAX_PARAMETERS)                                    return false;                                var dataId = _processDetailDisplayDic.ContainsKey(node.Name) ? _processDetailDisplayDic[node.Name] : node.Name;                                var module = dataId.Split('.').ToList()[0];                                _isAdding = true;                                foreach (var recipe in RecipeDatas)                                {                                    TimeChartDataLine line;                                    if (IsStepVisiable)                                        line = new TimeChartDataLine(node.Name.Replace("Tube", "PM1"), module, StepStartTime, StepEndTime);                                    else                                        line = new TimeChartDataLine(node.Name.Replace("Tube", "PM1"), module, recipe.StartTime, recipe.EndTime);                                    line.DataSource = $"{recipe.BatchID}.{recipe.RecipeName}";                                    line.Tag = node;                                    if (isExist)                                    {                                        line.Stroke = item.Stroke;                                        line.ClearData();                                        SelectedData.Remove(item);                                    }                                    SelectedData.Add(line);                                    AddToMonitor(line);                                }                                _isAdding = false;                                if (!isExist)                                    SelectedDataChanged();                            }                        }                        this.NotifyOfPropertyChange(nameof(SelectedData));                        //}                    }                }                finally                {                    if (lockTaken)                    {                        Monitor.Exit(_lockSelection);                    }                }            }            return true;        }        private void AddToMonitor(TimeChartDataLine line)        {            QueryIndexer indexer = new QueryIndexer()            {                DataLine = line,                DataList = new List<string>() { line.DataName },                TimeToken = line.StartTime,            };            _lstTokenTimeData.Add(indexer);        }        /// <summary>        /// Refresh tree node status from current to parent        /// </summary>        /// <param name="node"></param>        /// <returns></returns>        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()        {            //uncheck all tree nodes            foreach (ChartDataLine<T> cp in SelectedData)            {                (cp.Tag as ParameterNode).Selected = false;                RefreshTreeStatusToParent(cp.Tag as ParameterNode);            }            SelectedData.Clear();        }        private void SetParameterNode(ObservableCollection<ParameterNode> nodes, bool isChecked)        {            foreach (ParameterNode n in nodes)            {                n.Selected = isChecked;                SetParameterNode(n.ChildNodes, isChecked);            }        }        public void Delete(ChartDataLine<T> cp)        {            if (cp != null && SelectedData.Contains(cp))            {                //uncheck tree node                (cp.Tag as ParameterNode).Selected = false;                RefreshTreeStatusToParent(cp.Tag as ParameterNode);                SelectedData.Remove(cp);            }        }        public async void ExportAll()        {            try            {                if (SelectedData.Count == 0)                {                    MessageBox.Show($"Please select the data you want to export.", "Export", MessageBoxButton.OK,                        MessageBoxImage.Warning);                    return;                }                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 = $"{DisplayName}_{string.Join(",", RecipeDatas.Select(x => x.RecipeName).ToArray())}_{DateTime.Now:yyyyMMdd_HHmmss}";                Nullable<bool> result = dlg.ShowDialog();// Show open file dialog box                if (result == true) // Process open file dialog box results                {                    Exporting?.Invoke(this, System.EventArgs.Empty);                    _cancellationTokenSource = new CancellationTokenSource();                    var sw = new Stopwatch();                    sw.Restart();                    System.Data.DataSet ds = new System.Data.DataSet();                    ds.Tables.Add(new System.Data.DataTable($"{DisplayName}_{DateTime.Now:yyyyMMdd_HHmmss}"));                    ds.Tables[0].Columns.Add("Recipe Info");                    ds.Tables[0].Columns[0].DataType = typeof(string);                    ds.Tables[0].Columns.Add("Date");                    ds.Tables[0].Columns[1].DataType = typeof(string);                    ds.Tables[0].Columns.Add("Time");                    ds.Tables[0].Columns[2].DataType = typeof(string);                    ds.Tables[0].Columns.Add("Step ID");                    ds.Tables[0].Columns[3].DataType = typeof(string);                    ds.Tables[0].Columns.Add("Step Name");                    ds.Tables[0].Columns[4].DataType = typeof(string);                    Dictionary<T, double[]> timeValue = new Dictionary<T, double[]>();                    await Task.Run(() =>                    {                        for (int i = 0; i < SelectedData.Count; i++)                        {                            List<Tuple<T, double>> data = (SelectedData[i] as ChartDataLine<T>).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<T>).DataName);                            ds.Tables[0].Columns[i + 5].DataType = typeof(double);                        }                        var recipeInfoRow = ds.Tables[0].NewRow();                        recipeInfoRow[0] = $"Recipe:{string.Join(",", RecipeDatas.Select(x => x.RecipeName).ToArray())}";                        ds.Tables[0].Rows.Add(recipeInfoRow);                        recipeInfoRow = ds.Tables[0].NewRow();                        recipeInfoRow[0] = $"Start Time";                        recipeInfoRow[1] = string.Join(",", RecipeDatas.Select(x => x.StartTime).ToArray());                        recipeInfoRow[2] = string.Join(",", RecipeDatas.Select(x => x.StartTime).ToArray());                        ds.Tables[0].Rows.Add(recipeInfoRow);                        recipeInfoRow = ds.Tables[0].NewRow();                        recipeInfoRow[0] = $"End Time";                        recipeInfoRow[1] = string.Join(",", RecipeDatas.Select(x => x.EndTime).ToArray());                        recipeInfoRow[2] = string.Join(",", RecipeDatas.Select(x => x.EndTime).ToArray());                        ds.Tables[0].Rows.Add(recipeInfoRow);                        DateTime startTime = StepStartTime;                        QueryDataClientFromTable(ds);                    }, _cancellationTokenSource.Token).ContinueWith(t =>                 {                     if (t.IsCanceled || t.IsFaulted)                         return;                 });                    if (_cancellationTokenSource?.Token.IsCancellationRequested == true)                        return;                    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 DGSelectionChanged(object sender, EventArgs e)        {            var temp = (DataGrid)sender;            var tempSelected = (IRenderableSeries)temp.SelectedItem;            tempSelected.IsVisible = !tempSelected.IsVisible;        }        private void QueryDataClientFromTable(DataSet ds)        {            DateTime startTime = StepStartTime;            DateTime endTime = StepEndTime;            if (StepStartTime.Date == StepEndTime.Date)            {                SaveDataToTable(ds, startTime, endTime);            }            else            {                endTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, 23, 59, 59);                while (endTime < StepEndTime)                {                    SaveDataToTable(ds, startTime, endTime);                    startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, 0, 0, 0).AddDays(1);                    endTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, 23, 59, 59);                }                SaveDataToTable(ds, startTime, StepEndTime);            }        }        private void SaveDataToTable(DataSet ds, DateTime startTime, DateTime endTime)        {            string stepID = "", stepName = "";            string pmsql = "select time AS InternalTimeStamp";            List<string> keys = SelectedData.Select(x => (x as ChartDataLine<T>).DataName).ToList();            DataTable pmDataTable = null;            if (keys != null && keys.Count > 0)            {                List<string> pmList = new List<string>();                foreach (var dataKey in keys)                {                    var dataId = _processDetailDisplayDic.ContainsKey(dataKey) ? _processDetailDisplayDic[dataKey] : dataKey;                    var module = dataId.Split('.').ToList()[0];                    if (module.ToLower() == "pm1")                    {                        pmList.Add(dataId);                        pmsql += "," + string.Format("\"{0}\"", dataId);                    }                }                if (pmList.Count > 0)                {                    pmsql += string.Format(" from \"{0}\" where time > {1} and time <= {2} order by time asc",                        startTime.ToString("yyyyMMdd") + "." + "PM1", startTime.Ticks, endTime.Ticks);                    pmDataTable = QueryDataClient.Instance.Service.QueryData(pmsql);                    if (pmDataTable == null)                    {                        MessageBox.Show($"Export failed, sql:{pmsql}", "Export", MessageBoxButton.OK, MessageBoxImage.Warning);                        return;                    }                }            }            string systemsql = "select time AS InternalTimeStamp";            DataTable systemDataTable = null;            if (keys != null && keys.Count > 0)            {                List<string> systemList = new List<string>();                foreach (var dataKey in keys)                {                    var dataId = _processDetailDisplayDic.ContainsKey(dataKey) ? _processDetailDisplayDic[dataKey] : dataKey;                    var module = dataId.Split('.').ToList()[0];                    if (module.ToLower() == "system")                    {                        systemsql += "," + string.Format("\"{0}\"", dataId);                        systemList.Add(dataId);                    }                }                if (systemList.Count > 0)                {                    systemsql += string.Format(" from \"{0}\" where time > {1} and time <= {2} order by time asc",                        startTime.ToString("yyyyMMdd") + "." + "System", startTime.Ticks, endTime.Ticks);                    systemDataTable = QueryDataClient.Instance.Service.QueryData(systemsql);                    if (systemDataTable == null)                    {                        MessageBox.Show($"Export failed, sql:{systemsql}", "Export", MessageBoxButton.OK, MessageBoxImage.Warning);                        return;                    }                }            }            int maxRow = 0;            if ((pmDataTable == null || pmDataTable.Rows.Count == 0))            {                if (systemDataTable != null)                {                    maxRow = systemDataTable.Rows.Count;                }            }            else if ((systemDataTable == null || systemDataTable.Rows.Count == 0))            {                if (pmDataTable != null)                {                    maxRow = pmDataTable.Rows.Count;                }            }            else            {                maxRow = pmDataTable.Rows.Count > systemDataTable.Rows.Count ? systemDataTable.Rows.Count : pmDataTable.Rows.Count;            }            for (int i = 0; i < maxRow; i++)            {                var pmRow = pmDataTable != null ? pmDataTable.Rows[i] : null;                var systemRow = systemDataTable != null ? systemDataTable.Rows[i] : null;                //float timeIndex = 0;                //float.TryParse(item.Key.ToString(), out timeIndex);                //DateTime dateTimeKey = startTime.AddMilliseconds(timeIndex * 1000); ;// DateTime.Parse(item.Key.ToString());                DateTime dateTimeKey = new DateTime(pmRow != null ? (long)pmRow[0] : (long)systemRow[0]);                var tempStepInfo = _stepInfo.FirstOrDefault(x => x.StartTime < dateTimeKey && x.EndTime > dateTimeKey);                if (tempStepInfo != null)// && dateTimeKey > _stepInfo[iIndex].StartTime                {                    stepID = tempStepInfo.StepNo;                    stepName = tempStepInfo.StepName;                }                var row = ds.Tables[0].NewRow();                row[1] = dateTimeKey.ToString("yyyy/MM/dd");                row[2] = dateTimeKey.ToString("HH:mm:ss:fff");                row[3] = stepID;                row[4] = stepName;                for (int j = 5; j < ds.Tables[0].Columns.Count; j++)                {                    string colName = ds.Tables[0].Columns[j].ColumnName;                    DataRow dataRow = null;                    var dataId = _processDetailDisplayDic.ContainsKey(colName) ? _processDetailDisplayDic[colName] : colName;                    var module = dataId.Split('.').ToList()[0];                    int index = 0;                    if (module == "PM1")                    {                        dataRow = pmRow;                        foreach (var item in pmDataTable.Columns)                        {                            if (((DataColumn)item).ColumnName == dataId)                            {                                break;                            }                            index++;                        }                    }                    else if (module == "System")                    {                        dataRow = systemRow;                        foreach (var item in systemDataTable.Columns)                        {                            if (((DataColumn)item).ColumnName == dataId)                            {                                break;                            }                            index++;                        }                    }                    if (dataRow[index] is DBNull || dataRow[index] == null)                    {                        row[j] = dataRow[index];                    }                    else if (dataRow[index] is bool)                    {                        row[j] = (bool)dataRow[index] ? 1 : 0;                    }                    else                    {                        var value = float.Parse(dataRow[index].ToString()).ToString(_resolution);                        row[j] = float.Parse(value);                    }                }                ds.Tables[0].Rows.Add(row);            }        }        public void Export(ChartDataLine<T> cp)        {            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<bool> 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);                    DateTime startTime = StepStartTime;                    foreach (var item in cp.Points)                    {                        var row = ds.Tables[0].NewRow();                        row[0] = startTime.AddMilliseconds(Convert.ToDouble(item.Item1) * 1000);                        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<T> 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 };            }        }        public void CloseCmd()        {            ((Window)GetView()).Close();        }        #endregion        #region SciChart Move        public void RefresCharView()        {            this.view.sciChart.ZoomExtents();        }        public void ToLeftClick()        {            //var view = GetView() as ProcessDetailView;            this.view.sciChart.ChartModifier.XAxis.Scroll(-50, SciChart.Charting.ClipMode.ClipAtMin);        }        public void ToRightClick()        {            //var view = GetView() as ProcessDetailView;            this.view.sciChart.ChartModifier.XAxis.Scroll(50, SciChart.Charting.ClipMode.ClipAtMax);        }        public void ZoomInClick()        {            //var view = GetView() as ProcessDetailView;            this.view.sciChart.ChartModifier.XAxis.ZoomBy(-0.1, -0.1);            this.view.sciChart.ChartModifier.YAxis.ZoomBy(-0.1, -0.1);        }        public void ZoomOutClick()        {            //var view = GetView() as ProcessDetailView;            this.view.sciChart.ChartModifier.XAxis.ZoomBy(0.1, 0.1);            this.view.sciChart.ChartModifier.YAxis.ZoomBy(0.1, 0.1);        }        public void ToMoveUpClick()        {            //var view = GetView() as ProcessDetailView;            this.view.sciChart.ChartModifier.YAxis.Scroll(-50, SciChart.Charting.ClipMode.ClipAtMin);        }        public void ToMoveDownClick()        {            //var view = GetView() as ProcessDetailView;            this.view.sciChart.ChartModifier.YAxis.Scroll(50, SciChart.Charting.ClipMode.ClipAtMax);        }        public void SelectStep()        {            ObservableCollection<Option> Items = new ObservableCollection<Option>();            foreach (var item in StepInfo)            {                Items.Add(new Option() { Name = $"{item.StepNo} {item.StepName}", Index = int.Parse(item.StepNo) });            }            ItemsSelectDialogViewModel itemsSelectDialogView = new ItemsSelectDialogViewModel();            itemsSelectDialogView.Items = Items;            itemsSelectDialogView.ColumnsCount = Items.Count / 10 + 1;            WindowManager windowManager = IoC.Get<IWindowManager>() as WindowManager;            if ((bool)(windowManager as WindowManager)?.ShowDialogWithNoWindow(itemsSelectDialogView))            {                var startItem = StepInfo.FirstOrDefault(step => step.StepNo == Items.FirstOrDefault(x => x.IsChecked)?.Index.ToString());                var endItem = StepInfo.FirstOrDefault(step => step.StepNo == Items.LastOrDefault(x => x.IsChecked)?.Index.ToString());                if (startItem == null)                {                    DialogBox.ShowError("Please select begin step!");                    return;                }                if (endItem == null)                {                    DialogBox.ShowError("Please select end step!");                    return;                }                if (Items.Where(x => x.IsChecked).Count() > 2)                {                    DialogBox.ShowError("The selected step numbers must be 1 or 2.");                    return;                }                StepStartTime = startItem.StartTime;                StepEndTime = endItem.EndTime;                List<ParameterNode> allCheckNode = new List<ParameterNode>();                ParameterNodes.ToList().ForEach(x =>                {                    allCheckNode.AddRange(GetAllCheckedLeafNode(x));                });                allCheckNode.ForEach(x => { ParameterCheck(x); });            }        }        private List<ParameterNode> GetAllCheckedLeafNode(ParameterNode parameterNode)        {            List<ParameterNode> retNodes = new List<ParameterNode>();            if (parameterNode.ChildNodes != null && parameterNode.ChildNodes.Count > 0)            {                foreach (var item in parameterNode.ChildNodes)                {                    retNodes.AddRange(GetAllCheckedLeafNode(item));                }            }            else            {                if (parameterNode.Selected)                    retNodes.Add(parameterNode);            }            return retNodes;        }        private void GridMouseLeftButtonDown(ChartDataLine<T> chartDataLine)        {            chartDataLine.IsVisible = !chartDataLine.IsVisible;        }        #endregion        #endregion    }    public class ProcessDataLot : NotifiableItem    {        private string _guid;        public string GUID        {            get => _guid;            set            {                _guid = value;                InvokePropertyChanged(nameof(GUID));            }        }        private DateTime _processBeginTime;        public DateTime ProcessBeginTime        {            get => _processBeginTime;            set            {                _processBeginTime = value;                InvokePropertyChanged(nameof(ProcessBeginTime));            }        }        private DateTime _processEndTime;        public DateTime ProcessEndTime        {            get => _processEndTime;            set            {                _processEndTime = value;                InvokePropertyChanged(nameof(ProcessEndTime));            }        }        private string _recipeName;        public string RecipeName        {            get => _recipeName;            set            {                _recipeName = value;                InvokePropertyChanged(nameof(RecipeName));            }        }        private string _processStatus;        public string ProcessStatus        {            get => _processStatus;            set            {                _processStatus = value;                InvokePropertyChanged(nameof(ProcessStatus));            }        }        private string _waferDataguid;        public string WaferDataGUID        {            get => _waferDataguid;            set            {                _waferDataguid = value;                InvokePropertyChanged(nameof(WaferDataGUID));            }        }        private string _processIn;        public string ProcessIn        {            get => _processIn;            set            {                _processIn = value;                InvokePropertyChanged(nameof(ProcessIn));            }        }        private int _recipeSettingTime;        public int RecipeSettingTime        {            get => _recipeSettingTime;            set            {                _recipeSettingTime = value;                InvokePropertyChanged(nameof(RecipeSettingTime));            }        }    }}
 |