From 2ce6afb909f34af7d78c20cfeb9f2d8311e91336 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Fri, 3 Oct 2025 01:55:11 +0300 Subject: Changed RealTimeGraphX to .NET 4.6.1 --- .../Tango.FSE.Diagnostics.csproj | 4 +- .../Tango.FSE.PPCConsole.csproj | 4 +- .../Tango.FSE.Procedures.csproj | 5 +- .../FSE/Tango.FSE.Common/Tango.FSE.Common.csproj | 4 +- .../FSE/Tango.FSE.UI/Tango.FSE.UI.csproj | 4 +- .../Tango.MachineStudio.ColorCapture.csproj | 4 +- .../Tango.MachineStudio.Technician.csproj | 6 +- .../Tango.MachineStudio.Common.csproj | 6 +- .../Tango.MachineStudio.UI.csproj | 6 +- .../PPC/Tango.PPC.UI/Tango.PPC.UI.csproj | 6 +- .../RealTimeGraphX.WPF.Demo.csproj | 4 - .../RealTimeGraphX.WPF/RealTimeGraphX.WPF.csproj | 4 +- .../RealTimeGraphX/DataPoints/DateTimeDataPoint.cs | 178 ++++++ .../RealTimeGraphX/DataPoints/DoubleDataPoint.cs | 178 ++++++ .../RealTimeGraphX/DataPoints/FloatDataPoint.cs | 178 ++++++ .../RealTimeGraphX/DataPoints/Int32DataPoint.cs | 183 ++++++ .../RealTimeGraphX/DataPoints/TimeSpanDataPoint.cs | 180 ++++++ .../EventArguments/RangeChangedEventArgs.cs | 58 ++ .../RealTimeGraphX/GraphCommand.cs | 77 +++ .../RealTimeGraphX/GraphController.cs | 662 +++++++++++++++++++++ .../RealTimeGraphX/GraphDataPoint.cs | 412 +++++++++++++ .../RealTimeGraphX/GraphDataPointHelper.cs | 48 ++ .../RealTimeGraphX/GraphDataPointTypeConverter.cs | 82 +++ .../RealTimeGraphX/GraphDataQueue.cs | 63 ++ .../RealTimeGraphX/GraphObject.cs | 42 ++ .../RealTimeGraphXNet/RealTimeGraphX/GraphRange.cs | 138 +++++ .../RealTimeGraphX/GraphRenderer.cs | 76 +++ .../RealTimeGraphX/GraphTransform.cs | 39 ++ .../RealTimeGraphX/IGraphComponent.cs | 10 + .../RealTimeGraphX/IGraphController.cs | 190 ++++++ .../RealTimeGraphX/IGraphDataPoint.cs | 94 +++ .../RealTimeGraphX/IGraphDataSeries.cs | 36 ++ .../RealTimeGraphX/IGraphRenderer.cs | 41 ++ .../RealTimeGraphX/IGraphSurface.cs | 74 +++ .../RealTimeGraphX/Properties/AssemblyInfo.cs | 36 ++ .../RealTimeGraphX/RealTimeGraphX.csproj | 71 +++ .../Renderers/ScrollingLineRenderer.cs | 84 +++ Software/Visual_Studio/Tango.sln | 383 ++++-------- 38 files changed, 3385 insertions(+), 285 deletions(-) create mode 100644 Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/DataPoints/DateTimeDataPoint.cs create mode 100644 Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/DataPoints/DoubleDataPoint.cs create mode 100644 Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/DataPoints/FloatDataPoint.cs create mode 100644 Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/DataPoints/Int32DataPoint.cs create mode 100644 Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/DataPoints/TimeSpanDataPoint.cs create mode 100644 Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/EventArguments/RangeChangedEventArgs.cs create mode 100644 Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphCommand.cs create mode 100644 Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphController.cs create mode 100644 Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphDataPoint.cs create mode 100644 Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphDataPointHelper.cs create mode 100644 Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphDataPointTypeConverter.cs create mode 100644 Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphDataQueue.cs create mode 100644 Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphObject.cs create mode 100644 Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphRange.cs create mode 100644 Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphRenderer.cs create mode 100644 Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphTransform.cs create mode 100644 Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/IGraphComponent.cs create mode 100644 Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/IGraphController.cs create mode 100644 Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/IGraphDataPoint.cs create mode 100644 Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/IGraphDataSeries.cs create mode 100644 Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/IGraphRenderer.cs create mode 100644 Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/IGraphSurface.cs create mode 100644 Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/Properties/AssemblyInfo.cs create mode 100644 Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/RealTimeGraphX.csproj create mode 100644 Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/Renderers/ScrollingLineRenderer.cs (limited to 'Software/Visual_Studio') diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Tango.FSE.Diagnostics.csproj b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Tango.FSE.Diagnostics.csproj index c6ba79753..cbfd2138c 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Tango.FSE.Diagnostics.csproj +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/Tango.FSE.Diagnostics.csproj @@ -252,8 +252,8 @@ {6b9774f7-960d-438e-ad81-c6b9be328d50} RealTimeGraphX.WPF - - {f13a489c-80ee-4cd0-bdd4-92d959215646} + + {1490b50f-234c-400b-8704-7673435143f2} RealTimeGraphX diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Tango.FSE.PPCConsole.csproj b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Tango.FSE.PPCConsole.csproj index e6104f060..79f7ac1a6 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Tango.FSE.PPCConsole.csproj +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/Tango.FSE.PPCConsole.csproj @@ -201,8 +201,8 @@ {6b9774f7-960d-438e-ad81-c6b9be328d50} RealTimeGraphX.WPF - - {f13a489c-80ee-4cd0-bdd4-92d959215646} + + {1490b50f-234c-400b-8704-7673435143f2} RealTimeGraphX diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Tango.FSE.Procedures.csproj b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Tango.FSE.Procedures.csproj index 1c2638abb..4bcacb652 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Tango.FSE.Procedures.csproj +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Tango.FSE.Procedures.csproj @@ -84,6 +84,7 @@ + ..\..\..\packages\System.Reactive.Core.3.1.1\lib\net46\System.Reactive.Core.dll @@ -288,8 +289,8 @@ {6b9774f7-960d-438e-ad81-c6b9be328d50} RealTimeGraphX.WPF - - {f13a489c-80ee-4cd0-bdd4-92d959215646} + + {1490b50f-234c-400b-8704-7673435143f2} RealTimeGraphX diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj b/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj index eb77ed1da..4e82295d3 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj @@ -549,8 +549,8 @@ {6b9774f7-960d-438e-ad81-c6b9be328d50} RealTimeGraphX.WPF - - {f13a489c-80ee-4cd0-bdd4-92d959215646} + + {1490b50f-234c-400b-8704-7673435143f2} RealTimeGraphX diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj index 9816ca740..d147320b9 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj @@ -674,8 +674,8 @@ {6b9774f7-960d-438e-ad81-c6b9be328d50} RealTimeGraphX.WPF - - {f13a489c-80ee-4cd0-bdd4-92d959215646} + + {1490b50f-234c-400b-8704-7673435143f2} RealTimeGraphX diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Tango.MachineStudio.ColorCapture.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Tango.MachineStudio.ColorCapture.csproj index 4e6feceb5..fb1dabca3 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Tango.MachineStudio.ColorCapture.csproj +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Tango.MachineStudio.ColorCapture.csproj @@ -170,8 +170,8 @@ {6b9774f7-960d-438e-ad81-c6b9be328d50} RealTimeGraphX.WPF - - {f13a489c-80ee-4cd0-bdd4-92d959215646} + + {1490b50f-234c-400b-8704-7673435143f2} RealTimeGraphX diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/Tango.MachineStudio.Technician.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/Tango.MachineStudio.Technician.csproj index 809eb2496..9ff5e72a0 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/Tango.MachineStudio.Technician.csproj +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/Tango.MachineStudio.Technician.csproj @@ -530,8 +530,8 @@ {6b9774f7-960d-438e-ad81-c6b9be328d50} RealTimeGraphX.WPF - - {f13a489c-80ee-4cd0-bdd4-92d959215646} + + {1490b50f-234c-400b-8704-7673435143f2} RealTimeGraphX @@ -728,7 +728,7 @@ - + \ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj index 736858d39..ee29aab21 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj @@ -272,8 +272,8 @@ {6b9774f7-960d-438e-ad81-c6b9be328d50} RealTimeGraphX.WPF - - {f13a489c-80ee-4cd0-bdd4-92d959215646} + + {1490b50f-234c-400b-8704-7673435143f2} RealTimeGraphX @@ -462,7 +462,7 @@ - + diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj index 4dbcbf600..e7ae4f1de 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj @@ -396,10 +396,6 @@ {6b9774f7-960d-438e-ad81-c6b9be328d50} RealTimeGraphX.WPF - - {f13a489c-80ee-4cd0-bdd4-92d959215646} - RealTimeGraphX - {bb2abb74-ba58-4812-83aa-ec8171f42df4} Tango.AutoComplete @@ -727,7 +723,7 @@ if $(ConfigurationName) == Release RD /S /Q "$(TargetDir)lib\" - + \ No newline at end of file diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj b/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj index 99a7e7c75..d09948ff7 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj @@ -883,8 +883,8 @@ {6b9774f7-960d-438e-ad81-c6b9be328d50} RealTimeGraphX.WPF - - {f13a489c-80ee-4cd0-bdd4-92d959215646} + + {1490b50f-234c-400b-8704-7673435143f2} RealTimeGraphX @@ -1216,7 +1216,7 @@ if $(ConfigurationName) == X1 copy /Y "$(ProjectDir)Intro.wmv" "$(TargetDir)" - + diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/RealTimeGraphX.WPF.Demo.csproj b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/RealTimeGraphX.WPF.Demo.csproj index 5b430a90c..5f4b0860b 100644 --- a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/RealTimeGraphX.WPF.Demo.csproj +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/RealTimeGraphX.WPF.Demo.csproj @@ -106,10 +106,6 @@ {6b9774f7-960d-438e-ad81-c6b9be328d50} RealTimeGraphX.WPF - - {61f001e1-6e17-4ca6-8f3a-8a11d7166815} - RealTimeGraphX - diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/RealTimeGraphX.WPF.csproj b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/RealTimeGraphX.WPF.csproj index 6446fc93f..d61369b2a 100644 --- a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/RealTimeGraphX.WPF.csproj +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/RealTimeGraphX.WPF.csproj @@ -88,8 +88,8 @@ - - {61f001e1-6e17-4ca6-8f3a-8a11d7166815} + + {1490b50f-234c-400b-8704-7673435143f2} RealTimeGraphX diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/DataPoints/DateTimeDataPoint.cs b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/DataPoints/DateTimeDataPoint.cs new file mode 100644 index 000000000..9ec750af9 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/DataPoints/DateTimeDataPoint.cs @@ -0,0 +1,178 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace RealTimeGraphX.DataPoints +{ + public class DateTimeDataPoint : GraphDataPoint + { + /// + /// Initializes a new instance of the class. + /// + public DateTimeDataPoint() : base() + { + + } + + /// + /// Initializes a new instance of the class. + /// + /// The value. + public DateTimeDataPoint(DateTime value) : base(value) + { + + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value. + /// + /// The result of the conversion. + /// + public static implicit operator DateTimeDataPoint(DateTime value) + { + return new DateTimeDataPoint(value); + } + + /// + /// Implements the operator -. + /// + /// a. + /// The b. + /// + /// The result of the operator. + /// + public static DateTimeDataPoint operator -(DateTimeDataPoint a, DateTimeDataPoint b) + { + return new DateTimeDataPoint(new DateTime(a.Value.Ticks - b.Value.Ticks)); + } + + /// + /// Implements the operator +. + /// + /// a. + /// The b. + /// + /// The result of the operator. + /// + public static DateTimeDataPoint operator +(DateTimeDataPoint a, DateTimeDataPoint b) + { + return new DateTimeDataPoint(new DateTime(a.Value.Ticks + b.Value.Ticks)); + } + + /// + /// Sums the value of this instance with another instance value and returns the result. + /// + /// The other instance. + /// + public override IGraphDataPoint Add(IGraphDataPoint other) + { + return new DateTimeDataPoint(new DateTime(this.Value.Ticks + (other as DateTimeDataPoint).Value.Ticks)); + } + + /// + /// Subtract the value of another instance from this instance and returns the result. + /// + /// The other instance. + /// + public override IGraphDataPoint Subtract(IGraphDataPoint other) + { + return new DateTimeDataPoint(new DateTime(this.Value.Ticks - (other as DateTimeDataPoint).Value.Ticks)); + } + + /// + /// Multiplies the value of this instance with another instance value and returns the result. + /// + /// The other instance. + /// + public override IGraphDataPoint Multiply(IGraphDataPoint other) + { + return new DateTimeDataPoint(new DateTime(this.Value.Ticks * (other as DateTimeDataPoint).Value.Ticks)); + } + + /// + /// Divides the value of this instance with another instance value and returns the result. + /// + /// The other instance. + /// + public override IGraphDataPoint Divide(IGraphDataPoint other) + { + return new DateTimeDataPoint(new DateTime(this.Value.Ticks / (other as DateTimeDataPoint).Value.Ticks)); + } + + /// + /// Returns the percentage value of this instance between the specified minimum and maximum values. + /// + /// The minimum. + /// The maximum. + /// + public override double ComputeRelativePosition(IGraphDataPoint min, IGraphDataPoint max) + { + DateTime dMin = min as DateTimeDataPoint; + DateTime dMax = max as DateTimeDataPoint; + + if (dMax.Ticks - dMin.Ticks == 0) //Prevent divide by zero + { + return dMin.Ticks; + } + + var result = ((Value.Ticks - dMin.Ticks) * 100) / (dMax.Ticks - dMin.Ticks); + + return double.IsNaN(result) ? dMin.Ticks : result; + } + + /// + /// Returns the absolute value of the specified percentage value between the specified minimum and maximum values. + /// + /// The minimum. + /// The maximum. + /// The percentage. + /// + public override IGraphDataPoint ComputeAbsolutePosition(IGraphDataPoint min, IGraphDataPoint max, double percentage) + { + double minimum = ((DateTime)min.GetValue()).Ticks; + double maximum = ((DateTime)max.GetValue()).Ticks; + + return new DateTimeDataPoint(new DateTime((long)(minimum + (maximum - minimum) * percentage))); + } + + /// + /// Creates a range of values from the specified minimum and maximum. + /// + /// The minimum. + /// The maximum. + /// The count. + /// + public override IEnumerable CreateRange(IGraphDataPoint min, IGraphDataPoint max, int count) + { + double minimum = ((DateTime)min.GetValue()).Ticks; + double maximum = ((DateTime)max.GetValue()).Ticks; + + return Enumerable.Range(0, count). + Select(i => minimum + (maximum - minimum) * ((double)i / (count - 1))). + Select(x => new DateTimeDataPoint(new DateTime((long)x))); + } + + /// + /// Returns a formated string of this data point. + /// + /// The format. + /// + public override string ToString(string format) + { + return Value.ToString(format); + } + + /// + /// Parses the specified value and returns a new instance of data point. + /// + /// The value. + /// + public override IGraphDataPoint Parse(string value) + { + return new DateTimeDataPoint(DateTime.Parse(value)); + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/DataPoints/DoubleDataPoint.cs b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/DataPoints/DoubleDataPoint.cs new file mode 100644 index 000000000..b4740fcfa --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/DataPoints/DoubleDataPoint.cs @@ -0,0 +1,178 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RealTimeGraphX.DataPoints +{ + /// + /// Represents a graph value data point. + /// + /// + public class DoubleDataPoint : GraphDataPoint + { + /// + /// Initializes a new instance of the class. + /// + public DoubleDataPoint() : base() + { + + } + + /// + /// Initializes a new instance of the class. + /// + /// The value. + public DoubleDataPoint(double value) : base(value) + { + + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value. + /// + /// The result of the conversion. + /// + public static implicit operator DoubleDataPoint(double value) + { + return new DoubleDataPoint(value); + } + + /// + /// Implements the operator -. + /// + /// a. + /// The b. + /// + /// The result of the operator. + /// + public static DoubleDataPoint operator -(DoubleDataPoint a, DoubleDataPoint b) + { + return new DoubleDataPoint(a.Value - b.Value); + } + + /// + /// Implements the operator +. + /// + /// a. + /// The b. + /// + /// The result of the operator. + /// + public static DoubleDataPoint operator +(DoubleDataPoint a, DoubleDataPoint b) + { + return new DoubleDataPoint(a.Value + b.Value); + } + + /// + /// Sums the value of this instance with another instance value and returns the result. + /// + /// The other instance. + /// + public override IGraphDataPoint Add(IGraphDataPoint other) + { + return new DoubleDataPoint(this.Value + (other as DoubleDataPoint).Value); + } + + /// + /// Subtract the value of another instance from this instance and returns the result. + /// + /// The other instance. + /// + public override IGraphDataPoint Subtract(IGraphDataPoint other) + { + return new DoubleDataPoint(this.Value - (other as DoubleDataPoint).Value); + } + + /// + /// Multiplies the value of this instance with another instance value and returns the result. + /// + /// The other instance. + /// + public override IGraphDataPoint Multiply(IGraphDataPoint other) + { + return new DoubleDataPoint(this.Value * (other as DoubleDataPoint).Value); + } + + /// + /// Divides the value of this instance with another instance value and returns the result. + /// + /// The other instance. + /// + public override IGraphDataPoint Divide(IGraphDataPoint other) + { + return new DoubleDataPoint(this.Value / (other as DoubleDataPoint).Value); + } + + /// + /// Returns the percentage value of this instance between the specified minimum and maximum values. + /// + /// The minimum. + /// The maximum. + /// + public override double ComputeRelativePosition(IGraphDataPoint min, IGraphDataPoint max) + { + DoubleDataPoint dMin = min as DoubleDataPoint; + DoubleDataPoint dMax = max as DoubleDataPoint; + + var result = ((Value - dMin) * 100) / (dMax - dMin); + + return double.IsNaN(result) || double.IsInfinity(result) ? dMin.Value : result; + } + + /// + /// Returns the absolute value of the specified percentage value between the specified minimum and maximum values. + /// + /// The minimum. + /// The maximum. + /// The percentage. + /// + public override IGraphDataPoint ComputeAbsolutePosition(IGraphDataPoint min, IGraphDataPoint max, double percentage) + { + double minimum = (double)min.GetValue(); + double maximum = (double)max.GetValue(); + + return new DoubleDataPoint(minimum + (maximum - minimum) * percentage); + } + + /// + /// Creates a range of values from the specified minimum and maximum. + /// + /// The minimum. + /// The maximum. + /// The count. + /// + public override IEnumerable CreateRange(IGraphDataPoint min, IGraphDataPoint max, int count) + { + double minimum = (double)min.GetValue(); + double maximum = (double)max.GetValue(); + + return Enumerable.Range(0, count). + Select(i => minimum + (maximum - minimum) * ((double)i / (count - 1))). + Select(x => new DoubleDataPoint(x)); + } + + /// + /// Returns a formated string of this data point. + /// + /// The format. + /// + public override string ToString(string format) + { + return Value.ToString(format); + } + + /// + /// Parses the specified value and returns a new instance of data point. + /// + /// The value. + /// + public override IGraphDataPoint Parse(string value) + { + return new DoubleDataPoint(double.Parse(value)); + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/DataPoints/FloatDataPoint.cs b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/DataPoints/FloatDataPoint.cs new file mode 100644 index 000000000..6e225a679 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/DataPoints/FloatDataPoint.cs @@ -0,0 +1,178 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RealTimeGraphX.DataPoints +{ + /// + /// Represents a graph value data point. + /// + /// + public class FloatDataPoint : GraphDataPoint + { + /// + /// Initializes a new instance of the class. + /// + public FloatDataPoint() : base() + { + + } + + /// + /// Initializes a new instance of the class. + /// + /// The value. + public FloatDataPoint(float value) : base(value) + { + + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value. + /// + /// The result of the conversion. + /// + public static implicit operator FloatDataPoint(float value) + { + return new FloatDataPoint(value); + } + + /// + /// Implements the operator -. + /// + /// a. + /// The b. + /// + /// The result of the operator. + /// + public static FloatDataPoint operator -(FloatDataPoint a, FloatDataPoint b) + { + return new FloatDataPoint(a.Value - b.Value); + } + + /// + /// Implements the operator +. + /// + /// a. + /// The b. + /// + /// The result of the operator. + /// + public static FloatDataPoint operator +(FloatDataPoint a, FloatDataPoint b) + { + return new FloatDataPoint(a.Value + b.Value); + } + + /// + /// Sums the value of this instance with another instance value and returns the result. + /// + /// The other instance. + /// + public override IGraphDataPoint Add(IGraphDataPoint other) + { + return new FloatDataPoint(this.Value + (other as FloatDataPoint).Value); + } + + /// + /// Subtract the value of another instance from this instance and returns the result. + /// + /// The other instance. + /// + public override IGraphDataPoint Subtract(IGraphDataPoint other) + { + return new FloatDataPoint(this.Value - (other as FloatDataPoint).Value); + } + + /// + /// Multiplies the value of this instance with another instance value and returns the result. + /// + /// The other instance. + /// + public override IGraphDataPoint Multiply(IGraphDataPoint other) + { + return new FloatDataPoint(this.Value * (other as FloatDataPoint).Value); + } + + /// + /// Divides the value of this instance with another instance value and returns the result. + /// + /// The other instance. + /// + public override IGraphDataPoint Divide(IGraphDataPoint other) + { + return new FloatDataPoint(this.Value / (other as FloatDataPoint).Value); + } + + /// + /// Returns the percentage value of this instance between the specified minimum and maximum values. + /// + /// The minimum. + /// The maximum. + /// + public override double ComputeRelativePosition(IGraphDataPoint min, IGraphDataPoint max) + { + FloatDataPoint dMin = min as FloatDataPoint; + FloatDataPoint dMax = max as FloatDataPoint; + + var result = ((Value - dMin) * 100) / (dMax - dMin); + + return double.IsNaN(result) ? dMin.Value : result; + } + + /// + /// Returns the absolute value of the specified percentage value between the specified minimum and maximum values. + /// + /// The minimum. + /// The maximum. + /// The percentage. + /// + public override IGraphDataPoint ComputeAbsolutePosition(IGraphDataPoint min, IGraphDataPoint max, double percentage) + { + double minimum = (double)min.GetValue(); + double maximum = (double)max.GetValue(); + + return new FloatDataPoint((float)(minimum + (maximum - minimum) * percentage)); + } + + /// + /// Creates a range of values from the specified minimum and maximum. + /// + /// The minimum. + /// The maximum. + /// The count. + /// + public override IEnumerable CreateRange(IGraphDataPoint min, IGraphDataPoint max, int count) + { + double minimum = (double)min.GetValue(); + double maximum = (double)max.GetValue(); + + return Enumerable.Range(0, count). + Select(i => minimum + (maximum - minimum) * ((double)i / (count - 1))). + Select(x => new FloatDataPoint((float)x)); + } + + /// + /// Returns a formated string of this data point. + /// + /// The format. + /// + public override string ToString(string format) + { + return Value.ToString(format); + } + + /// + /// Parses the specified value and returns a new instance of data point. + /// + /// The value. + /// + public override IGraphDataPoint Parse(string value) + { + return new FloatDataPoint(float.Parse(value)); + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/DataPoints/Int32DataPoint.cs b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/DataPoints/Int32DataPoint.cs new file mode 100644 index 000000000..787e59aae --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/DataPoints/Int32DataPoint.cs @@ -0,0 +1,183 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RealTimeGraphX.DataPoints +{ + /// + /// Represents a graph value data point. + /// + /// + public class Int32DataPoint : GraphDataPoint + { + /// + /// Initializes a new instance of the class. + /// + public Int32DataPoint() : base() + { + + } + + /// + /// Initializes a new instance of the class. + /// + /// The value. + public Int32DataPoint(int value) : base(value) + { + + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value. + /// + /// The result of the conversion. + /// + public static implicit operator Int32DataPoint(int value) + { + return new Int32DataPoint(value); + } + + /// + /// Implements the operator -. + /// + /// a. + /// The b. + /// + /// The result of the operator. + /// + public static Int32DataPoint operator -(Int32DataPoint a, Int32DataPoint b) + { + return new Int32DataPoint(a.Value - b.Value); + } + + /// + /// Implements the operator +. + /// + /// a. + /// The b. + /// + /// The result of the operator. + /// + public static Int32DataPoint operator +(Int32DataPoint a, Int32DataPoint b) + { + return new Int32DataPoint(a.Value + b.Value); + } + + /// + /// Sums the value of this instance with another instance value and returns the result. + /// + /// The other instance. + /// + public override IGraphDataPoint Add(IGraphDataPoint other) + { + return new Int32DataPoint(this.Value + (other as Int32DataPoint).Value); + } + + /// + /// Subtract the value of another instance from this instance and returns the result. + /// + /// The other instance. + /// + public override IGraphDataPoint Subtract(IGraphDataPoint other) + { + return new Int32DataPoint(this.Value - (other as Int32DataPoint).Value); + } + + /// + /// Multiplies the value of this instance with another instance value and returns the result. + /// + /// The other instance. + /// + public override IGraphDataPoint Multiply(IGraphDataPoint other) + { + return new Int32DataPoint(this.Value * (other as Int32DataPoint).Value); + } + + /// + /// Divides the value of this instance with another instance value and returns the result. + /// + /// The other instance. + /// + public override IGraphDataPoint Divide(IGraphDataPoint other) + { + return new Int32DataPoint(this.Value / (other as Int32DataPoint).Value); + } + + /// + /// Returns the percentage value of this instance between the specified minimum and maximum values. + /// + /// The minimum. + /// The maximum. + /// + public override double ComputeRelativePosition(IGraphDataPoint min, IGraphDataPoint max) + { + Int32DataPoint dMin = min as Int32DataPoint; + Int32DataPoint dMax = max as Int32DataPoint; + + if (dMax - dMin == 0) //Prevent divide by zero + { + return dMin; + } + + var result = ((Value - dMin) * 100) / (dMax - dMin); + + return result; + } + + /// + /// Returns the absolute value of the specified percentage value between the specified minimum and maximum values. + /// + /// The minimum. + /// The maximum. + /// The percentage. + /// + public override IGraphDataPoint ComputeAbsolutePosition(IGraphDataPoint min, IGraphDataPoint max, double percentage) + { + int minimum = (int)min.GetValue(); + int maximum = (int)max.GetValue(); + + return new Int32DataPoint((int)(minimum + (maximum - minimum) * percentage)); + } + + /// + /// Creates a range of values from the specified minimum and maximum. + /// + /// The minimum. + /// The maximum. + /// The count. + /// + public override IEnumerable CreateRange(IGraphDataPoint min, IGraphDataPoint max, int count) + { + double minimum = (int)min.GetValue(); + double maximum = (int)max.GetValue(); + + return Enumerable.Range(0, count). + Select(i => minimum + (maximum - minimum) * ((double)i / (count - 1))). + Select(x => new Int32DataPoint((int)x)); + } + + /// + /// Returns a formated string of this data point. + /// + /// The format. + /// + public override string ToString(string format) + { + return Value.ToString(format); + } + + /// + /// Parses the specified value and returns a new instance of data point. + /// + /// The value. + /// + public override IGraphDataPoint Parse(string value) + { + return new Int32DataPoint(int.Parse(value)); + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/DataPoints/TimeSpanDataPoint.cs b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/DataPoints/TimeSpanDataPoint.cs new file mode 100644 index 000000000..737c93c81 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/DataPoints/TimeSpanDataPoint.cs @@ -0,0 +1,180 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RealTimeGraphX.DataPoints +{ + /// + /// Represents a graph value data point. + /// + /// + public class TimeSpanDataPoint : GraphDataPoint + { + /// + /// Initializes a new instance of the class. + /// + public TimeSpanDataPoint() : base() + { + + } + + /// + /// Initializes a new instance of the class. + /// + /// The value. + public TimeSpanDataPoint(TimeSpan value) : base(value) + { + + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value. + /// + /// The result of the conversion. + /// + public static implicit operator TimeSpanDataPoint(TimeSpan value) + { + return new TimeSpanDataPoint(value); + } + + /// + /// Implements the operator -. + /// + /// a. + /// The b. + /// + /// The result of the operator. + /// + public static TimeSpanDataPoint operator -(TimeSpanDataPoint a, TimeSpanDataPoint b) + { + return new TimeSpanDataPoint(a.Value - b.Value); + } + + /// + /// Implements the operator +. + /// + /// a. + /// The b. + /// + /// The result of the operator. + /// + public static TimeSpanDataPoint operator +(TimeSpanDataPoint a, TimeSpanDataPoint b) + { + return new TimeSpanDataPoint(a.Value + b.Value); + } + + /// + /// Sums the value of this instance with another instance value and returns the result. + /// + /// The other instance. + /// + public override IGraphDataPoint Add(IGraphDataPoint other) + { + return new TimeSpanDataPoint(this.Value + (other as TimeSpanDataPoint).Value); + } + + /// + /// Subtract the value of another instance from this instance and returns the result. + /// + /// The other instance. + /// + public override IGraphDataPoint Subtract(IGraphDataPoint other) + { + return new TimeSpanDataPoint(this.Value - (other as TimeSpanDataPoint).Value); + } + + /// + /// Multiplies the value of this instance with another instance value and returns the result. + /// + /// The other instance. + /// + public override IGraphDataPoint Multiply(IGraphDataPoint other) + { + return new TimeSpanDataPoint(TimeSpan.FromMilliseconds(this.Value.TotalMilliseconds * (other as TimeSpanDataPoint).Value.TotalMilliseconds)); + } + + /// + /// Divides the value of this instance with another instance value and returns the result. + /// + /// The other instance. + /// + public override IGraphDataPoint Divide(IGraphDataPoint other) + { + return new TimeSpanDataPoint(TimeSpan.FromMilliseconds(this.Value.TotalMilliseconds / (other as TimeSpanDataPoint).Value.TotalMilliseconds)); + } + + /// + /// Returns the percentage value of this instance between the specified minimum and maximum values. + /// + /// The minimum. + /// The maximum. + /// + public override double ComputeRelativePosition(IGraphDataPoint min, IGraphDataPoint max) + { + TimeSpan dMin = min as TimeSpanDataPoint; + TimeSpan dMax = max as TimeSpanDataPoint; + + var result = ((Value.TotalMilliseconds - dMin.TotalMilliseconds) * 100) / (dMax.TotalMilliseconds - dMin.TotalMilliseconds); + + return double.IsNaN(result) ? dMin.TotalMilliseconds : result; + } + + /// + /// Returns the absolute value of the specified percentage value between the specified minimum and maximum values. + /// + /// The minimum. + /// The maximum. + /// The percentage. + /// + public override IGraphDataPoint ComputeAbsolutePosition(IGraphDataPoint min, IGraphDataPoint max, double percentage) + { + double minimum = ((TimeSpan)min.GetValue()).TotalMilliseconds; + double maximum = ((TimeSpan)max.GetValue()).TotalMilliseconds; + + return new TimeSpanDataPoint(TimeSpan.FromMilliseconds(minimum + (maximum - minimum) * percentage)); + } + + /// + /// Creates a range of values from the specified minimum and maximum. + /// + /// The minimum. + /// The maximum. + /// The count. + /// + public override IEnumerable CreateRange(IGraphDataPoint min, IGraphDataPoint max, int count) + { + double minimum = ((TimeSpan)min.GetValue()).TotalMilliseconds; + double maximum = ((TimeSpan)max.GetValue()).TotalMilliseconds; + + return Enumerable.Range(0, count). + Select(i => minimum + (maximum - minimum) * ((double)i / (count - 1))). + Select(x => new TimeSpanDataPoint(TimeSpan.FromMilliseconds(x))); + } + + /// + /// Returns a formated string of this data point. + /// + /// The format. + /// + public override string ToString(string format) + { + return Value.ToString(format); + } + + /// + /// Parses the specified value and returns a new instance of data point. + /// + /// The value. + /// + public override IGraphDataPoint Parse(string value) + { + return new TimeSpanDataPoint(TimeSpan.Parse(value)); + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/EventArguments/RangeChangedEventArgs.cs b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/EventArguments/RangeChangedEventArgs.cs new file mode 100644 index 000000000..15d5bb7ba --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/EventArguments/RangeChangedEventArgs.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RealTimeGraphX.EventArguments +{ + /// + /// Represents a graph range change event arguments. + /// + /// + public class RangeChangedEventArgs : EventArgs + { + /// + /// Gets or sets the minimum x value. + /// + public GraphDataPoint MinimumX { get; set; } + + /// + /// Gets or sets the maximum x value. + /// + public GraphDataPoint MaximumX { get; set; } + + /// + /// Gets or sets the minimum y value. + /// + public GraphDataPoint MinimumY { get; set; } + + /// + /// Gets or sets the maximum y value. + /// + public GraphDataPoint MaximumY { get; set; } + + /// + /// Initializes a new instance of the class. + /// + public RangeChangedEventArgs() + { + + } + + /// + /// Initializes a new instance of the class. + /// + /// The minimum x value. + /// The maximum x value. + /// The minimum y value. + /// The maximum y value. + public RangeChangedEventArgs(GraphDataPoint minimumX, GraphDataPoint maximumX,GraphDataPoint minimumY,GraphDataPoint maximumY) : this() + { + MinimumX = minimumX; + MaximumX = maximumX; + MinimumY = minimumY; + MaximumY = maximumY; + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphCommand.cs b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphCommand.cs new file mode 100644 index 000000000..e16ecd675 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphCommand.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Input; + +namespace RealTimeGraphX +{ + /// + /// Represents a graph relay command. + /// + /// + public class GraphCommand : ICommand + { + private Action _action; + private Func _canExecute; + + /// + /// Initializes a new instance of the class. + /// + /// The action. + /// The can execute. + public GraphCommand(Action action, Func canExecute) + { + _action = action; + _canExecute = canExecute; + } + + /// + /// Initializes a new instance of the class. + /// + /// The action. + public GraphCommand(Action action) : this(action, null) + { + + } + + /// + /// Defines the method that determines whether the command can execute in its current state. + /// + /// Data used by the command. If the command does not require data to be passed, this object can be set to null. + /// + /// true if this command can be executed; otherwise, false. + /// + public bool CanExecute(object parameter) + { + if (_canExecute != null) + { + return _canExecute(); + } + + return true; + } + + /// + /// Defines the method to be called when the command is invoked. + /// + /// Data used by the command. If the command does not require data to be passed, this object can be set to null. + public void Execute(object parameter) + { + _action(); + } + + /// + /// Raises the can execute changed event. + /// + public void RaiseCanExecuteChanged() + { + CanExecuteChanged?.Invoke(this, new EventArgs()); + } + + /// + /// Occurs when changes occur that affect whether or not the command should execute. + /// + /// + public event EventHandler CanExecuteChanged; + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphController.cs b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphController.cs new file mode 100644 index 000000000..1b452df57 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphController.cs @@ -0,0 +1,662 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Text; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using System.Drawing; +using RealTimeGraphX.EventArguments; +using RealTimeGraphX.Renderers; +using System.Diagnostics; + +namespace RealTimeGraphX +{ + /// + /// Represents an base class. + /// + /// The type of the data series. + /// The type of the x data point. + /// The type of the y data point. + /// + /// + public abstract class GraphController : GraphObject, IGraphController + where TXDataPoint : GraphDataPoint + where TYDataPoint : GraphDataPoint + where TDataSeries : IGraphDataSeries + { + private GraphDataQueue> _pending_series_collection; + private Dictionary _to_render; + private DateTime _last_render_time; + private object _render_lock = new object(); + private Thread _render_thread; + + #region Pending Series Class + + protected class PendingSeries + { + public TDataSeries Series { get; set; } + public List XX { get; set; } + public List YY { get; set; } + + public int NewItemsCount + { + get { return XX.Count - RenderedItems; } + } + + public int RenderedItems { get; set; } + + public bool IsClearSeries { get; set; } + + public bool IsUpdateSeries { get; set; } + } + + #endregion + + #region Events + + /// + /// Occurs when the current effective minimum/maximum has changed. + /// + public event EventHandler EffectiveRangeChanged; + + /// + /// Occurs when the current virtual (effective minimum/maximum after transformation) minimum/maximum has changed. + /// + public event EventHandler VirtualRangeChanged; + + #endregion + + #region Properties + + /// + /// Gets or sets the controller refresh rate. + /// Higher rate requires more CPU time. + /// + public TimeSpan RefreshRate { get; set; } + + /// + /// Gets or sets a value indicating whether to pause rendering. + /// + public bool IsPaused { get; set; } + + /// + /// Gets or sets a value indicating whether to disable the rendering of data. + /// + public bool DisableRendering { get; set; } + + /// + /// Gets the data series collection. + /// + public ObservableCollection DataSeriesCollection { get; } + + private IGraphRenderer _renderer; + /// + /// Gets or sets the graph renderer. + /// + public IGraphRenderer Renderer + { + get + { + return _renderer; + } + set + { + _renderer = value; RaisePropertyChangedAuto(); + } + } + + private IGraphSurface _surface; + /// + /// Gets or sets the rendering surface. + /// + public IGraphSurface Surface + { + get { return _surface; } + set + { + var previous = _surface; + _surface = value; + RequestVirtualRangeChange(); + OnSurfaceChanged(previous, _surface); + } + } + + private GraphRange _range; + /// + /// Gets or sets the graph range (data point boundaries). + /// + public GraphRange Range + { + get + { + return _range; + } + set + { + _range = value; RaisePropertyChangedAuto(); + } + } + + /// + /// Gets the current effective x-axis minimum. + /// + public GraphDataPoint EffectiveMinimumX { get; private set; } + + /// + /// Gets the current effective x-axis maximum. + /// + public GraphDataPoint EffectiveMaximumX { get; private set; } + + /// + /// Gets the current effective y-axis minimum. + /// + public GraphDataPoint EffectiveMinimumY { get; private set; } + + /// + /// Gets the current effective y-axis maximum. + /// + public GraphDataPoint EffectiveMaximumY { get; private set; } + + /// + /// Gets the current virtual (effective minimum/maximum after transformation) x-axis minimum. + /// + public GraphDataPoint VirtualMinimumX { get; private set; } + + /// + /// Gets the current virtual (effective minimum/maximum after transformation) x-axis maximum. + /// + public GraphDataPoint VirtualMaximumX { get; private set; } + + /// + /// Gets the current virtual (effective minimum/maximum after transformation) y-axis minimum. + /// + public GraphDataPoint VirtualMinimumY { get; private set; } + + /// + /// Gets the current virtual (effective minimum/maximum after transformation) y-axis maximum. + /// + public GraphDataPoint VirtualMaximumY { get; private set; } + + #endregion + + #region Commands + + /// + /// Gets the clear command. + /// + public GraphCommand ClearCommand { get; private set; } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + public GraphController() + { + Renderer = new ScrollingLineRenderer(); + + DataSeriesCollection = new ObservableCollection(); + Range = new GraphRange(); + + _last_render_time = DateTime.Now; + _to_render = new Dictionary(); + _pending_series_collection = new GraphDataQueue>(); + RefreshRate = TimeSpan.FromMilliseconds(50); + + ClearCommand = new GraphCommand(Clear); + + _render_thread = new Thread(RenderThreadMethod); + _render_thread.IsBackground = true; + _render_thread.Priority = ThreadPriority.Highest; + _render_thread.Start(); + } + + #endregion + + #region Render Thread + + /// + /// The rendering thread method. + /// + private void RenderThreadMethod() + { + while (true) + { + if (!IsPaused && !DisableRendering) + { + try + { + List> pending_lists = new List>(); + + var pending_list_first = _pending_series_collection.BlockDequeue(); + pending_lists.Add(pending_list_first); + + while (_pending_series_collection.Count > 0) + { + var pending_list = _pending_series_collection.BlockDequeue(); + pending_lists.Add(pending_list); + } + + foreach (var pending_list in pending_lists) + { + foreach (var pending_series in pending_list) + { + if (pending_series.IsClearSeries) + { + _pending_series_collection = new GraphDataQueue>(); + _to_render.Clear(); + } + else if (!pending_series.IsUpdateSeries) + { + if (_to_render.ContainsKey(pending_series.Series)) + { + var s = _to_render[pending_series.Series]; + s.XX.AddRange(pending_series.XX); + s.YY.AddRange(pending_series.YY); + } + else + { + _to_render[pending_series.Series] = pending_series; + } + } + } + } + + if (_to_render.Count > 0) + { + GraphDataPoint min_x = _range.MaximumX - _range.MaximumX; + GraphDataPoint max_x = _range.MaximumX; + GraphDataPoint min_y = _range.MinimumY; + GraphDataPoint max_y = _range.MaximumY; + + if (_to_render.Count > 0 && _to_render.First().Value.XX.Count > 0) + { + min_x = _to_render.First().Value.XX.First(); + max_x = _to_render.First().Value.XX.Last(); + } + else + { + continue; + } + + if (_range.AutoY) + { + min_y = _to_render.Select(x => x.Value).SelectMany(x => x.YY).Min(); + max_y = _to_render.Select(x => x.Value).SelectMany(x => x.YY).Max(); + } + + if (min_y == max_y) + { + min_y = _range.MinimumY; + max_y = _range.MaximumY; + } + + EffectiveMinimumX = min_x; + EffectiveMaximumX = max_x; + EffectiveMinimumY = min_y; + EffectiveMaximumY = max_y; + + VirtualMinimumX = EffectiveMinimumX; + VirtualMaximumX = EffectiveMaximumX; + VirtualMinimumY = EffectiveMinimumY; + VirtualMaximumY = EffectiveMaximumY; + + _last_render_time = DateTime.Now; + + if (Surface != null) + { + var surface_size = Surface.GetSize(); + var zoom_rect = Surface.GetZoomRect(); + + Surface.BeginDraw(); + + if (zoom_rect.Width > 0 && zoom_rect.Height > 0) + { + var zoom_rect_top_percentage = zoom_rect.Top / surface_size.Height; + var zoom_rect_bottom_percentage = zoom_rect.Bottom / surface_size.Height; + var zoom_rect_left_percentage = zoom_rect.Left / surface_size.Width; + var zoom_rect_right_percentage = zoom_rect.Right / surface_size.Width; + + VirtualMinimumY = EffectiveMaximumY - GraphDataPointHelper.ComputeAbsolutePosition(EffectiveMinimumY, EffectiveMaximumY, zoom_rect_bottom_percentage); + VirtualMaximumY = EffectiveMaximumY - GraphDataPointHelper.ComputeAbsolutePosition(EffectiveMinimumY, EffectiveMaximumY, zoom_rect_top_percentage); + + VirtualMinimumX = GraphDataPointHelper.ComputeAbsolutePosition(EffectiveMinimumX, EffectiveMaximumX, zoom_rect_left_percentage); + VirtualMaximumX = GraphDataPointHelper.ComputeAbsolutePosition(EffectiveMinimumX, EffectiveMaximumX, zoom_rect_right_percentage); + + GraphTransform transform = new GraphTransform(); + var scale_x = (float)(surface_size.Width / zoom_rect.Width); + var scale_y = (float)(surface_size.Height / zoom_rect.Height); + var translate_x = (float)-zoom_rect.Left * scale_x; + var translate_y = (float)-zoom_rect.Top * scale_y; + + transform = new GraphTransform(); + transform.TranslateX = translate_x; + transform.TranslateY = translate_y; + transform.ScaleX = scale_x; + transform.ScaleY = scale_y; + + Surface.SetTransform(transform); + } + + List>> to_draw = new List>>(); + + var to_render = _to_render.Select(x => x.Value).ToList(); + + foreach (var item in to_render) + { + if (item.YY.Count > 0) + { + item.Series.CurrentValue = item.YY.Last().GetValue(); + } + + var points = Renderer.Render(Surface, item.Series, _range, item.XX, item.YY, min_x, max_x, min_y, max_y); + to_draw.Add(new Tuple>(item.Series, points)); + } + + for (int i = 0; i < to_draw.Count; i++) + { + if (to_draw[i].Item2.Count() > 2) + { + if (to_draw[i].Item1.IsVisible) + { + Renderer.Draw(Surface, to_draw[i].Item1, to_draw[i].Item2, i, to_draw.Count); + } + } + } + + Surface.EndDraw(); + } + + OnEffectiveRangeChanged(EffectiveMinimumX, EffectiveMaximumX, EffectiveMinimumY, EffectiveMaximumY); + OnVirtualRangeChanged(VirtualMinimumX, VirtualMaximumX, VirtualMinimumY, VirtualMaximumY); + } + } + catch (Exception ex) + { + Debug.WriteLine($"Error in RealTimeGraphX:\n{ex.ToString()}"); + } + } + else + { + Thread.Sleep(RefreshRate); + } + } + } + + #endregion + + #region Protected Methods + + /// + /// Called when the surface has changed. + /// + /// The previous. + /// The surface. + protected virtual void OnSurfaceChanged(IGraphSurface previous, IGraphSurface surface) + { + if (previous != null) + { + previous.SurfaceSizeChanged += Surface_SurfaceSizeChanged; + previous.ZoomRectChanged += Surface_ZoomRectChanged; + } + + if (surface != null) + { + surface.SurfaceSizeChanged += Surface_SurfaceSizeChanged; + surface.ZoomRectChanged += Surface_ZoomRectChanged; + } + } + + /// + /// Raises the event. + /// + /// The minimum x. + /// The maximum x. + /// The minimum y. + /// The maximum y. + protected virtual void OnEffectiveRangeChanged(GraphDataPoint minimumX, GraphDataPoint maximumX, GraphDataPoint minimumY, GraphDataPoint maximumY) + { + EffectiveRangeChanged?.Invoke(this, new RangeChangedEventArgs(minimumX, maximumX, minimumY, maximumY)); + } + + /// + /// Raises the event. + /// + /// The minimum x. + /// The maximum x. + /// The minimum y. + /// The maximum y. + protected virtual void OnVirtualRangeChanged(GraphDataPoint minimumX, GraphDataPoint maximumX, GraphDataPoint minimumY, GraphDataPoint maximumY) + { + var range = new RangeChangedEventArgs(minimumX, maximumX, minimumY, maximumY); + VirtualRangeChanged?.Invoke(this, range); + } + + /// + /// Converts the specified relative x position to graph absolute position. + /// + /// The relative x position. + /// + protected virtual float ConvertXValueToRendererValue(double x) + { + return (float)(x * Surface.GetSize().Width / 100); + } + + /// + /// Converts the specified relative y position to graph absolute position. + /// + /// The relative y position. + /// + protected virtual float ConvertYValueToRendererValue(double y) + { + return (float)(Surface.GetSize().Height - (y * Surface.GetSize().Height / 100)); + } + + #endregion + + #region Surface Event Handlers + + /// + /// Handles the ZoomRectChanged event of the Surface control. + /// + /// The source of the event. + /// The instance containing the event data. + private void Surface_ZoomRectChanged(object sender, EventArgs e) + { + if (!_pending_series_collection.ToList().SelectMany(x => x).ToList().Exists(x => x.IsUpdateSeries)) + { + List updateSeries = new List(); + + foreach (var pending_Series in _to_render) + { + updateSeries.Add(new PendingSeries() + { + IsUpdateSeries = true, + Series = pending_Series.Value.Series, + XX = new List(), + YY = new List(), + }); + } + + _pending_series_collection.BlockEnqueue(updateSeries); + } + } + + /// + /// Handles the SurfaceSizeChanged event of the Surface control. + /// + /// The source of the event. + /// The instance containing the event data. + private void Surface_SurfaceSizeChanged(object sender, EventArgs e) + { + if (!_pending_series_collection.ToList().SelectMany(x => x).ToList().Exists(x => x.IsUpdateSeries)) + { + List updateSeries = new List(); + + foreach (var pending_Series in _to_render) + { + updateSeries.Add(new PendingSeries() + { + IsUpdateSeries = true, + Series = pending_Series.Value.Series, + XX = new List(), + YY = new List(), + }); + } + + _pending_series_collection.BlockEnqueue(updateSeries); + } + } + + #endregion + + #region Public Methods + + /// + /// Submits the specified x and y data points. + /// If the controller has more than one data series the data points will be duplicated. + /// + /// X data point. + /// Y data point. + public void PushData(TXDataPoint x, TYDataPoint y) + { + if (DataSeriesCollection.Count == 0) return; + + List> xxxx = new List>(); + List> yyyy = new List>(); + + foreach (var series in DataSeriesCollection.ToList()) + { + xxxx.Add(new List() { x }); + yyyy.Add(new List() { y }); + } + + PushData(xxxx, yyyy); + } + + /// + /// Submits the specified collections of x and y data points. + /// If the controller has more than one data series the data points will be distributed evenly. + /// + /// X data point collection. + /// Y data point collection. + public void PushData(IEnumerable xx, IEnumerable yy) + { + if (DataSeriesCollection.Count == 0) return; + + var xList = xx.ToList(); + var yList = yy.ToList(); + + List> xxxx = new List>(); + List> yyyy = new List>(); + + foreach (var series in DataSeriesCollection.ToList()) + { + xxxx.Add(new List()); + yyyy.Add(new List()); + } + + int counter = 0; + + for (int i = 0; i < xList.Count; i++) + { + xxxx[counter].Add(xList[i]); + yyyy[counter].Add(yList[i]); + + counter++; + + if (counter >= xxxx.Count) + { + counter = 0; + } + } + + PushData(xxxx, yyyy); + } + + /// + /// Submits a matrix of x and y data points. Meaning each data series should process a single collection of x/y data points. + /// + /// X matrix. + /// Y matrix. + public void PushData(IEnumerable> xxxx, IEnumerable> yyyy) + { + if (DataSeriesCollection.Count == 0) return; + + IEnumerable> xxxxI = xxxx.Select(x => x.ToList()).ToList(); + IEnumerable> yyyyI = yyyy.Select(x => x.ToList()).ToList(); + + List> xxxxList = xxxxI.Select(x => x.ToList()).ToList(); + List> yyyyList = yyyyI.Select(x => x.ToList()).ToList(); + + int first_count_x = xxxxList[0].Count; + int first_count_y = yyyyList[0].Count; + + + bool is_data_valid = true; + + for (int i = 0; i < xxxxList.Count; i++) + { + if (xxxxList[0].Count != first_count_x) + { + is_data_valid = false; + break; + } + + if (xxxxList[0].Count != yyyyList[0].Count) + { + is_data_valid = false; + break; + } + } + + if (!is_data_valid) + { + throw new ArgumentOutOfRangeException("When pushing data to a multi series renderer, each series must contain the same amount of data."); + } + + var list = DataSeriesCollection.ToList(); + + var pending_list = new List(); + + for (int i = 0; i < list.Count; i++) + { + pending_list.Add(new PendingSeries() + { + Series = list[i], + XX = xxxxList[i].ToList(), + YY = yyyyList[i].ToList(), + }); + } + + _pending_series_collection.BlockEnqueue(pending_list); + } + + /// + /// Clears all data points from this controller. + /// + public void Clear() + { + _pending_series_collection.BlockEnqueue(new List() + { + new PendingSeries() + { + IsClearSeries = true + }, + }); + } + + /// + /// Requests the controller to invoke a virtual range change event. + /// + public void RequestVirtualRangeChange() + { + OnVirtualRangeChanged(Range.MaximumX, Range.MaximumX, Range.MinimumY, Range.MaximumY); + } + + #endregion + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphDataPoint.cs b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphDataPoint.cs new file mode 100644 index 000000000..e069d8950 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphDataPoint.cs @@ -0,0 +1,412 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RealTimeGraphX +{ + /// + /// Represents an base class. + /// + /// + public abstract class GraphDataPoint : IGraphDataPoint + { + #region IComparable + + /// + /// Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes, follows, or occurs in the same position in the sort order as the other object. + /// + /// An object to compare with this instance. + /// + /// A value that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less than zero This instance precedes in the sort order. Zero This instance occurs in the same position in the sort order as . Greater than zero This instance follows in the sort order. + /// + public abstract int CompareTo(object obj); + + /// + /// Determines whether the specified , is equal to this instance. + /// + /// The to compare with this instance. + /// + /// true if the specified is equal to this instance; otherwise, false. + /// + public override bool Equals(object obj) + { + return base.Equals(obj); + } + + /// + /// Returns a hash code for this instance. + /// + /// + /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. + /// + public override int GetHashCode() + { + return base.GetHashCode(); + } + + #endregion + + #region Logical Operators + + /// + /// Implements the operator >. + /// + /// + /// The result of the operator. + /// + public static bool operator >(GraphDataPoint a, GraphDataPoint b) + { + return a.CompareTo(b) == 1; + } + + /// + /// Implements the operator <. + /// + /// + /// The result of the operator. + /// + public static bool operator <(GraphDataPoint a, GraphDataPoint b) + { + return a.CompareTo(b) == -1; + } + + /// + /// Implements the operator ==. + /// + /// + /// The result of the operator. + /// + public static bool operator ==(GraphDataPoint a, GraphDataPoint b) + { + if (Object.ReferenceEquals(a, null) && Object.ReferenceEquals(b, null)) return true; + if (Object.ReferenceEquals(a, null) && !Object.ReferenceEquals(b, null)) return false; + + return a.CompareTo(b) == 0; + } + + /// + /// Implements the operator !=. + /// + /// + /// The result of the operator. + /// + public static bool operator !=(GraphDataPoint a, GraphDataPoint b) + { + if (Object.ReferenceEquals(a, null) && Object.ReferenceEquals(b, null)) return false; + if (Object.ReferenceEquals(a, null) && !Object.ReferenceEquals(b, null)) return true; + + return a.CompareTo(b) != 0; + } + + #endregion + + #region Arithmetic Operators + + /// + /// Implements the operator -. + /// + /// + /// The result of the operator. + /// + public static GraphDataPoint operator -(GraphDataPoint a, GraphDataPoint b) + { + return (GraphDataPoint)a.Subtract(b); + } + + /// + /// Implements the operator +. + /// + /// + /// The result of the operator. + /// + public static GraphDataPoint operator +(GraphDataPoint a, GraphDataPoint b) + { + return (GraphDataPoint)a.Add(b); + } + + /// + /// Implements the operator /. + /// + /// + /// The result of the operator. + /// + public static GraphDataPoint operator /(GraphDataPoint a, GraphDataPoint b) + { + return (GraphDataPoint)a.Divide(b); + } + + /// + /// Implements the operator *. + /// + /// + /// The result of the operator. + /// + public static GraphDataPoint operator *(GraphDataPoint a, GraphDataPoint b) + { + return (GraphDataPoint)a.Multiply(b); + } + + #endregion + + #region IGraphDataPoint + + /// + /// Sums the value of this instance with another instance value and returns the result. + /// + /// The other instance. + /// + public abstract IGraphDataPoint Add(IGraphDataPoint other); + + /// + /// Subtract the value of another instance from this instance and returns the result. + /// + /// The other instance. + /// + public abstract IGraphDataPoint Subtract(IGraphDataPoint other); + + /// + /// Multiplies the value of this instance with another instance value and returns the result. + /// + /// The other instance. + /// + public abstract IGraphDataPoint Multiply(IGraphDataPoint other); + + /// + /// Divides the value of this instance with another instance value and returns the result. + /// + /// The other instance. + /// + public abstract IGraphDataPoint Divide(IGraphDataPoint other); + + /// + /// Returns the percentage value of this instance between the specified minimum and maximum values. + /// + /// The minimum. + /// The maximum. + /// + public abstract double ComputeRelativePosition(IGraphDataPoint min, IGraphDataPoint max); + + /// + /// Returns the absolute value of the specified percentage value between the specified minimum and maximum values. + /// + /// The minimum. + /// The maximum. + /// The percentage. + /// + public abstract IGraphDataPoint ComputeAbsolutePosition(IGraphDataPoint min, IGraphDataPoint max, double percentage); + + /// + /// Creates a range of values from the specified minimum and maximum. + /// + /// The minimum. + /// The maximum. + /// The count. + /// + public abstract IEnumerable CreateRange(IGraphDataPoint min, IGraphDataPoint max, int count); + + /// + /// Gets the inner value. + /// + /// + public abstract object GetValue(); + + /// + /// Sets the inner value. + /// + /// The value. + public abstract void SetValue(object value); + + /// + /// Returns a formated string of this data point. + /// + /// The format. + /// + public abstract string ToString(string format); + + /// + /// Parses the specified value. + /// + /// The value. + /// + public abstract IGraphDataPoint Parse(string value); + + #endregion + + #region Properties + + /// + /// Gets the type of this graph data point. + /// + public Type Type + { + get { return GetType(); } + } + + #endregion + } + + /// + /// Represents an base class. + /// + /// + /// The type of the data type. + /// + public abstract class GraphDataPoint : GraphDataPoint where T : IComparable where TDataType : GraphDataPoint + { + #region Properties + + /// + /// Gets or sets the encapsulated data point value. + /// + public T Value { get; set; } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + public GraphDataPoint() + { + + } + + /// + /// Initializes a new instance of the class. + /// + /// The value. + public GraphDataPoint(T value) + { + Value = value; + } + + #endregion + + #region IComparable + + /// + /// Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes, follows, or occurs in the same position in the sort order as the other object. + /// + /// An object to compare with this instance. + /// + /// A value that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less than zero This instance precedes in the sort order. Zero This instance occurs in the same position in the sort order as . Greater than zero This instance follows in the sort order. + /// + public override int CompareTo(object obj) + { + if (Object.ReferenceEquals(obj, null)) return -1; + + GraphDataPoint b = obj as GraphDataPoint; + return Value.CompareTo(b.Value); + } + + /// + /// Determines whether the specified , is equal to this instance. + /// + /// The to compare with this instance. + /// + /// true if the specified is equal to this instance; otherwise, false. + /// + public override bool Equals(object obj) + { + var @base = obj as GraphDataPoint; + return @base != null && + EqualityComparer.Default.Equals(Value, @base.Value); + } + + /// + /// Returns a hash code for this instance. + /// + /// + /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. + /// + public override int GetHashCode() + { + return -1937169414 + EqualityComparer.Default.GetHashCode(Value); + } + + #endregion + + #region ToString + + /// + /// Returns a that represents this instance. + /// + /// + /// A that represents this instance. + /// + public override string ToString() + { + return Value.ToString(); + } + + #endregion + + #region IGraphDataPoint + + /// + /// Gets the inner value. + /// + /// + public override object GetValue() + { + return Value; + } + + /// + /// Sets the inner value. + /// + /// The value. + public override void SetValue(object value) + { + Value = (T)value; + } + + #endregion + + #region Parsing + + /// + /// Parses the specified value and returns a new instance of data point. + /// + /// The value. + /// + public static TDataType ParseFrom(String value) + { + return Activator.CreateInstance().Parse(value) as TDataType; + } + + #endregion + + #region Implicit Operators + + /// + /// Performs an implicit conversion from to . + /// + /// The value. + /// + /// The result of the conversion. + /// + public static implicit operator GraphDataPoint(T value) + { + return Activator.CreateInstance(typeof(TDataType), value) as GraphDataPoint; + } + + /// + /// Performs an implicit conversion from to . + /// + /// The instance. + /// + /// The result of the conversion. + /// + public static implicit operator T(GraphDataPoint instance) + { + return instance.Value; + } + + #endregion + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphDataPointHelper.cs b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphDataPointHelper.cs new file mode 100644 index 000000000..b28d7a501 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphDataPointHelper.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RealTimeGraphX +{ + /// + /// Represents an helper class. + /// + public static class GraphDataPointHelper + { + /// + /// Returns the absolute value of the specified percentage value between the specified minimum and maximum values. + /// + /// The minimum. + /// The maximum. + /// The percentage. + /// + public static T ComputeAbsolutePosition(T min, T max, double percentage) where T : class, IGraphDataPoint + { + return (Activator.CreateInstance(min.GetType()) as T).ComputeAbsolutePosition(min, max, percentage) as T; + } + + /// + /// Creates a range of values from the specified minimum and maximum. + /// + /// The minimum. + /// The maximum. + /// The count. + /// + public static IEnumerable CreateRange(IGraphDataPoint min, IGraphDataPoint max, int count) where T : class, IGraphDataPoint + { + return (Activator.CreateInstance(min.GetType()) as T).CreateRange(min, max, count) as IEnumerable; + } + + /// + /// Initializes a new instance of the specified type. + /// + /// + /// + public static T Init() where T : class, IGraphDataPoint + { + return Activator.CreateInstance(typeof(T)) as T; + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphDataPointTypeConverter.cs b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphDataPointTypeConverter.cs new file mode 100644 index 000000000..edbd78cf1 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphDataPointTypeConverter.cs @@ -0,0 +1,82 @@ +using RealTimeGraphX.DataPoints; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Globalization; +using System.Text; + +namespace RealTimeGraphX +{ + /// + /// Represents the type converter. + /// + public class GraphDataPointTypeConverter : TypeConverter + { + private IGraphDataPoint _instance; + + /// + /// Returns whether this converter can convert an object of the given type to the type of this converter, using the specified context. + /// + /// An that provides a format context. + /// A that represents the type you want to convert from. + /// + /// true if this converter can perform the conversion; otherwise, false. + /// + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + return sourceType == typeof(String); + } + + /// + /// Converts the given object to the type of this converter, using the specified context and culture information. + /// + /// An that provides a format context. + /// The to use as the current culture. + /// The to convert. + /// + /// An that represents the converted value. + /// + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + if (value != null && _instance != null) + { + try + { + return _instance.Parse(value.ToString()); + } + catch {} + } + + return _instance; + } + + /// + /// Returns whether this converter can convert the object to the specified type, using the specified context. + /// + /// An that provides a format context. + /// A that represents the type you want to convert to. + /// + /// true if this converter can perform the conversion; otherwise, false. + /// + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + { + return destinationType == typeof(String); + } + + /// + /// Converts the given value object to the specified type, using the specified context and culture information. + /// + /// An that provides a format context. + /// A . If null is passed, the current culture is assumed. + /// The to convert. + /// The to convert the value parameter to. + /// + /// An that represents the converted value. + /// + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + _instance = value as IGraphDataPoint; + return value != null ? value.ToString() : null; + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphDataQueue.cs b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphDataQueue.cs new file mode 100644 index 000000000..cb28231ab --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphDataQueue.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace RealTimeGraphX +{ + /// + /// Represents a blocking concurrent queue for graph data consumption. + /// + /// + /// + public class GraphDataQueue : BlockingCollection + { + /// + /// Initializes a new instance of the GraphDataQueue, Use Add and TryAdd for Enqueue and TryEnqueue and Take and TryTake for Dequeue and TryDequeue functionality + /// + public GraphDataQueue() + : base(new ConcurrentQueue()) + { + } + + /// + /// Initializes a new instance of the GraphDataQueue, Use Add and TryAdd for Enqueue and TryEnqueue and Take and TryTake for Dequeue and TryDequeue functionality + /// + /// + public GraphDataQueue(int maxSize) + : base(new ConcurrentQueue(), maxSize) + { + } + + /// + /// Enqueues the specified item. + /// + /// The item. + public void BlockEnqueue(T item) + { + Add(item); + } + + /// + /// Blocks until an item is available for dequeuing. + /// + /// + public T BlockDequeue() + { + return Take(); + } + + /// + /// Blocks until an item is available for dequeuing. + /// + /// The cancellation token. + /// + public T BlockDequeue(CancellationToken cancellationToken) + { + return Take(cancellationToken); + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphObject.cs b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphObject.cs new file mode 100644 index 000000000..d37110c5c --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphObject.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; +using System.Windows; + +namespace RealTimeGraphX +{ + /// + /// Represents an supported graph object. + /// + /// + public abstract class GraphObject : INotifyPropertyChanged + { + /// + /// Occurs when a property value changes. + /// + [field: NonSerialized] + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the property changed event. + /// + /// Name of the property. + protected virtual void RaisePropertyChangedAuto([CallerMemberName] string caller = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(caller)); + } + + /// + /// Raises the property changed event. + /// + /// Name of the property. + protected virtual void RaisePropertyChanged(String propName) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName)); + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphRange.cs b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphRange.cs new file mode 100644 index 000000000..521f9f0b6 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphRange.cs @@ -0,0 +1,138 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RealTimeGraphX +{ + /// + /// Represents a graph x/y data points boundaries. + /// + public interface IGraphRange : IGraphComponent + { + /// + /// Gets or sets the maximum x value. + /// + GraphDataPoint MaximumX { get; set; } + + /// + /// Gets or sets the minimum x value. + /// + GraphDataPoint MinimumY { get; set; } + + /// + /// Gets or sets the maximum y value. + /// + GraphDataPoint MaximumY { get; set; } + + /// + /// Gets or sets a value indicating whether to automatically adjust the graph and according to the current effective data points. + /// + bool AutoY { get; set; } + } + + /// + /// Represents a graph X/Y range boundaries. + /// + /// Type of x-axis data point. + /// Type of y-axis data point. + /// + public class GraphRange : GraphObject, IGraphRange where XDataPoint : GraphDataPoint where YDataPoint : GraphDataPoint + { + private XDataPoint _maximumX; + /// + /// Gets or sets the maximum x value. + /// + public XDataPoint MaximumX + { + get { return _maximumX; } + set { _maximumX = value; RaisePropertyChangedAuto(); } + } + + private YDataPoint _minimumY; + /// + /// Gets or sets the minimum x value. + /// + public YDataPoint MinimumY + { + get { return _minimumY; } + set { _minimumY = value; RaisePropertyChangedAuto(); } + } + + private YDataPoint _maximumY; + /// + /// Gets or sets the maximum y value. + /// + public YDataPoint MaximumY + { + get { return _maximumY; } + set { _maximumY = value; RaisePropertyChangedAuto(); } + } + + private bool _autoY; + /// + /// Gets or sets a value indicating whether to automatically adjust the graph and according to the current visible data points. + /// + public bool AutoY + { + get { return _autoY; } + set { _autoY = value; RaisePropertyChangedAuto(); } + } + + /// + /// Initializes a new instance of the class. + /// + public GraphRange() + { + MinimumY = GraphDataPointHelper.Init(); + MaximumX = GraphDataPointHelper.Init(); + MaximumY = GraphDataPointHelper.Init(); + } + + /// + /// Gets or sets the maximum x value. + /// + GraphDataPoint IGraphRange.MaximumX + { + get + { + return MaximumX; + } + set + { + MaximumX = (XDataPoint)value; + } + } + + /// + /// Gets or sets the minimum x value. + /// + GraphDataPoint IGraphRange.MinimumY + { + get + { + return MinimumY; + } + set + { + MinimumY = (YDataPoint)value; + } + } + + /// + /// Gets or sets the maximum y value. + /// + GraphDataPoint IGraphRange.MaximumY + { + get + { + return MaximumY; + } + set + { + MaximumY = (YDataPoint)value; + } + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphRenderer.cs b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphRenderer.cs new file mode 100644 index 000000000..c42fcb4ab --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphRenderer.cs @@ -0,0 +1,76 @@ +using System.Collections.Generic; +using System.Linq; +using System.Drawing; + +namespace RealTimeGraphX +{ + /// + /// Represents an base class. + /// + /// The type of the data series. + /// + /// + public abstract class GraphRenderer : GraphObject, IGraphRenderer where TDataSeries : IGraphDataSeries + { + /// + /// Converts the specified relative x position to a graph surface absolute position. + /// + /// The target surface. + /// The relative x position. + /// + protected virtual float ConvertXValueToRendererValue(IGraphSurface surface, double x) + { + return (float)(x * surface.GetSize().Width / 100); + } + + /// + /// Converts the specified relative y position to a graph surface absolute position. + /// + /// The surface. + /// The relative y position. + /// + protected virtual float ConvertYValueToRendererValue(IGraphSurface surface, double y) + { + return (float)(surface.GetSize().Height - (y * surface.GetSize().Height / 100)); + } + + /// + /// Arranges the series of data points and returns a series of drawing points. + /// + /// The target graph surface. + /// The instance of the current rendered data series. + /// Instance of graph range. + /// Collection of x coordinates. + /// Collection of y coordinates. + /// The minimum x coordinates value. + /// The maximum x coordinates value. + /// The minimum y coordinates value. + /// The maximum y coordinates value. + /// + public abstract IEnumerable Render(IGraphSurface surface, TDataSeries series, IGraphRange range, List xx, List yy, GraphDataPoint minimumX, GraphDataPoint maximumX, GraphDataPoint minimumY, GraphDataPoint maximumY); + + /// + /// Draws the specified data series points on the target surface. + /// + /// The target graph surface. + /// The instance of the current rendered data series. + /// The collection of the current data series drawing points. + /// The index of the current data series within the collection of data series. + /// The length of the data series collection. + public abstract void Draw(IGraphSurface surface, TDataSeries series, IEnumerable points, int index, int count); + + /// + /// Gets a closed polygon version of the specified drawing points. + /// + /// The target surface. + /// The drawing points. + /// + protected virtual IEnumerable GetFillPoints(IGraphSurface surface, IEnumerable points) + { + List closed = points.ToList(); + closed.Add(new PointF(points.Last().X, surface.GetSize().Width)); + closed.Add(new PointF(0, surface.GetSize().Height)); + return closed.ToArray(); + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphTransform.cs b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphTransform.cs new file mode 100644 index 000000000..efcf4b052 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/GraphTransform.cs @@ -0,0 +1,39 @@ +namespace RealTimeGraphX +{ + /// + /// Represents a graph transformation. + /// + public class GraphTransform + { + /// + /// Gets or sets the horizontal scale factor. + /// + public float ScaleX { get; set; } + + /// + /// Gets or sets the vertical scale factor. + /// + public float ScaleY { get; set; } + + /// + /// Gets or sets the horizontal translate transformation. + /// + public float TranslateX { get; set; } + + /// + /// Gets or sets the vertical translate transformation. + /// + public float TranslateY { get; set; } + + /// + /// Initializes a new instance of the class. + /// + public GraphTransform() + { + ScaleX = 1; + ScaleY = 1; + TranslateX = 0; + TranslateY = 0; + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/IGraphComponent.cs b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/IGraphComponent.cs new file mode 100644 index 000000000..dd8f4ee1d --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/IGraphComponent.cs @@ -0,0 +1,10 @@ +namespace RealTimeGraphX +{ + /// + /// Represents a RealTimeGraphX component. + /// + public interface IGraphComponent + { + + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/IGraphController.cs b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/IGraphController.cs new file mode 100644 index 000000000..4e36641e7 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/IGraphController.cs @@ -0,0 +1,190 @@ +using RealTimeGraphX.EventArguments; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; + +namespace RealTimeGraphX +{ + /// + /// Represents a graph controller. + /// + /// + public interface IGraphController : IGraphComponent + { + #region Events + + /// + /// Occurs when the current effective minimum/maximum values have changed. + /// + event EventHandler EffectiveRangeChanged; + + /// + /// Occurs when the current virtual (effective minimum/maximum after transformation) minimum/maximum values have changed. + /// + event EventHandler VirtualRangeChanged; + + #endregion + + #region Properties + + /// + /// Gets or sets the controller refresh rate. + /// Higher rate requires more CPU time. + /// + TimeSpan RefreshRate { get; set; } + + /// + /// Gets or sets a value indicating whether to pause the rendering. + /// + bool IsPaused { get; set; } + + /// + /// Gets or sets a value indicating whether to disable the rendering of data. + /// + bool DisableRendering { get; set; } + + /// + /// Gets the current effective x-axis minimum. + /// + GraphDataPoint EffectiveMinimumX { get; } + + /// + /// Gets the current effective x-axis maximum. + /// + GraphDataPoint EffectiveMaximumX { get; } + + /// + /// Gets the current effective y-axis minimum. + /// + GraphDataPoint EffectiveMinimumY { get; } + + /// + /// Gets the current effective y-axis maximum. + /// + GraphDataPoint EffectiveMaximumY { get; } + + /// + /// Gets the current virtual (effective minimum/maximum after transformation) x-axis minimum. + /// + GraphDataPoint VirtualMinimumX { get; } + + /// + /// Gets the current virtual (effective minimum/maximum after transformation) x-axis maximum. + /// + GraphDataPoint VirtualMaximumX { get; } + + /// + /// Gets the current virtual (effective minimum/maximum after transformation) y-axis minimum. + /// + GraphDataPoint VirtualMinimumY { get; } + + /// + /// Gets the current virtual (effective minimum/maximum after transformation) y-axis maximum. + /// + GraphDataPoint VirtualMaximumY { get; } + + /// + /// Clears all data points from this controller. + /// + void Clear(); + + #endregion + + #region Commands + + /// + /// Gets the clear command. + /// + GraphCommand ClearCommand { get; } + + #endregion + + #region Methods + + /// + /// Requests the controller to invoke a virtual range change event. + /// + void RequestVirtualRangeChange(); + + #endregion + } + + /// + /// Represents a graph controller capable of pushing data points to it's associated Graph Renderer + /// and rendering them to it's associated Graph Surface. + /// + /// The type of the data series. + /// + public interface IGraphController : IGraphController where TDataSeries : IGraphDataSeries + { + #region Properties + + /// + /// Gets the data series collection. + /// + ObservableCollection DataSeriesCollection { get; } + + /// + /// Gets or sets the graph renderer. + /// + IGraphRenderer Renderer { get; set; } + + /// + /// Gets or sets the graph surface. + /// + IGraphSurface Surface { get; set; } + + #endregion + } + + + /// + /// Represents a graph controller capable of pushing data points to it's associated Graph Renderer + /// and rendering them to it's associated Graph Surface. + /// + /// The type of the data series. + /// The type of the x data point. + /// The type of the y data point. + /// + public interface IGraphController : IGraphController + where TXDataPoint : GraphDataPoint + where TYDataPoint : GraphDataPoint + where TDataSeries : IGraphDataSeries + { + #region Properties + + /// + /// Gets or sets the graph range (data point boundaries). + /// + GraphRange Range { get; set; } + + #endregion + + #region Methods + + /// + /// Submits the specified x and y data points. + /// If the controller has more than one data series the data points will be duplicated. + /// + /// X data point. + /// Y data point. + void PushData(TXDataPoint x, TYDataPoint y); + + /// + /// Submits the specified collections of x and y data points. + /// If the controller has more than one data series the data points will be distributed evenly. + /// + /// X data point collection. + /// Y data point collection. + void PushData(IEnumerable xx, IEnumerable yy); + + /// + /// Submits a matrix of x and y data points. Meaning each data series should process a single collection of x/y data points. + /// + /// X matrix. + /// Y matrix. + void PushData(IEnumerable> xxxx, IEnumerable> yyyy); + + #endregion + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/IGraphDataPoint.cs b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/IGraphDataPoint.cs new file mode 100644 index 000000000..9ecae4a8a --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/IGraphDataPoint.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; + +namespace RealTimeGraphX +{ + /// + /// Represents a graph X or Y data point that can be pushed to a Graph Controller. + /// + /// + [TypeConverter(typeof(GraphDataPointTypeConverter))] + public interface IGraphDataPoint : IComparable + { + /// + /// Sums the value of this instance with another instance value and returns the result. + /// + /// The other instance. + /// + IGraphDataPoint Add(IGraphDataPoint other); + + /// + /// Subtract the value of another instance from this instance and returns the result. + /// + /// The other instance. + /// + IGraphDataPoint Subtract(IGraphDataPoint other); + + /// + /// Multiplies the value of this instance with another instance value and returns the result. + /// + /// The other instance. + /// + IGraphDataPoint Multiply(IGraphDataPoint other); + + /// + /// Divides the value of this instance with another instance value and returns the result. + /// + /// The other instance. + /// + IGraphDataPoint Divide(IGraphDataPoint other); + + /// + /// Creates a range of values from the specified minimum and maximum. + /// + /// The minimum. + /// The maximum. + /// The count. + /// + IEnumerable CreateRange(IGraphDataPoint min, IGraphDataPoint max, int count); + + /// + /// Returns the percentage value of this instance between the specified minimum and maximum values. + /// + /// The minimum. + /// The maximum. + /// + double ComputeRelativePosition(IGraphDataPoint min, IGraphDataPoint max); + + /// + /// Returns the absolute value of the specified percentage value between the specified minimum and maximum values. + /// + /// The minimum. + /// The maximum. + /// The percentage. + /// + IGraphDataPoint ComputeAbsolutePosition(IGraphDataPoint min, IGraphDataPoint max, double percentage); + + /// + /// Gets the encapsulated value. + /// + /// + object GetValue(); + + /// + /// Sets the encapsulated value. + /// + /// The value. + void SetValue(object value); + + /// + /// Returns a formated string of this data point. + /// + /// The format. + /// + String ToString(String format); + + /// + /// Parses the specified value. + /// + /// The value. + /// + IGraphDataPoint Parse(String value); + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/IGraphDataSeries.cs b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/IGraphDataSeries.cs new file mode 100644 index 000000000..03640e44a --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/IGraphDataSeries.cs @@ -0,0 +1,36 @@ +using System; + +namespace RealTimeGraphX +{ + /// + /// Represents a graph data series. + /// + /// + public interface IGraphDataSeries : IGraphComponent + { + /// + /// Gets or sets the series name. + /// + String Name { get; set; } + + /// + /// Gets or sets the stroke thickness. + /// + float StrokeThickness { get; set; } + + /// + /// Gets or sets a value indicating whether to fill the series. + /// + bool UseFill { get; } + + /// + /// Gets or sets a value indicating whether this series should be visible. + /// + bool IsVisible { get; set; } + + /// + /// Gets the current value. + /// + Object CurrentValue { get; set; } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/IGraphRenderer.cs b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/IGraphRenderer.cs new file mode 100644 index 000000000..fdd3b17e8 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/IGraphRenderer.cs @@ -0,0 +1,41 @@ +using RealTimeGraphX.EventArguments; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Text; + +namespace RealTimeGraphX +{ + /// + /// Represents a graph renderer capable of receiving a series of data points from a controller and transforming them to drawing points. + /// + /// The type of the data series. + /// + public interface IGraphRenderer : IGraphComponent where TDataSeries : IGraphDataSeries + { + /// + /// Arranges the series of data points and returns a series of drawing points. + /// + /// The target graph surface. + /// The instance of the current rendered data series. + /// Instance of graph range. + /// Collection of x coordinates. + /// Collection of y coordinates. + /// The minimum x coordinates value. + /// The maximum x coordinates value. + /// The minimum y coordinates value. + /// The maximum y coordinates value. + /// + IEnumerable Render(IGraphSurface surface, TDataSeries series, IGraphRange range, List xx, List yy, GraphDataPoint minimumX, GraphDataPoint maximumX, GraphDataPoint minimumY, GraphDataPoint maximumY); + + /// + /// Draws the specified data series points on the target surface. + /// + /// The target graph surface. + /// The instance of the current rendered data series. + /// The collection of the current data series drawing points. + /// The index of the current data series within the collection of data series. + /// The length of the data series collection. + void Draw(IGraphSurface surface, TDataSeries series, IEnumerable points, int index, int count); + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/IGraphSurface.cs b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/IGraphSurface.cs new file mode 100644 index 000000000..a3aeb90d9 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/IGraphSurface.cs @@ -0,0 +1,74 @@ +using RealTimeGraphX.EventArguments; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Text; + +namespace RealTimeGraphX +{ + /// + /// Represents a graph drawing surface capable of drawing a series of points submitted by a graph renderer. + /// + public interface IGraphSurface : IGraphComponent + { + /// + /// Occurs when the surface size has changed. + /// + event EventHandler SurfaceSizeChanged; + + /// + /// Occurs when the surface zoom rectangle has changed. + /// + event EventHandler ZoomRectChanged; + + /// + /// Returns the actual size of the surface. + /// + /// + SizeF GetSize(); + + /// + /// Returns the current bounds of the zooming rectangle. + /// + /// + RectangleF GetZoomRect(); + } + + /// + /// Represents a graph drawing surface capable of drawing a series of points submitted by a graph renderer. + /// + /// The type of the data series. + /// + public interface IGraphSurface : IGraphSurface where TDataSeries : IGraphDataSeries + { + /// + /// Called before drawing has started. + /// + void BeginDraw(); + + /// + /// Draws the stroke of the specified data series points. + /// + /// The data series. + /// The points. + void DrawSeries(TDataSeries dataSeries, IEnumerable points); + + /// + /// Fills the specified data series points. + /// + /// The data series. + /// The points. + void FillSeries(TDataSeries dataSeries, IEnumerable points); + + /// + /// Applies transformation on the current pass. + /// + /// The transform. + void SetTransform(GraphTransform transform); + + /// + /// Called when drawing has completed. + /// + void EndDraw(); + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/Properties/AssemblyInfo.cs b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..66f46dd2b --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("RealTimeGraphX")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("RealTimeGraphX")] +[assembly: AssemblyCopyright("Copyright © 2025")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("1490b50f-234c-400b-8704-7673435143f2")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/RealTimeGraphX.csproj b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/RealTimeGraphX.csproj new file mode 100644 index 000000000..6f0a69255 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/RealTimeGraphX.csproj @@ -0,0 +1,71 @@ + + + + + Debug + AnyCPU + {1490B50F-234C-400B-8704-7673435143F2} + Library + Properties + RealTimeGraphX + RealTimeGraphX + v4.6.1 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/Renderers/ScrollingLineRenderer.cs b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/Renderers/ScrollingLineRenderer.cs new file mode 100644 index 000000000..0a4ac8368 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphXNet/RealTimeGraphX/Renderers/ScrollingLineRenderer.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; + +namespace RealTimeGraphX.Renderers +{ + /// + /// Represents a scrolling style . + /// + /// The type of the data series. + /// + public class ScrollingLineRenderer : GraphRenderer where TDataSeries : IGraphDataSeries + { + /// + /// Arranges the series of data points and returns a series of drawing points. + /// + /// The target graph surface. + /// The instance of the current rendered data series. + /// Instance of graph range. + /// Collection of x coordinates. + /// Collection of y coordinates. + /// The minimum x coordinates value. + /// The maximum x coordinates value. + /// The minimum y coordinates value. + /// The maximum y coordinates value. + /// + public override IEnumerable Render(IGraphSurface surface, TDataSeries series, IGraphRange range, List xx, List yy, GraphDataPoint minimumX, GraphDataPoint maximumX, GraphDataPoint minimumY, GraphDataPoint maximumY) + { + var dxList = xx.Select(x => x.ComputeRelativePosition(minimumX, maximumX)).ToList(); + var dyList = yy.Select(x => x.ComputeRelativePosition(minimumY, maximumY)).ToList(); + + if (maximumX - minimumX > range.MaximumX) + { + var offset = ((maximumX - minimumX) - range.MaximumX) + minimumX; + + for (int i = 0; i < xx.Count; i++) + { + if (xx[i] < offset) + { + xx.RemoveAt(i); + yy.RemoveAt(i); + i--; + } + else + { + break; + } + } + } + + List points = new List(); + + for (int i = 0; i < dxList.Count; i++) + { + float image_x = ConvertXValueToRendererValue(surface,dxList[i]); + float image_y = (float)Math.Min(ConvertYValueToRendererValue(surface, dyList[i]), surface.GetSize().Height - 2); + + PointF point = new PointF(image_x, image_y); + points.Add(point); + } + + return points; + } + + /// + /// Draws the specified data series points on the target surface. + /// + /// The target graph surface. + /// The instance of the current rendered data series. + /// The collection of the current data series drawing points. + /// The index of the current data series within the collection of data series. + /// The length of the data series collection. + public override void Draw(IGraphSurface surface, TDataSeries series, IEnumerable points, int index, int count) + { + if (series.UseFill) + { + surface.FillSeries(series, GetFillPoints(surface, points)); + } + + surface.DrawSeries(series, GetFillPoints(surface, points)); + } + } +} diff --git a/Software/Visual_Studio/Tango.sln b/Software/Visual_Studio/Tango.sln index e04a41be4..e35325286 100644 --- a/Software/Visual_Studio/Tango.sln +++ b/Software/Visual_Studio/Tango.sln @@ -275,12 +275,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.Scripting.IDE.UI", "S EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.CatalogImporter", "Utilities\Tango.CatalogImporter\Tango.CatalogImporter.csproj", "{1066BC62-F167-4FC3-8F8B-982A9F632B4A}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RealTimeGraphX", "SideChains\RealTimeGraphX-master\RealTimeGraphX\RealTimeGraphX.csproj", "{F13A489C-80EE-4CD0-BDD4-92D959215646}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RealTimeGraphX.WPF", "SideChains\RealTimeGraphX-master\RealTimeGraphX.WPF\RealTimeGraphX.WPF.csproj", "{6B9774F7-960D-438E-AD81-C6B9BE328D50}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RealTimeGraphX.WPF.Demo", "SideChains\RealTimeGraphX-master\RealTimeGraphX.WPF.Demo\RealTimeGraphX.WPF.Demo.csproj", "{B822CBD9-1113-4668-85C9-22AA9C24CE60}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.CoatsCatalogImporter", "Utilities\Tango.CoatsCatalogImporter\Tango.CoatsCatalogImporter.csproj", "{0C596287-D63B-4BB7-A3D7-B682DD9EC60B}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.AlarmParametersGenerator", "Utilities\Tango.AlarmParametersGenerator\Tango.AlarmParametersGenerator.csproj", "{CC6D5193-434D-410F-B0F3-BE2017D86FCE}" @@ -489,6 +485,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.TelemetryTester.CLI", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.Telemetry.Tester.IOT.CLI", "Utilities\Tango.Telemetry.Tester.IOT.CLI\Tango.Telemetry.Tester.IOT.CLI.csproj", "{C891B2F7-E63A-40E2-B6CE-A22A69B4D86A}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RealTimeGraphX", "SideChains\RealTimeGraphXNet\RealTimeGraphX\RealTimeGraphX.csproj", "{1490B50F-234C-400B-8704-7673435143F2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution AppVeyor|Any CPU = AppVeyor|Any CPU @@ -14091,126 +14089,6 @@ Global {1066BC62-F167-4FC3-8F8B-982A9F632B4A}.X1|x64.Build.0 = Release|Any CPU {1066BC62-F167-4FC3-8F8B-982A9F632B4A}.X1|x86.ActiveCfg = Release|Any CPU {1066BC62-F167-4FC3-8F8B-982A9F632B4A}.X1|x86.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.AppVeyor|Any CPU.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.AppVeyor|Any CPU.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.AppVeyor|ARM.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.AppVeyor|ARM.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.AppVeyor|ARM64.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.AppVeyor|ARM64.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.AppVeyor|x64.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.AppVeyor|x64.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.AppVeyor|x86.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.AppVeyor|x86.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Debug|ARM.ActiveCfg = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Debug|ARM.Build.0 = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Debug|ARM64.Build.0 = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Debug|x64.ActiveCfg = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Debug|x64.Build.0 = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Debug|x86.ActiveCfg = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Debug|x86.Build.0 = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Eureka_Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Eureka_Debug|Any CPU.Build.0 = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Eureka_Debug|ARM.ActiveCfg = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Eureka_Debug|ARM.Build.0 = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Eureka_Debug|ARM64.ActiveCfg = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Eureka_Debug|ARM64.Build.0 = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Eureka_Debug|x64.ActiveCfg = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Eureka_Debug|x64.Build.0 = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Eureka_Debug|x86.ActiveCfg = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Eureka_Debug|x86.Build.0 = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Eureka|Any CPU.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Eureka|Any CPU.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Eureka|ARM.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Eureka|ARM.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Eureka|ARM64.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Eureka|ARM64.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Eureka|x64.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Eureka|x64.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Eureka|x86.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Eureka|x86.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.0|Any CPU.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.0|Any CPU.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.0|ARM.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.0|ARM.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.0|ARM64.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.0|ARM64.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.0|x64.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.0|x64.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.0|x86.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.0|x86.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.5|Any CPU.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.5|Any CPU.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.5|ARM.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.5|ARM.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.5|ARM64.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.5|ARM64.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.5|x64.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.5|x64.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.5|x86.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.5|x86.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.6.1|Any CPU.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.6.1|Any CPU.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.6.1|ARM.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.6.1|ARM.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.6.1|ARM64.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.6.1|ARM64.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.6.1|x64.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.6.1|x64.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.6.1|x86.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release 4.6.1|x86.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release|Any CPU.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release|ARM.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release|ARM.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release|ARM64.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release|ARM64.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release|x64.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release|x64.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release|x86.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.Release|x86.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.TS_Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.TS_Debug|Any CPU.Build.0 = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.TS_Debug|ARM.ActiveCfg = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.TS_Debug|ARM.Build.0 = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.TS_Debug|ARM64.ActiveCfg = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.TS_Debug|ARM64.Build.0 = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.TS_Debug|x64.ActiveCfg = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.TS_Debug|x64.Build.0 = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.TS_Debug|x86.ActiveCfg = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.TS_Debug|x86.Build.0 = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.TS|Any CPU.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.TS|Any CPU.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.TS|ARM.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.TS|ARM.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.TS|ARM64.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.TS|ARM64.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.TS|x64.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.TS|x64.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.TS|x86.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.TS|x86.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.X1_Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.X1_Debug|Any CPU.Build.0 = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.X1_Debug|ARM.ActiveCfg = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.X1_Debug|ARM.Build.0 = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.X1_Debug|ARM64.ActiveCfg = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.X1_Debug|ARM64.Build.0 = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.X1_Debug|x64.ActiveCfg = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.X1_Debug|x64.Build.0 = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.X1_Debug|x86.ActiveCfg = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.X1_Debug|x86.Build.0 = Debug|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.X1|Any CPU.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.X1|Any CPU.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.X1|ARM.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.X1|ARM.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.X1|ARM64.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.X1|ARM64.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.X1|x64.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.X1|x64.Build.0 = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.X1|x86.ActiveCfg = Release|Any CPU - {F13A489C-80EE-4CD0-BDD4-92D959215646}.X1|x86.Build.0 = Release|Any CPU {6B9774F7-960D-438E-AD81-C6B9BE328D50}.AppVeyor|Any CPU.ActiveCfg = Release|Any CPU {6B9774F7-960D-438E-AD81-C6B9BE328D50}.AppVeyor|Any CPU.Build.0 = Release|Any CPU {6B9774F7-960D-438E-AD81-C6B9BE328D50}.AppVeyor|ARM.ActiveCfg = Release|Any CPU @@ -14331,126 +14209,6 @@ Global {6B9774F7-960D-438E-AD81-C6B9BE328D50}.X1|x64.Build.0 = Release|Any CPU {6B9774F7-960D-438E-AD81-C6B9BE328D50}.X1|x86.ActiveCfg = Release|Any CPU {6B9774F7-960D-438E-AD81-C6B9BE328D50}.X1|x86.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.AppVeyor|Any CPU.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.AppVeyor|Any CPU.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.AppVeyor|ARM.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.AppVeyor|ARM.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.AppVeyor|ARM64.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.AppVeyor|ARM64.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.AppVeyor|x64.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.AppVeyor|x64.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.AppVeyor|x86.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.AppVeyor|x86.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Debug|ARM.ActiveCfg = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Debug|ARM.Build.0 = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Debug|ARM64.Build.0 = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Debug|x64.ActiveCfg = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Debug|x64.Build.0 = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Debug|x86.ActiveCfg = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Debug|x86.Build.0 = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Eureka_Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Eureka_Debug|Any CPU.Build.0 = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Eureka_Debug|ARM.ActiveCfg = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Eureka_Debug|ARM.Build.0 = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Eureka_Debug|ARM64.ActiveCfg = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Eureka_Debug|ARM64.Build.0 = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Eureka_Debug|x64.ActiveCfg = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Eureka_Debug|x64.Build.0 = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Eureka_Debug|x86.ActiveCfg = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Eureka_Debug|x86.Build.0 = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Eureka|Any CPU.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Eureka|Any CPU.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Eureka|ARM.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Eureka|ARM.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Eureka|ARM64.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Eureka|ARM64.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Eureka|x64.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Eureka|x64.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Eureka|x86.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Eureka|x86.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.0|Any CPU.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.0|Any CPU.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.0|ARM.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.0|ARM.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.0|ARM64.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.0|ARM64.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.0|x64.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.0|x64.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.0|x86.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.0|x86.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.5|Any CPU.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.5|Any CPU.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.5|ARM.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.5|ARM.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.5|ARM64.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.5|ARM64.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.5|x64.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.5|x64.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.5|x86.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.5|x86.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.6.1|Any CPU.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.6.1|Any CPU.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.6.1|ARM.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.6.1|ARM.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.6.1|ARM64.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.6.1|ARM64.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.6.1|x64.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.6.1|x64.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.6.1|x86.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release 4.6.1|x86.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release|Any CPU.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release|ARM.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release|ARM.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release|ARM64.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release|ARM64.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release|x64.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release|x64.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release|x86.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.Release|x86.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.TS_Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.TS_Debug|Any CPU.Build.0 = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.TS_Debug|ARM.ActiveCfg = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.TS_Debug|ARM.Build.0 = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.TS_Debug|ARM64.ActiveCfg = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.TS_Debug|ARM64.Build.0 = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.TS_Debug|x64.ActiveCfg = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.TS_Debug|x64.Build.0 = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.TS_Debug|x86.ActiveCfg = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.TS_Debug|x86.Build.0 = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.TS|Any CPU.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.TS|Any CPU.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.TS|ARM.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.TS|ARM.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.TS|ARM64.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.TS|ARM64.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.TS|x64.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.TS|x64.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.TS|x86.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.TS|x86.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.X1_Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.X1_Debug|Any CPU.Build.0 = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.X1_Debug|ARM.ActiveCfg = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.X1_Debug|ARM.Build.0 = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.X1_Debug|ARM64.ActiveCfg = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.X1_Debug|ARM64.Build.0 = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.X1_Debug|x64.ActiveCfg = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.X1_Debug|x64.Build.0 = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.X1_Debug|x86.ActiveCfg = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.X1_Debug|x86.Build.0 = Debug|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.X1|Any CPU.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.X1|Any CPU.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.X1|ARM.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.X1|ARM.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.X1|ARM64.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.X1|ARM64.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.X1|x64.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.X1|x64.Build.0 = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.X1|x86.ActiveCfg = Release|Any CPU - {B822CBD9-1113-4668-85C9-22AA9C24CE60}.X1|x86.Build.0 = Release|Any CPU {0C596287-D63B-4BB7-A3D7-B682DD9EC60B}.AppVeyor|Any CPU.ActiveCfg = Release|Any CPU {0C596287-D63B-4BB7-A3D7-B682DD9EC60B}.AppVeyor|Any CPU.Build.0 = Release|Any CPU {0C596287-D63B-4BB7-A3D7-B682DD9EC60B}.AppVeyor|ARM.ActiveCfg = Release|Any CPU @@ -25867,6 +25625,126 @@ Global {C891B2F7-E63A-40E2-B6CE-A22A69B4D86A}.X1|x64.Build.0 = Release|Any CPU {C891B2F7-E63A-40E2-B6CE-A22A69B4D86A}.X1|x86.ActiveCfg = Release|Any CPU {C891B2F7-E63A-40E2-B6CE-A22A69B4D86A}.X1|x86.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.AppVeyor|Any CPU.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.AppVeyor|Any CPU.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.AppVeyor|ARM.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.AppVeyor|ARM.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.AppVeyor|ARM64.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.AppVeyor|ARM64.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.AppVeyor|x64.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.AppVeyor|x64.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.AppVeyor|x86.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.AppVeyor|x86.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Debug|ARM.ActiveCfg = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Debug|ARM.Build.0 = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Debug|ARM64.Build.0 = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Debug|x64.ActiveCfg = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Debug|x64.Build.0 = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Debug|x86.ActiveCfg = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Debug|x86.Build.0 = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Eureka_Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Eureka_Debug|Any CPU.Build.0 = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Eureka_Debug|ARM.ActiveCfg = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Eureka_Debug|ARM.Build.0 = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Eureka_Debug|ARM64.ActiveCfg = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Eureka_Debug|ARM64.Build.0 = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Eureka_Debug|x64.ActiveCfg = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Eureka_Debug|x64.Build.0 = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Eureka_Debug|x86.ActiveCfg = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Eureka_Debug|x86.Build.0 = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Eureka|Any CPU.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Eureka|Any CPU.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Eureka|ARM.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Eureka|ARM.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Eureka|ARM64.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Eureka|ARM64.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Eureka|x64.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Eureka|x64.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Eureka|x86.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Eureka|x86.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.0|Any CPU.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.0|Any CPU.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.0|ARM.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.0|ARM.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.0|ARM64.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.0|ARM64.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.0|x64.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.0|x64.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.0|x86.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.0|x86.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.5|Any CPU.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.5|Any CPU.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.5|ARM.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.5|ARM.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.5|ARM64.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.5|ARM64.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.5|x64.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.5|x64.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.5|x86.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.5|x86.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.6.1|Any CPU.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.6.1|Any CPU.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.6.1|ARM.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.6.1|ARM.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.6.1|ARM64.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.6.1|ARM64.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.6.1|x64.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.6.1|x64.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.6.1|x86.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release 4.6.1|x86.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release|Any CPU.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release|ARM.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release|ARM.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release|ARM64.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release|ARM64.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release|x64.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release|x64.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release|x86.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.Release|x86.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.TS_Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.TS_Debug|Any CPU.Build.0 = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.TS_Debug|ARM.ActiveCfg = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.TS_Debug|ARM.Build.0 = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.TS_Debug|ARM64.ActiveCfg = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.TS_Debug|ARM64.Build.0 = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.TS_Debug|x64.ActiveCfg = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.TS_Debug|x64.Build.0 = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.TS_Debug|x86.ActiveCfg = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.TS_Debug|x86.Build.0 = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.TS|Any CPU.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.TS|Any CPU.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.TS|ARM.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.TS|ARM.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.TS|ARM64.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.TS|ARM64.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.TS|x64.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.TS|x64.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.TS|x86.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.TS|x86.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.X1_Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.X1_Debug|Any CPU.Build.0 = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.X1_Debug|ARM.ActiveCfg = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.X1_Debug|ARM.Build.0 = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.X1_Debug|ARM64.ActiveCfg = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.X1_Debug|ARM64.Build.0 = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.X1_Debug|x64.ActiveCfg = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.X1_Debug|x64.Build.0 = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.X1_Debug|x86.ActiveCfg = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.X1_Debug|x86.Build.0 = Debug|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.X1|Any CPU.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.X1|Any CPU.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.X1|ARM.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.X1|ARM.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.X1|ARM64.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.X1|ARM64.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.X1|x64.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.X1|x64.Build.0 = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.X1|x86.ActiveCfg = Release|Any CPU + {1490B50F-234C-400B-8704-7673435143F2}.X1|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -25953,9 +25831,7 @@ Global {C9F60285-91FB-4293-BCF5-164D76755CDD} = {3D750293-C243-48F6-9112-A6B3FF650C0D} {B0EFE7A0-7039-4DC4-8B39-465E521299F6} = {3D750293-C243-48F6-9112-A6B3FF650C0D} {1066BC62-F167-4FC3-8F8B-982A9F632B4A} = {5F6BBAA8-EAD0-4B18-97E5-55B4F56DD760} - {F13A489C-80EE-4CD0-BDD4-92D959215646} = {EC62BC9C-F2FE-4333-B7E4-110E38D43958} {6B9774F7-960D-438E-AD81-C6B9BE328D50} = {EC62BC9C-F2FE-4333-B7E4-110E38D43958} - {B822CBD9-1113-4668-85C9-22AA9C24CE60} = {EC62BC9C-F2FE-4333-B7E4-110E38D43958} {0C596287-D63B-4BB7-A3D7-B682DD9EC60B} = {5F6BBAA8-EAD0-4B18-97E5-55B4F56DD760} {CC6D5193-434D-410F-B0F3-BE2017D86FCE} = {5F6BBAA8-EAD0-4B18-97E5-55B4F56DD760} {7D0FCE3C-9A37-439C-9F9F-B26CFD6A8A33} = {B2AF4F3F-2828-47C3-8F3E-A0EA0BD66FF8} @@ -26043,15 +25919,16 @@ Global {F63B7F20-FAA3-40A6-8E34-F02369189DF8} = {59B2E8DA-2D5D-48FA-9A96-F53BDB7EF7A9} {DB3A1470-994B-46DF-9BE8-F905CDB97A3A} = {5F6BBAA8-EAD0-4B18-97E5-55B4F56DD760} {C891B2F7-E63A-40E2-B6CE-A22A69B4D86A} = {5F6BBAA8-EAD0-4B18-97E5-55B4F56DD760} + {1490B50F-234C-400B-8704-7673435143F2} = {EC62BC9C-F2FE-4333-B7E4-110E38D43958} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - BuildVersion_UseGlobalSettings = False - BuildVersion_AssemblyInfoFilename = Properties\AssemblyInfo.cs - BuildVersion_StartDate = 2000/1/1 - BuildVersion_UpdateFileVersion = False - BuildVersion_UpdateAssemblyVersion = True - BuildVersion_BuildVersioningStyle = None.None.Increment.DeltaBaseYearDayOfYear - SolutionGuid = {7986F7F4-A86A-4994-B1B6-0988D7F057B6} EnterpriseLibraryConfigurationToolBinariesPathV6 = packages\EnterpriseLibrary.TransientFaultHandling.6.0.1304.0\lib\portable-net45+win+wp8 + SolutionGuid = {7986F7F4-A86A-4994-B1B6-0988D7F057B6} + BuildVersion_BuildVersioningStyle = None.None.Increment.DeltaBaseYearDayOfYear + BuildVersion_UpdateAssemblyVersion = True + BuildVersion_UpdateFileVersion = False + BuildVersion_StartDate = 2000/1/1 + BuildVersion_AssemblyInfoFilename = Properties\AssemblyInfo.cs + BuildVersion_UseGlobalSettings = False EndGlobalSection EndGlobal -- cgit v1.3.1