Sfoglia il codice sorgente

Reformat DBInfoTrace

Zixuan 22 ore fa
parent
commit
e9a9ecea97

+ 1 - 0
Analizer/ProximaAnalizer/App.xaml.cs

@@ -24,6 +24,7 @@ public partial class App : PrismApplication
         containerRegistry.RegisterForNavigation<DBInfoAlarm, DBInfoAlarmViewModel>("DBInfoAlarm");
 
         containerRegistry.RegisterDialog<LinePicker, DialogPickerViewModel>("LinePicker");
+        containerRegistry.RegisterDialog<TraceDataList, TraceDataListViewModel>("TraceData");
 
         containerRegistry.RegisterSingleton<SqlSugarCustom>();
         containerRegistry.RegisterSingleton<TraceData>();

+ 100 - 0
Analizer/ProximaAnalizer/Helpers/DBDisplayHelper.cs

@@ -0,0 +1,100 @@
+namespace ProximaAnalizer.Helpers;
+
+internal class DBDisplayHelper(IDictionary<string, object> Left, IDictionary<string, object> Right)
+{
+    public readonly HashSet<DateTime> Time = [];
+    public readonly Dictionary<string, List<float>> DataLeft = [];
+    public readonly Dictionary<string, List<float>> DataRight = [];
+
+    public void CreateData(List<dynamic> main, List<dynamic> sub)
+    {
+        while (main.Count != sub.Count!)
+        {
+            switch (main.Count > sub.Count)
+            {
+                case true:
+                    main.RemoveAt(main.Count - 1);
+                    break;
+                case false:
+                    sub.RemoveAt(sub.Count - 1);
+                    break;
+            }
+        }
+
+        foreach (var item in main)
+        {
+            if (item is not IDictionary<string, object> data)
+                continue;
+
+            long ticks = (long)data["time"];
+            //ticks -= ticks % 10000000;
+            DateTime time = new(ticks);
+            Time.Add(time);
+
+            foreach (string key in Left.Keys)
+            {
+                if (!data.TryGetValue(key, out object? value) || value is null)
+                    continue;
+
+                if (!DataLeft.TryGetValue(key, out List<float>? collections) || collections is null)
+                {
+                    collections = [];
+                    DataLeft[key] = collections;
+                }
+                collections.Add(Convert.ToSingle(value));
+            }
+
+            foreach (string key in Right.Keys)
+            {
+                if (!data.TryGetValue(key, out object? value) || value is null)
+                    continue;
+
+                if (!DataRight.TryGetValue(key, out List<float>? collections) || collections is null)
+                {
+                    collections = [];
+                    DataRight[key] = collections;
+                }
+                collections.Add(Convert.ToSingle(value));
+            }
+        }
+
+        foreach (var item in sub)
+        {
+            if (item is not IDictionary<string, object> data)
+                continue;
+
+            foreach (string key in Left.Keys)
+            {
+                if (!data.TryGetValue(key, out object? value) || value is null)
+                    continue;
+
+                if (!DataLeft.TryGetValue(key, out List<float>? collections) || collections is null)
+                {
+                    collections = [];
+                    DataLeft[key] = collections;
+                }
+                collections.Add(Convert.ToSingle(value));
+            }
+
+            foreach (string key in Right.Keys)
+            {
+                if (!data.TryGetValue(key, out object? value) || value is null)
+                    continue;
+
+                if (!DataRight.TryGetValue(key, out List<float>? collections) || collections is null)
+                {
+                    collections = [];
+                    DataRight[key] = collections;
+                }
+                collections.Add(Convert.ToSingle(value));
+            }
+        }
+    }
+
+    public void ClearData()
+    {
+        this.Time.Clear();
+        this.DataLeft.Clear();
+        this.DataRight.Clear();
+    }
+}

+ 209 - 0
Analizer/ProximaAnalizer/Helpers/DBProcessData.cs

@@ -0,0 +1,209 @@
+using Universal;
+
+namespace ProximaAnalizer.Helpers;
+
+public class DBProcessData<T_Hierarchy>(char spilter, int skip)
+    where T_Hierarchy : IDictionary<string, object>, new()
+{
+    public bool ToDictionary(IDictionary<string, object> input, out T_Hierarchy? output)
+    {
+        output = default;
+
+        if (input is null)
+            return false;
+
+        T_Hierarchy cache = [];
+        foreach (KeyValuePair<string, object> rawData in input)
+        {
+            Span<string> source = rawData.Key.Split(spilter).AsSpan()[skip..];
+            ColumAnalizer(cache, source, rawData.Key);
+        }
+
+        output = cache;
+        return true;
+    }
+
+    private static void ColumAnalizer(/*ref*/ T_Hierarchy cache, Span<string> seprated, object value)
+    {
+        if (seprated.Length <= 1)
+        {
+            cache[seprated[0]] = value;
+            return;
+        }
+
+        if (!cache.TryGetValue(seprated[0], out object? output) || output is not T_Hierarchy hierarchy)
+        {
+            hierarchy = [];
+            cache[seprated[0]] = hierarchy;
+        }
+
+        cache = hierarchy;
+        ColumAnalizer(cache, seprated[1..], value);
+    }
+}
+
+public class GeneralProcessData(int skip = 0) : DBProcessData<Dictionary<string, object>>('.', skip)
+{
+    public bool CreateTablePM(IDictionary<string, object> data, IDictionary<string, object> cache)
+    {
+        Dictionary<string, object> ValueSensor = [];
+        Dictionary<string, object> StatusSensor = [];
+        Dictionary<string, object> leakCheck = [];
+        Dictionary<string, object> recipe = [];
+        Dictionary<string, object> aoValue = [];
+
+        Dictionary<string, object> ffu = [];
+        Dictionary<string, object> mfc = [];
+        Dictionary<string, object> gaslineHeater = [];
+        Dictionary<string, object> bufferFoup = [];
+        Dictionary<string, object> avValue = [];
+
+        foreach (var item in data)
+        {
+            if (item.Value is not IDictionary<string, object> values)
+            {
+                switch (item.Key)
+                {
+                    case string s when s.EndsWith("Enable"):
+                        continue;
+                    case string s when s.StartsWith("LeakCheck"):
+                        leakCheck.Add(item.Key, item.Value);
+                        continue;
+                    default:
+                        recipe.Add(item.Key, item.Value);
+                        continue;
+                }
+            }
+
+            switch (item.Key)
+            {
+                case "APC":
+                case "APCVATGV":
+                case "BoatElevatorServo":
+                case "BoatRotationServo":
+                case "BufferServo":
+                case "Shutter":
+                    CreateTable(cache, item.Key, values);
+                    continue;
+
+                case string s when s.StartsWith("Trig"):
+                    if (item.Value is IDictionary<string, object> value)
+                        aoValue.Add(item.Key, value["AOValue"]);
+                    continue;
+
+                case string s when s.StartsWith("FS"):
+                case string s1 when s1.StartsWith("PG"):
+                case string s2 when s2.StartsWith("PS"):
+                case string s3 when s3.StartsWith("VG"):
+                    if (item.Value is IDictionary<string, object> vss)
+                        ValueSensor.Add(item.Key, vss["Value"]);
+                    continue;
+
+                case string s when s.StartsWith("Sensor"):
+                    if (item.Value is IDictionary<string, object> status)
+                        StatusSensor.Add(item.Key, status["Value"]);
+                    continue;
+                case string s when s.StartsWith("MFC"):
+                    if (item.Value is IDictionary<string, object> mfcs)
+                        mfcs.Foreach(t => mfc.Add($"{item.Key}_{t.Key}", t.Value));
+                    continue;
+                case string s when s.StartsWith("FFU"):
+                    if (item.Value is IDictionary<string, object> ffus)
+                        ffus.Foreach(t => ffu.Add($"{item.Key}_{t.Key}", t.Value));
+                    continue;
+                case string s when s.StartsWith("GaselineHeater"):
+                    if (item.Value is IDictionary<string, object> gaslines)
+                        gaslines.Foreach(t => gaslineHeater.Add($"{item.Key}_{t.Key}", t.Value));
+                    continue;
+                case string s when s.StartsWith("Valve"):
+                    if (item.Value is IDictionary<string, object> valves)
+                        valves.Foreach(t => avValue.Add($"{item.Key}_{t.Key}", t.Value));
+                    continue;
+                default:
+                    continue;
+            }
+        }
+        CreateTable(cache, "MFC", mfc);
+        CreateTable(cache, "FFU", ffu);
+        CreateTable(cache, "Valve", avValue);
+        CreateTable(cache, "GaselineHeater", gaslineHeater);
+        CreateTable(cache, "ValueSensor", ValueSensor);
+        CreateTable(cache, "StatusSensor", StatusSensor);
+        CreateTable(cache, "LeakCheck", leakCheck);
+        CreateTable(cache, "AoValue", aoValue);
+        CreateTable(cache, "Recipe", recipe);
+
+        return true;
+    }
+
+    public void CreateTableSystem(IDictionary<string, object> data, IDictionary<string, object> cache)
+    {
+        Dictionary<string, object> systemCollection = [];
+        Dictionary<string, object> alarmCollection = [];
+
+        Dictionary<string, object> Heater = [];
+        Dictionary<string, object> Stocker = [];
+        Dictionary<string, object> LoadPort = [];
+        Dictionary<string, object> FIMS = [];
+
+        foreach (var item in data)
+        {
+            if (item.Value is not IDictionary<string, object> values)
+                continue;
+
+            switch (item.Key)
+            {
+                case "Boat":
+                case "CarrierRobot":
+                case "Scheduler":
+                case "WaferRobot":
+                    CreateTable(cache, item.Key, values);
+                    continue;
+                case string s when s.StartsWith("Stocker"):
+                    Stocker.Add(item.Key, values);
+                    continue;
+                case string s when s.StartsWith("LP"):
+                    LoadPort.Add(item.Key, values);
+                    continue;
+                //case string s when s.StartsWith("FIMS"):
+                //    FIMS.Add(item.Key, values);
+                //    continue;
+
+                case "System":
+                    if (values is not IDictionary<string, object> systems)
+                        continue;
+                    foreach (var system in systems)
+                    {
+                        switch (system.Key)
+                        {
+                            case string s when s.StartsWith("Heater"):
+                                Heater.Add(system.Key, system.Value);
+                                continue;
+                            case string s when s.StartsWith("AlarmSignalHeater"):
+                                alarmCollection.Add(system.Key, ((IDictionary<string, object>)system.Value)["Value"] ??= false);
+                                continue;
+                            default:
+                                systemCollection.Add(system.Key, system.Value);
+                                break;
+                        }
+                    }
+                    continue;
+                default:
+                    break;
+            }
+
+            //CreateTable(cache, "FIMS", FIMS);
+            CreateTable(cache, "Heater", Heater);
+            CreateTable(cache, "LoadPort", LoadPort);
+            CreateTable(cache, "Stocker", Stocker);
+            CreateTable(cache, "System", systemCollection);
+            CreateTable(cache, "AlarmSignalHeater", alarmCollection);
+        }
+    }
+
+    private bool CreateTable(IDictionary<string, object> cache, string key, object value)
+    {
+        return cache.TryAdd(key, value);
+    }
+
+}

+ 85 - 0
Analizer/ProximaAnalizer/Helpers/PlotHepler.cs

@@ -0,0 +1,85 @@
+using ScottPlot;
+using ScottPlot.Plottables;
+using ScottPlot.WPF;
+using System.Windows.Media;
+
+namespace ProximaAnalizer.Helpers;
+
+internal class PlotHepler(WpfPlot PlotControl)
+{
+    public void InitPlot()
+    {
+        PlotControl.Plot.Grid.XAxisStyle.MajorLineStyle.Width = 1f;
+        PlotControl.Plot.Grid.YAxisStyle.MajorLineStyle.Width = 1f;
+        PlotControl.Plot.Axes.Bottom.TickLabelStyle.Alignment = Alignment.MiddleLeft;
+        PlotControl.Plot.Axes.DateTimeTicksBottom();
+        PlotControl.Background = (Brush)App.Current.Resources.FindName("BackgroundColor");
+        PlotControl.Plot.RenderManager.RenderStarting += (s, e) =>
+        {
+            Tick[] ticks = PlotControl.Plot.Axes.Bottom.TickGenerator.Ticks;
+            for (int i = 0; i < ticks.Length; i++)
+            {
+                DateTime dt = DateTime.FromOADate(ticks[i].Position);
+                //string label = $"{dt:MM-dd  HH:mm:ss}";
+                string label = $"{dt:HH:mm:ss}";
+                ticks[i] = new Tick(ticks[i].Position, label);
+            }
+        };
+
+        PlotControl.Plot.FigureBackground.Color = ScottPlot.Colors.Transparent;
+        PlotControl.Plot.Axes.Bottom.TickLabelStyle.Rotation = 90;
+        PlotControl.Plot.Axes.Bottom.TickLabelStyle.Alignment = Alignment.MiddleLeft;
+        PixelPadding padding = new(48, 48, 56, 40);
+        PlotControl.Plot.Layout.Fixed(padding);
+        PlotControl.Plot.FigureBackground.Color = ScottPlot.Colors.Transparent;
+
+        PlotControl.Plot.Grid.MajorLineColor = ScottPlot.Colors.LightGray.WithOpacity(1);
+        PlotControl.Plot.Grid.MajorLineWidth = 2;
+
+        PlotControl.Plot.Grid.MinorLineColor = ScottPlot.Colors.Black.WithOpacity(.2);
+        PlotControl.Plot.Grid.MinorLineWidth = 0f;
+    }
+
+
+    public void AddLeftLine(IEnumerable<DateTime> time, List<float> value, LinePattern linePattern, MarkerStyle markerStyle, float lineWidth, string color)
+    {
+        Scatter mainScatter = PlotControl.Plot.Add.Scatter(time.ToList(), value);
+        mainScatter.MarkerStyle = markerStyle;
+        mainScatter.LineWidth = lineWidth;
+        mainScatter.LinePattern = linePattern;
+        mainScatter.Color = new ScottPlot.Color(color);
+        mainScatter.Axes.YAxis = PlotControl.Plot.Axes.Left;
+    }
+
+    public void AddRightLine(IEnumerable<DateTime> time, List<float> value, LinePattern linePattern, MarkerStyle markerStyle, float lineWidth, string color)
+    {
+        Scatter mainScatter = PlotControl.Plot.Add.Scatter(time.ToList(), value);
+        mainScatter.MarkerStyle = markerStyle;
+        mainScatter.LineWidth = lineWidth;
+        mainScatter.LinePattern = linePattern;
+        mainScatter.Color = new ScottPlot.Color(color);
+        mainScatter.Axes.YAxis = PlotControl.Plot.Axes.Right;
+    }
+
+    public bool AddAlarmLine(DateTime dateTime, string text)
+    {
+        var line = PlotControl.Plot.Add.VerticalLine(dateTime.ToOADate());
+        line.Color = new ScottPlot.Color("DC143C");
+        line.Text = text;
+        line.LineWidth = 0.4f;
+        line.LabelOppositeAxis = true;
+        return true;
+    }
+
+    public bool AddWarningLine(DateTime dateTime, string text)
+    {
+        var line = PlotControl.Plot.Add.VerticalLine(dateTime.ToOADate());
+        line.Color = new ScottPlot.Color("FFA500");
+        line.LineWidth = 0.4f;
+        line.Text = text;
+        line.LabelOppositeAxis = true;
+        return true;
+    }
+
+
+}

+ 3 - 0
Analizer/ProximaAnalizer/ProximaAnalizer.csproj.user

@@ -11,6 +11,9 @@
     <Compile Update="Views\Dialog\LinePicker.xaml.cs">
       <SubType>Code</SubType>
     </Compile>
+    <Compile Update="Views\Dialog\TraceDataList.xaml.cs">
+      <SubType>Code</SubType>
+    </Compile>
     <Compile Update="Views\Loading.xaml.cs">
       <SubType>Code</SubType>
     </Compile>

+ 59 - 358
Analizer/ProximaAnalizer/ViewModels/DBInfoTraceViewModel.cs

@@ -1,4 +1,6 @@
 using Mapster;
+using OpenTK.Graphics.ES20;
+using ProximaAnalizer.Helpers;
 using ScottPlot;
 using ScottPlot.Plottables;
 using ScottPlot.WPF;
@@ -19,47 +21,23 @@ internal partial class DBInfoTraceViewModel : ObservableObject
         this.traceData = traceData;
         this.sqlSugarCustom = sqlSugarCustom;
         this.dialogService = dialogService;
+        this.Left = [];
+        this.Right = [];
         this.PlotControl = new();
-        this.InitPlot();
+        this._DBDisplayHelper = new(Left, Right);
+        this._PlotHelper = new(this.PlotControl);
+        this._PlotHelper.InitPlot();
         eventAggregator.GetEvent<RefreshRecipeData>().Subscribe(Search);
     }
-
-    private void InitPlot()
-    {
-        this.PlotControl.Plot.Grid.XAxisStyle.MajorLineStyle.Width = 1f;
-        this.PlotControl.Plot.Grid.YAxisStyle.MajorLineStyle.Width = 1f;
-        this.PlotControl.Plot.Axes.Bottom.TickLabelStyle.Alignment = Alignment.MiddleLeft;
-        this.PlotControl.Plot.Axes.DateTimeTicksBottom();
-        this.PlotControl.Background = (Brush)App.Current.Resources.FindName("BackgroundColor");
-        this.PlotControl.Plot.RenderManager.RenderStarting += (s, e) =>
-        {
-            Tick[] ticks = this.PlotControl.Plot.Axes.Bottom.TickGenerator.Ticks;
-            for (int i = 0; i < ticks.Length; i++)
-            {
-                DateTime dt = DateTime.FromOADate(ticks[i].Position);
-                //string label = $"{dt:MM-dd  HH:mm:ss}";
-                string label = $"{dt:HH:mm:ss}";
-                ticks[i] = new Tick(ticks[i].Position, label);
-            }
-        };
-
-        this.PlotControl.Plot.FigureBackground.Color = ScottPlot.Colors.Transparent;
-        this.PlotControl.Plot.Axes.Bottom.TickLabelStyle.Rotation = 90;
-        this.PlotControl.Plot.Axes.Bottom.TickLabelStyle.Alignment = Alignment.MiddleLeft;
-        PixelPadding padding = new(48, 48, 56, 40);
-        this.PlotControl.Plot.Layout.Fixed(padding);
-        this.PlotControl.Plot.FigureBackground.Color = ScottPlot.Colors.Transparent;
-
-        //UpdateDetail();
-    }
-
+    private readonly TraceData traceData;
+    private readonly SqlSugarCustom sqlSugarCustom;
+    private readonly IDialogService dialogService;
+    private readonly PlotHepler _PlotHelper;
+    private readonly DBDisplayHelper _DBDisplayHelper;
 
     [ObservableProperty]
     private WpfPlot _PlotControl;
 
-    private readonly TraceData traceData;
-    private readonly SqlSugarCustom sqlSugarCustom;
-    private readonly IDialogService dialogService;
     [ObservableProperty]
     private ObservableDictionary<DateTime, SelectRecipeStep> _RecipeSteps = [];
 
@@ -74,6 +52,9 @@ internal partial class DBInfoTraceViewModel : ObservableObject
 
     private readonly Stack<IDictionary<string, object>> Cache = new();
 
+    [ObservableProperty]
+    private bool _DisplayAlarm = false;
+
     private bool AutoGenerated = false;
     [RelayCommand]
     private void Selected(SelectRecipeStep step)
@@ -124,17 +105,17 @@ internal partial class DBInfoTraceViewModel : ObservableObject
         //this.Left.TryAdd((string)item.Value, item.Value);
         //IDialogParameters parameters, Action< IDialogResult > callback
         IDialogParameters para = new DialogParameters() { { "Line", item.Value } };
-        dialogService.Show("LinePicker", para, AddLine);
+        dialogService.Show("LinePicker", para, AddLineCallback);
     }
 
     [RelayCommand]
     private void EditLine(KeyValuePair<string, object> item)
     {
         IDialogParameters para = new DialogParameters() { { "Line", item.Key } };
-        dialogService.Show("LinePicker", para, AddLine);
+        dialogService.Show("LinePicker", para, AddLineCallback);
     }
 
-    private void AddLine(IDialogResult dialogResult)
+    private void AddLineCallback(IDialogResult dialogResult)
     {
         dialogResult.Parameters.TryGetValue("Line", out LineType? lineType);
         dialogResult.Parameters.TryGetValue("Name", out string? line);
@@ -177,7 +158,7 @@ internal partial class DBInfoTraceViewModel : ObservableObject
         this.Cache.Clear();
         this.RecipeSteps ??= [];
         this.RecipeSteps.Clear();
-        this.Clear("");
+        this.Clear(string.Empty);
 
         DateTime beginTime = traceData.ProcessData.Process_Begin_Time;
         DateTime endTime = traceData.ProcessData.Process_End_Time;
@@ -213,11 +194,11 @@ internal partial class DBInfoTraceViewModel : ObservableObject
             this.RecipeSteps.TryAdd(item.Step_Begin_Time, step);
         }
 
-        dynamic f;
+        dynamic pm;
         dynamic system;
         try
         {
-            f = sqlSugarCustom.Client.Queryable<dynamic>().AS($"\"{beginTime:yyyyMMdd}.PM1\"").First();
+            pm = sqlSugarCustom.Client.Queryable<dynamic>().AS($"\"{beginTime:yyyyMMdd}.PM1\"").First();
             system = sqlSugarCustom.Client.Queryable<dynamic>().AS($"\"{beginTime:yyyyMMdd}.System\"").First();
         }
         catch
@@ -227,7 +208,7 @@ internal partial class DBInfoTraceViewModel : ObservableObject
         }
         GeneralProcessData processData = new();
 
-        if (f is not IDictionary<string, object> input)
+        if (pm is not IDictionary<string, object> input)
             return;
 
         if (!processData.ToDictionary(input, out Dictionary<string, object>? output) || output is null)
@@ -244,178 +225,12 @@ internal partial class DBInfoTraceViewModel : ObservableObject
         Dictionary<string, object> System = [];
         temp.Add("PM1", PM1);
         temp.Add("System", System);
-        this.CreateTablePM(pmData, PM1);
-        this.CreateTableSystem(systemDic!, System);
+        processData.CreateTablePM(pmData, PM1);
+        processData.CreateTableSystem(systemDic!, System);
         this.Hierachy = temp;
         this.Cache.Push(temp);
     }
 
-    private bool CreateTablePM(IDictionary<string, object> data, IDictionary<string, object> cache)
-    {
-        Dictionary<string, object> ValueSensor = [];
-        Dictionary<string, object> StatusSensor = [];
-        Dictionary<string, object> leakCheck = [];
-        Dictionary<string, object> recipe = [];
-        Dictionary<string, object> aoValue = [];
-
-        Dictionary<string, object> ffu = [];
-        Dictionary<string, object> mfc = [];
-        Dictionary<string, object> gaslineHeater = [];
-        Dictionary<string, object> bufferFoup = [];
-        Dictionary<string, object> avValue = [];
-
-
-
-        foreach (var item in data)
-        {
-            if (item.Value is not IDictionary<string, object> values)
-            {
-                switch (item.Key)
-                {
-                    case string s when s.EndsWith("Enable"):
-                        continue;
-                    case string s when s.StartsWith("LeakCheck"):
-                        leakCheck.Add(item.Key, item.Value);
-                        continue;
-                    default:
-                        recipe.Add(item.Key, item.Value);
-                        continue;
-                }
-            }
-
-            switch (item.Key)
-            {
-                case "APC":
-                case "APCVATGV":
-                case "BoatElevatorServo":
-                case "BoatRotationServo":
-                case "BufferServo":
-                case "Shutter":
-                    CreateTable(cache, item.Key, values);
-                    continue;
-
-                case string s when s.StartsWith("Trig"):
-                    if (item.Value is IDictionary<string, object> value)
-                        aoValue.Add(item.Key, value["AOValue"]);
-                    continue;
-
-                case string s when s.StartsWith("FS"):
-                case string s1 when s1.StartsWith("PG"):
-                case string s2 when s2.StartsWith("PS"):
-                case string s3 when s3.StartsWith("VG"):
-                    if (item.Value is IDictionary<string, object> vss)
-                        ValueSensor.Add(item.Key, vss["Value"]);
-                    continue;
-
-                case string s when s.StartsWith("Sensor"):
-                    if (item.Value is IDictionary<string, object> status)
-                        StatusSensor.Add(item.Key, status["Value"]);
-                    continue;
-                case string s when s.StartsWith("MFC"):
-                    if (item.Value is IDictionary<string, object> mfcs)
-                        mfcs.Foreach(t => mfc.Add($"{item.Key}_{t.Key}", t.Value));
-                    continue;
-                case string s when s.StartsWith("FFU"):
-                    if (item.Value is IDictionary<string, object> ffus)
-                        ffus.Foreach(t => ffu.Add($"{item.Key}_{t.Key}", t.Value));
-                    continue;
-                case string s when s.StartsWith("GaselineHeater"):
-                    if (item.Value is IDictionary<string, object> gaslines)
-                        gaslines.Foreach(t => gaslineHeater.Add($"{item.Key}_{t.Key}", t.Value));
-                    continue;
-                case string s when s.StartsWith("Valve"):
-                    if (item.Value is IDictionary<string, object> valves)
-                        valves.Foreach(t => avValue.Add($"{item.Key}_{t.Key}", t.Value));
-                    continue;
-                default:
-                    continue;
-            }
-        }
-        CreateTable(cache, "MFC", mfc);
-        CreateTable(cache, "FFU", ffu);
-        CreateTable(cache, "Valve", avValue);
-        CreateTable(cache, "GaselineHeater", gaslineHeater);
-        CreateTable(cache, "ValueSensor", ValueSensor);
-        CreateTable(cache, "StatusSensor", StatusSensor);
-        CreateTable(cache, "LeakCheck", leakCheck);
-        CreateTable(cache, "AoValue", aoValue);
-        CreateTable(cache, "Recipe", recipe);
-
-
-
-        return true;
-    }
-
-    private void CreateTableSystem(IDictionary<string, object> data, IDictionary<string, object> cache)
-    {
-        Dictionary<string, object> systemCollection = [];
-        Dictionary<string, object> alarmCollection = [];
-
-        Dictionary<string, object> Heater = [];
-        Dictionary<string, object> Stocker = [];
-        Dictionary<string, object> LoadPort = [];
-        Dictionary<string, object> FIMS = [];
-
-        foreach (var item in data)
-        {
-            if (item.Value is not IDictionary<string, object> values)
-                continue;
-
-            switch (item.Key)
-            {
-                case "Boat":
-                case "CarrierRobot":
-                case "Scheduler":
-                case "WaferRobot":
-                    CreateTable(cache, item.Key, values);
-                    continue;
-                case string s when s.StartsWith("Stocker"):
-                    Stocker.Add(item.Key, values);
-                    continue;
-                case string s when s.StartsWith("LP"):
-                    LoadPort.Add(item.Key, values);
-                    continue;
-                //case string s when s.StartsWith("FIMS"):
-                //    FIMS.Add(item.Key, values);
-                //    continue;
-
-                case "System":
-                    if (values is not IDictionary<string, object> systems)
-                        continue;
-                    foreach (var system in systems)
-                    {
-                        switch (system.Key)
-                        {
-                            case string s when s.StartsWith("Heater"):
-                                Heater.Add(system.Key, system.Value);
-                                continue;
-                            case string s when s.StartsWith("AlarmSignalHeater"):
-                                alarmCollection.Add(system.Key, ((IDictionary<string, object>)system.Value)["Value"] ??= false);
-                                continue;
-                            default:
-                                systemCollection.Add(system.Key, system.Value);
-                                break;
-                        }
-                    }
-                    continue;
-                default:
-                    break;
-            }
-
-            //CreateTable(cache, "FIMS", FIMS);
-            CreateTable(cache, "Heater", Heater);
-            CreateTable(cache, "LoadPort", LoadPort);
-            CreateTable(cache, "Stocker", Stocker);
-            CreateTable(cache, "System", systemCollection);
-            CreateTable(cache, "AlarmSignalHeater", alarmCollection);
-        }
-    }
-
-    private bool CreateTable(IDictionary<string, object> cache, string key, object value)
-    {
-        return cache.TryAdd(key, value);
-    }
-
     [RelayCommand]
     private void RemoveLeft(string key)
     {
@@ -454,7 +269,6 @@ internal partial class DBInfoTraceViewModel : ObservableObject
         }
     }
 
-
     [RelayCommand]
     private void GeneratePlot()
     {
@@ -463,125 +277,57 @@ internal partial class DBInfoTraceViewModel : ObservableObject
         if (!this.RecipeSteps.Any(t => t.Value.IsSelected))
             return;
 
-        DateTime start = this.RecipeSteps.Where(t => t.Value.IsSelected).First().Key;
-        DateTime end = this.RecipeSteps.Where(t => t.Value.IsSelected).Last().Key;
-
-        var whereFunc = ObjectFuncModel.Create("Format", "time", ">", "{long}:" + $"{start.Ticks}", "&&", "time", "<", "{long}:" + $"{end.Ticks}");
-        var f = sqlSugarCustom.Client.Queryable<dynamic>().AS($"\"{start:yyyyMMdd}.PM1\"").Where(whereFunc).ToList();
-        var system = sqlSugarCustom.Client.Queryable<dynamic>().AS($"\"{start:yyyyMMdd}.System\"").Where(whereFunc).ToList();
-
-        var alarmwhereFunc = ObjectFuncModel.Create("Format", "time", ">", "{long}:" + $"{start.Ticks}", "&&", "time", "<", "{long}:" + $"{end.Ticks}");
-        var alarm = sqlSugarCustom.Client.Queryable<EventData>().AS($"event_data").Where(t => t.Occur_Time >= start && t.Occur_Time <= end && (t.Level == "Alarm" || t.Level == "Warning")).ToList();
-
-
-        f.AddRange(system);
+        DateTime startTime = this.RecipeSteps.Where(t => t.Value.IsSelected).First().Key;
+        DateTime endTime = this.RecipeSteps.Where(t => t.Value.IsSelected).Last().Key;
 
-        Dictionary<string, List<float>> cacheLeft = [];
-        Dictionary<string, List<float>> cacheRight = [];
-        List<DateTime> time = [];
-        foreach (var item in f)
-        {
-            if (item is not IDictionary<string, object> data)
-                continue;
-
-            time.Add(new DateTime((long)data["time"]));
-
-            foreach (string key in Left.Keys)
-            {
-                if (!data.TryGetValue(key, out object? value) || value is null)
-                    continue;
-
-                if (!cacheLeft.TryGetValue(key, out List<float>? collections) || collections is null)
-                {
-                    collections = [];
-                    cacheLeft[key] = collections;
-                }
-                collections.Add((float)value);
-            }
-
-            foreach (string key in Right.Keys)
-            {
-                if (!data.TryGetValue(key, out object? value) || value is null)
-                    continue;
-
-                if (!cacheRight.TryGetValue(key, out List<float>? collections) || collections is null)
-                {
-                    collections = [];
-                    cacheRight[key] = collections;
-                }
-                collections.Add((float)value);
-            }
+        ObjectFuncModel whereFunc = ObjectFuncModel.Create("Format", "time", ">", "{long}:" + $"{startTime.Ticks}", "&&", "time", "<", "{long}:" + $"{endTime.Ticks}");
+        List<dynamic> pm1 = sqlSugarCustom.Client.Queryable<dynamic>().AS($"\"{startTime:yyyyMMdd}.PM1\"").Where(whereFunc).ToList();
+        List<dynamic> system = sqlSugarCustom.Client.Queryable<dynamic>().AS($"\"{startTime:yyyyMMdd}.System\"").Where(whereFunc).ToList();
 
-        }
+        this._DBDisplayHelper.ClearData();
+        this._DBDisplayHelper.CreateData(pm1, system);
 
         this.PlotControl.Plot.Clear();
 
-        foreach (var item in cacheLeft)
-            this.SetLeftLine(time, item.Value, ((LineType)Left[item.Key])!.LinePattern, MarkerStyle.None, 2f, ((LineType)Left[item.Key])!.HexRGB);
-
-        foreach (var item in cacheRight)
-            this.SetRightLine(time, item.Value, ((LineType)Right[item.Key])!.LinePattern, MarkerStyle.None, 2f, ((LineType)Right[item.Key])!.HexRGB);
+        foreach (var item in this._DBDisplayHelper.DataLeft)
+            this._PlotHelper.AddLeftLine(this._DBDisplayHelper.Time, item.Value, ((LineType)Left[item.Key])!.LinePattern, MarkerStyle.None, 1.5f, ((LineType)Left[item.Key])!.HexRGB);
 
-        foreach (var item in alarm)
-        {
-            switch (item.Level)
-            {
-                case "Alarm":
-                    this.SetAlarmLine(item.Occur_Time, $"{item.Source}");
-                    break;
-
-                case "Warning":
-                    this.SetWarningLine(item.Occur_Time, $"{item.Source}");
-                    break;
-                default:
-                    break;
-            }
-        }
-        this.PlotControl.Plot.Axes.Bottom.TickLabelStyle.OffsetY = 0;
-        this.PlotControl.Plot.Axes.AutoScale();
-        this.PlotControl.Plot.Axes.Zoom(1.085, 1);
-        this.PlotControl.Background = (Brush)App.Current.Resources.FindName("BackgroundColor");
+        foreach (var item in this._DBDisplayHelper.DataRight)
+            this._PlotHelper.AddRightLine(this._DBDisplayHelper.Time, item.Value, ((LineType)Right[item.Key])!.LinePattern, MarkerStyle.None, 1.5f, ((LineType)Right[item.Key])!.HexRGB);
 
-        PlotControl.Refresh();
+        if (this.DisplayAlarm)
+            this.CreateAlarm(startTime, endTime);
 
+        this.PlotControl.Plot.Axes.AutoScale();
+        this.PlotControl.Refresh();
     }
 
-    private void SetLeftLine(List<DateTime> time, List<float> value, LinePattern linePattern, MarkerStyle markerStyle, float lineWidth, string color)
+    private void CreateAlarm(DateTime start, DateTime end)
     {
-        Scatter mainScatter = this.PlotControl.Plot.Add.Scatter(time, value);
-        mainScatter.MarkerStyle = markerStyle;
-        mainScatter.LineWidth = lineWidth;
-        mainScatter.LinePattern = linePattern;
-        mainScatter.Color = new ScottPlot.Color(color);
-        mainScatter.Axes.YAxis = this.PlotControl.Plot.Axes.Left;
-    }
+        if (this.sqlSugarCustom is null || sqlSugarCustom.Client is null)
+            return;
 
-    private void SetRightLine(List<DateTime> time, List<float> value, LinePattern linePattern, MarkerStyle markerStyle, float lineWidth, string color)
-    {
-        Scatter mainScatter = this.PlotControl.Plot.Add.Scatter(time, value);
-        mainScatter.MarkerStyle = markerStyle;
-        mainScatter.LineWidth = lineWidth;
-        mainScatter.LinePattern = linePattern;
-        mainScatter.Color = new ScottPlot.Color(color);
-        mainScatter.Axes.YAxis = this.PlotControl.Plot.Axes.Right;
-    }
+        List<EventData> alarm = sqlSugarCustom.Client.Queryable<EventData>().AS($"event_data").Where(t => t.Occur_Time >= start && t.Occur_Time <= end && (t.Level == "Alarm" || t.Level == "Warning")).ToList();
 
-    private void SetAlarmLine(DateTime dateTime, string text)
-    {
-        var line = this.PlotControl.Plot.Add.VerticalLine(dateTime.ToOADate());
-        line.Color = new ScottPlot.Color("DC143C");
-        line.Text = text;
-        line.LineWidth = 0.4f;
-        line.LabelOppositeAxis = true;
+        if (alarm is null)
+            return;
+
+        alarm.Foreach(item => _ = item.Level switch
+        {
+            "Alarm" => this._PlotHelper.AddAlarmLine(item.Occur_Time, $"{item.Source}"),
+            "Warning" => this._PlotHelper.AddWarningLine(item.Occur_Time, $"{item.Source}"),
+            _ => true
+        });
     }
 
-    private void SetWarningLine(DateTime dateTime, string text)
+    [RelayCommand]
+    private void ViewTraceData()
     {
-        var line = this.PlotControl.Plot.Add.VerticalLine(dateTime.ToOADate());
-        line.Color = new ScottPlot.Color("FFA500");
-        line.LineWidth = 0.4f;
-        line.Text = text;
-        line.LabelOppositeAxis = true;
+        IDialogParameters para = new DialogParameters
+        {
+            { "Data", this._DBDisplayHelper},
+        };
+        this.dialogService.Show("TraceData", para, null);
     }
 
     [RelayCommand]
@@ -630,49 +376,4 @@ public partial class SelectRecipeStep : ObservableObject
     public string? Sub_Recipe_Loop_Info { get; set; }
     public string? Temp_correction { get; set; }
     public string? Temp_pid { get; set; }
-}
-
-
-public class DBProcessData<T_Hierarchy>(char spilter, int skip)
-    where T_Hierarchy : IDictionary<string, object>, new()
-{
-    public bool ToDictionary(IDictionary<string, object> input, out T_Hierarchy? output)
-    {
-        output = default;
-
-        if (input is null)
-            return false;
-
-        T_Hierarchy cache = [];
-        foreach (KeyValuePair<string, object> rawData in input)
-        {
-            Span<string> source = rawData.Key.Split(spilter).AsSpan()[skip..];
-            ColumAnalizer(cache, source, rawData.Key);
-        }
-
-        output = cache;
-        return true;
-    }
-
-    private static void ColumAnalizer(/*ref*/ T_Hierarchy cache, Span<string> seprated, object value)
-    {
-        if (seprated.Length <= 1)
-        {
-            cache[seprated[0]] = value;
-            return;
-        }
-
-        if (!cache.TryGetValue(seprated[0], out object? output) || output is not T_Hierarchy hierarchy)
-        {
-            hierarchy = [];
-            cache[seprated[0]] = hierarchy;
-        }
-
-        cache = hierarchy;
-        ColumAnalizer(cache, seprated[1..], value);
-    }
-}
-
-public class GeneralProcessData(int skip = 0) : DBProcessData<Dictionary<string, object>>('.', skip)
-{
 }

+ 20 - 0
Analizer/ProximaAnalizer/ViewModels/Dialog/TraceDataListViewModel.cs

@@ -0,0 +1,20 @@
+namespace ProximaAnalizer.ViewModels.Dialog;
+
+internal partial class TraceDataListViewModel : ObservableObject, IDialogAware
+{
+    public DialogCloseListener RequestClose { get; set; }
+
+    public bool CanCloseDialog()
+    {
+
+        return true;
+    }
+
+    public void OnDialogClosed()
+    {
+    }
+
+    public void OnDialogOpened(IDialogParameters parameters)
+    {
+    }
+}

+ 9 - 6
Analizer/ProximaAnalizer/Views/DBInfoTrace.xaml

@@ -87,7 +87,8 @@
                             <RowDefinition Height="auto"/>
                             <RowDefinition Height="4"/>
                             <RowDefinition Height="*"/>
-
+                            <RowDefinition Height="4"/>
+                            <RowDefinition Height="auto"/>
                         </Grid.RowDefinitions>
                         <Button Grid.Row="0" Style="{StaticResource FunctionButton}" Command="{Binding ReturnCommand}" Margin="4">返回上级</Button>
                         <ScrollViewer Grid.Row="2">
@@ -102,13 +103,14 @@
                                 </ItemsControl.ItemTemplate>
                             </ItemsControl>
                         </ScrollViewer>
+                        <CheckBox Grid.Row="4" Margin="0" Style="{StaticResource FunctionCheckBox}" IsChecked="{Binding DisplayAlarm, Mode=TwoWay}" VerticalAlignment="Center">显示报警信息</CheckBox>
 
                     </Grid>
                 </GroupBox>
             </Grid>
         </Expander>
 
-        <GroupBox Grid.Column="2" Header="数据图表" Margin="6">
+        <GroupBox Grid.Column="2" Header="数据图表" Margin="6"  BorderBrush="{StaticResource DarkBorderColor}">
 
             <Grid >
                 <Grid.RowDefinitions>
@@ -122,7 +124,7 @@
                 <WrapPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Center" >
                     <StackPanel Orientation="Horizontal" Margin="12,0">
                         <Button Width="120" Height="24"  Style="{StaticResource FunctionButton}" Command="{Binding GeneratePlotCommand}">绘制图标</Button>
-                        <Button Width="120" Height="24" Margin="4" Style="{StaticResource FunctionButton}" >查看数据</Button>
+                        <Button Width="120" Height="24" Margin="4" Style="{StaticResource FunctionButton}" Command="{Binding ViewTraceDataCommand}">查看数据</Button>
                     </StackPanel>
 
                     <StackPanel Orientation="Horizontal" Margin="12,0">
@@ -134,11 +136,14 @@
                         <Button Width="120" Height="24"  Style="{StaticResource FunctionButton}" Command="{Binding ReScaleCommand}" CommandParameter="add">纵坐标 放大</Button>
                         <Button Width="120" Height="24" Margin="4" Style="{StaticResource FunctionButton}" Command="{Binding ReScaleCommand}" CommandParameter="minus">纵坐标 缩小</Button>
                     </StackPanel>
-                    <Button Width="120" Height="24" Margin="12,0" Style="{StaticResource FunctionButton}" Command="{Binding ReScaleCommand}" CommandParameter="">重置缩放</Button>
+                    <StackPanel Orientation="Horizontal" Margin="12,0">
+                        <Button Width="120" Height="24" Style="{StaticResource FunctionButton}" Command="{Binding ReScaleCommand}" CommandParameter="">重置缩放</Button>
+                    </StackPanel>
                 </WrapPanel>
 
             </Grid>
         </GroupBox>
+
         <Grid Grid.Row="2" Grid.ColumnSpan="3" Margin="2,0,6,2">
             <Grid.ColumnDefinitions>
                 <ColumnDefinition/>
@@ -223,7 +228,5 @@
                 </Border>
             </Grid>
         </Grid>
-
-
     </Grid>
 </UserControl>

+ 12 - 0
Analizer/ProximaAnalizer/Views/Dialog/TraceDataList.xaml

@@ -0,0 +1,12 @@
+<UserControl x:Class="ProximaAnalizer.Views.Dialog.TraceDataList"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+             xmlns:local="clr-namespace:ProximaAnalizer.Views.Dialog"
+             mc:Ignorable="d" 
+             d:DesignHeight="450" d:DesignWidth="800">
+    <Grid>
+            
+    </Grid>
+</UserControl>

+ 28 - 0
Analizer/ProximaAnalizer/Views/Dialog/TraceDataList.xaml.cs

@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace ProximaAnalizer.Views.Dialog
+{
+    /// <summary>
+    /// Interaction logic for TraceDataList.xaml
+    /// </summary>
+    public partial class TraceDataList : UserControl
+    {
+        public TraceDataList()
+        {
+            InitializeComponent();
+        }
+    }
+}

+ 1 - 1
UICommon/Styles/CheckBoxStyle.xaml

@@ -203,7 +203,7 @@
                     <Border Background="{TemplateBinding Background}"  Margin="{TemplateBinding Margin}" CornerRadius="4">
 
                         <Grid >
-                            <ContentPresenter Panel.ZIndex="0" VerticalAlignment="Center" HorizontalAlignment="Center" TextElement.Foreground="{StaticResource TextColor}" Margin="8,12"/>
+                            <ContentPresenter Panel.ZIndex="0" VerticalAlignment="Center" HorizontalAlignment="Center" TextElement.Foreground="{StaticResource TextColor}" Margin="8,6"/>
                             <Border x:Name="_borderOver" Background="Transparent" BorderBrush="Transparent" BorderThickness="1" Margin="1">
 
                             </Border>