diff options
| author | Roy Ben Shabat <roy.mail.net@gmail.com> | 2025-10-03 01:55:11 +0300 |
|---|---|---|
| committer | Roy Ben Shabat <roy.mail.net@gmail.com> | 2025-10-03 01:55:11 +0300 |
| commit | 2ce6afb909f34af7d78c20cfeb9f2d8311e91336 (patch) | |
| tree | 5a679973db7ee6446df1cde1690634b422ade35c | |
| parent | 9c858b7b51be2eb5b2f515912d436224d7e6483c (diff) | |
| download | Tango-2ce6afb909f34af7d78c20cfeb9f2d8311e91336.tar.gz Tango-2ce6afb909f34af7d78c20cfeb9f2d8311e91336.zip | |
Changed RealTimeGraphX to .NET 4.6.1
38 files changed, 3385 insertions, 285 deletions
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 @@ <Project>{6b9774f7-960d-438e-ad81-c6b9be328d50}</Project> <Name>RealTimeGraphX.WPF</Name> </ProjectReference> - <ProjectReference Include="..\..\..\SideChains\RealTimeGraphX-master\RealTimeGraphX\RealTimeGraphX.csproj"> - <Project>{f13a489c-80ee-4cd0-bdd4-92d959215646}</Project> + <ProjectReference Include="..\..\..\SideChains\RealTimeGraphXNet\RealTimeGraphX\RealTimeGraphX.csproj"> + <Project>{1490b50f-234c-400b-8704-7673435143f2}</Project> <Name>RealTimeGraphX</Name> </ProjectReference> <ProjectReference Include="..\..\..\SideChains\Tango.AutoComplete\Tango.AutoComplete.csproj"> 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 @@ <Project>{6b9774f7-960d-438e-ad81-c6b9be328d50}</Project> <Name>RealTimeGraphX.WPF</Name> </ProjectReference> - <ProjectReference Include="..\..\..\SideChains\RealTimeGraphX-master\RealTimeGraphX\RealTimeGraphX.csproj"> - <Project>{f13a489c-80ee-4cd0-bdd4-92d959215646}</Project> + <ProjectReference Include="..\..\..\SideChains\RealTimeGraphXNet\RealTimeGraphX\RealTimeGraphX.csproj"> + <Project>{1490b50f-234c-400b-8704-7673435143f2}</Project> <Name>RealTimeGraphX</Name> </ProjectReference> <ProjectReference Include="..\..\..\SideChains\Tango.AutoComplete\Tango.AutoComplete.csproj"> 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 @@ <Reference Include="System.ComponentModel.DataAnnotations" /> <Reference Include="System.Data" /> <Reference Include="System.Drawing" /> + <Reference Include="System.IO.Compression, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL" /> <Reference Include="System.Reactive.Core, Version=3.0.3000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL"> <HintPath>..\..\..\packages\System.Reactive.Core.3.1.1\lib\net46\System.Reactive.Core.dll</HintPath> </Reference> @@ -288,8 +289,8 @@ <Project>{6b9774f7-960d-438e-ad81-c6b9be328d50}</Project> <Name>RealTimeGraphX.WPF</Name> </ProjectReference> - <ProjectReference Include="..\..\..\SideChains\RealTimeGraphX-master\RealTimeGraphX\RealTimeGraphX.csproj"> - <Project>{f13a489c-80ee-4cd0-bdd4-92d959215646}</Project> + <ProjectReference Include="..\..\..\SideChains\RealTimeGraphXNet\RealTimeGraphX\RealTimeGraphX.csproj"> + <Project>{1490b50f-234c-400b-8704-7673435143f2}</Project> <Name>RealTimeGraphX</Name> </ProjectReference> <ProjectReference Include="..\..\..\SideChains\Tango.AutoComplete\Tango.AutoComplete.csproj"> 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 @@ <Project>{6b9774f7-960d-438e-ad81-c6b9be328d50}</Project> <Name>RealTimeGraphX.WPF</Name> </ProjectReference> - <ProjectReference Include="..\..\SideChains\RealTimeGraphX-master\RealTimeGraphX\RealTimeGraphX.csproj"> - <Project>{f13a489c-80ee-4cd0-bdd4-92d959215646}</Project> + <ProjectReference Include="..\..\SideChains\RealTimeGraphXNet\RealTimeGraphX\RealTimeGraphX.csproj"> + <Project>{1490b50f-234c-400b-8704-7673435143f2}</Project> <Name>RealTimeGraphX</Name> </ProjectReference> <ProjectReference Include="..\..\SideChains\Tango.AutoComplete\Tango.AutoComplete.csproj"> 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 @@ <Project>{6b9774f7-960d-438e-ad81-c6b9be328d50}</Project> <Name>RealTimeGraphX.WPF</Name> </ProjectReference> - <ProjectReference Include="..\..\SideChains\RealTimeGraphX-master\RealTimeGraphX\RealTimeGraphX.csproj"> - <Project>{f13a489c-80ee-4cd0-bdd4-92d959215646}</Project> + <ProjectReference Include="..\..\SideChains\RealTimeGraphXNet\RealTimeGraphX\RealTimeGraphX.csproj"> + <Project>{1490b50f-234c-400b-8704-7673435143f2}</Project> <Name>RealTimeGraphX</Name> </ProjectReference> <ProjectReference Include="..\..\SideChains\Tango.AutoComplete\Tango.AutoComplete.csproj"> 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 @@ <Project>{6b9774f7-960d-438e-ad81-c6b9be328d50}</Project> <Name>RealTimeGraphX.WPF</Name> </ProjectReference> - <ProjectReference Include="..\..\..\SideChains\RealTimeGraphX-master\RealTimeGraphX\RealTimeGraphX.csproj"> - <Project>{f13a489c-80ee-4cd0-bdd4-92d959215646}</Project> + <ProjectReference Include="..\..\..\SideChains\RealTimeGraphXNet\RealTimeGraphX\RealTimeGraphX.csproj"> + <Project>{1490b50f-234c-400b-8704-7673435143f2}</Project> <Name>RealTimeGraphX</Name> </ProjectReference> <ProjectReference Include="..\..\..\Tango.BL\Tango.BL.csproj"> 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 @@ <Project>{6b9774f7-960d-438e-ad81-c6b9be328d50}</Project> <Name>RealTimeGraphX.WPF</Name> </ProjectReference> - <ProjectReference Include="..\..\..\SideChains\RealTimeGraphX-master\RealTimeGraphX\RealTimeGraphX.csproj"> - <Project>{f13a489c-80ee-4cd0-bdd4-92d959215646}</Project> + <ProjectReference Include="..\..\..\SideChains\RealTimeGraphXNet\RealTimeGraphX\RealTimeGraphX.csproj"> + <Project>{1490b50f-234c-400b-8704-7673435143f2}</Project> <Name>RealTimeGraphX</Name> </ProjectReference> <ProjectReference Include="..\..\..\Tango.BL\Tango.BL.csproj"> @@ -728,7 +728,7 @@ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <ProjectExtensions> <VisualStudio> - <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" /> + <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" /> </VisualStudio> </ProjectExtensions> </Project>
\ 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 @@ <Project>{6b9774f7-960d-438e-ad81-c6b9be328d50}</Project> <Name>RealTimeGraphX.WPF</Name> </ProjectReference> - <ProjectReference Include="..\..\SideChains\RealTimeGraphX-master\RealTimeGraphX\RealTimeGraphX.csproj"> - <Project>{f13a489c-80ee-4cd0-bdd4-92d959215646}</Project> + <ProjectReference Include="..\..\SideChains\RealTimeGraphXNet\RealTimeGraphX\RealTimeGraphX.csproj"> + <Project>{1490b50f-234c-400b-8704-7673435143f2}</Project> <Name>RealTimeGraphX</Name> </ProjectReference> <ProjectReference Include="..\..\SideChains\Tango.AutoComplete\Tango.AutoComplete.csproj"> @@ -462,7 +462,7 @@ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <ProjectExtensions> <VisualStudio> - <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" /> + <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" /> </VisualStudio> </ProjectExtensions> <PropertyGroup> 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 @@ <Project>{6b9774f7-960d-438e-ad81-c6b9be328d50}</Project> <Name>RealTimeGraphX.WPF</Name> </ProjectReference> - <ProjectReference Include="..\..\SideChains\RealTimeGraphX-master\RealTimeGraphX\RealTimeGraphX.csproj"> - <Project>{f13a489c-80ee-4cd0-bdd4-92d959215646}</Project> - <Name>RealTimeGraphX</Name> - </ProjectReference> <ProjectReference Include="..\..\SideChains\Tango.AutoComplete\Tango.AutoComplete.csproj"> <Project>{bb2abb74-ba58-4812-83aa-ec8171f42df4}</Project> <Name>Tango.AutoComplete</Name> @@ -727,7 +723,7 @@ if $(ConfigurationName) == Release RD /S /Q "$(TargetDir)lib\"</PostBuildEvent> </Target> <ProjectExtensions> <VisualStudio> - <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_BuildVersioningStyle="None.None.Increment.DeltaBaseYearDayOfYear" BuildVersion_UpdateFileVersion="True" BuildVersion_DetectChanges="True" BuildVersion_UseGlobalSettings="False" /> + <UserProperties BuildVersion_UseGlobalSettings="False" BuildVersion_DetectChanges="True" BuildVersion_UpdateFileVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.DeltaBaseYearDayOfYear" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_StartDate="2000/1/1" /> </VisualStudio> </ProjectExtensions> </Project>
\ 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 @@ <Project>{6b9774f7-960d-438e-ad81-c6b9be328d50}</Project> <Name>RealTimeGraphX.WPF</Name> </ProjectReference> - <ProjectReference Include="..\..\SideChains\RealTimeGraphX-master\RealTimeGraphX\RealTimeGraphX.csproj"> - <Project>{f13a489c-80ee-4cd0-bdd4-92d959215646}</Project> + <ProjectReference Include="..\..\SideChains\RealTimeGraphXNet\RealTimeGraphX\RealTimeGraphX.csproj"> + <Project>{1490b50f-234c-400b-8704-7673435143f2}</Project> <Name>RealTimeGraphX</Name> </ProjectReference> <ProjectReference Include="..\..\Tango.AnimatedGif\Tango.AnimatedGif.csproj"> @@ -1216,7 +1216,7 @@ if $(ConfigurationName) == X1 copy /Y "$(ProjectDir)Intro.wmv" "$(TargetDir)" </PropertyGroup> <ProjectExtensions> <VisualStudio> - <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" /> + <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" /> </VisualStudio> </ProjectExtensions> <Import Project="..\..\packages\WPFMediaKit.2.2.0\build\WPFMediaKit.targets" Condition="Exists('..\..\packages\WPFMediaKit.2.2.0\build\WPFMediaKit.targets')" /> 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 @@ <Project>{6b9774f7-960d-438e-ad81-c6b9be328d50}</Project> <Name>RealTimeGraphX.WPF</Name> </ProjectReference> - <ProjectReference Include="..\RealTimeGraphX\RealTimeGraphX.csproj"> - <Project>{61f001e1-6e17-4ca6-8f3a-8a11d7166815}</Project> - <Name>RealTimeGraphX</Name> - </ProjectReference> </ItemGroup> <ItemGroup /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> 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 @@ </None> </ItemGroup> <ItemGroup> - <ProjectReference Include="..\RealTimeGraphX\RealTimeGraphX.csproj"> - <Project>{61f001e1-6e17-4ca6-8f3a-8a11d7166815}</Project> + <ProjectReference Include="..\..\RealTimeGraphXNet\RealTimeGraphX\RealTimeGraphX.csproj"> + <Project>{1490b50f-234c-400b-8704-7673435143f2}</Project> <Name>RealTimeGraphX</Name> </ProjectReference> </ItemGroup> 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<DateTime, DateTimeDataPoint> + { + /// <summary> + /// Initializes a new instance of the <see cref="DateTimeDataPoint"/> class. + /// </summary> + public DateTimeDataPoint() : base() + { + + } + + /// <summary> + /// Initializes a new instance of the <see cref="DateTimeDataPoint"/> class. + /// </summary> + /// <param name="value">The value.</param> + public DateTimeDataPoint(DateTime value) : base(value) + { + + } + + /// <summary> + /// Performs an implicit conversion from <see cref="System.TimeSpan"/> to <see cref="DateTimeDataPoint"/>. + /// </summary> + /// <param name="value">The value.</param> + /// <returns> + /// The result of the conversion. + /// </returns> + public static implicit operator DateTimeDataPoint(DateTime value) + { + return new DateTimeDataPoint(value); + } + + /// <summary> + /// Implements the operator -. + /// </summary> + /// <param name="a">a.</param> + /// <param name="b">The b.</param> + /// <returns> + /// The result of the operator. + /// </returns> + public static DateTimeDataPoint operator -(DateTimeDataPoint a, DateTimeDataPoint b) + { + return new DateTimeDataPoint(new DateTime(a.Value.Ticks - b.Value.Ticks)); + } + + /// <summary> + /// Implements the operator +. + /// </summary> + /// <param name="a">a.</param> + /// <param name="b">The b.</param> + /// <returns> + /// The result of the operator. + /// </returns> + public static DateTimeDataPoint operator +(DateTimeDataPoint a, DateTimeDataPoint b) + { + return new DateTimeDataPoint(new DateTime(a.Value.Ticks + b.Value.Ticks)); + } + + /// <summary> + /// Sums the value of this instance with another instance value and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + public override IGraphDataPoint Add(IGraphDataPoint other) + { + return new DateTimeDataPoint(new DateTime(this.Value.Ticks + (other as DateTimeDataPoint).Value.Ticks)); + } + + /// <summary> + /// Subtract the value of another instance from this instance and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + public override IGraphDataPoint Subtract(IGraphDataPoint other) + { + return new DateTimeDataPoint(new DateTime(this.Value.Ticks - (other as DateTimeDataPoint).Value.Ticks)); + } + + /// <summary> + /// Multiplies the value of this instance with another instance value and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + public override IGraphDataPoint Multiply(IGraphDataPoint other) + { + return new DateTimeDataPoint(new DateTime(this.Value.Ticks * (other as DateTimeDataPoint).Value.Ticks)); + } + + /// <summary> + /// Divides the value of this instance with another instance value and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + public override IGraphDataPoint Divide(IGraphDataPoint other) + { + return new DateTimeDataPoint(new DateTime(this.Value.Ticks / (other as DateTimeDataPoint).Value.Ticks)); + } + + /// <summary> + /// Returns the percentage value of this instance between the specified minimum and maximum values. + /// </summary> + /// <param name="min">The minimum.</param> + /// <param name="max">The maximum.</param> + /// <returns></returns> + 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; + } + + /// <summary> + /// Returns the absolute value of the specified percentage value between the specified minimum and maximum values. + /// </summary> + /// <param name="min">The minimum.</param> + /// <param name="max">The maximum.</param> + /// <param name="percentage">The percentage.</param> + /// <returns></returns> + 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))); + } + + /// <summary> + /// Creates a range of values from the specified minimum and maximum. + /// </summary> + /// <param name="min">The minimum.</param> + /// <param name="max">The maximum.</param> + /// <param name="count">The count.</param> + /// <returns></returns> + public override IEnumerable<IGraphDataPoint> 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))); + } + + /// <summary> + /// Returns a formated string of this data point. + /// </summary> + /// <param name="format">The format.</param> + /// <returns></returns> + public override string ToString(string format) + { + return Value.ToString(format); + } + + /// <summary> + /// Parses the specified value and returns a new instance of <see cref="!:TDataType" /> data point. + /// </summary> + /// <param name="value">The value.</param> + /// <returns></returns> + 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 +{ + /// <summary> + /// Represents a graph <see cref="Double"/> value data point. + /// </summary> + /// <seealso cref="RealTimeGraphX.GraphDataPoint{System.Double, RealTimeGraphX.DataPoints.DoubleDataPoint}" /> + public class DoubleDataPoint : GraphDataPoint<Double, DoubleDataPoint> + { + /// <summary> + /// Initializes a new instance of the <see cref="DoubleDataPoint"/> class. + /// </summary> + public DoubleDataPoint() : base() + { + + } + + /// <summary> + /// Initializes a new instance of the <see cref="DoubleDataPoint"/> class. + /// </summary> + /// <param name="value">The value.</param> + public DoubleDataPoint(double value) : base(value) + { + + } + + /// <summary> + /// Performs an implicit conversion from <see cref="System.Double"/> to <see cref="DoubleDataPoint"/>. + /// </summary> + /// <param name="value">The value.</param> + /// <returns> + /// The result of the conversion. + /// </returns> + public static implicit operator DoubleDataPoint(double value) + { + return new DoubleDataPoint(value); + } + + /// <summary> + /// Implements the operator -. + /// </summary> + /// <param name="a">a.</param> + /// <param name="b">The b.</param> + /// <returns> + /// The result of the operator. + /// </returns> + public static DoubleDataPoint operator -(DoubleDataPoint a, DoubleDataPoint b) + { + return new DoubleDataPoint(a.Value - b.Value); + } + + /// <summary> + /// Implements the operator +. + /// </summary> + /// <param name="a">a.</param> + /// <param name="b">The b.</param> + /// <returns> + /// The result of the operator. + /// </returns> + public static DoubleDataPoint operator +(DoubleDataPoint a, DoubleDataPoint b) + { + return new DoubleDataPoint(a.Value + b.Value); + } + + /// <summary> + /// Sums the value of this instance with another instance value and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + public override IGraphDataPoint Add(IGraphDataPoint other) + { + return new DoubleDataPoint(this.Value + (other as DoubleDataPoint).Value); + } + + /// <summary> + /// Subtract the value of another instance from this instance and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + public override IGraphDataPoint Subtract(IGraphDataPoint other) + { + return new DoubleDataPoint(this.Value - (other as DoubleDataPoint).Value); + } + + /// <summary> + /// Multiplies the value of this instance with another instance value and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + public override IGraphDataPoint Multiply(IGraphDataPoint other) + { + return new DoubleDataPoint(this.Value * (other as DoubleDataPoint).Value); + } + + /// <summary> + /// Divides the value of this instance with another instance value and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + public override IGraphDataPoint Divide(IGraphDataPoint other) + { + return new DoubleDataPoint(this.Value / (other as DoubleDataPoint).Value); + } + + /// <summary> + /// Returns the percentage value of this instance between the specified minimum and maximum values. + /// </summary> + /// <param name="min">The minimum.</param> + /// <param name="max">The maximum.</param> + /// <returns></returns> + 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; + } + + /// <summary> + /// Returns the absolute value of the specified percentage value between the specified minimum and maximum values. + /// </summary> + /// <param name="min">The minimum.</param> + /// <param name="max">The maximum.</param> + /// <param name="percentage">The percentage.</param> + /// <returns></returns> + 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); + } + + /// <summary> + /// Creates a range of values from the specified minimum and maximum. + /// </summary> + /// <param name="min">The minimum.</param> + /// <param name="max">The maximum.</param> + /// <param name="count">The count.</param> + /// <returns></returns> + public override IEnumerable<IGraphDataPoint> 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)); + } + + /// <summary> + /// Returns a formated string of this data point. + /// </summary> + /// <param name="format">The format.</param> + /// <returns></returns> + public override string ToString(string format) + { + return Value.ToString(format); + } + + /// <summary> + /// Parses the specified value and returns a new instance of <see cref="!:TDataType" /> data point. + /// </summary> + /// <param name="value">The value.</param> + /// <returns></returns> + 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 +{ + /// <summary> + /// Represents a graph <see cref="float"/> value data point. + /// </summary> + /// <seealso cref="RealTimeGraphX.GraphDataPoint{float, RealTimeGraphX.DataPoints.FloatDataPoint}" /> + public class FloatDataPoint : GraphDataPoint<float, FloatDataPoint> + { + /// <summary> + /// Initializes a new instance of the <see cref="FloatDataPoint"/> class. + /// </summary> + public FloatDataPoint() : base() + { + + } + + /// <summary> + /// Initializes a new instance of the <see cref="FloatDataPoint"/> class. + /// </summary> + /// <param name="value">The value.</param> + public FloatDataPoint(float value) : base(value) + { + + } + + /// <summary> + /// Performs an implicit conversion from <see cref="float"/> to <see cref="FloatDataPoint"/>. + /// </summary> + /// <param name="value">The value.</param> + /// <returns> + /// The result of the conversion. + /// </returns> + public static implicit operator FloatDataPoint(float value) + { + return new FloatDataPoint(value); + } + + /// <summary> + /// Implements the operator -. + /// </summary> + /// <param name="a">a.</param> + /// <param name="b">The b.</param> + /// <returns> + /// The result of the operator. + /// </returns> + public static FloatDataPoint operator -(FloatDataPoint a, FloatDataPoint b) + { + return new FloatDataPoint(a.Value - b.Value); + } + + /// <summary> + /// Implements the operator +. + /// </summary> + /// <param name="a">a.</param> + /// <param name="b">The b.</param> + /// <returns> + /// The result of the operator. + /// </returns> + public static FloatDataPoint operator +(FloatDataPoint a, FloatDataPoint b) + { + return new FloatDataPoint(a.Value + b.Value); + } + + /// <summary> + /// Sums the value of this instance with another instance value and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + public override IGraphDataPoint Add(IGraphDataPoint other) + { + return new FloatDataPoint(this.Value + (other as FloatDataPoint).Value); + } + + /// <summary> + /// Subtract the value of another instance from this instance and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + public override IGraphDataPoint Subtract(IGraphDataPoint other) + { + return new FloatDataPoint(this.Value - (other as FloatDataPoint).Value); + } + + /// <summary> + /// Multiplies the value of this instance with another instance value and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + public override IGraphDataPoint Multiply(IGraphDataPoint other) + { + return new FloatDataPoint(this.Value * (other as FloatDataPoint).Value); + } + + /// <summary> + /// Divides the value of this instance with another instance value and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + public override IGraphDataPoint Divide(IGraphDataPoint other) + { + return new FloatDataPoint(this.Value / (other as FloatDataPoint).Value); + } + + /// <summary> + /// Returns the percentage value of this instance between the specified minimum and maximum values. + /// </summary> + /// <param name="min">The minimum.</param> + /// <param name="max">The maximum.</param> + /// <returns></returns> + 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; + } + + /// <summary> + /// Returns the absolute value of the specified percentage value between the specified minimum and maximum values. + /// </summary> + /// <param name="min">The minimum.</param> + /// <param name="max">The maximum.</param> + /// <param name="percentage">The percentage.</param> + /// <returns></returns> + 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)); + } + + /// <summary> + /// Creates a range of values from the specified minimum and maximum. + /// </summary> + /// <param name="min">The minimum.</param> + /// <param name="max">The maximum.</param> + /// <param name="count">The count.</param> + /// <returns></returns> + public override IEnumerable<IGraphDataPoint> 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)); + } + + /// <summary> + /// Returns a formated string of this data point. + /// </summary> + /// <param name="format">The format.</param> + /// <returns></returns> + public override string ToString(string format) + { + return Value.ToString(format); + } + + /// <summary> + /// Parses the specified value and returns a new instance of <see cref="!:TDataType" /> data point. + /// </summary> + /// <param name="value">The value.</param> + /// <returns></returns> + 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 +{ + /// <summary> + /// Represents a graph <see cref="Int32"/> value data point. + /// </summary> + /// <seealso cref="RealTimeGraphX.GraphDataPoint{System.Int32, RealTimeGraphX.DataPoints.Int32DataPoint}" /> + public class Int32DataPoint : GraphDataPoint<Int32, Int32DataPoint> + { + /// <summary> + /// Initializes a new instance of the <see cref="Int32DataPoint"/> class. + /// </summary> + public Int32DataPoint() : base() + { + + } + + /// <summary> + /// Initializes a new instance of the <see cref="Int32DataPoint"/> class. + /// </summary> + /// <param name="value">The value.</param> + public Int32DataPoint(int value) : base(value) + { + + } + + /// <summary> + /// Performs an implicit conversion from <see cref="System.Int32"/> to <see cref="Int32DataPoint"/>. + /// </summary> + /// <param name="value">The value.</param> + /// <returns> + /// The result of the conversion. + /// </returns> + public static implicit operator Int32DataPoint(int value) + { + return new Int32DataPoint(value); + } + + /// <summary> + /// Implements the operator -. + /// </summary> + /// <param name="a">a.</param> + /// <param name="b">The b.</param> + /// <returns> + /// The result of the operator. + /// </returns> + public static Int32DataPoint operator -(Int32DataPoint a, Int32DataPoint b) + { + return new Int32DataPoint(a.Value - b.Value); + } + + /// <summary> + /// Implements the operator +. + /// </summary> + /// <param name="a">a.</param> + /// <param name="b">The b.</param> + /// <returns> + /// The result of the operator. + /// </returns> + public static Int32DataPoint operator +(Int32DataPoint a, Int32DataPoint b) + { + return new Int32DataPoint(a.Value + b.Value); + } + + /// <summary> + /// Sums the value of this instance with another instance value and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + public override IGraphDataPoint Add(IGraphDataPoint other) + { + return new Int32DataPoint(this.Value + (other as Int32DataPoint).Value); + } + + /// <summary> + /// Subtract the value of another instance from this instance and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + public override IGraphDataPoint Subtract(IGraphDataPoint other) + { + return new Int32DataPoint(this.Value - (other as Int32DataPoint).Value); + } + + /// <summary> + /// Multiplies the value of this instance with another instance value and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + public override IGraphDataPoint Multiply(IGraphDataPoint other) + { + return new Int32DataPoint(this.Value * (other as Int32DataPoint).Value); + } + + /// <summary> + /// Divides the value of this instance with another instance value and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + public override IGraphDataPoint Divide(IGraphDataPoint other) + { + return new Int32DataPoint(this.Value / (other as Int32DataPoint).Value); + } + + /// <summary> + /// Returns the percentage value of this instance between the specified minimum and maximum values. + /// </summary> + /// <param name="min">The minimum.</param> + /// <param name="max">The maximum.</param> + /// <returns></returns> + 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; + } + + /// <summary> + /// Returns the absolute value of the specified percentage value between the specified minimum and maximum values. + /// </summary> + /// <param name="min">The minimum.</param> + /// <param name="max">The maximum.</param> + /// <param name="percentage">The percentage.</param> + /// <returns></returns> + 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)); + } + + /// <summary> + /// Creates a range of values from the specified minimum and maximum. + /// </summary> + /// <param name="min">The minimum.</param> + /// <param name="max">The maximum.</param> + /// <param name="count">The count.</param> + /// <returns></returns> + public override IEnumerable<IGraphDataPoint> 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)); + } + + /// <summary> + /// Returns a formated string of this data point. + /// </summary> + /// <param name="format">The format.</param> + /// <returns></returns> + public override string ToString(string format) + { + return Value.ToString(format); + } + + /// <summary> + /// Parses the specified value and returns a new instance of <see cref="!:TDataType" /> data point. + /// </summary> + /// <param name="value">The value.</param> + /// <returns></returns> + 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 +{ + /// <summary> + /// Represents a graph <see cref="TimeSpan"/> value data point. + /// </summary> + /// <seealso cref="RealTimeGraphX.GraphDataPoint{System.TimeSpan, RealTimeGraphX.DataPoints.TimeSpanDataPoint}" /> + public class TimeSpanDataPoint : GraphDataPoint<TimeSpan, TimeSpanDataPoint> + { + /// <summary> + /// Initializes a new instance of the <see cref="TimeSpanDataPoint"/> class. + /// </summary> + public TimeSpanDataPoint() : base() + { + + } + + /// <summary> + /// Initializes a new instance of the <see cref="TimeSpanDataPoint"/> class. + /// </summary> + /// <param name="value">The value.</param> + public TimeSpanDataPoint(TimeSpan value) : base(value) + { + + } + + /// <summary> + /// Performs an implicit conversion from <see cref="System.TimeSpan"/> to <see cref="TimeSpanDataPoint"/>. + /// </summary> + /// <param name="value">The value.</param> + /// <returns> + /// The result of the conversion. + /// </returns> + public static implicit operator TimeSpanDataPoint(TimeSpan value) + { + return new TimeSpanDataPoint(value); + } + + /// <summary> + /// Implements the operator -. + /// </summary> + /// <param name="a">a.</param> + /// <param name="b">The b.</param> + /// <returns> + /// The result of the operator. + /// </returns> + public static TimeSpanDataPoint operator -(TimeSpanDataPoint a, TimeSpanDataPoint b) + { + return new TimeSpanDataPoint(a.Value - b.Value); + } + + /// <summary> + /// Implements the operator +. + /// </summary> + /// <param name="a">a.</param> + /// <param name="b">The b.</param> + /// <returns> + /// The result of the operator. + /// </returns> + public static TimeSpanDataPoint operator +(TimeSpanDataPoint a, TimeSpanDataPoint b) + { + return new TimeSpanDataPoint(a.Value + b.Value); + } + + /// <summary> + /// Sums the value of this instance with another instance value and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + public override IGraphDataPoint Add(IGraphDataPoint other) + { + return new TimeSpanDataPoint(this.Value + (other as TimeSpanDataPoint).Value); + } + + /// <summary> + /// Subtract the value of another instance from this instance and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + public override IGraphDataPoint Subtract(IGraphDataPoint other) + { + return new TimeSpanDataPoint(this.Value - (other as TimeSpanDataPoint).Value); + } + + /// <summary> + /// Multiplies the value of this instance with another instance value and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + public override IGraphDataPoint Multiply(IGraphDataPoint other) + { + return new TimeSpanDataPoint(TimeSpan.FromMilliseconds(this.Value.TotalMilliseconds * (other as TimeSpanDataPoint).Value.TotalMilliseconds)); + } + + /// <summary> + /// Divides the value of this instance with another instance value and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + public override IGraphDataPoint Divide(IGraphDataPoint other) + { + return new TimeSpanDataPoint(TimeSpan.FromMilliseconds(this.Value.TotalMilliseconds / (other as TimeSpanDataPoint).Value.TotalMilliseconds)); + } + + /// <summary> + /// Returns the percentage value of this instance between the specified minimum and maximum values. + /// </summary> + /// <param name="min">The minimum.</param> + /// <param name="max">The maximum.</param> + /// <returns></returns> + 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; + } + + /// <summary> + /// Returns the absolute value of the specified percentage value between the specified minimum and maximum values. + /// </summary> + /// <param name="min">The minimum.</param> + /// <param name="max">The maximum.</param> + /// <param name="percentage">The percentage.</param> + /// <returns></returns> + 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)); + } + + /// <summary> + /// Creates a range of values from the specified minimum and maximum. + /// </summary> + /// <param name="min">The minimum.</param> + /// <param name="max">The maximum.</param> + /// <param name="count">The count.</param> + /// <returns></returns> + public override IEnumerable<IGraphDataPoint> 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))); + } + + /// <summary> + /// Returns a formated string of this data point. + /// </summary> + /// <param name="format">The format.</param> + /// <returns></returns> + public override string ToString(string format) + { + return Value.ToString(format); + } + + /// <summary> + /// Parses the specified value and returns a new instance of <see cref="!:TDataType" /> data point. + /// </summary> + /// <param name="value">The value.</param> + /// <returns></returns> + 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 +{ + /// <summary> + /// Represents a graph range change event arguments. + /// </summary> + /// <seealso cref="System.EventArgs" /> + public class RangeChangedEventArgs : EventArgs + { + /// <summary> + /// Gets or sets the minimum x value. + /// </summary> + public GraphDataPoint MinimumX { get; set; } + + /// <summary> + /// Gets or sets the maximum x value. + /// </summary> + public GraphDataPoint MaximumX { get; set; } + + /// <summary> + /// Gets or sets the minimum y value. + /// </summary> + public GraphDataPoint MinimumY { get; set; } + + /// <summary> + /// Gets or sets the maximum y value. + /// </summary> + public GraphDataPoint MaximumY { get; set; } + + /// <summary> + /// Initializes a new instance of the <see cref="RangeChangedEventArgs"/> class. + /// </summary> + public RangeChangedEventArgs() + { + + } + + /// <summary> + /// Initializes a new instance of the <see cref="RangeChangedEventArgs"/> class. + /// </summary> + /// <param name="minimumX">The minimum x value.</param> + /// <param name="maximumX">The maximum x value.</param> + /// <param name="minimumY">The minimum y value.</param> + /// <param name="maximumY">The maximum y value.</param> + 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 +{ + /// <summary> + /// Represents a graph relay command. + /// </summary> + /// <seealso cref="System.Windows.Input.ICommand" /> + public class GraphCommand : ICommand + { + private Action _action; + private Func<bool> _canExecute; + + /// <summary> + /// Initializes a new instance of the <see cref="GraphCommand"/> class. + /// </summary> + /// <param name="action">The action.</param> + /// <param name="canExecute">The can execute.</param> + public GraphCommand(Action action, Func<bool> canExecute) + { + _action = action; + _canExecute = canExecute; + } + + /// <summary> + /// Initializes a new instance of the <see cref="GraphCommand"/> class. + /// </summary> + /// <param name="action">The action.</param> + public GraphCommand(Action action) : this(action, null) + { + + } + + /// <summary> + /// Defines the method that determines whether the command can execute in its current state. + /// </summary> + /// <param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to null.</param> + /// <returns> + /// true if this command can be executed; otherwise, false. + /// </returns> + public bool CanExecute(object parameter) + { + if (_canExecute != null) + { + return _canExecute(); + } + + return true; + } + + /// <summary> + /// Defines the method to be called when the command is invoked. + /// </summary> + /// <param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to null.</param> + public void Execute(object parameter) + { + _action(); + } + + /// <summary> + /// Raises the can execute changed event. + /// </summary> + public void RaiseCanExecuteChanged() + { + CanExecuteChanged?.Invoke(this, new EventArgs()); + } + + /// <summary> + /// Occurs when changes occur that affect whether or not the command should execute. + /// </summary> + /// <returns></returns> + 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 +{ + /// <summary> + /// Represents an <see cref="IGraphController{TDataSeries, TXDataPoint, TYDataPoint}"/> base class. + /// </summary> + /// <typeparam name="TDataSeries">The type of the data series.</typeparam> + /// <typeparam name="TXDataPoint">The type of the x data point.</typeparam> + /// <typeparam name="TYDataPoint">The type of the y data point.</typeparam> + /// <seealso cref="RealTimeGraphX.GraphObject" /> + /// <seealso cref="RealTimeGraphX.IGraphController{TDataSeries, TXDataPoint, TYDataPoint}" /> + public abstract class GraphController<TDataSeries, TXDataPoint, TYDataPoint> : GraphObject, IGraphController<TDataSeries, TXDataPoint, TYDataPoint> + where TXDataPoint : GraphDataPoint + where TYDataPoint : GraphDataPoint + where TDataSeries : IGraphDataSeries + { + private GraphDataQueue<List<PendingSeries>> _pending_series_collection; + private Dictionary<TDataSeries, PendingSeries> _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<GraphDataPoint> XX { get; set; } + public List<GraphDataPoint> 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 + + /// <summary> + /// Occurs when the current effective minimum/maximum has changed. + /// </summary> + public event EventHandler<RangeChangedEventArgs> EffectiveRangeChanged; + + /// <summary> + /// Occurs when the current virtual (effective minimum/maximum after transformation) minimum/maximum has changed. + /// </summary> + public event EventHandler<RangeChangedEventArgs> VirtualRangeChanged; + + #endregion + + #region Properties + + /// <summary> + /// Gets or sets the controller refresh rate. + /// Higher rate requires more CPU time. + /// </summary> + public TimeSpan RefreshRate { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether to pause rendering. + /// </summary> + public bool IsPaused { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether to disable the rendering of data. + /// </summary> + public bool DisableRendering { get; set; } + + /// <summary> + /// Gets the data series collection. + /// </summary> + public ObservableCollection<TDataSeries> DataSeriesCollection { get; } + + private IGraphRenderer<TDataSeries> _renderer; + /// <summary> + /// Gets or sets the graph renderer. + /// </summary> + public IGraphRenderer<TDataSeries> Renderer + { + get + { + return _renderer; + } + set + { + _renderer = value; RaisePropertyChangedAuto(); + } + } + + private IGraphSurface<TDataSeries> _surface; + /// <summary> + /// Gets or sets the rendering surface. + /// </summary> + public IGraphSurface<TDataSeries> Surface + { + get { return _surface; } + set + { + var previous = _surface; + _surface = value; + RequestVirtualRangeChange(); + OnSurfaceChanged(previous, _surface); + } + } + + private GraphRange<TXDataPoint, TYDataPoint> _range; + /// <summary> + /// Gets or sets the graph range (data point boundaries). + /// </summary> + public GraphRange<TXDataPoint, TYDataPoint> Range + { + get + { + return _range; + } + set + { + _range = value; RaisePropertyChangedAuto(); + } + } + + /// <summary> + /// Gets the current effective x-axis minimum. + /// </summary> + public GraphDataPoint EffectiveMinimumX { get; private set; } + + /// <summary> + /// Gets the current effective x-axis maximum. + /// </summary> + public GraphDataPoint EffectiveMaximumX { get; private set; } + + /// <summary> + /// Gets the current effective y-axis minimum. + /// </summary> + public GraphDataPoint EffectiveMinimumY { get; private set; } + + /// <summary> + /// Gets the current effective y-axis maximum. + /// </summary> + public GraphDataPoint EffectiveMaximumY { get; private set; } + + /// <summary> + /// Gets the current virtual (effective minimum/maximum after transformation) x-axis minimum. + /// </summary> + public GraphDataPoint VirtualMinimumX { get; private set; } + + /// <summary> + /// Gets the current virtual (effective minimum/maximum after transformation) x-axis maximum. + /// </summary> + public GraphDataPoint VirtualMaximumX { get; private set; } + + /// <summary> + /// Gets the current virtual (effective minimum/maximum after transformation) y-axis minimum. + /// </summary> + public GraphDataPoint VirtualMinimumY { get; private set; } + + /// <summary> + /// Gets the current virtual (effective minimum/maximum after transformation) y-axis maximum. + /// </summary> + public GraphDataPoint VirtualMaximumY { get; private set; } + + #endregion + + #region Commands + + /// <summary> + /// Gets the clear command. + /// </summary> + public GraphCommand ClearCommand { get; private set; } + + #endregion + + #region Constructors + + /// <summary> + /// Initializes a new instance of the <see cref="GraphController{TDataSeries, TXDataPoint, TYDataPoint}"/> class. + /// </summary> + public GraphController() + { + Renderer = new ScrollingLineRenderer<TDataSeries>(); + + DataSeriesCollection = new ObservableCollection<TDataSeries>(); + Range = new GraphRange<TXDataPoint, TYDataPoint>(); + + _last_render_time = DateTime.Now; + _to_render = new Dictionary<TDataSeries, PendingSeries>(); + _pending_series_collection = new GraphDataQueue<List<PendingSeries>>(); + 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 + + /// <summary> + /// The rendering thread method. + /// </summary> + private void RenderThreadMethod() + { + while (true) + { + if (!IsPaused && !DisableRendering) + { + try + { + List<List<PendingSeries>> pending_lists = new List<List<PendingSeries>>(); + + 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<List<PendingSeries>>(); + _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<Tuple<TDataSeries, IEnumerable<PointF>>> to_draw = new List<Tuple<TDataSeries, IEnumerable<PointF>>>(); + + 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<TDataSeries, IEnumerable<PointF>>(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 + + /// <summary> + /// Called when the surface has changed. + /// </summary> + /// <param name="previous">The previous.</param> + /// <param name="surface">The surface.</param> + protected virtual void OnSurfaceChanged(IGraphSurface<TDataSeries> previous, IGraphSurface<TDataSeries> surface) + { + if (previous != null) + { + previous.SurfaceSizeChanged += Surface_SurfaceSizeChanged; + previous.ZoomRectChanged += Surface_ZoomRectChanged; + } + + if (surface != null) + { + surface.SurfaceSizeChanged += Surface_SurfaceSizeChanged; + surface.ZoomRectChanged += Surface_ZoomRectChanged; + } + } + + /// <summary> + /// Raises the <see cref="EffectiveRangeChanged"/> event. + /// </summary> + /// <param name="minimumX">The minimum x.</param> + /// <param name="maximumX">The maximum x.</param> + /// <param name="minimumY">The minimum y.</param> + /// <param name="maximumY">The maximum y.</param> + protected virtual void OnEffectiveRangeChanged(GraphDataPoint minimumX, GraphDataPoint maximumX, GraphDataPoint minimumY, GraphDataPoint maximumY) + { + EffectiveRangeChanged?.Invoke(this, new RangeChangedEventArgs(minimumX, maximumX, minimumY, maximumY)); + } + + /// <summary> + /// Raises the <see cref="VirtualRangeChanged"/> event. + /// </summary> + /// <param name="minimumX">The minimum x.</param> + /// <param name="maximumX">The maximum x.</param> + /// <param name="minimumY">The minimum y.</param> + /// <param name="maximumY">The maximum y.</param> + protected virtual void OnVirtualRangeChanged(GraphDataPoint minimumX, GraphDataPoint maximumX, GraphDataPoint minimumY, GraphDataPoint maximumY) + { + var range = new RangeChangedEventArgs(minimumX, maximumX, minimumY, maximumY); + VirtualRangeChanged?.Invoke(this, range); + } + + /// <summary> + /// Converts the specified relative x position to graph absolute position. + /// </summary> + /// <param name="x">The relative x position.</param> + /// <returns></returns> + protected virtual float ConvertXValueToRendererValue(double x) + { + return (float)(x * Surface.GetSize().Width / 100); + } + + /// <summary> + /// Converts the specified relative y position to graph absolute position. + /// </summary> + /// <param name="y">The relative y position.</param> + /// <returns></returns> + protected virtual float ConvertYValueToRendererValue(double y) + { + return (float)(Surface.GetSize().Height - (y * Surface.GetSize().Height / 100)); + } + + #endregion + + #region Surface Event Handlers + + /// <summary> + /// Handles the ZoomRectChanged event of the Surface control. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> + private void Surface_ZoomRectChanged(object sender, EventArgs e) + { + if (!_pending_series_collection.ToList().SelectMany(x => x).ToList().Exists(x => x.IsUpdateSeries)) + { + List<PendingSeries> updateSeries = new List<PendingSeries>(); + + foreach (var pending_Series in _to_render) + { + updateSeries.Add(new PendingSeries() + { + IsUpdateSeries = true, + Series = pending_Series.Value.Series, + XX = new List<GraphDataPoint>(), + YY = new List<GraphDataPoint>(), + }); + } + + _pending_series_collection.BlockEnqueue(updateSeries); + } + } + + /// <summary> + /// Handles the SurfaceSizeChanged event of the Surface control. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> + private void Surface_SurfaceSizeChanged(object sender, EventArgs e) + { + if (!_pending_series_collection.ToList().SelectMany(x => x).ToList().Exists(x => x.IsUpdateSeries)) + { + List<PendingSeries> updateSeries = new List<PendingSeries>(); + + foreach (var pending_Series in _to_render) + { + updateSeries.Add(new PendingSeries() + { + IsUpdateSeries = true, + Series = pending_Series.Value.Series, + XX = new List<GraphDataPoint>(), + YY = new List<GraphDataPoint>(), + }); + } + + _pending_series_collection.BlockEnqueue(updateSeries); + } + } + + #endregion + + #region Public Methods + + /// <summary> + /// Submits the specified x and y data points. + /// If the controller has more than one data series the data points will be duplicated. + /// </summary> + /// <param name="x">X data point.</param> + /// <param name="y">Y data point.</param> + public void PushData(TXDataPoint x, TYDataPoint y) + { + if (DataSeriesCollection.Count == 0) return; + + List<List<TXDataPoint>> xxxx = new List<List<TXDataPoint>>(); + List<List<TYDataPoint>> yyyy = new List<List<TYDataPoint>>(); + + foreach (var series in DataSeriesCollection.ToList()) + { + xxxx.Add(new List<TXDataPoint>() { x }); + yyyy.Add(new List<TYDataPoint>() { y }); + } + + PushData(xxxx, yyyy); + } + + /// <summary> + /// 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. + /// </summary> + /// <param name="xx">X data point collection.</param> + /// <param name="yy">Y data point collection.</param> + public void PushData(IEnumerable<TXDataPoint> xx, IEnumerable<TYDataPoint> yy) + { + if (DataSeriesCollection.Count == 0) return; + + var xList = xx.ToList(); + var yList = yy.ToList(); + + List<List<TXDataPoint>> xxxx = new List<List<TXDataPoint>>(); + List<List<TYDataPoint>> yyyy = new List<List<TYDataPoint>>(); + + foreach (var series in DataSeriesCollection.ToList()) + { + xxxx.Add(new List<TXDataPoint>()); + yyyy.Add(new List<TYDataPoint>()); + } + + 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); + } + + /// <summary> + /// Submits a matrix of x and y data points. Meaning each data series should process a single collection of x/y data points. + /// </summary> + /// <param name="xxxx">X matrix.</param> + /// <param name="yyyy">Y matrix.</param> + public void PushData(IEnumerable<IEnumerable<TXDataPoint>> xxxx, IEnumerable<IEnumerable<TYDataPoint>> yyyy) + { + if (DataSeriesCollection.Count == 0) return; + + IEnumerable<IEnumerable<GraphDataPoint>> xxxxI = xxxx.Select(x => x.ToList()).ToList(); + IEnumerable<IEnumerable<GraphDataPoint>> yyyyI = yyyy.Select(x => x.ToList()).ToList(); + + List<List<GraphDataPoint>> xxxxList = xxxxI.Select(x => x.ToList()).ToList(); + List<List<GraphDataPoint>> 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<PendingSeries>(); + + 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); + } + + /// <summary> + /// Clears all data points from this controller. + /// </summary> + public void Clear() + { + _pending_series_collection.BlockEnqueue(new List<PendingSeries>() + { + new PendingSeries() + { + IsClearSeries = true + }, + }); + } + + /// <summary> + /// Requests the controller to invoke a virtual range change event. + /// </summary> + 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 +{ + /// <summary> + /// Represents an <see cref="IGraphDataPoint"/> base class. + /// </summary> + /// <seealso cref="RealTimeGraphX.IGraphDataPoint" /> + public abstract class GraphDataPoint : IGraphDataPoint + { + #region IComparable + + /// <summary> + /// 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. + /// </summary> + /// <param name="obj">An object to compare with this instance.</param> + /// <returns> + /// 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 <paramref name="obj" /> in the sort order. Zero This instance occurs in the same position in the sort order as <paramref name="obj" />. Greater than zero This instance follows <paramref name="obj" /> in the sort order. + /// </returns> + public abstract int CompareTo(object obj); + + /// <summary> + /// Determines whether the specified <see cref="System.Object" />, is equal to this instance. + /// </summary> + /// <param name="obj">The <see cref="System.Object" /> to compare with this instance.</param> + /// <returns> + /// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>. + /// </returns> + public override bool Equals(object obj) + { + return base.Equals(obj); + } + + /// <summary> + /// Returns a hash code for this instance. + /// </summary> + /// <returns> + /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. + /// </returns> + public override int GetHashCode() + { + return base.GetHashCode(); + } + + #endregion + + #region Logical Operators + + /// <summary> + /// Implements the operator >. + /// </summary> + /// <returns> + /// The result of the operator. + /// </returns> + public static bool operator >(GraphDataPoint a, GraphDataPoint b) + { + return a.CompareTo(b) == 1; + } + + /// <summary> + /// Implements the operator <. + /// </summary> + /// <returns> + /// The result of the operator. + /// </returns> + public static bool operator <(GraphDataPoint a, GraphDataPoint b) + { + return a.CompareTo(b) == -1; + } + + /// <summary> + /// Implements the operator ==. + /// </summary> + /// <returns> + /// The result of the operator. + /// </returns> + 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; + } + + /// <summary> + /// Implements the operator !=. + /// </summary> + /// <returns> + /// The result of the operator. + /// </returns> + 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 + + /// <summary> + /// Implements the operator -. + /// </summary> + /// <returns> + /// The result of the operator. + /// </returns> + public static GraphDataPoint operator -(GraphDataPoint a, GraphDataPoint b) + { + return (GraphDataPoint)a.Subtract(b); + } + + /// <summary> + /// Implements the operator +. + /// </summary> + /// <returns> + /// The result of the operator. + /// </returns> + public static GraphDataPoint operator +(GraphDataPoint a, GraphDataPoint b) + { + return (GraphDataPoint)a.Add(b); + } + + /// <summary> + /// Implements the operator /. + /// </summary> + /// <returns> + /// The result of the operator. + /// </returns> + public static GraphDataPoint operator /(GraphDataPoint a, GraphDataPoint b) + { + return (GraphDataPoint)a.Divide(b); + } + + /// <summary> + /// Implements the operator *. + /// </summary> + /// <returns> + /// The result of the operator. + /// </returns> + public static GraphDataPoint operator *(GraphDataPoint a, GraphDataPoint b) + { + return (GraphDataPoint)a.Multiply(b); + } + + #endregion + + #region IGraphDataPoint + + /// <summary> + /// Sums the value of this instance with another instance value and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + public abstract IGraphDataPoint Add(IGraphDataPoint other); + + /// <summary> + /// Subtract the value of another instance from this instance and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + public abstract IGraphDataPoint Subtract(IGraphDataPoint other); + + /// <summary> + /// Multiplies the value of this instance with another instance value and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + public abstract IGraphDataPoint Multiply(IGraphDataPoint other); + + /// <summary> + /// Divides the value of this instance with another instance value and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + public abstract IGraphDataPoint Divide(IGraphDataPoint other); + + /// <summary> + /// Returns the percentage value of this instance between the specified minimum and maximum values. + /// </summary> + /// <param name="min">The minimum.</param> + /// <param name="max">The maximum.</param> + /// <returns></returns> + public abstract double ComputeRelativePosition(IGraphDataPoint min, IGraphDataPoint max); + + /// <summary> + /// Returns the absolute value of the specified percentage value between the specified minimum and maximum values. + /// </summary> + /// <param name="min">The minimum.</param> + /// <param name="max">The maximum.</param> + /// <param name="percentage">The percentage.</param> + /// <returns></returns> + public abstract IGraphDataPoint ComputeAbsolutePosition(IGraphDataPoint min, IGraphDataPoint max, double percentage); + + /// <summary> + /// Creates a range of values from the specified minimum and maximum. + /// </summary> + /// <param name="min">The minimum.</param> + /// <param name="max">The maximum.</param> + /// <param name="count">The count.</param> + /// <returns></returns> + public abstract IEnumerable<IGraphDataPoint> CreateRange(IGraphDataPoint min, IGraphDataPoint max, int count); + + /// <summary> + /// Gets the inner value. + /// </summary> + /// <returns></returns> + public abstract object GetValue(); + + /// <summary> + /// Sets the inner value. + /// </summary> + /// <param name="value">The value.</param> + public abstract void SetValue(object value); + + /// <summary> + /// Returns a formated string of this data point. + /// </summary> + /// <param name="format">The format.</param> + /// <returns></returns> + public abstract string ToString(string format); + + /// <summary> + /// Parses the specified value. + /// </summary> + /// <param name="value">The value.</param> + /// <returns></returns> + public abstract IGraphDataPoint Parse(string value); + + #endregion + + #region Properties + + /// <summary> + /// Gets the type of this graph data point. + /// </summary> + public Type Type + { + get { return GetType(); } + } + + #endregion + } + + /// <summary> + /// Represents an <see cref="IGraphDataPoint"/> base class. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <typeparam name="TDataType">The type of the data type.</typeparam> + /// <seealso cref="RealTimeGraphX.GraphDataPoint" /> + public abstract class GraphDataPoint<T, TDataType> : GraphDataPoint where T : IComparable where TDataType : GraphDataPoint<T, TDataType> + { + #region Properties + + /// <summary> + /// Gets or sets the encapsulated data point value. + /// </summary> + public T Value { get; set; } + + #endregion + + #region Constructors + + /// <summary> + /// Initializes a new instance of the <see cref="GraphDataPoint{T, TDataType}"/> class. + /// </summary> + public GraphDataPoint() + { + + } + + /// <summary> + /// Initializes a new instance of the <see cref="GraphDataPoint{T, TDataType}"/> class. + /// </summary> + /// <param name="value">The value.</param> + public GraphDataPoint(T value) + { + Value = value; + } + + #endregion + + #region IComparable + + /// <summary> + /// 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. + /// </summary> + /// <param name="obj">An object to compare with this instance.</param> + /// <returns> + /// 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 <paramref name="obj" /> in the sort order. Zero This instance occurs in the same position in the sort order as <paramref name="obj" />. Greater than zero This instance follows <paramref name="obj" /> in the sort order. + /// </returns> + public override int CompareTo(object obj) + { + if (Object.ReferenceEquals(obj, null)) return -1; + + GraphDataPoint<T, TDataType> b = obj as GraphDataPoint<T, TDataType>; + return Value.CompareTo(b.Value); + } + + /// <summary> + /// Determines whether the specified <see cref="System.Object" />, is equal to this instance. + /// </summary> + /// <param name="obj">The <see cref="System.Object" /> to compare with this instance.</param> + /// <returns> + /// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>. + /// </returns> + public override bool Equals(object obj) + { + var @base = obj as GraphDataPoint<T, TDataType>; + return @base != null && + EqualityComparer<T>.Default.Equals(Value, @base.Value); + } + + /// <summary> + /// Returns a hash code for this instance. + /// </summary> + /// <returns> + /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. + /// </returns> + public override int GetHashCode() + { + return -1937169414 + EqualityComparer<T>.Default.GetHashCode(Value); + } + + #endregion + + #region ToString + + /// <summary> + /// Returns a <see cref="System.String" /> that represents this instance. + /// </summary> + /// <returns> + /// A <see cref="System.String" /> that represents this instance. + /// </returns> + public override string ToString() + { + return Value.ToString(); + } + + #endregion + + #region IGraphDataPoint + + /// <summary> + /// Gets the inner value. + /// </summary> + /// <returns></returns> + public override object GetValue() + { + return Value; + } + + /// <summary> + /// Sets the inner value. + /// </summary> + /// <param name="value">The value.</param> + public override void SetValue(object value) + { + Value = (T)value; + } + + #endregion + + #region Parsing + + /// <summary> + /// Parses the specified value and returns a new instance of <see cref="TDataType"/> data point. + /// </summary> + /// <param name="value">The value.</param> + /// <returns></returns> + public static TDataType ParseFrom(String value) + { + return Activator.CreateInstance<TDataType>().Parse(value) as TDataType; + } + + #endregion + + #region Implicit Operators + + /// <summary> + /// Performs an implicit conversion from <see cref="T"/> to <see cref="GraphDataPoint{T, TDataType}"/>. + /// </summary> + /// <param name="value">The value.</param> + /// <returns> + /// The result of the conversion. + /// </returns> + public static implicit operator GraphDataPoint<T, TDataType>(T value) + { + return Activator.CreateInstance(typeof(TDataType), value) as GraphDataPoint<T, TDataType>; + } + + /// <summary> + /// Performs an implicit conversion from <see cref="GraphDataPoint{T, TDataType}"/> to <see cref="T"/>. + /// </summary> + /// <param name="instance">The instance.</param> + /// <returns> + /// The result of the conversion. + /// </returns> + public static implicit operator T(GraphDataPoint<T, TDataType> 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 +{ + /// <summary> + /// Represents an <see cref="IGraphDataPoint"/> helper class. + /// </summary> + public static class GraphDataPointHelper + { + /// <summary> + /// Returns the absolute value of the specified percentage value between the specified minimum and maximum values. + /// </summary> + /// <param name="min">The minimum.</param> + /// <param name="max">The maximum.</param> + /// <param name="percentage">The percentage.</param> + /// <returns></returns> + public static T ComputeAbsolutePosition<T>(T min, T max, double percentage) where T : class, IGraphDataPoint + { + return (Activator.CreateInstance(min.GetType()) as T).ComputeAbsolutePosition(min, max, percentage) as T; + } + + /// <summary> + /// Creates a range of values from the specified minimum and maximum. + /// </summary> + /// <param name="min">The minimum.</param> + /// <param name="max">The maximum.</param> + /// <param name="count">The count.</param> + /// <returns></returns> + public static IEnumerable<T> CreateRange<T>(IGraphDataPoint min, IGraphDataPoint max, int count) where T : class, IGraphDataPoint + { + return (Activator.CreateInstance(min.GetType()) as T).CreateRange(min, max, count) as IEnumerable<T>; + } + + /// <summary> + /// Initializes a new instance of the specified <see cref="IGraphDataPoint"/> type. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <returns></returns> + public static T Init<T>() 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 +{ + /// <summary> + /// Represents the <see cref="TimeSpanDataPoint"/> type converter. + /// </summary> + public class GraphDataPointTypeConverter : TypeConverter + { + private IGraphDataPoint _instance; + + /// <summary> + /// Returns whether this converter can convert an object of the given type to the type of this converter, using the specified context. + /// </summary> + /// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"></see> that provides a format context.</param> + /// <param name="sourceType">A <see cref="T:System.Type"></see> that represents the type you want to convert from.</param> + /// <returns> + /// true if this converter can perform the conversion; otherwise, false. + /// </returns> + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + return sourceType == typeof(String); + } + + /// <summary> + /// Converts the given object to the type of this converter, using the specified context and culture information. + /// </summary> + /// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"></see> that provides a format context.</param> + /// <param name="culture">The <see cref="T:System.Globalization.CultureInfo"></see> to use as the current culture.</param> + /// <param name="value">The <see cref="T:System.Object"></see> to convert.</param> + /// <returns> + /// An <see cref="T:System.Object"></see> that represents the converted value. + /// </returns> + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + if (value != null && _instance != null) + { + try + { + return _instance.Parse(value.ToString()); + } + catch {} + } + + return _instance; + } + + /// <summary> + /// Returns whether this converter can convert the object to the specified type, using the specified context. + /// </summary> + /// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"></see> that provides a format context.</param> + /// <param name="destinationType">A <see cref="T:System.Type"></see> that represents the type you want to convert to.</param> + /// <returns> + /// true if this converter can perform the conversion; otherwise, false. + /// </returns> + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + { + return destinationType == typeof(String); + } + + /// <summary> + /// Converts the given value object to the specified type, using the specified context and culture information. + /// </summary> + /// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"></see> that provides a format context.</param> + /// <param name="culture">A <see cref="T:System.Globalization.CultureInfo"></see>. If null is passed, the current culture is assumed.</param> + /// <param name="value">The <see cref="T:System.Object"></see> to convert.</param> + /// <param name="destinationType">The <see cref="T:System.Type"></see> to convert the value parameter to.</param> + /// <returns> + /// An <see cref="T:System.Object"></see> that represents the converted value. + /// </returns> + 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 +{ + /// <summary> + /// Represents a blocking concurrent queue for graph data consumption. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <seealso cref="System.Collections.Concurrent.BlockingCollection{T}" /> + public class GraphDataQueue<T> : BlockingCollection<T> + { + /// <summary> + /// Initializes a new instance of the GraphDataQueue, Use Add and TryAdd for Enqueue and TryEnqueue and Take and TryTake for Dequeue and TryDequeue functionality + /// </summary> + public GraphDataQueue() + : base(new ConcurrentQueue<T>()) + { + } + + /// <summary> + /// Initializes a new instance of the GraphDataQueue, Use Add and TryAdd for Enqueue and TryEnqueue and Take and TryTake for Dequeue and TryDequeue functionality + /// </summary> + /// <param name="maxSize"></param> + public GraphDataQueue(int maxSize) + : base(new ConcurrentQueue<T>(), maxSize) + { + } + + /// <summary> + /// Enqueues the specified item. + /// </summary> + /// <param name="item">The item.</param> + public void BlockEnqueue(T item) + { + Add(item); + } + + /// <summary> + /// Blocks until an item is available for dequeuing. + /// </summary> + /// <returns></returns> + public T BlockDequeue() + { + return Take(); + } + + /// <summary> + /// Blocks until an item is available for dequeuing. + /// </summary> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns></returns> + 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 +{ + /// <summary> + /// Represents an <see cref="INotifyPropertyChanged"/> supported graph object. + /// </summary> + /// <seealso cref="System.ComponentModel.INotifyPropertyChanged" /> + public abstract class GraphObject : INotifyPropertyChanged + { + /// <summary> + /// Occurs when a property value changes. + /// </summary> + [field: NonSerialized] + public event PropertyChangedEventHandler PropertyChanged; + + /// <summary> + /// Raises the property changed event. + /// </summary> + /// <param name="propName">Name of the property.</param> + protected virtual void RaisePropertyChangedAuto([CallerMemberName] string caller = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(caller)); + } + + /// <summary> + /// Raises the property changed event. + /// </summary> + /// <param name="propName">Name of the property.</param> + 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 +{ + /// <summary> + /// Represents a graph x/y data points boundaries. + /// </summary> + public interface IGraphRange : IGraphComponent + { + /// <summary> + /// Gets or sets the maximum x value. + /// </summary> + GraphDataPoint MaximumX { get; set; } + + /// <summary> + /// Gets or sets the minimum x value. + /// </summary> + GraphDataPoint MinimumY { get; set; } + + /// <summary> + /// Gets or sets the maximum y value. + /// </summary> + GraphDataPoint MaximumY { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether to automatically adjust the graph <see cref="MaximumY"/> and <see cref="MinimumY"/> according to the current effective data points. + /// </summary> + bool AutoY { get; set; } + } + + /// <summary> + /// Represents a graph X/Y range boundaries. + /// </summary> + /// <typeparam name="XDataPoint">Type of x-axis data point.</typeparam> + /// <typeparam name="YDataPoint">Type of y-axis data point.</typeparam> + /// <seealso cref="RealTimeGraphX.GraphObject" /> + public class GraphRange<XDataPoint, YDataPoint> : GraphObject, IGraphRange where XDataPoint : GraphDataPoint where YDataPoint : GraphDataPoint + { + private XDataPoint _maximumX; + /// <summary> + /// Gets or sets the maximum x value. + /// </summary> + public XDataPoint MaximumX + { + get { return _maximumX; } + set { _maximumX = value; RaisePropertyChangedAuto(); } + } + + private YDataPoint _minimumY; + /// <summary> + /// Gets or sets the minimum x value. + /// </summary> + public YDataPoint MinimumY + { + get { return _minimumY; } + set { _minimumY = value; RaisePropertyChangedAuto(); } + } + + private YDataPoint _maximumY; + /// <summary> + /// Gets or sets the maximum y value. + /// </summary> + public YDataPoint MaximumY + { + get { return _maximumY; } + set { _maximumY = value; RaisePropertyChangedAuto(); } + } + + private bool _autoY; + /// <summary> + /// Gets or sets a value indicating whether to automatically adjust the graph <see cref="MaximumY"/> and <see cref="MinimumY"/> according to the current visible data points. + /// </summary> + public bool AutoY + { + get { return _autoY; } + set { _autoY = value; RaisePropertyChangedAuto(); } + } + + /// <summary> + /// Initializes a new instance of the <see cref="GraphRange{XDataPoint, YDataPoint}"/> class. + /// </summary> + public GraphRange() + { + MinimumY = GraphDataPointHelper.Init<YDataPoint>(); + MaximumX = GraphDataPointHelper.Init<XDataPoint>(); + MaximumY = GraphDataPointHelper.Init<YDataPoint>(); + } + + /// <summary> + /// Gets or sets the maximum x value. + /// </summary> + GraphDataPoint IGraphRange.MaximumX + { + get + { + return MaximumX; + } + set + { + MaximumX = (XDataPoint)value; + } + } + + /// <summary> + /// Gets or sets the minimum x value. + /// </summary> + GraphDataPoint IGraphRange.MinimumY + { + get + { + return MinimumY; + } + set + { + MinimumY = (YDataPoint)value; + } + } + + /// <summary> + /// Gets or sets the maximum y value. + /// </summary> + 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 +{ + /// <summary> + /// Represents an <see cref="IGraphRenderer{TDataSeries}"/> base class. + /// </summary> + /// <typeparam name="TDataSeries">The type of the data series.</typeparam> + /// <seealso cref="RealTimeGraphX.GraphObject" /> + /// <seealso cref="RealTimeGraphX.IGraphRenderer{TDataSeries}" /> + public abstract class GraphRenderer<TDataSeries> : GraphObject, IGraphRenderer<TDataSeries> where TDataSeries : IGraphDataSeries + { + /// <summary> + /// Converts the specified relative x position to a graph surface absolute position. + /// </summary> + /// <param name="surface">The target surface.</param> + /// <param name="x">The relative x position.</param> + /// <returns></returns> + protected virtual float ConvertXValueToRendererValue(IGraphSurface<TDataSeries> surface, double x) + { + return (float)(x * surface.GetSize().Width / 100); + } + + /// <summary> + /// Converts the specified relative y position to a graph surface absolute position. + /// </summary> + /// <param name="surface">The surface.</param> + /// <param name="y">The relative y position.</param> + /// <returns></returns> + protected virtual float ConvertYValueToRendererValue(IGraphSurface<TDataSeries> surface, double y) + { + return (float)(surface.GetSize().Height - (y * surface.GetSize().Height / 100)); + } + + /// <summary> + /// Arranges the series of data points and returns a series of drawing points. + /// </summary> + /// <param name="surface">The target graph surface.</param> + /// <param name="series">The instance of the current rendered data series.</param> + /// <param name="range">Instance of graph range.</param> + /// <param name="xx">Collection of x coordinates.</param> + /// <param name="yy">Collection of y coordinates.</param> + /// <param name="minimumX">The minimum x coordinates value.</param> + /// <param name="maximumX">The maximum x coordinates value.</param> + /// <param name="minimumY">The minimum y coordinates value.</param> + /// <param name="maximumY">The maximum y coordinates value.</param> + /// <returns></returns> + public abstract IEnumerable<PointF> Render(IGraphSurface<TDataSeries> surface, TDataSeries series, IGraphRange range, List<GraphDataPoint> xx, List<GraphDataPoint> yy, GraphDataPoint minimumX, GraphDataPoint maximumX, GraphDataPoint minimumY, GraphDataPoint maximumY); + + /// <summary> + /// Draws the specified data series points on the target surface. + /// </summary> + /// <param name="surface">The target graph surface.</param> + /// <param name="series">The instance of the current rendered data series.</param> + /// <param name="points">The collection of the current data series drawing points.</param> + /// <param name="index">The index of the current data series within the collection of data series.</param> + /// <param name="count">The length of the data series collection.</param> + public abstract void Draw(IGraphSurface<TDataSeries> surface, TDataSeries series, IEnumerable<PointF> points, int index, int count); + + /// <summary> + /// Gets a closed polygon version of the specified drawing points. + /// </summary> + /// <param name="surface">The target surface.</param> + /// <param name="points">The drawing points.</param> + /// <returns></returns> + protected virtual IEnumerable<PointF> GetFillPoints(IGraphSurface<TDataSeries> surface, IEnumerable<PointF> points) + { + List<PointF> 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 +{ + /// <summary> + /// Represents a graph transformation. + /// </summary> + public class GraphTransform + { + /// <summary> + /// Gets or sets the horizontal scale factor. + /// </summary> + public float ScaleX { get; set; } + + /// <summary> + /// Gets or sets the vertical scale factor. + /// </summary> + public float ScaleY { get; set; } + + /// <summary> + /// Gets or sets the horizontal translate transformation. + /// </summary> + public float TranslateX { get; set; } + + /// <summary> + /// Gets or sets the vertical translate transformation. + /// </summary> + public float TranslateY { get; set; } + + /// <summary> + /// Initializes a new instance of the <see cref="GraphTransform"/> class. + /// </summary> + 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 +{ + /// <summary> + /// Represents a RealTimeGraphX component. + /// </summary> + 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 +{ + /// <summary> + /// Represents a graph controller. + /// </summary> + /// <seealso cref="RealTimeGraphX.IGraphComponent" /> + public interface IGraphController : IGraphComponent + { + #region Events + + /// <summary> + /// Occurs when the current effective minimum/maximum values have changed. + /// </summary> + event EventHandler<RangeChangedEventArgs> EffectiveRangeChanged; + + /// <summary> + /// Occurs when the current virtual (effective minimum/maximum after transformation) minimum/maximum values have changed. + /// </summary> + event EventHandler<RangeChangedEventArgs> VirtualRangeChanged; + + #endregion + + #region Properties + + /// <summary> + /// Gets or sets the controller refresh rate. + /// Higher rate requires more CPU time. + /// </summary> + TimeSpan RefreshRate { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether to pause the rendering. + /// </summary> + bool IsPaused { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether to disable the rendering of data. + /// </summary> + bool DisableRendering { get; set; } + + /// <summary> + /// Gets the current effective x-axis minimum. + /// </summary> + GraphDataPoint EffectiveMinimumX { get; } + + /// <summary> + /// Gets the current effective x-axis maximum. + /// </summary> + GraphDataPoint EffectiveMaximumX { get; } + + /// <summary> + /// Gets the current effective y-axis minimum. + /// </summary> + GraphDataPoint EffectiveMinimumY { get; } + + /// <summary> + /// Gets the current effective y-axis maximum. + /// </summary> + GraphDataPoint EffectiveMaximumY { get; } + + /// <summary> + /// Gets the current virtual (effective minimum/maximum after transformation) x-axis minimum. + /// </summary> + GraphDataPoint VirtualMinimumX { get; } + + /// <summary> + /// Gets the current virtual (effective minimum/maximum after transformation) x-axis maximum. + /// </summary> + GraphDataPoint VirtualMaximumX { get; } + + /// <summary> + /// Gets the current virtual (effective minimum/maximum after transformation) y-axis minimum. + /// </summary> + GraphDataPoint VirtualMinimumY { get; } + + /// <summary> + /// Gets the current virtual (effective minimum/maximum after transformation) y-axis maximum. + /// </summary> + GraphDataPoint VirtualMaximumY { get; } + + /// <summary> + /// Clears all data points from this controller. + /// </summary> + void Clear(); + + #endregion + + #region Commands + + /// <summary> + /// Gets the clear command. + /// </summary> + GraphCommand ClearCommand { get; } + + #endregion + + #region Methods + + /// <summary> + /// Requests the controller to invoke a virtual range change event. + /// </summary> + void RequestVirtualRangeChange(); + + #endregion + } + + /// <summary> + /// Represents a graph controller capable of pushing data points to it's associated <see cref="IGraphRenderer{TDataSeries}">Graph Renderer</see> + /// and rendering them to it's associated <see cref="IGraphSurface{TDataSeries}">Graph Surface</see>. + /// </summary> + /// <typeparam name="TDataSeries">The type of the data series.</typeparam> + /// <seealso cref="RealTimeGraphX.IGraphComponent" /> + public interface IGraphController<TDataSeries> : IGraphController where TDataSeries : IGraphDataSeries + { + #region Properties + + /// <summary> + /// Gets the data series collection. + /// </summary> + ObservableCollection<TDataSeries> DataSeriesCollection { get; } + + /// <summary> + /// Gets or sets the graph renderer. + /// </summary> + IGraphRenderer<TDataSeries> Renderer { get; set; } + + /// <summary> + /// Gets or sets the graph surface. + /// </summary> + IGraphSurface<TDataSeries> Surface { get; set; } + + #endregion + } + + + /// <summary> + /// Represents a graph controller capable of pushing data points to it's associated <see cref="IGraphRenderer{TDataSeries}">Graph Renderer</see> + /// and rendering them to it's associated <see cref="IGraphSurface{TDataSeries}">Graph Surface</see>. + /// </summary> + /// <typeparam name="TDataSeries">The type of the data series.</typeparam> + /// <typeparam name="TXDataPoint">The type of the x data point.</typeparam> + /// <typeparam name="TYDataPoint">The type of the y data point.</typeparam> + /// <seealso cref="RealTimeGraphX.IGraphComponent" /> + public interface IGraphController<TDataSeries, TXDataPoint, TYDataPoint> : IGraphController<TDataSeries> + where TXDataPoint : GraphDataPoint + where TYDataPoint : GraphDataPoint + where TDataSeries : IGraphDataSeries + { + #region Properties + + /// <summary> + /// Gets or sets the graph range (data point boundaries). + /// </summary> + GraphRange<TXDataPoint, TYDataPoint> Range { get; set; } + + #endregion + + #region Methods + + /// <summary> + /// Submits the specified x and y data points. + /// If the controller has more than one data series the data points will be duplicated. + /// </summary> + /// <param name="x">X data point.</param> + /// <param name="y">Y data point.</param> + void PushData(TXDataPoint x, TYDataPoint y); + + /// <summary> + /// 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. + /// </summary> + /// <param name="xx">X data point collection.</param> + /// <param name="yy">Y data point collection.</param> + void PushData(IEnumerable<TXDataPoint> xx, IEnumerable<TYDataPoint> yy); + + /// <summary> + /// Submits a matrix of x and y data points. Meaning each data series should process a single collection of x/y data points. + /// </summary> + /// <param name="xxxx">X matrix.</param> + /// <param name="yyyy">Y matrix.</param> + void PushData(IEnumerable<IEnumerable<TXDataPoint>> xxxx, IEnumerable<IEnumerable<TYDataPoint>> 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 +{ + /// <summary> + /// Represents a graph X or Y data point that can be pushed to a <see cref="IGraphController{TColor, TBrush, TXDataPoint, TYDataPoint}">Graph Controller</see>. + /// </summary> + /// <seealso cref="System.IComparable" /> + [TypeConverter(typeof(GraphDataPointTypeConverter))] + public interface IGraphDataPoint : IComparable + { + /// <summary> + /// Sums the value of this instance with another instance value and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + IGraphDataPoint Add(IGraphDataPoint other); + + /// <summary> + /// Subtract the value of another instance from this instance and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + IGraphDataPoint Subtract(IGraphDataPoint other); + + /// <summary> + /// Multiplies the value of this instance with another instance value and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + IGraphDataPoint Multiply(IGraphDataPoint other); + + /// <summary> + /// Divides the value of this instance with another instance value and returns the result. + /// </summary> + /// <param name="other">The other instance.</param> + /// <returns></returns> + IGraphDataPoint Divide(IGraphDataPoint other); + + /// <summary> + /// Creates a range of values from the specified minimum and maximum. + /// </summary> + /// <param name="min">The minimum.</param> + /// <param name="max">The maximum.</param> + /// <param name="count">The count.</param> + /// <returns></returns> + IEnumerable<IGraphDataPoint> CreateRange(IGraphDataPoint min, IGraphDataPoint max, int count); + + /// <summary> + /// Returns the percentage value of this instance between the specified minimum and maximum values. + /// </summary> + /// <param name="min">The minimum.</param> + /// <param name="max">The maximum.</param> + /// <returns></returns> + double ComputeRelativePosition(IGraphDataPoint min, IGraphDataPoint max); + + /// <summary> + /// Returns the absolute value of the specified percentage value between the specified minimum and maximum values. + /// </summary> + /// <param name="min">The minimum.</param> + /// <param name="max">The maximum.</param> + /// <param name="percentage">The percentage.</param> + /// <returns></returns> + IGraphDataPoint ComputeAbsolutePosition(IGraphDataPoint min, IGraphDataPoint max, double percentage); + + /// <summary> + /// Gets the encapsulated value. + /// </summary> + /// <returns></returns> + object GetValue(); + + /// <summary> + /// Sets the encapsulated value. + /// </summary> + /// <param name="value">The value.</param> + void SetValue(object value); + + /// <summary> + /// Returns a formated string of this data point. + /// </summary> + /// <param name="format">The format.</param> + /// <returns></returns> + String ToString(String format); + + /// <summary> + /// Parses the specified value. + /// </summary> + /// <param name="value">The value.</param> + /// <returns></returns> + 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 +{ + /// <summary> + /// Represents a graph data series. + /// </summary> + /// <seealso cref="RealTimeGraphX.IGraphComponent" /> + public interface IGraphDataSeries : IGraphComponent + { + /// <summary> + /// Gets or sets the series name. + /// </summary> + String Name { get; set; } + + /// <summary> + /// Gets or sets the stroke thickness. + /// </summary> + float StrokeThickness { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether to fill the series. + /// </summary> + bool UseFill { get; } + + /// <summary> + /// Gets or sets a value indicating whether this series should be visible. + /// </summary> + bool IsVisible { get; set; } + + /// <summary> + /// Gets the current value. + /// </summary> + 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 +{ + /// <summary> + /// Represents a graph renderer capable of receiving a series of data points from a controller and transforming them to drawing points. + /// </summary> + /// <typeparam name="TDataSeries">The type of the data series.</typeparam> + /// <seealso cref="RealTimeGraphX.IGraphComponent" /> + public interface IGraphRenderer<TDataSeries> : IGraphComponent where TDataSeries : IGraphDataSeries + { + /// <summary> + /// Arranges the series of data points and returns a series of drawing points. + /// </summary> + /// <param name="surface">The target graph surface.</param> + /// <param name="series">The instance of the current rendered data series.</param> + /// <param name="range">Instance of graph range.</param> + /// <param name="xx">Collection of x coordinates.</param> + /// <param name="yy">Collection of y coordinates.</param> + /// <param name="minimumX">The minimum x coordinates value.</param> + /// <param name="maximumX">The maximum x coordinates value.</param> + /// <param name="minimumY">The minimum y coordinates value.</param> + /// <param name="maximumY">The maximum y coordinates value.</param> + /// <returns></returns> + IEnumerable<PointF> Render(IGraphSurface<TDataSeries> surface, TDataSeries series, IGraphRange range, List<GraphDataPoint> xx, List<GraphDataPoint> yy, GraphDataPoint minimumX, GraphDataPoint maximumX, GraphDataPoint minimumY, GraphDataPoint maximumY); + + /// <summary> + /// Draws the specified data series points on the target surface. + /// </summary> + /// <param name="surface">The target graph surface.</param> + /// <param name="series">The instance of the current rendered data series.</param> + /// <param name="points">The collection of the current data series drawing points.</param> + /// <param name="index">The index of the current data series within the collection of data series.</param> + /// <param name="count">The length of the data series collection.</param> + void Draw(IGraphSurface<TDataSeries> surface, TDataSeries series, IEnumerable<PointF> 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 +{ + /// <summary> + /// Represents a graph drawing surface capable of drawing a series of points submitted by a graph renderer. + /// </summary> + public interface IGraphSurface : IGraphComponent + { + /// <summary> + /// Occurs when the surface size has changed. + /// </summary> + event EventHandler SurfaceSizeChanged; + + /// <summary> + /// Occurs when the surface zoom rectangle has changed. + /// </summary> + event EventHandler ZoomRectChanged; + + /// <summary> + /// Returns the actual size of the surface. + /// </summary> + /// <returns></returns> + SizeF GetSize(); + + /// <summary> + /// Returns the current bounds of the zooming rectangle. + /// </summary> + /// <returns></returns> + RectangleF GetZoomRect(); + } + + /// <summary> + /// Represents a graph drawing surface capable of drawing a series of points submitted by a graph renderer. + /// </summary> + /// <typeparam name="TDataSeries">The type of the data series.</typeparam> + /// <seealso cref="RealTimeGraphX.IGraphComponent" /> + public interface IGraphSurface<TDataSeries> : IGraphSurface where TDataSeries : IGraphDataSeries + { + /// <summary> + /// Called before drawing has started. + /// </summary> + void BeginDraw(); + + /// <summary> + /// Draws the stroke of the specified data series points. + /// </summary> + /// <param name="dataSeries">The data series.</param> + /// <param name="points">The points.</param> + void DrawSeries(TDataSeries dataSeries, IEnumerable<PointF> points); + + /// <summary> + /// Fills the specified data series points. + /// </summary> + /// <param name="dataSeries">The data series.</param> + /// <param name="points">The points.</param> + void FillSeries(TDataSeries dataSeries, IEnumerable<PointF> points); + + /// <summary> + /// Applies transformation on the current pass. + /// </summary> + /// <param name="transform">The transform.</param> + void SetTransform(GraphTransform transform); + + /// <summary> + /// Called when drawing has completed. + /// </summary> + 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 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectGuid>{1490B50F-234C-400B-8704-7673435143F2}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>RealTimeGraphX</RootNamespace> + <AssemblyName>RealTimeGraphX</AssemblyName> + <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + <Deterministic>true</Deterministic> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.Core" /> + <Reference Include="System.Drawing" /> + <Reference Include="System.Xml.Linq" /> + <Reference Include="System.Data.DataSetExtensions" /> + <Reference Include="Microsoft.CSharp" /> + <Reference Include="System.Data" /> + <Reference Include="System.Net.Http" /> + <Reference Include="System.Xml" /> + </ItemGroup> + <ItemGroup> + <Compile Include="DataPoints\DateTimeDataPoint.cs" /> + <Compile Include="DataPoints\DoubleDataPoint.cs" /> + <Compile Include="DataPoints\FloatDataPoint.cs" /> + <Compile Include="DataPoints\Int32DataPoint.cs" /> + <Compile Include="DataPoints\TimeSpanDataPoint.cs" /> + <Compile Include="EventArguments\RangeChangedEventArgs.cs" /> + <Compile Include="GraphCommand.cs" /> + <Compile Include="GraphController.cs" /> + <Compile Include="GraphDataPoint.cs" /> + <Compile Include="GraphDataPointHelper.cs" /> + <Compile Include="GraphDataPointTypeConverter.cs" /> + <Compile Include="GraphDataQueue.cs" /> + <Compile Include="GraphObject.cs" /> + <Compile Include="GraphRange.cs" /> + <Compile Include="GraphRenderer.cs" /> + <Compile Include="GraphTransform.cs" /> + <Compile Include="IGraphComponent.cs" /> + <Compile Include="IGraphController.cs" /> + <Compile Include="IGraphDataPoint.cs" /> + <Compile Include="IGraphDataSeries.cs" /> + <Compile Include="IGraphRenderer.cs" /> + <Compile Include="IGraphSurface.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="Renderers\ScrollingLineRenderer.cs" /> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> +</Project>
\ 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 +{ + /// <summary> + /// Represents a scrolling style <see cref="GraphRenderer{TDataSeries}"/>. + /// </summary> + /// <typeparam name="TDataSeries">The type of the data series.</typeparam> + /// <seealso cref="RealTimeGraphX.GraphRenderer{TDataSeries}" /> + public class ScrollingLineRenderer<TDataSeries> : GraphRenderer<TDataSeries> where TDataSeries : IGraphDataSeries + { + /// <summary> + /// Arranges the series of data points and returns a series of drawing points. + /// </summary> + /// <param name="surface">The target graph surface.</param> + /// <param name="series">The instance of the current rendered data series.</param> + /// <param name="range">Instance of graph range.</param> + /// <param name="xx">Collection of x coordinates.</param> + /// <param name="yy">Collection of y coordinates.</param> + /// <param name="minimumX">The minimum x coordinates value.</param> + /// <param name="maximumX">The maximum x coordinates value.</param> + /// <param name="minimumY">The minimum y coordinates value.</param> + /// <param name="maximumY">The maximum y coordinates value.</param> + /// <returns></returns> + public override IEnumerable<PointF> Render(IGraphSurface<TDataSeries> surface, TDataSeries series, IGraphRange range, List<GraphDataPoint> xx, List<GraphDataPoint> 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<PointF> points = new List<PointF>(); + + 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; + } + + /// <summary> + /// Draws the specified data series points on the target surface. + /// </summary> + /// <param name="surface">The target graph surface.</param> + /// <param name="series">The instance of the current rendered data series.</param> + /// <param name="points">The collection of the current data series drawing points.</param> + /// <param name="index">The index of the current data series within the collection of data series.</param> + /// <param name="count">The length of the data series collection.</param> + public override void Draw(IGraphSurface<TDataSeries> surface, TDataSeries series, IEnumerable<PointF> 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 |
