浏览代码

Update Alarm
Optimizi DB Search
Module all DB Trace

Zixuan 1 天之前
父节点
当前提交
7d10d2bd56

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

@@ -1,4 +1,5 @@
 using ProximaAnalizer.Data;
 using ProximaAnalizer.Data;
+using ProximaAnalizer.Helpers;
 using ProximaAnalizer.ViewModels;
 using ProximaAnalizer.ViewModels;
 using ProximaAnalizer.ViewModels.Dialog;
 using ProximaAnalizer.ViewModels.Dialog;
 using ProximaAnalizer.Views;
 using ProximaAnalizer.Views;
@@ -29,5 +30,6 @@ public partial class App : PrismApplication
         containerRegistry.RegisterSingleton<SqlSugarCustom>();
         containerRegistry.RegisterSingleton<SqlSugarCustom>();
         containerRegistry.RegisterSingleton<TraceData>();
         containerRegistry.RegisterSingleton<TraceData>();
         containerRegistry.RegisterSingleton<LineCollection>();
         containerRegistry.RegisterSingleton<LineCollection>();
+        containerRegistry.RegisterSingleton<DBDataHelper>();
     }
     }
 }
 }

+ 5 - 7
Analizer/ProximaAnalizer/Data/LineType.cs

@@ -12,9 +12,8 @@ internal partial class LineCollection : ObservableObject
         this.LinesDash.Add(new("7B68EE", [2, 2]));
         this.LinesDash.Add(new("7B68EE", [2, 2]));
         this.LinesDash.Add(new("0000FF", [2, 2]));
         this.LinesDash.Add(new("0000FF", [2, 2]));
         this.LinesDash.Add(new("1E90FF", [2, 2]));
         this.LinesDash.Add(new("1E90FF", [2, 2]));
-        this.LinesDash.Add(new("00FFFF", [2, 2]));
-        this.LinesDash.Add(new("00FF7F", [2, 2]));
-        this.LinesDash.Add(new("FFD700", [2, 2]));
+        this.LinesDash.Add(new("32CD32", [2, 2]));
+        this.LinesDash.Add(new("A0522D", [2, 2]));
         this.LinesDash.Add(new("FF8C00", [2, 2]));
         this.LinesDash.Add(new("FF8C00", [2, 2]));
         this.LinesDash.Add(new("FF0000", [2, 2]));
         this.LinesDash.Add(new("FF0000", [2, 2]));
         this.LinesDash.Add(new("696969", [2, 2]));
         this.LinesDash.Add(new("696969", [2, 2]));
@@ -24,9 +23,8 @@ internal partial class LineCollection : ObservableObject
         this.LinesSolid.Add(new("7B68EE", [2, 0]));
         this.LinesSolid.Add(new("7B68EE", [2, 0]));
         this.LinesSolid.Add(new("0000FF", [2, 0]));
         this.LinesSolid.Add(new("0000FF", [2, 0]));
         this.LinesSolid.Add(new("1E90FF", [2, 0]));
         this.LinesSolid.Add(new("1E90FF", [2, 0]));
-        this.LinesSolid.Add(new("00FFFF", [2, 0]));
-        this.LinesSolid.Add(new("00FF7F", [2, 0]));
-        this.LinesSolid.Add(new("FFD700", [2, 0]));
+        this.LinesSolid.Add(new("32CD32", [2, 0]));
+        this.LinesSolid.Add(new("A0522D", [2, 0]));
         this.LinesSolid.Add(new("FF8C00", [2, 0]));
         this.LinesSolid.Add(new("FF8C00", [2, 0]));
         this.LinesSolid.Add(new("FF0000", [2, 0]));
         this.LinesSolid.Add(new("FF0000", [2, 0]));
         this.LinesSolid.Add(new("696969", [2, 0]));
         this.LinesSolid.Add(new("696969", [2, 0]));
@@ -48,7 +46,7 @@ internal partial class LineType : ObservableObject
         this.HexRGB = color;
         this.HexRGB = color;
         this.DashArray = dash;
         this.DashArray = dash;
         if (dash[1] != 0)
         if (dash[1] != 0)
-            LinePattern = ScottPlot.LinePattern.Dashed;
+            LinePattern = ScottPlot.LinePattern.DenselyDashed;
         else
         else
             LinePattern = ScottPlot.LinePattern.Solid;
             LinePattern = ScottPlot.LinePattern.Solid;
     }
     }

+ 212 - 0
Analizer/ProximaAnalizer/Helpers/DBDataHelper.cs

@@ -0,0 +1,212 @@
+using SqlSugar;
+
+namespace ProximaAnalizer.Helpers;
+
+internal class DBDataHelper(SqlSugarCustom sqlSugarCustom)
+{
+    public bool GetRecipeSteps(string? guid, out string reason, out List<RecipeStepData>? recipeSteps)
+    {
+        recipeSteps = default;
+        reason = string.Empty;
+        if (string.IsNullOrEmpty(guid))
+            return false;
+
+        if (sqlSugarCustom.Client is null)
+            return false;
+
+        try
+        {
+            recipeSteps = sqlSugarCustom.Client.Queryable<RecipeStepData>().AS("recipe_step_data")
+                .Where(t => t.Process_Data_Guid == guid)
+                .OrderBy(t => t.Step_Begin_Time).ToList();
+        }
+        catch
+        {
+            reason = "recipe_step_data 记录不存在";
+            return false;
+        }
+
+        if (recipeSteps.Count == 0)
+        {
+            reason = "recipe_step 步骤数量为0";
+            return false;
+        }
+
+        return true;
+    }
+
+    public bool GetFirstData(DateTime beginTime, out string reason, out Dictionary<string, object>? temp)
+    {
+        temp = default;
+        reason = string.Empty;
+        if (sqlSugarCustom.Client is null)
+            return false;
+
+        dynamic pm;
+        dynamic system;
+        try
+        {
+            pm = sqlSugarCustom.Client.Queryable<dynamic>().AS($"\"{beginTime:yyyyMMdd}.PM1\"").First();
+            system = sqlSugarCustom.Client.Queryable<dynamic>().AS($"\"{beginTime:yyyyMMdd}.System\"").First();
+        }
+        catch
+        {
+            reason = $"{beginTime:yyyyMMdd} 记录不存在";
+            return false;
+        }
+
+        if (pm is not IDictionary<string, object> input)
+            return false;
+
+        GeneralProcessData processData = new();
+
+        if (!processData.ToDictionary(input, out Dictionary<string, object>? output) || output is null)
+            return false;
+
+        if (output["PM1"] is not IDictionary<string, object> pmData)
+            return false;
+
+        if (!processData.ToDictionary(system, out Dictionary<string, object>? systemDic) || systemDic is null)
+            return false;
+
+        temp = [];
+        Dictionary<string, object> PM1 = [];
+        Dictionary<string, object> System = [];
+        temp.Add("PM1", PM1);
+        temp.Add("System", System);
+
+        GeneralProcessData.CreateTablePM(pmData, PM1);
+        GeneralProcessData.CreateTableSystem(systemDic!, System);
+        return true;
+    }
+
+
+    public DateTime? StartTime { get; internal set; }
+    public DateTime? EndTime { get; internal set; }
+
+    private ObjectFuncModel? _whereFunc;
+
+    public void SetTimeRange(DateTime startTime, DateTime endTime)
+    {
+        this.StartTime = startTime;
+        this.EndTime = endTime;
+        _whereFunc = ObjectFuncModel.Create("Format", "time", ">", "{long}:" + $"{startTime.Ticks}", "&&", "time", "<", "{long}:" + $"{endTime.Ticks}");
+    }
+
+    public bool GetPMData(out List<dynamic>? pm1)
+    {
+        pm1 = null;
+        if (this._whereFunc is null)
+            return false;
+        if (sqlSugarCustom.Client is null)
+            return false;
+        try
+        {
+            pm1 = sqlSugarCustom.Client
+                .Queryable<dynamic>()
+                .AS($"\"{StartTime:yyyyMMdd}.PM1\"")
+                .Where(_whereFunc).ToList();
+        }
+        catch
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+    public bool GetPMData(IEnumerable<string> fields, out List<dynamic>? pm1)
+    {
+        pm1 = null;
+        if (this._whereFunc is null)
+            return false;
+        if (sqlSugarCustom.Client is null)
+            return false;
+
+        List<SelectModel> selectModels = [];
+
+        foreach (var field in fields)
+            selectModels.Add(new() { FieldName = $"\"{field}\"" });
+
+        try
+        {
+            pm1 = sqlSugarCustom.Client
+                .Queryable<dynamic>()
+                .AS($"\"{StartTime:yyyyMMdd}.PM1\"")
+                .Select(selectModels)
+                .Where(_whereFunc).ToList();
+        }
+        catch
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+    public bool GetSystemData(out List<dynamic>? systemData)
+    {
+        systemData = default;
+        if (this._whereFunc is null)
+            return false;
+        if (sqlSugarCustom.Client is null)
+            return false;
+        try
+        {
+            systemData = sqlSugarCustom.Client
+                .Queryable<dynamic>()
+                .AS($"\"{StartTime:yyyyMMdd}.System\"")
+                .Where(_whereFunc).ToList();
+        }
+        catch
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+    public bool GetSystemData(IEnumerable<string> fields, out List<dynamic>? systemData)
+    {
+        systemData = default;
+        if (this._whereFunc is null)
+            return false;
+        if (sqlSugarCustom.Client is null)
+            return false;
+
+        List<SelectModel> selectModels = [];
+
+        foreach (var field in fields)
+            selectModels.Add(new() { FieldName = $"\"{field}\"" });
+        try
+        {
+            systemData = sqlSugarCustom.Client
+                .Queryable<dynamic>()
+                .AS($"\"{StartTime:yyyyMMdd}.System\"")
+                .Select(selectModels)
+                .Where(_whereFunc).ToList();
+        }
+        catch
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+    public bool GetAlarmData(out List<EventData>? alarm)
+    {
+        alarm = default;
+        if (this._whereFunc is null)
+            return false;
+        if (sqlSugarCustom.Client is null)
+            return false;
+
+        alarm = sqlSugarCustom.Client
+            .Queryable<EventData>()
+            .AS($"event_data")
+            .Where(t => t.Occur_Time >= this.StartTime && t.Occur_Time <= this.EndTime && (t.Level == "Alarm" || t.Level == "Warning")).ToList();
+
+        return alarm is not null;
+    }
+}

+ 4 - 5
Analizer/ProximaAnalizer/Helpers/DBProcessData.cs

@@ -44,7 +44,7 @@ public class DBProcessData<T_Hierarchy>(char spilter, int skip)
 
 
 public class GeneralProcessData(int skip = 0) : DBProcessData<Dictionary<string, object>>('.', skip)
 public class GeneralProcessData(int skip = 0) : DBProcessData<Dictionary<string, object>>('.', skip)
 {
 {
-    public bool CreateTablePM(IDictionary<string, object> data, IDictionary<string, object> cache)
+    public static bool CreateTablePM(IDictionary<string, object> data, IDictionary<string, object> cache)
     {
     {
         Dictionary<string, object> ValueSensor = [];
         Dictionary<string, object> ValueSensor = [];
         Dictionary<string, object> StatusSensor = [];
         Dictionary<string, object> StatusSensor = [];
@@ -136,7 +136,7 @@ public class GeneralProcessData(int skip = 0) : DBProcessData<Dictionary<string,
         return true;
         return true;
     }
     }
 
 
-    public void CreateTableSystem(IDictionary<string, object> data, IDictionary<string, object> cache)
+    public static void CreateTableSystem(IDictionary<string, object> data, IDictionary<string, object> cache)
     {
     {
         Dictionary<string, object> systemCollection = [];
         Dictionary<string, object> systemCollection = [];
         Dictionary<string, object> alarmCollection = [];
         Dictionary<string, object> alarmCollection = [];
@@ -144,7 +144,7 @@ public class GeneralProcessData(int skip = 0) : DBProcessData<Dictionary<string,
         Dictionary<string, object> Heater = [];
         Dictionary<string, object> Heater = [];
         Dictionary<string, object> Stocker = [];
         Dictionary<string, object> Stocker = [];
         Dictionary<string, object> LoadPort = [];
         Dictionary<string, object> LoadPort = [];
-        Dictionary<string, object> FIMS = [];
+        //Dictionary<string, object> FIMS = [];
 
 
         foreach (var item in data)
         foreach (var item in data)
         {
         {
@@ -201,9 +201,8 @@ public class GeneralProcessData(int skip = 0) : DBProcessData<Dictionary<string,
         }
         }
     }
     }
 
 
-    private bool CreateTable(IDictionary<string, object> cache, string key, object value)
+    private static bool CreateTable(IDictionary<string, object> cache, string key, object value)
     {
     {
         return cache.TryAdd(key, value);
         return cache.TryAdd(key, value);
     }
     }
-
 }
 }

+ 11 - 6
Analizer/ProximaAnalizer/Helpers/DBDisplayHelper.cs

@@ -1,14 +1,14 @@
 namespace ProximaAnalizer.Helpers;
 namespace ProximaAnalizer.Helpers;
 
 
-internal class DBDisplayHelper(IDictionary<string, object> Left, IDictionary<string, object> Right)
+internal class DisplayDataHelper(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 HashSet<DateTime> Time { get; } = [];
+    public Dictionary<string, List<float>> DataLeft { get; } = [];
+    public Dictionary<string, List<float>> DataRight { get; } = [];
 
 
-    public void CreateData(List<dynamic> main, List<dynamic> sub)
+    public void CreateData(List<dynamic> main, List<dynamic>? sub)
     {
     {
-        while (main.Count != sub.Count!)
+        while (sub is not null && main.Count != sub.Count!)
         {
         {
             switch (main.Count > sub.Count)
             switch (main.Count > sub.Count)
             {
             {
@@ -21,6 +21,8 @@ internal class DBDisplayHelper(IDictionary<string, object> Left, IDictionary<str
             }
             }
         }
         }
 
 
+        this.ClearData();
+
         foreach (var item in main)
         foreach (var item in main)
         {
         {
             if (item is not IDictionary<string, object> data)
             if (item is not IDictionary<string, object> data)
@@ -58,6 +60,9 @@ internal class DBDisplayHelper(IDictionary<string, object> Left, IDictionary<str
             }
             }
         }
         }
 
 
+        if (sub is null)
+            return;
+
         foreach (var item in sub)
         foreach (var item in sub)
         {
         {
             if (item is not IDictionary<string, object> data)
             if (item is not IDictionary<string, object> data)

+ 2 - 2
Analizer/ProximaAnalizer/Helpers/PlotHepler.cs

@@ -66,7 +66,7 @@ internal class PlotHepler(WpfPlot PlotControl)
         var line = PlotControl.Plot.Add.VerticalLine(dateTime.ToOADate());
         var line = PlotControl.Plot.Add.VerticalLine(dateTime.ToOADate());
         line.Color = new ScottPlot.Color("DC143C");
         line.Color = new ScottPlot.Color("DC143C");
         line.Text = text;
         line.Text = text;
-        line.LineWidth = 0.4f;
+        line.LineWidth = 1f;
         line.LabelOppositeAxis = true;
         line.LabelOppositeAxis = true;
         return true;
         return true;
     }
     }
@@ -75,7 +75,7 @@ internal class PlotHepler(WpfPlot PlotControl)
     {
     {
         var line = PlotControl.Plot.Add.VerticalLine(dateTime.ToOADate());
         var line = PlotControl.Plot.Add.VerticalLine(dateTime.ToOADate());
         line.Color = new ScottPlot.Color("FFA500");
         line.Color = new ScottPlot.Color("FFA500");
-        line.LineWidth = 0.4f;
+        line.LineWidth = 1f;
         line.Text = text;
         line.Text = text;
         line.LabelOppositeAxis = true;
         line.LabelOppositeAxis = true;
         return true;
         return true;

+ 176 - 150
Analizer/ProximaAnalizer/ViewModels/DBInfoTraceViewModel.cs

@@ -1,68 +1,93 @@
 using Mapster;
 using Mapster;
-using OpenTK.Graphics.ES20;
 using ProximaAnalizer.Helpers;
 using ProximaAnalizer.Helpers;
 using ScottPlot;
 using ScottPlot;
-using ScottPlot.Plottables;
 using ScottPlot.WPF;
 using ScottPlot.WPF;
 using SqlSugar;
 using SqlSugar;
+using System.Collections.ObjectModel;
 using System.Windows;
 using System.Windows;
-using System.Windows.Media;
 using Universal;
 using Universal;
 
 
 namespace ProximaAnalizer.ViewModels;
 namespace ProximaAnalizer.ViewModels;
 
 
 internal partial class DBInfoTraceViewModel : ObservableObject
 internal partial class DBInfoTraceViewModel : ObservableObject
 {
 {
-    public DBInfoTraceViewModel(TraceData traceData,
-        SqlSugarCustom sqlSugarCustom,
-        IEventAggregator eventAggregator,
-        IDialogService dialogService)
+    public DBInfoTraceViewModel(
+            TraceData traceData,
+            DBDataHelper dBDataHelper,
+            IEventAggregator eventAggregator,
+            IDialogService dialogService)
     {
     {
-        this.traceData = traceData;
-        this.sqlSugarCustom = sqlSugarCustom;
-        this.dialogService = dialogService;
+        this._DBDataHelper = dBDataHelper;
+        this._traceData = traceData;
+        this._dialogService = dialogService;
         this.Left = [];
         this.Left = [];
         this.Right = [];
         this.Right = [];
         this.PlotControl = new();
         this.PlotControl = new();
-        this._DBDisplayHelper = new(Left, Right);
+        this._DisplayDataHelper = new(Left, Right);
         this._PlotHelper = new(this.PlotControl);
         this._PlotHelper = new(this.PlotControl);
         this._PlotHelper.InitPlot();
         this._PlotHelper.InitPlot();
-        eventAggregator.GetEvent<RefreshRecipeData>().Subscribe(Search);
+        eventAggregator.GetEvent<RefreshRecipeData>().Subscribe(InitDisplayData);
     }
     }
-    private readonly TraceData traceData;
-    private readonly SqlSugarCustom sqlSugarCustom;
-    private readonly IDialogService dialogService;
+    private readonly TraceData _traceData;
+    private readonly IDialogService _dialogService;
+
     private readonly PlotHepler _PlotHelper;
     private readonly PlotHepler _PlotHelper;
-    private readonly DBDisplayHelper _DBDisplayHelper;
+    private readonly DBDataHelper _DBDataHelper;
+    private readonly DisplayDataHelper _DisplayDataHelper;
 
 
     [ObservableProperty]
     [ObservableProperty]
     private WpfPlot _PlotControl;
     private WpfPlot _PlotControl;
 
 
     [ObservableProperty]
     [ObservableProperty]
-    private ObservableDictionary<DateTime, SelectRecipeStep> _RecipeSteps = [];
+    private bool _DisplayAlarm = false;
 
 
     [ObservableProperty]
     [ObservableProperty]
-    private IDictionary<string, object>? _Hierachy;
+    private bool _DisplayWarning = false;
 
 
     [ObservableProperty]
     [ObservableProperty]
-    private ObservableDictionary<string, object> _Left = [];
+    private double _AlarmInverval = 60d;
 
 
-    [ObservableProperty]
-    private ObservableDictionary<string, object> _Right = [];
+    private void InitDisplayData()
+    {
+        if (_traceData.ProcessData is null)
+            return;
+
+        this._HierachyCache.Clear();
+        this.RecipeSteps.Clear();
+        this.Clear("Both");
+
+        if (!this._DBDataHelper.GetRecipeSteps(_traceData.ProcessData.Guid, out string reason, out List<RecipeStepData>? recipeSteps) || recipeSteps is null)
+        {
+            MessageBox.Show(reason, "Warning", MessageBoxButton.OK, MessageBoxImage.Error);
+            return;
+        }
+
+        recipeSteps.ForEach(t => this.RecipeSteps.TryAdd(t.Step_Begin_Time, t.Adapt<SelectRecipeStep>()));
 
 
-    private readonly Stack<IDictionary<string, object>> Cache = new();
+        if (!this._DBDataHelper.GetFirstData(_traceData.ProcessData.Process_Begin_Time, out string error, out Dictionary<string, object>? firstData) || firstData is null)
+        {
+            MessageBox.Show(error, "Warning", MessageBoxButton.OK, MessageBoxImage.Error);
+            return;
+        }
+
+        this.Hierachy = firstData;
+        this._HierachyCache.Push(firstData);
 
 
+        this.Alarms.Clear();
+    }
+
+
+    #region Step Operations
     [ObservableProperty]
     [ObservableProperty]
-    private bool _DisplayAlarm = false;
+    private ObservableDictionary<DateTime, SelectRecipeStep> _RecipeSteps = [];
 
 
     private bool AutoGenerated = false;
     private bool AutoGenerated = false;
+
     [RelayCommand]
     [RelayCommand]
     private void Selected(SelectRecipeStep step)
     private void Selected(SelectRecipeStep step)
     {
     {
         if (RecipeSteps is null)
         if (RecipeSteps is null)
             return;
             return;
-        if (sqlSugarCustom.Client is null)
-            return;
 
 
         if (AutoGenerated)
         if (AutoGenerated)
         {
         {
@@ -78,7 +103,6 @@ internal partial class DBInfoTraceViewModel : ObservableObject
 
 
         RecipeSteps.Where(t => t.Key >= start && t.Key <= end).Foreach(t => t.Value.IsSelected = true);
         RecipeSteps.Where(t => t.Key >= start && t.Key <= end).Foreach(t => t.Value.IsSelected = true);
 
 
-
         this.AutoGenerated = true;
         this.AutoGenerated = true;
     }
     }
 
 
@@ -88,6 +112,14 @@ internal partial class DBInfoTraceViewModel : ObservableObject
         RecipeSteps.Where(t => t.Value.IsSelected).Foreach(t => t.Value.IsSelected = false);
         RecipeSteps.Where(t => t.Value.IsSelected).Foreach(t => t.Value.IsSelected = false);
         this.AutoGenerated = false;
         this.AutoGenerated = false;
     }
     }
+    #endregion
+
+
+    #region Data Hierachy Operations
+    [ObservableProperty]
+    private IDictionary<string, object>? _Hierachy;
+
+    private readonly Stack<IDictionary<string, object>> _HierachyCache = new();
 
 
     [RelayCommand]
     [RelayCommand]
     private void SelectHierachy(KeyValuePair<string, object> item)
     private void SelectHierachy(KeyValuePair<string, object> item)
@@ -97,24 +129,37 @@ internal partial class DBInfoTraceViewModel : ObservableObject
 
 
         if (item.Value is IDictionary<string, object> next)
         if (item.Value is IDictionary<string, object> next)
         {
         {
-            this.Cache.Push(this.Hierachy);
+            this._HierachyCache.Push(this.Hierachy);
             this.Hierachy = next;
             this.Hierachy = next;
             return;
             return;
         }
         }
 
 
-        //this.Left.TryAdd((string)item.Value, item.Value);
-        //IDialogParameters parameters, Action< IDialogResult > callback
         IDialogParameters para = new DialogParameters() { { "Line", item.Value } };
         IDialogParameters para = new DialogParameters() { { "Line", item.Value } };
-        dialogService.Show("LinePicker", para, AddLineCallback);
+        _dialogService.Show("LinePicker", para, AddLineCallback);
+    }
+
+    [RelayCommand]
+    private void Return()
+    {
+        if (this._HierachyCache.TryPop(out var output) && output is not null)
+            this.Hierachy = output;
     }
     }
+    #endregion
+
+
+    #region Line Operations
+    [ObservableProperty]
+    private ObservableDictionary<string, object> _Left = [];
+
+    [ObservableProperty]
+    private ObservableDictionary<string, object> _Right = [];
 
 
     [RelayCommand]
     [RelayCommand]
     private void EditLine(KeyValuePair<string, object> item)
     private void EditLine(KeyValuePair<string, object> item)
     {
     {
         IDialogParameters para = new DialogParameters() { { "Line", item.Key } };
         IDialogParameters para = new DialogParameters() { { "Line", item.Key } };
-        dialogService.Show("LinePicker", para, AddLineCallback);
+        _dialogService.Show("LinePicker", para, AddLineCallback);
     }
     }
-
     private void AddLineCallback(IDialogResult dialogResult)
     private void AddLineCallback(IDialogResult dialogResult)
     {
     {
         dialogResult.Parameters.TryGetValue("Line", out LineType? lineType);
         dialogResult.Parameters.TryGetValue("Line", out LineType? lineType);
@@ -139,98 +184,6 @@ internal partial class DBInfoTraceViewModel : ObservableObject
         lineCollection[line] = lineType;
         lineCollection[line] = lineType;
     }
     }
 
 
-
-    [RelayCommand]
-    private void Return()
-    {
-        if (this.Cache.TryPop(out var output) && output is not null)
-            this.Hierachy = output;
-    }
-
-
-    [RelayCommand]
-    private void Search()
-    {
-        if (traceData.ProcessData is null)
-            return;
-        if (sqlSugarCustom.Client is null)
-            return;
-        this.Cache.Clear();
-        this.RecipeSteps ??= [];
-        this.RecipeSteps.Clear();
-        this.Clear(string.Empty);
-
-        DateTime beginTime = traceData.ProcessData.Process_Begin_Time;
-        DateTime endTime = traceData.ProcessData.Process_End_Time;
-
-        long beginTicks = beginTime.Ticks;
-        long endTicks = endTime.Ticks;
-
-        List<RecipeStepData> recipeSteps;
-
-        try
-        {
-            recipeSteps = sqlSugarCustom.Client.Queryable<RecipeStepData>().AS("recipe_step_data")
-                .Where(t => t.Process_Data_Guid == traceData.ProcessData.Guid)
-                .OrderBy(t => t.Step_Begin_Time).ToList();
-        }
-        catch
-        {
-            MessageBox.Show($"recipe_step_data 记录不存在", "Warning", MessageBoxButton.OK, MessageBoxImage.Error);
-            return;
-        }
-
-        if (recipeSteps.Count == 0)
-        {
-            MessageBox.Show($"recipe_step 步骤数量为0", "Warning", MessageBoxButton.OK, MessageBoxImage.Error);
-            return;
-        }
-
-
-        foreach (var item in recipeSteps)
-        {
-            SelectRecipeStep step = new();
-            item.Adapt(step);
-            this.RecipeSteps.TryAdd(item.Step_Begin_Time, step);
-        }
-
-        dynamic pm;
-        dynamic system;
-        try
-        {
-            pm = sqlSugarCustom.Client.Queryable<dynamic>().AS($"\"{beginTime:yyyyMMdd}.PM1\"").First();
-            system = sqlSugarCustom.Client.Queryable<dynamic>().AS($"\"{beginTime:yyyyMMdd}.System\"").First();
-        }
-        catch
-        {
-            MessageBox.Show($"{beginTime:yyyyMMdd} 记录不存在", "Warning", MessageBoxButton.OK, MessageBoxImage.Error);
-            return;
-        }
-        GeneralProcessData processData = new();
-
-        if (pm is not IDictionary<string, object> input)
-            return;
-
-        if (!processData.ToDictionary(input, out Dictionary<string, object>? output) || output is null)
-            return;
-
-        if (output["PM1"] is not IDictionary<string, object> pmData)
-            return;
-
-        if (!processData.ToDictionary(system, out Dictionary<string, object>? systemDic) || systemDic is null)
-            return;
-
-        Dictionary<string, object> temp = [];
-        Dictionary<string, object> PM1 = [];
-        Dictionary<string, object> System = [];
-        temp.Add("PM1", PM1);
-        temp.Add("System", System);
-        processData.CreateTablePM(pmData, PM1);
-        processData.CreateTableSystem(systemDic!, System);
-        this.Hierachy = temp;
-        this.Cache.Push(temp);
-    }
-
     [RelayCommand]
     [RelayCommand]
     private void RemoveLeft(string key)
     private void RemoveLeft(string key)
     {
     {
@@ -268,56 +221,128 @@ internal partial class DBInfoTraceViewModel : ObservableObject
                 break;
                 break;
         }
         }
     }
     }
+    #endregion
+
+
+    #region Plot Operations
+    [ObservableProperty]
+    private ObservableCollection<EventData> _Alarms = [];
 
 
     [RelayCommand]
     [RelayCommand]
     private void GeneratePlot()
     private void GeneratePlot()
     {
     {
-        if (this.sqlSugarCustom.Client is null)
-            return;
         if (!this.RecipeSteps.Any(t => t.Value.IsSelected))
         if (!this.RecipeSteps.Any(t => t.Value.IsSelected))
+        {
+            MessageBox.Show("Recipe Step 未选择", "Warning", MessageBoxButton.OK, MessageBoxImage.Error);
+            return;
+        }
+
+        if (this.Left.Count == 0 && Right.Count == 0)
+        {
+            MessageBox.Show("分析数据 未选择", "Warning", MessageBoxButton.OK, MessageBoxImage.Error);
             return;
             return;
+        }
 
 
         DateTime startTime = this.RecipeSteps.Where(t => t.Value.IsSelected).First().Key;
         DateTime startTime = this.RecipeSteps.Where(t => t.Value.IsSelected).First().Key;
         DateTime endTime = this.RecipeSteps.Where(t => t.Value.IsSelected).Last().Key;
         DateTime endTime = this.RecipeSteps.Where(t => t.Value.IsSelected).Last().Key;
+        this._DBDataHelper.SetTimeRange(startTime, endTime);
 
 
-        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.GetDBFields(out HashSet<string> pmFields, out HashSet<string> systemFields);
 
 
-        this._DBDisplayHelper.ClearData();
-        this._DBDisplayHelper.CreateData(pm1, system);
+        if (!this._DBDataHelper.GetPMData(pmFields, out List<dynamic>? mainData) || mainData is null)
+            return;
+
+        this._DBDataHelper.GetSystemData(systemFields, out List<dynamic>? subData);
+
+        this._DisplayDataHelper.ClearData();
+        this._DisplayDataHelper.CreateData(mainData, subData);
 
 
         this.PlotControl.Plot.Clear();
         this.PlotControl.Plot.Clear();
 
 
-        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 this._DisplayDataHelper.DataLeft)
+            this._PlotHelper.AddLeftLine(this._DisplayDataHelper.Time, item.Value, ((LineType)Left[item.Key])!.LinePattern, MarkerStyle.None, 1.5f, ((LineType)Left[item.Key])!.HexRGB);
+
+        foreach (var item in this._DisplayDataHelper.DataRight)
+            this._PlotHelper.AddRightLine(this._DisplayDataHelper.Time, item.Value, ((LineType)Right[item.Key])!.LinePattern, MarkerStyle.None, 1.5f, ((LineType)Right[item.Key])!.HexRGB);
 
 
-        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);
+        if (!this._DBDataHelper.GetAlarmData(out List<EventData>? alarm) || alarm is null)
+            return;
 
 
-        if (this.DisplayAlarm)
-            this.CreateAlarm(startTime, endTime);
+        this.GenerateAlarm(alarm);
 
 
         this.PlotControl.Plot.Axes.AutoScale();
         this.PlotControl.Plot.Axes.AutoScale();
         this.PlotControl.Refresh();
         this.PlotControl.Refresh();
     }
     }
 
 
-    private void CreateAlarm(DateTime start, DateTime end)
+    public void GenerateAlarm(List<EventData> alarm)
     {
     {
-        if (this.sqlSugarCustom is null || sqlSugarCustom.Client is null)
-            return;
+        this.Alarms.Clear();
+        this.Alarms.AddRange(alarm);
 
 
-        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();
+        Dictionary<string, DateTime> intervalFilter = [];
+        HashSet<DateTime> dup = [];
+        foreach (EventData item in alarm)
+        {
+            if (string.IsNullOrEmpty(item.Description))
+                continue;
 
 
-        if (alarm is null)
-            return;
+            if (intervalFilter.TryGetValue(item.Description, out DateTime time) &&
+                (item.Occur_Time - time).TotalSeconds < AlarmInverval)
+                continue;
+            intervalFilter[item.Description] = item.Occur_Time;
 
 
-        alarm.Foreach(item => _ = item.Level switch
+
+            switch (item.Level)
+            {
+                case "Alarm":
+                    if (!this.DisplayAlarm)
+                        continue;
+
+                    if (!dup.Add(item.Occur_Time))
+                        continue;
+
+                    this._PlotHelper.AddAlarmLine(item.Occur_Time, $"{item.Source}");
+                    break;
+
+                case "Warning":
+                    if (!this.DisplayWarning)
+                        continue;
+
+                    if (!dup.Add(item.Occur_Time))
+                        continue;
+
+                    this._PlotHelper.AddWarningLine(item.Occur_Time, $"{item.Source}");
+                    break;
+
+                default:
+                    break;
+            }
+        }
+    }
+
+    private void GetDBFields(out HashSet<string> pmFields, out HashSet<string> systemFields)
+    {
+        pmFields = ["time"];
+        systemFields = [];
+        foreach (string field in this.Left.Keys)
         {
         {
-            "Alarm" => this._PlotHelper.AddAlarmLine(item.Occur_Time, $"{item.Source}"),
-            "Warning" => this._PlotHelper.AddWarningLine(item.Occur_Time, $"{item.Source}"),
-            _ => true
-        });
+            _ = field switch
+            {
+                string s when s.Contains("PM1") => pmFields.Add(field),
+                string s when s.Contains("System") => systemFields.Add(field),
+                _ => systemFields.Add(field)
+            };
+        }
+
+        foreach (string field in this.Right.Keys)
+        {
+            _ = field switch
+            {
+                string s when s.Contains("PM1") => pmFields.Add(field),
+                string s when s.Contains("System") => systemFields.Add(field),
+                _ => systemFields.Add(field)
+            };
+        }
     }
     }
 
 
     [RelayCommand]
     [RelayCommand]
@@ -325,9 +350,9 @@ internal partial class DBInfoTraceViewModel : ObservableObject
     {
     {
         IDialogParameters para = new DialogParameters
         IDialogParameters para = new DialogParameters
         {
         {
-            { "Data", this._DBDisplayHelper},
+            { "Data", this._DisplayDataHelper},
         };
         };
-        this.dialogService.Show("TraceData", para, null);
+        this._dialogService.Show("TraceData", para, null);
     }
     }
 
 
     [RelayCommand]
     [RelayCommand]
@@ -355,6 +380,7 @@ internal partial class DBInfoTraceViewModel : ObservableObject
         }
         }
         this.PlotControl.Refresh();
         this.PlotControl.Refresh();
     }
     }
+    #endregion
 }
 }
 
 
 
 

+ 1 - 3
Analizer/ProximaAnalizer/ViewModels/LoadingViewModel.cs

@@ -1,6 +1,4 @@
-
-
-namespace ProximaAnalizer.ViewModels;
+namespace ProximaAnalizer.ViewModels;
 
 
 internal partial class LoadingViewModel : ObservableObject
 internal partial class LoadingViewModel : ObservableObject
 {
 {

+ 192 - 128
Analizer/ProximaAnalizer/Views/DBInfoTrace.xaml

@@ -14,145 +14,207 @@
         <ResourceDictionary Source="/UICommon;component/Resources.xaml"/>
         <ResourceDictionary Source="/UICommon;component/Resources.xaml"/>
     </UserControl.Resources>
     </UserControl.Resources>
     <Grid Margin="8">
     <Grid Margin="8">
-        <Grid.ColumnDefinitions>
-            <ColumnDefinition Width="auto"/>
-            <ColumnDefinition Width="2"/>
-            <ColumnDefinition Width="*"/>
-        </Grid.ColumnDefinitions>
         <Grid.RowDefinitions>
         <Grid.RowDefinitions>
             <RowDefinition/>
             <RowDefinition/>
             <RowDefinition Height="2"/>
             <RowDefinition Height="2"/>
-            <RowDefinition Height="180"/>
+            <RowDefinition Height="200"/>
         </Grid.RowDefinitions>
         </Grid.RowDefinitions>
+        <Grid>
+            <Grid.ColumnDefinitions>
+                <ColumnDefinition Width="auto"/>
+                <ColumnDefinition Width="2"/>
+                <ColumnDefinition Width="*"/>
+            </Grid.ColumnDefinitions>
 
 
-        <Expander ExpandDirection="Right"  IsExpanded="True" Margin="0,6" Padding="0,-2" TextElement.FontSize="14">
-            <Expander.Header>
-                <TextBlock Text="数据编辑" HorizontalAlignment="Center" Margin="4">
-                    <TextBlock.LayoutTransform>
-                        <RotateTransform Angle="-90"/>
-                    </TextBlock.LayoutTransform>
-                </TextBlock>
-            </Expander.Header>
-            <Grid>
-                <Grid.ColumnDefinitions>
-                    <ColumnDefinition Width="auto"/>
-                    <ColumnDefinition Width="4"/>
-                    <ColumnDefinition Width="auto"/>
-                </Grid.ColumnDefinitions>
-                <GroupBox Header="时间范围" Margin="4,0" MinWidth="240" BorderBrush="{StaticResource DarkBorderColor}">
-                    <ScrollViewer >
-                        <ItemsControl ItemsSource="{Binding RecipeSteps}" Margin="4">
-                            <ItemsControl.ItemTemplate>
-                                <DataTemplate>
-                                    <CheckBox Margin="0,1" VerticalAlignment="Center" Style="{StaticResource StepCheckBox}" IsChecked="{Binding Value.IsSelected, Mode=TwoWay}">
-                                        <i:Interaction.Triggers>
-                                            <i:EventTrigger EventName="Checked">
-                                                <prism:InvokeCommandAction  Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:DBInfoTrace}, 
+            <Expander ExpandDirection="Right"  IsExpanded="True" Margin="0,6" Padding="0,-2" TextElement.FontSize="14">
+                <Expander.Header>
+                    <TextBlock Text="数据编辑" HorizontalAlignment="Center" Margin="4">
+                        <TextBlock.LayoutTransform>
+                            <RotateTransform Angle="-90"/>
+                        </TextBlock.LayoutTransform>
+                    </TextBlock>
+                </Expander.Header>
+                <Grid>
+                    <Grid.ColumnDefinitions>
+                        <ColumnDefinition Width="auto"/>
+                        <ColumnDefinition Width="4"/>
+                        <ColumnDefinition Width="auto"/>
+                    </Grid.ColumnDefinitions>
+                    <GroupBox Header="时间范围" Margin="4,0" MinWidth="240" BorderBrush="{StaticResource DarkBorderColor}">
+                        <ScrollViewer >
+                            <ItemsControl ItemsSource="{Binding RecipeSteps}" Margin="4">
+                                <ItemsControl.ItemTemplate>
+                                    <DataTemplate>
+                                        <CheckBox Margin="0,1" VerticalAlignment="Center" Style="{StaticResource StepCheckBox}" IsChecked="{Binding Value.IsSelected, Mode=TwoWay}">
+                                            <i:Interaction.Triggers>
+                                                <i:EventTrigger EventName="Checked">
+                                                    <prism:InvokeCommandAction  Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:DBInfoTrace}, 
                                                                                         Path=DataContext.SelectedCommand}" 
                                                                                         Path=DataContext.SelectedCommand}" 
                                                                             CommandParameter="{Binding Value}"/>
                                                                             CommandParameter="{Binding Value}"/>
-                                            </i:EventTrigger>
-                                            <i:EventTrigger EventName="Unchecked">
-                                                <prism:InvokeCommandAction  Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:DBInfoTrace}, 
+                                                </i:EventTrigger>
+                                                <i:EventTrigger EventName="Unchecked">
+                                                    <prism:InvokeCommandAction  Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:DBInfoTrace}, 
                                                                                         Path=DataContext.UnSelectedCommand}" 
                                                                                         Path=DataContext.UnSelectedCommand}" 
                                                                             CommandParameter="{Binding Value}"/>
                                                                             CommandParameter="{Binding Value}"/>
-                                            </i:EventTrigger>
-                                        </i:Interaction.Triggers>
-                                        <Grid HorizontalAlignment="Left" Margin="8,0,0,0" VerticalAlignment="Center">
-                                            <Grid.ColumnDefinitions>
-                                                <ColumnDefinition Width="auto"/>
-                                                <ColumnDefinition Width="12"/>
-                                                <ColumnDefinition Width="0"/>
-                                                <ColumnDefinition Width="12"/>
-                                                <ColumnDefinition Width="auto"/>
-                                            </Grid.ColumnDefinitions>
-                                            <TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="{Binding Key, StringFormat=yyyy-MM-dd  HH:mm:ss.f}"/>
-                                            <!--<TextBlock Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Center" Text="{Binding Value.Step_Number}"/>-->
-                                            <TextBlock Grid.Column="4" VerticalAlignment="Center" HorizontalAlignment="Center" Text="{Binding Value.Step_Name}"/>
-                                        </Grid>
-                                    </CheckBox>
-                                </DataTemplate>
-                            </ItemsControl.ItemTemplate>
-                            <ItemsControl.ItemsPanel>
-                                <ItemsPanelTemplate>
-                                    <StackPanel Orientation="Vertical"/>
-                                </ItemsPanelTemplate>
-                            </ItemsControl.ItemsPanel>
-                        </ItemsControl>
-                    </ScrollViewer>
-                </GroupBox>
-
-                <GroupBox Grid.Column="2" Margin="4,0" Header="数据选择" MinWidth="240" BorderBrush="{StaticResource DarkBorderColor}">
-                    <Grid>
-                        <Grid.RowDefinitions>
-                            <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">
-                            <ItemsControl ItemsSource="{Binding Hierachy}">
-                                <ItemsControl.ItemTemplate>
-                                    <DataTemplate>
-                                        <Button Content="{Binding Key}" VerticalContentAlignment="Center" HorizontalContentAlignment="Left"
-                                            Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:DBInfoTrace}, Path=DataContext.SelectHierachyCommand}"
-                                            CommandParameter="{Binding}" Margin="4" Padding="8,2" Background="Transparent"></Button>
-                                        <!--<TextBlock Text="{Binding Key}"></TextBlock>-->
+                                                </i:EventTrigger>
+                                            </i:Interaction.Triggers>
+                                            <Grid HorizontalAlignment="Left" Margin="8,0,0,0" VerticalAlignment="Center">
+                                                <Grid.ColumnDefinitions>
+                                                    <ColumnDefinition Width="auto"/>
+                                                    <ColumnDefinition Width="8"/>
+                                                    <ColumnDefinition Width="0"/>
+                                                    <ColumnDefinition Width="0"/>
+                                                    <ColumnDefinition Width="auto"/>
+                                                </Grid.ColumnDefinitions>
+                                                <TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="{Binding Key, StringFormat=yyyy-MM-dd  HH:mm:ss.f}"/>
+                                                <!--<TextBlock Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Center" Text="{Binding Value.Step_Number}"/>-->
+                                                <TextBlock Grid.Column="4" VerticalAlignment="Center" HorizontalAlignment="Center" Text="{Binding Value.Step_Name}"/>
+                                            </Grid>
+                                        </CheckBox>
                                     </DataTemplate>
                                     </DataTemplate>
                                 </ItemsControl.ItemTemplate>
                                 </ItemsControl.ItemTemplate>
+                                <ItemsControl.ItemsPanel>
+                                    <ItemsPanelTemplate>
+                                        <StackPanel Orientation="Vertical"/>
+                                    </ItemsPanelTemplate>
+                                </ItemsControl.ItemsPanel>
                             </ItemsControl>
                             </ItemsControl>
                         </ScrollViewer>
                         </ScrollViewer>
-                        <CheckBox Grid.Row="4" Margin="0" Style="{StaticResource FunctionCheckBox}" IsChecked="{Binding DisplayAlarm, Mode=TwoWay}" VerticalAlignment="Center">显示报警信息</CheckBox>
+                    </GroupBox>
 
 
-                    </Grid>
-                </GroupBox>
-            </Grid>
-        </Expander>
+                    <GroupBox Grid.Column="2" Margin="4,0" Header="数据选择" MinWidth="240" BorderBrush="{StaticResource DarkBorderColor}">
+                        <Grid>
+                            <Grid.RowDefinitions>
+                                <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">
+                                <ItemsControl ItemsSource="{Binding Hierachy}">
+                                    <ItemsControl.ItemTemplate>
+                                        <DataTemplate>
+                                            <Button Content="{Binding Key}" VerticalContentAlignment="Center" HorizontalContentAlignment="Left"
+                                            Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:DBInfoTrace}, Path=DataContext.SelectHierachyCommand}"
+                                            CommandParameter="{Binding}" Margin="4" Padding="8,2" Background="Transparent"></Button>
+                                            <!--<TextBlock Text="{Binding Key}"></TextBlock>-->
+                                        </DataTemplate>
+                                    </ItemsControl.ItemTemplate>
+                                </ItemsControl>
+                            </ScrollViewer>
+                            <!--<Grid Grid.Row="4">
+                                <Grid.ColumnDefinitions>
+                                    <ColumnDefinition/>
+                                    <ColumnDefinition Width="2"/>
+                                    <ColumnDefinition/>
+                                </Grid.ColumnDefinitions>
+                                <CheckBox Grid.Column="0" Style="{StaticResource FunctionCheckBox}" IsChecked="{Binding DisplayAlarm, Mode=TwoWay}" VerticalAlignment="Center">显示Alarm</CheckBox>
+                                <CheckBox Grid.Column="2" Style="{StaticResource FunctionCheckBox}" IsChecked="{Binding DisplayWarning, Mode=TwoWay}" VerticalAlignment="Center">显示Warning</CheckBox>
+                            </Grid>-->
+                        </Grid>
+                    </GroupBox>
+                </Grid>
+            </Expander>
 
 
-        <GroupBox Grid.Column="2" Header="数据图表" Margin="6"  BorderBrush="{StaticResource DarkBorderColor}">
+            <GroupBox Grid.Column="2" Header="数据图表" Margin="6"  BorderBrush="{StaticResource DarkBorderColor}">
 
 
-            <Grid >
-                <Grid.RowDefinitions>
-                    <RowDefinition/>
-                    <RowDefinition Height="8"/>
-                    <RowDefinition Height="auto"/>
-                    <RowDefinition Height="0"/>
-                </Grid.RowDefinitions>
-                <ContentControl Content="{Binding PlotControl, Mode=OneTime}" />
+                <Grid >
+                    <Grid.RowDefinitions>
+                        <RowDefinition/>
+                        <RowDefinition Height="8"/>
+                        <RowDefinition Height="auto"/>
+                        <RowDefinition Height="0"/>
+                    </Grid.RowDefinitions>
+                    <ContentControl Content="{Binding PlotControl, Mode=OneTime}" />
 
 
-                <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}" Command="{Binding ViewTraceDataCommand}">查看数据</Button>
-                    </StackPanel>
+                    <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}" Command="{Binding ViewTraceDataCommand}">查看数据</Button>
+                        </StackPanel>
 
 
-                    <StackPanel Orientation="Horizontal" Margin="12,0">
-                        <Button Width="120" Height="24"  Style="{StaticResource FunctionButton}" Command="{Binding ReScaleCommand}" CommandParameter="+">横坐标 放大</Button>
-                        <Button Width="120" Height="24" Margin="4" Style="{StaticResource FunctionButton}" Command="{Binding ReScaleCommand}" CommandParameter="-">横坐标 缩小</Button>
-                    </StackPanel>
+                        <StackPanel Orientation="Horizontal" Margin="12,0">
+                            <Button Width="120" Height="24"  Style="{StaticResource FunctionButton}" Command="{Binding ReScaleCommand}" CommandParameter="+">横坐标 放大</Button>
+                            <Button Width="120" Height="24" Margin="4" Style="{StaticResource FunctionButton}" Command="{Binding ReScaleCommand}" CommandParameter="-">横坐标 缩小</Button>
+                        </StackPanel>
 
 
-                    <StackPanel Orientation="Horizontal" Margin="12,0">
-                        <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>
-                    <StackPanel Orientation="Horizontal" Margin="12,0">
-                        <Button Width="120" Height="24" Style="{StaticResource FunctionButton}" Command="{Binding ReScaleCommand}" CommandParameter="">重置缩放</Button>
-                    </StackPanel>
-                </WrapPanel>
+                        <StackPanel Orientation="Horizontal" Margin="12,0">
+                            <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>
+                        <StackPanel Orientation="Horizontal" Margin="12,0">
+                            <Button Width="120" Height="24" Style="{StaticResource FunctionButton}" Command="{Binding ReScaleCommand}" CommandParameter="">重置缩放</Button>
+                        </StackPanel>
+                    </WrapPanel>
 
 
-            </Grid>
-        </GroupBox>
+                </Grid>
+            </GroupBox>
+        </Grid>
 
 
-        <Grid Grid.Row="2" Grid.ColumnSpan="3" Margin="2,0,6,2">
+        <Grid Grid.Row="2" Grid.Column="2" Grid.ColumnSpan="3" Margin="2,0,6,2">
             <Grid.ColumnDefinitions>
             <Grid.ColumnDefinitions>
+                <ColumnDefinition />
+                <ColumnDefinition Width="16"/>
                 <ColumnDefinition/>
                 <ColumnDefinition/>
                 <ColumnDefinition Width="16"/>
                 <ColumnDefinition Width="16"/>
                 <ColumnDefinition/>
                 <ColumnDefinition/>
             </Grid.ColumnDefinitions>
             </Grid.ColumnDefinitions>
-            <Grid >
+            <Grid Grid.Column="0" >
                 <Grid.RowDefinitions>
                 <Grid.RowDefinitions>
-                    <RowDefinition Height="auto"/>
+                    <RowDefinition Height="24"/>
+                    <RowDefinition Height="4"/>
+                    <RowDefinition/>
+                </Grid.RowDefinitions>
+                <TextBlock VerticalAlignment="Center">报警信息</TextBlock>
+
+                <Grid Grid.Row="0" HorizontalAlignment="Right">
+                    <Grid.ColumnDefinitions>
+                        <ColumnDefinition Width="auto"/>
+                        <ColumnDefinition Width="12"/>
+                        <ColumnDefinition Width="auto"/>
+                        <ColumnDefinition Width="12"/>
+                        <ColumnDefinition Width="auto"/>
+                    </Grid.ColumnDefinitions>
+                    <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
+                        <TextBox Width="40" HorizontalContentAlignment="Center" Margin="4,0" Text="{Binding AlarmInverval}"/>
+                        <TextBlock VerticalAlignment="Center">秒内重复不显示</TextBlock>
+                    </StackPanel>
+                    <CheckBox Grid.Column="2"  IsChecked="{Binding DisplayAlarm, Mode=TwoWay}" VerticalAlignment="Center">显示Alarm</CheckBox>
+                    <CheckBox Grid.Column="4" IsChecked="{Binding DisplayWarning, Mode=TwoWay}" VerticalAlignment="Center">显示Warning</CheckBox>
+                </Grid>
+
+                <Border Grid.Row="2" BorderBrush="{StaticResource DarkBorderColor}" BorderThickness="1">
+                    <ScrollViewer HorizontalScrollBarVisibility="Auto">
+                        <ItemsControl ItemsSource="{Binding Alarms}" Margin="2">
+                            <ItemsControl.ItemTemplate>
+                                <DataTemplate>
+                                    <Grid Margin="2">
+                                        <Grid.ColumnDefinitions>
+                                            <ColumnDefinition Width="auto"/>
+                                            <ColumnDefinition Width="8"/>
+                                            <ColumnDefinition Width="48"/>
+                                            <ColumnDefinition Width="8"/>
+                                            <ColumnDefinition Width="48"/>
+                                            <ColumnDefinition Width="8"/>
+                                            <ColumnDefinition Width="auto"/>
+                                        </Grid.ColumnDefinitions>
+                                        <TextBlock VerticalAlignment="Center" HorizontalAlignment="Left"  Text="{Binding Occur_Time, StringFormat=HH:mm:ss.fff}"/>
+                                        <TextBlock Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Center" Text="{Binding Source}" ToolTip="{Binding Source}"/>
+                                        <TextBlock Grid.Column="4" VerticalAlignment="Center" HorizontalAlignment="Center" Text="{Binding Level}" ToolTip="{Binding Level}"/>
+                                        <TextBlock Grid.Column="6" VerticalAlignment="Center" HorizontalAlignment="Left" Text="{Binding Description}" ToolTip="{Binding Description}"/>
+                                    </Grid>
+                                </DataTemplate>
+                            </ItemsControl.ItemTemplate>
+                        </ItemsControl>
+                    </ScrollViewer>
+                </Border>
+            </Grid>
+
+            <Grid Grid.Column="2">
+                <Grid.RowDefinitions>
+                    <RowDefinition Height="24"/>
                     <RowDefinition Height="4"/>
                     <RowDefinition Height="4"/>
                     <RowDefinition/>
                     <RowDefinition/>
 
 
@@ -160,7 +222,7 @@
                 <TextBlock VerticalAlignment="Center">左侧坐标轴</TextBlock>
                 <TextBlock VerticalAlignment="Center">左侧坐标轴</TextBlock>
                 <Button HorizontalAlignment="Right" Width="80" Style="{StaticResource FunctionButton}" Command="{Binding ClearCommand}" CommandParameter="L">清除</Button>
                 <Button HorizontalAlignment="Right" Width="80" Style="{StaticResource FunctionButton}" Command="{Binding ClearCommand}" CommandParameter="L">清除</Button>
                 <Border Grid.Row="2" BorderBrush="{StaticResource DarkBorderColor}" BorderThickness="1">
                 <Border Grid.Row="2" BorderBrush="{StaticResource DarkBorderColor}" BorderThickness="1">
-                    <ScrollViewer >
+                    <ScrollViewer  HorizontalScrollBarVisibility="Auto">
                         <ItemsControl ItemsSource="{Binding Left}">
                         <ItemsControl ItemsSource="{Binding Left}">
                             <ItemsControl.ItemTemplate>
                             <ItemsControl.ItemTemplate>
                                 <DataTemplate>
                                 <DataTemplate>
@@ -172,16 +234,16 @@
                                             <ColumnDefinition Width="24"/>
                                             <ColumnDefinition Width="24"/>
                                             <ColumnDefinition Width="64"/>
                                             <ColumnDefinition Width="64"/>
                                         </Grid.ColumnDefinitions>
                                         </Grid.ColumnDefinitions>
-                                        <TextBlock Text="{Binding Key}"/>
+                                        <TextBlock Text="{Binding Key}" VerticalAlignment="Center"/>
                                         <Button  Grid.Column="2" Background="Transparent" HorizontalContentAlignment="Left" BorderThickness="0"
                                         <Button  Grid.Column="2" Background="Transparent" HorizontalContentAlignment="Left" BorderThickness="0"
-                                                 Command="{Binding RelativeSource={RelativeSource AncestorType=local:DBInfoTrace, Mode=FindAncestor}, Path=DataContext.EditLineCommand}"
-                                                 CommandParameter="{Binding}">
+                                      Command="{Binding RelativeSource={RelativeSource AncestorType=local:DBInfoTrace, Mode=FindAncestor}, Path=DataContext.EditLineCommand}"
+                                      CommandParameter="{Binding}">
                                             <Line X1="0" Y1="0" X2="100" Y2="0" Stretch="Fill" Stroke="{Binding Value.Brush}" StrokeDashArray="{Binding Value.DashArray}" StrokeThickness="3"/>
                                             <Line X1="0" Y1="0" X2="100" Y2="0" Stretch="Fill" Stroke="{Binding Value.Brush}" StrokeDashArray="{Binding Value.DashArray}" StrokeThickness="3"/>
                                         </Button>
                                         </Button>
                                         <Button Grid.Column="4" Style="{StaticResource FunctionButton}"
                                         <Button Grid.Column="4" Style="{StaticResource FunctionButton}"
-                                                Command="{Binding RelativeSource={RelativeSource AncestorType=local:DBInfoTrace, Mode=FindAncestor}, 
-                                                        Path=DataContext.RemoveLeftCommand}"
-                                                CommandParameter="{Binding Key}">移除</Button>
+                                     Command="{Binding RelativeSource={RelativeSource AncestorType=local:DBInfoTrace, Mode=FindAncestor}, 
+                                             Path=DataContext.RemoveLeftCommand}"
+                                     CommandParameter="{Binding Key}">移除</Button>
                                     </Grid>
                                     </Grid>
                                 </DataTemplate>
                                 </DataTemplate>
                             </ItemsControl.ItemTemplate>
                             </ItemsControl.ItemTemplate>
@@ -189,16 +251,17 @@
                     </ScrollViewer>
                     </ScrollViewer>
                 </Border>
                 </Border>
             </Grid>
             </Grid>
-            <Grid Grid.Column="2" >
+
+            <Grid Grid.Column="4" >
                 <Grid.RowDefinitions>
                 <Grid.RowDefinitions>
-                    <RowDefinition Height="auto"/>
+                    <RowDefinition Height="24"/>
                     <RowDefinition Height="4"/>
                     <RowDefinition Height="4"/>
                     <RowDefinition/>
                     <RowDefinition/>
                 </Grid.RowDefinitions>
                 </Grid.RowDefinitions>
                 <TextBlock VerticalAlignment="Center">右侧坐标轴</TextBlock>
                 <TextBlock VerticalAlignment="Center">右侧坐标轴</TextBlock>
                 <Button HorizontalAlignment="Right" Width="80" Style="{StaticResource FunctionButton}" Command="{Binding ClearCommand}" CommandParameter="R">清除</Button>
                 <Button HorizontalAlignment="Right" Width="80" Style="{StaticResource FunctionButton}" Command="{Binding ClearCommand}" CommandParameter="R">清除</Button>
                 <Border Grid.Row="2" BorderBrush="{StaticResource DarkBorderColor}" BorderThickness="1">
                 <Border Grid.Row="2" BorderBrush="{StaticResource DarkBorderColor}" BorderThickness="1">
-                    <ScrollViewer>
+                    <ScrollViewer  HorizontalScrollBarVisibility="Auto">
                         <ItemsControl ItemsSource="{Binding Right}">
                         <ItemsControl ItemsSource="{Binding Right}">
                             <ItemsControl.ItemTemplate>
                             <ItemsControl.ItemTemplate>
                                 <DataTemplate>
                                 <DataTemplate>
@@ -210,16 +273,16 @@
                                             <ColumnDefinition Width="24"/>
                                             <ColumnDefinition Width="24"/>
                                             <ColumnDefinition Width="64"/>
                                             <ColumnDefinition Width="64"/>
                                         </Grid.ColumnDefinitions>
                                         </Grid.ColumnDefinitions>
-                                        <TextBlock Text="{Binding Key}"/>
+                                        <TextBlock Text="{Binding Key}" VerticalAlignment="Center"/>
                                         <Button  Grid.Column="2" Background="Transparent" HorizontalContentAlignment="Left" BorderThickness="0"
                                         <Button  Grid.Column="2" Background="Transparent" HorizontalContentAlignment="Left" BorderThickness="0"
-                                                        Command="{Binding RelativeSource={RelativeSource AncestorType=local:DBInfoTrace, Mode=FindAncestor}, Path=DataContext.EditLineCommand}"
-                                                        CommandParameter="{Binding}">
+                                             Command="{Binding RelativeSource={RelativeSource AncestorType=local:DBInfoTrace, Mode=FindAncestor}, Path=DataContext.EditLineCommand}"
+                                             CommandParameter="{Binding}">
                                             <Line X1="0" Y1="0" X2="100" Y2="0" Stretch="Fill" Stroke="{Binding Value.Brush}" StrokeDashArray="{Binding Value.DashArray}" StrokeThickness="3"/>
                                             <Line X1="0" Y1="0" X2="100" Y2="0" Stretch="Fill" Stroke="{Binding Value.Brush}" StrokeDashArray="{Binding Value.DashArray}" StrokeThickness="3"/>
                                         </Button>
                                         </Button>
                                         <Button Grid.Column="4" Style="{StaticResource FunctionButton}"
                                         <Button Grid.Column="4" Style="{StaticResource FunctionButton}"
-                                              Command="{Binding RelativeSource={RelativeSource AncestorType=local:DBInfoTrace, Mode=FindAncestor}, 
-                                                      Path=DataContext.RemoveRightCommand}"
-                                              CommandParameter="{Binding Key}">移除</Button>
+                                   Command="{Binding RelativeSource={RelativeSource AncestorType=local:DBInfoTrace, Mode=FindAncestor}, 
+                                           Path=DataContext.RemoveRightCommand}"
+                                   CommandParameter="{Binding Key}">移除</Button>
                                     </Grid>
                                     </Grid>
                                 </DataTemplate>
                                 </DataTemplate>
                             </ItemsControl.ItemTemplate>
                             </ItemsControl.ItemTemplate>
@@ -228,5 +291,6 @@
                 </Border>
                 </Border>
             </Grid>
             </Grid>
         </Grid>
         </Grid>
+
     </Grid>
     </Grid>
 </UserControl>
 </UserControl>