diff options
| author | Roy Ben-Shabat <Roy@Twine-s.com> | 2019-04-15 12:06:30 +0300 |
|---|---|---|
| committer | Roy Ben-Shabat <Roy@Twine-s.com> | 2019-04-15 12:06:30 +0300 |
| commit | 3c5f32456c72b26497c05bb35fd64e3c77c6b0f5 (patch) | |
| tree | 4d6b489f02e147e89c23871011512a51daa478fa /Software/Visual_Studio/SideChains | |
| parent | 85a6112d2e1eac554cc4cbdfa31cca91d87e6ded (diff) | |
| download | Tango-3c5f32456c72b26497c05bb35fd64e3c77c6b0f5.tar.gz Tango-3c5f32456c72b26497c05bb35fd64e3c77c6b0f5.zip | |
Now using the latest RealTimeGraphX library! + infinity check!
Diffstat (limited to 'Software/Visual_Studio/SideChains')
54 files changed, 5250 insertions, 6 deletions
diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/App.config b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/App.config new file mode 100644 index 000000000..731f6de6c --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/App.config @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" ?> +<configuration> + <startup> + <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" /> + </startup> +</configuration>
\ No newline at end of file diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/App.xaml b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/App.xaml new file mode 100644 index 000000000..19410e824 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/App.xaml @@ -0,0 +1,9 @@ +<Application x:Class="RealTimeGraphX.WPF.Demo.App" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:local="clr-namespace:RealTimeGraphX.WPF.Demo" + StartupUri="MainWindow.xaml"> + <Application.Resources> + + </Application.Resources> +</Application> diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/App.xaml.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/App.xaml.cs new file mode 100644 index 000000000..16bbca639 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/App.xaml.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace RealTimeGraphX.WPF.Demo +{ + /// <summary> + /// Interaction logic for App.xaml + /// </summary> + public partial class App : Application + { + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/MainWindow.xaml b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/MainWindow.xaml new file mode 100644 index 000000000..89cdde87c --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/MainWindow.xaml @@ -0,0 +1,112 @@ +<Window x:Class="RealTimeGraphX.WPF.Demo.MainWindow" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:local="clr-namespace:RealTimeGraphX.WPF.Demo" + xmlns:collections="clr-namespace:System.Collections;assembly=mscorlib" + xmlns:realTimeGraphX="clr-namespace:RealTimeGraphX.WPF;assembly=RealTimeGraphX.WPF" + mc:Ignorable="d" + Title="RealtimeGraphX WPF Demo" Height="557" Width="1168.5" d:DataContext="{d:DesignData Type=local:MainWindowVM, IsDesignTimeCreatable=False}"> + + <Window.Resources> + <collections:ArrayList x:Key="colors"> + <Color>DodgerBlue</Color> + <Color>Red</Color> + <Color>Green</Color> + </collections:ArrayList> + + <collections:ArrayList x:Key="brushes"> + <SolidColorBrush Color="Transparent"></SolidColorBrush> + <SolidColorBrush Color="#861E90FF"></SolidColorBrush> + <LinearGradientBrush> + <GradientStop Offset="0" Color="#86FF0000" /> + <GradientStop Offset="1" Color="#80FFFF00" /> + </LinearGradientBrush> + </collections:ArrayList> + </Window.Resources> + + <Grid> + <TabControl Background="Transparent" Margin="20"> + <TabItem Header="Single Series"> + <Grid> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="1*"/> + <ColumnDefinition Width="200"/> + </Grid.ColumnDefinitions> + <local:WpfGraphControl Margin="10" Controller="{Binding Controller}" /> + + <Border Grid.Column="1" Margin="10" BorderBrush="Gray" BorderThickness="1" CornerRadius="5" Padding="5"> + <StackPanel> + <TextBlock FontSize="10">Duration</TextBlock> + <TextBox Margin="0 5 0 0" Text="{Binding Controller.Range.MaximumX,Mode=TwoWay}"></TextBox> + + <TextBlock FontSize="10" Margin="0 10 0 0">Refresh Rate</TextBlock> + <TextBox Margin="0 5 0 0" Text="{Binding Controller.RefreshRate,Mode=TwoWay}"></TextBox> + + <TextBlock FontSize="10" Margin="0 10 0 0">Minimum Y</TextBlock> + <TextBox Margin="0 5 0 0" Text="{Binding Controller.Range.MinimumY,Mode=TwoWay}"></TextBox> + + <TextBlock FontSize="10" Margin="0 10 0 0">Maximum Y</TextBlock> + <TextBox Margin="0 5 0 0" Text="{Binding Controller.Range.MaximumY,Mode=TwoWay}"></TextBox> + + <CheckBox Margin="0 5 0 0" IsChecked="{Binding Controller.Range.AutoY,Mode=TwoWay}">Auto Range (Y)</CheckBox> + + <TextBlock FontSize="10" Margin="0 20 0 0">Stroke</TextBlock> + <ComboBox Margin="0 5 0 0" ItemsSource="{StaticResource colors}" SelectedItem="{Binding Controller.DataSeriesCollection[0].Stroke}"/> + + <TextBlock FontSize="10" Margin="0 10 0 0">Thickness</TextBlock> + <Slider Margin="0 5 0 0" Minimum="1" Maximum="5" Value="{Binding Controller.DataSeriesCollection[0].StrokeThickness}" IsSnapToTickEnabled="True" TickFrequency="1" /> + + <TextBlock FontSize="10" Margin="0 10 0 0">Fill</TextBlock> + <ComboBox Margin="0 5 0 0" ItemsSource="{StaticResource brushes}" SelectedItem="{Binding Controller.DataSeriesCollection[0].Fill}"/> + + <CheckBox Margin="0 10 0 0" IsChecked="{Binding Controller.IsPaused,Mode=TwoWay}">Paused</CheckBox> + + <Button Margin="0 10 0 0" Padding="5" Command="{Binding Controller.ClearCommand}">Clear</Button> + </StackPanel> + </Border> + </Grid> + </TabItem> + <TabItem Header="Multi Series"> + <Grid> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="1*"/> + <ColumnDefinition Width="200"/> + </Grid.ColumnDefinitions> + <local:WpfGraphControl Margin="10" Controller="{Binding MultiController}" /> + + <Border Grid.Column="1" Margin="10" BorderBrush="Gray" BorderThickness="1" CornerRadius="5" Padding="5"> + <StackPanel> + <TextBlock FontSize="10">Duration</TextBlock> + <TextBox Margin="0 5 0 0" Text="{Binding MultiController.Range.MaximumX,Mode=TwoWay}"></TextBox> + + <TextBlock FontSize="10" Margin="0 10 0 0">Refresh Rate</TextBlock> + <TextBox Margin="0 5 0 0" Text="{Binding MultiController.RefreshRate,Mode=TwoWay}"></TextBox> + + <TextBlock FontSize="10" Margin="0 10 0 0">Minimum Y</TextBlock> + <TextBox Margin="0 5 0 0" Text="{Binding MultiController.Range.MinimumY,Mode=TwoWay}"></TextBox> + + <TextBlock FontSize="10" Margin="0 10 0 0">Maximum Y</TextBlock> + <TextBox Margin="0 5 0 0" Text="{Binding MultiController.Range.MaximumY,Mode=TwoWay}"></TextBox> + + <CheckBox Margin="0 5 0 0" IsChecked="{Binding MultiController.Range.AutoY,Mode=TwoWay}">Auto Range (Y)</CheckBox> + + <ListBox ItemsSource="{Binding MultiController.DataSeriesCollection}" Height="120" Margin="0 20"> + <ListBox.ItemTemplate> + <DataTemplate> + <StackPanel> + <CheckBox Content="{Binding Name}" IsChecked="{Binding IsVisible}" /> + </StackPanel> + </DataTemplate> + </ListBox.ItemTemplate> + </ListBox> + + <Button Margin="0 10 0 0" Padding="5" Command="{Binding MultiController.ClearCommand}">Clear</Button> + </StackPanel> + </Border> + </Grid> + </TabItem> + </TabControl> + </Grid> +</Window> diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/MainWindow.xaml.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/MainWindow.xaml.cs new file mode 100644 index 000000000..11bdb2d6a --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/MainWindow.xaml.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace RealTimeGraphX.WPF.Demo +{ + /// <summary> + /// Interaction logic for MainWindow.xaml + /// </summary> + public partial class MainWindow : Window + { + public MainWindow() + { + InitializeComponent(); + DataContext = new MainWindowVM(); + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/MainWindowVM.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/MainWindowVM.cs new file mode 100644 index 000000000..390230140 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/MainWindowVM.cs @@ -0,0 +1,107 @@ +using RealTimeGraphX.DataPoints; +using RealTimeGraphX.Renderers; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Media; + +namespace RealTimeGraphX.WPF.Demo +{ + public class MainWindowVM + { + public WpfGraphController<TimeSpanDataPoint, DoubleDataPoint> Controller { get; set; } + + public WpfGraphController<TimeSpanDataPoint, DoubleDataPoint> MultiController { get; set; } + + public MainWindowVM() + { + Controller = new WpfGraphController<TimeSpanDataPoint, DoubleDataPoint>(); + Controller.Range.MinimumY = 0; + Controller.Range.MaximumY = 1080; + Controller.Range.MaximumX = TimeSpan.FromSeconds(10); + Controller.Range.AutoY = true; + + Controller.DataSeriesCollection.Add(new WpfGraphDataSeries() + { + Name = "Series", + Stroke = Colors.DodgerBlue, + }); + + MultiController = new WpfGraphController<TimeSpanDataPoint, DoubleDataPoint>(); + MultiController.Range.MinimumY = 0; + MultiController.Range.MaximumY = 1080; + MultiController.Range.MaximumX = TimeSpan.FromSeconds(10); + MultiController.Range.AutoY = true; + + MultiController.DataSeriesCollection.Add(new WpfGraphDataSeries() + { + Name = "Series 1", + Stroke = Colors.Red, + }); + + MultiController.DataSeriesCollection.Add(new WpfGraphDataSeries() + { + Name = "Series 2", + Stroke = Colors.Green, + }); + + MultiController.DataSeriesCollection.Add(new WpfGraphDataSeries() + { + Name = "Series 3", + Stroke = Colors.Blue, + }); + + MultiController.DataSeriesCollection.Add(new WpfGraphDataSeries() + { + Name = "Series 4", + Stroke = Colors.Yellow, + }); + + MultiController.DataSeriesCollection.Add(new WpfGraphDataSeries() + { + Name = "Series 5", + Stroke = Colors.Gray, + }); + + Stopwatch watch = new Stopwatch(); + watch.Start(); + + Task.Factory.StartNew(() => + { + while (true) + { + var y = System.Windows.Forms.Cursor.Position.Y; + + List<DoubleDataPoint> yy = new List<DoubleDataPoint>() + { + y, + y + 20, + y + 40, + y + 60, + y + 80, + }; + + var x = watch.Elapsed; + + List<TimeSpanDataPoint> xx = new List<TimeSpanDataPoint>() + { + x, + x, + x, + x, + x + }; + + Controller.PushData(x, y); + MultiController.PushData(xx, yy); + + Thread.Sleep(30); + } + }); + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/Properties/AssemblyInfo.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..7e504011c --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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.WPF.Demo")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("RealTimeGraphX.WPF.Demo")] +[assembly: AssemblyCopyright("Copyright © 2018")] +[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)] + +//In order to begin building localizable applications, set +//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file +//inside a <PropertyGroup>. For example, if you are using US english +//in your source files, set the <UICulture> to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/Properties/Resources.Designer.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/Properties/Resources.Designer.cs new file mode 100644 index 000000000..b1dd1cfba --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/Properties/Resources.Designer.cs @@ -0,0 +1,71 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace RealTimeGraphX.WPF.Demo.Properties +{ + + + /// <summary> + /// A strongly-typed resource class, for looking up localized strings, etc. + /// </summary> + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources + { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() + { + } + + /// <summary> + /// Returns the cached ResourceManager instance used by this class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if ((resourceMan == null)) + { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("RealTimeGraphX.WPF.Demo.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// <summary> + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture + { + get + { + return resourceCulture; + } + set + { + resourceCulture = value; + } + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/Properties/Resources.resx b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/Properties/Resources.resx new file mode 100644 index 000000000..af7dbebba --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/Properties/Resources.resx @@ -0,0 +1,117 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> +</root>
\ No newline at end of file diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/Properties/Settings.Designer.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/Properties/Settings.Designer.cs new file mode 100644 index 000000000..d6fd721ce --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace RealTimeGraphX.WPF.Demo.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/Properties/Settings.settings b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/Properties/Settings.settings new file mode 100644 index 000000000..033d7a5e9 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/Properties/Settings.settings @@ -0,0 +1,7 @@ +<?xml version='1.0' encoding='utf-8'?> +<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)"> + <Profiles> + <Profile Name="(Default)" /> + </Profiles> + <Settings /> +</SettingsFile>
\ No newline at end of file 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 new file mode 100644 index 000000000..5b430a90c --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/RealTimeGraphX.WPF.Demo.csproj @@ -0,0 +1,116 @@ +<?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>{B822CBD9-1113-4668-85C9-22AA9C24CE60}</ProjectGuid> + <OutputType>WinExe</OutputType> + <RootNamespace>RealTimeGraphX.WPF.Demo</RootNamespace> + <AssemblyName>RealTimeGraphX.WPF.Demo</AssemblyName> + <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <WarningLevel>4</WarningLevel> + <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <PlatformTarget>AnyCPU</PlatformTarget> + <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' "> + <PlatformTarget>AnyCPU</PlatformTarget> + <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.Data" /> + <Reference Include="System.Drawing" /> + <Reference Include="System.Windows.Forms" /> + <Reference Include="System.Xml" /> + <Reference Include="Microsoft.CSharp" /> + <Reference Include="System.Core" /> + <Reference Include="System.Xml.Linq" /> + <Reference Include="System.Data.DataSetExtensions" /> + <Reference Include="System.Net.Http" /> + <Reference Include="System.Xaml"> + <RequiredTargetFramework>4.0</RequiredTargetFramework> + </Reference> + <Reference Include="WindowsBase" /> + <Reference Include="PresentationCore" /> + <Reference Include="PresentationFramework" /> + </ItemGroup> + <ItemGroup> + <ApplicationDefinition Include="App.xaml"> + <Generator>MSBuild:Compile</Generator> + <SubType>Designer</SubType> + </ApplicationDefinition> + <Compile Include="WpfGraphControl.cs" /> + <Page Include="MainWindow.xaml"> + <Generator>MSBuild:Compile</Generator> + <SubType>Designer</SubType> + </Page> + <Compile Include="App.xaml.cs"> + <DependentUpon>App.xaml</DependentUpon> + <SubType>Code</SubType> + </Compile> + <Compile Include="MainWindow.xaml.cs"> + <DependentUpon>MainWindow.xaml</DependentUpon> + <SubType>Code</SubType> + </Compile> + <Page Include="Themes\Generic.xaml"> + <Generator>MSBuild:Compile</Generator> + <SubType>Designer</SubType> + </Page> + </ItemGroup> + <ItemGroup> + <Compile Include="MainWindowVM.cs" /> + <Compile Include="Properties\AssemblyInfo.cs"> + <SubType>Code</SubType> + </Compile> + <Compile Include="Properties\Resources.Designer.cs"> + <AutoGen>True</AutoGen> + <DesignTime>True</DesignTime> + <DependentUpon>Resources.resx</DependentUpon> + </Compile> + <Compile Include="Properties\Settings.Designer.cs"> + <AutoGen>True</AutoGen> + <DependentUpon>Settings.settings</DependentUpon> + <DesignTimeSharedInput>True</DesignTimeSharedInput> + </Compile> + <EmbeddedResource Include="Properties\Resources.resx"> + <Generator>ResXFileCodeGenerator</Generator> + <LastGenOutput>Resources.Designer.cs</LastGenOutput> + </EmbeddedResource> + <None Include="Properties\Settings.settings"> + <Generator>SettingsSingleFileGenerator</Generator> + <LastGenOutput>Settings.Designer.cs</LastGenOutput> + </None> + </ItemGroup> + <ItemGroup> + <None Include="App.config" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\RealTimeGraphX.WPF\RealTimeGraphX.WPF.csproj"> + <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" /> +</Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/Themes/Generic.xaml b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/Themes/Generic.xaml new file mode 100644 index 000000000..6980437f1 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/Themes/Generic.xaml @@ -0,0 +1,53 @@ +<ResourceDictionary + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:realTimeGraphX="clr-namespace:RealTimeGraphX.WPF;assembly=RealTimeGraphX.WPF" + xmlns:local="clr-namespace:RealTimeGraphX.WPF.Demo"> + + + <Style TargetType="{x:Type local:WpfGraphControl}"> + <Setter Property="BorderThickness" Value="1"></Setter> + <Setter Property="BorderBrush" Value="#FF2E2E2E"></Setter> + <Setter Property="Padding" Value="20 20 30 20"></Setter> + <Setter Property="FontSize" Value="11"></Setter> + <Setter Property="Foreground" Value="DodgerBlue"></Setter> + <Setter Property="Background"> + <Setter.Value> + <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0" > + <GradientStop Color="Black"/> + <GradientStop Color="#FF333333" Offset="1"/> + </LinearGradientBrush> + </Setter.Value> + </Setter> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="{x:Type local:WpfGraphControl}"> + <Border Background="{TemplateBinding Background}" + BorderBrush="{TemplateBinding BorderBrush}" + BorderThickness="{TemplateBinding BorderThickness}" + CornerRadius="5" + Padding="{TemplateBinding Padding}"> + <Grid> + <Grid.RowDefinitions> + <RowDefinition Height="1*"/> + <RowDefinition Height="35"/> + </Grid.RowDefinitions> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="70"/> + <ColumnDefinition Width="1*"/> + </Grid.ColumnDefinitions> + + <Grid Grid.Column="1"> + <realTimeGraphX:WpfGraphGridLines Controller="{TemplateBinding Controller}" Foreground="#FF2E2E2E" /> + <realTimeGraphX:WpfGraphSurface x:Name="surface" Controller="{TemplateBinding Controller}" BorderThickness="1 0 0 1" BorderBrush="{TemplateBinding Foreground}" /> + </Grid> + + <realTimeGraphX:WpfGraphAxisControl Orientation="Vertical" Controller="{TemplateBinding Controller}" StringFormat="0.0" /> + <realTimeGraphX:WpfGraphAxisControl Orientation="Horizontal" Controller="{TemplateBinding Controller}" Grid.Column="1" Grid.Row="1" StringFormat="hh\:mm\:ss"/> + </Grid> + </Border> + </ControlTemplate> + </Setter.Value> + </Setter> + </Style> +</ResourceDictionary> diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/WpfGraphControl.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/WpfGraphControl.cs new file mode 100644 index 000000000..7c92e18bf --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF.Demo/WpfGraphControl.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace RealTimeGraphX.WPF.Demo +{ + public class WpfGraphControl : Control + { + /// <summary> + /// Gets or sets the graph controller. + /// </summary> + public IGraphController Controller + { + get { return (IGraphController)GetValue(ControllerProperty); } + set { SetValue(ControllerProperty, value); } + } + public static readonly DependencyProperty ControllerProperty = + DependencyProperty.Register("Controller", typeof(IGraphController), typeof(WpfGraphControl), new PropertyMetadata(null)); + + /// <summary> + /// Initializes the <see cref="WpfGraphControl"/> class. + /// </summary> + static WpfGraphControl() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(WpfGraphControl), new FrameworkPropertyMetadata(typeof(WpfGraphControl))); + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/ExtensionMethods.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/ExtensionMethods.cs new file mode 100644 index 000000000..39f113924 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/ExtensionMethods.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RealTimeGraphX.WPF +{ + /// <summary> + /// Contains a collection of extension methods. + /// </summary> + internal static class ExtensionMethods + { + /// <summary> + /// Converts this WPF color to a GDI color. + /// </summary> + /// <param name="color">The color.</param> + /// <returns></returns> + internal static Color ToGdiColor(this System.Windows.Media.Color color) + { + return Color.FromArgb(color.A, color.R, color.G, color.B); + } + + /// <summary> + /// Converts this WPF brush to a GDI brush. + /// </summary> + /// <param name="brush">The brush.</param> + /// <returns></returns> + internal static Brush ToGdiBrush(this System.Windows.Media.Brush brush) + { + if (brush.GetType() == typeof(System.Windows.Media.SolidColorBrush)) + { + return new SolidBrush((brush as System.Windows.Media.SolidColorBrush).Color.ToGdiColor()); + } + else if (brush.GetType() == typeof(System.Windows.Media.LinearGradientBrush)) + { + System.Windows.Media.LinearGradientBrush b = brush as System.Windows.Media.LinearGradientBrush; + + double angle = Math.Atan2(b.EndPoint.Y - b.StartPoint.Y, b.EndPoint.X - b.StartPoint.X) * 180 / Math.PI; + + LinearGradientBrush gradient = new LinearGradientBrush(new Rectangle(0, 0, 200, 100), Color.Black, Color.Black, (float)angle); + + ColorBlend blend = new ColorBlend(); + + List<Color> colors = new List<Color>(); + List<float> offsets = new List<float>(); + + foreach (var stop in b.GradientStops) + { + colors.Add(stop.Color.ToGdiColor()); + offsets.Add((float)stop.Offset); + } + + blend.Colors = colors.ToArray(); + blend.Positions = offsets.ToArray(); + + gradient.InterpolationColors = blend; + + return gradient; + } + else + { + return new LinearGradientBrush(new PointF(0, 0), new Point(200, 100), Color.Black, Color.Black); + } + } + + /// <summary> + /// Determines whether this dependency object is running in design mode. + /// </summary> + /// <param name="obj">The object.</param> + internal static bool IsInDesignMode(this System.Windows.DependencyObject obj) + { + return (DesignerProperties.GetIsInDesignMode(obj)); + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/Properties/AssemblyInfo.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..a08459ddd --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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.WPF")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("RealTimeGraphX.WPF")] +[assembly: AssemblyCopyright("Copyright © 2018")] +[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)] + +//In order to begin building localizable applications, set +//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file +//inside a <PropertyGroup>. For example, if you are using US english +//in your source files, set the <UICulture> to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly:ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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/RealTimeGraphX-master/RealTimeGraphX.WPF/Properties/Resources.Designer.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/Properties/Resources.Designer.cs new file mode 100644 index 000000000..601c8ad1d --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/Properties/Resources.Designer.cs @@ -0,0 +1,62 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace RealTimeGraphX.WPF.Properties { + + + /// <summary> + /// A strongly-typed resource class, for looking up localized strings, etc. + /// </summary> + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// <summary> + /// Returns the cached ResourceManager instance used by this class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if ((resourceMan == null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("RealTimeGraphX.WPF.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// <summary> + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/Properties/Resources.resx b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/Properties/Resources.resx new file mode 100644 index 000000000..af7dbebba --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/Properties/Resources.resx @@ -0,0 +1,117 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> +</root>
\ No newline at end of file diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/Properties/Settings.Designer.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/Properties/Settings.Designer.cs new file mode 100644 index 000000000..18340e385 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace RealTimeGraphX.WPF.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/Properties/Settings.settings b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/Properties/Settings.settings new file mode 100644 index 000000000..033d7a5e9 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/Properties/Settings.settings @@ -0,0 +1,7 @@ +<?xml version='1.0' encoding='utf-8'?> +<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)"> + <Profiles> + <Profile Name="(Default)" /> + </Profiles> + <Settings /> +</SettingsFile>
\ No newline at end of file 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 new file mode 100644 index 000000000..6446fc93f --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/RealTimeGraphX.WPF.csproj @@ -0,0 +1,97 @@ +<?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>{6B9774F7-960D-438E-AD81-C6B9BE328D50}</ProjectGuid> + <OutputType>library</OutputType> + <RootNamespace>RealTimeGraphX.WPF</RootNamespace> + <AssemblyName>RealTimeGraphX.WPF</AssemblyName> + <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <WarningLevel>4</WarningLevel> + </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.Data" /> + <Reference Include="System.Drawing" /> + <Reference Include="System.Xml" /> + <Reference Include="Microsoft.CSharp" /> + <Reference Include="System.Core" /> + <Reference Include="System.Xml.Linq" /> + <Reference Include="System.Data.DataSetExtensions" /> + <Reference Include="System.Net.Http" /> + <Reference Include="System.Xaml"> + <RequiredTargetFramework>4.0</RequiredTargetFramework> + </Reference> + <Reference Include="WindowsBase" /> + <Reference Include="PresentationCore" /> + <Reference Include="PresentationFramework" /> + </ItemGroup> + <ItemGroup> + <Page Include="Themes\Generic.xaml"> + <Generator>MSBuild:Compile</Generator> + <SubType>Designer</SubType> + </Page> + <Compile Include="ExtensionMethods.cs" /> + <Compile Include="WpfGraphAxisControl.cs" /> + <Compile Include="WpfGraphAxisPanel.cs" /> + <Compile Include="WpfGraphAxisTickData.cs" /> + <Compile Include="WpfGraphGridLines.cs" /> + <Compile Include="WpfGraphComponentBase.cs" /> + <Compile Include="WpfGraphDataSeries.cs" /> + <Compile Include="WpfGraphController.cs" /> + <Compile Include="WpfGraphSurface.cs"> + <SubType>Code</SubType> + </Compile> + </ItemGroup> + <ItemGroup> + <Compile Include="Properties\AssemblyInfo.cs"> + <SubType>Code</SubType> + </Compile> + <Compile Include="Properties\Resources.Designer.cs"> + <AutoGen>True</AutoGen> + <DesignTime>True</DesignTime> + <DependentUpon>Resources.resx</DependentUpon> + </Compile> + <Compile Include="Properties\Settings.Designer.cs"> + <AutoGen>True</AutoGen> + <DependentUpon>Settings.settings</DependentUpon> + <DesignTimeSharedInput>True</DesignTimeSharedInput> + </Compile> + <EmbeddedResource Include="Properties\Resources.resx"> + <Generator>ResXFileCodeGenerator</Generator> + <LastGenOutput>Resources.Designer.cs</LastGenOutput> + </EmbeddedResource> + <None Include="Properties\Settings.settings"> + <Generator>SettingsSingleFileGenerator</Generator> + <LastGenOutput>Settings.Designer.cs</LastGenOutput> + </None> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\RealTimeGraphX\RealTimeGraphX.csproj"> + <Project>{61f001e1-6e17-4ca6-8f3a-8a11d7166815}</Project> + <Name>RealTimeGraphX</Name> + </ProjectReference> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> +</Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/Themes/Generic.xaml b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/Themes/Generic.xaml new file mode 100644 index 000000000..1070736ef --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/Themes/Generic.xaml @@ -0,0 +1,143 @@ +<ResourceDictionary + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:local="clr-namespace:RealTimeGraphX.WPF"> + + <Style TargetType="{x:Type local:WpfGraphSurface}"> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="{x:Type local:WpfGraphSurface}"> + <Border Background="{TemplateBinding Background}" + BorderBrush="{TemplateBinding BorderBrush}" + BorderThickness="{TemplateBinding BorderThickness}"> + <Grid x:Name="PART_Grid" Margin="{TemplateBinding Padding}"> + <Image Source="{TemplateBinding Image}" Stretch="None"></Image> + + <Canvas x:Name="PART_SelectionCanvas" Background="Transparent"> + <Rectangle x:Name="PART_SelectionRectangle" Fill="#7BFFFFFF" Canvas.Top="0" Canvas.Left="0" Width="0" Height="0" Visibility="Hidden"></Rectangle> + </Canvas> + </Grid> + </Border> + </ControlTemplate> + </Setter.Value> + </Setter> + </Style> + + <Style TargetType="{x:Type local:WpfGraphAxisControl}"> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="{x:Type local:WpfGraphAxisControl}"> + <Border Background="{TemplateBinding Background}" + BorderBrush="{TemplateBinding BorderBrush}" + BorderThickness="{TemplateBinding BorderThickness}"> + + <ItemsControl x:Name="PART_ItemsControl" ItemsSource="{TemplateBinding Items}" ItemTemplate="{TemplateBinding ItemTemplate}"> + <ItemsControl.ItemsPanel> + <ItemsPanelTemplate> + <local:WpfGraphAxisPanel Orientation="{Binding RelativeSource={RelativeSource AncestorType=local:WpfGraphAxisControl},Path=Orientation}"></local:WpfGraphAxisPanel> + </ItemsPanelTemplate> + </ItemsControl.ItemsPanel> + </ItemsControl> + </Border> + </ControlTemplate> + </Setter.Value> + </Setter> + <Style.Triggers> + <Trigger Property="Orientation" Value="Vertical"> + <Setter Property="ItemTemplate"> + <Setter.Value> + <DataTemplate DataType="{x:Type local:WpfGraphAxisTickData}"> + <DockPanel VerticalAlignment="Top"> + <Rectangle DockPanel.Dock="Right" VerticalAlignment="Center" Stroke="{Binding RelativeSource={RelativeSource AncestorType=local:WpfGraphAxisControl},Path=Foreground}" StrokeThickness="1"> + <Rectangle.Style> + <Style TargetType="Rectangle"> + <Setter Property="Width" Value="4"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding IsEven}" Value="True"> + <Setter Property="Width" Value="6"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </Rectangle.Style> + </Rectangle> + <TextBlock Text="{Binding DisplayText}"></TextBlock> + </DockPanel> + </DataTemplate> + </Setter.Value> + </Setter> + </Trigger> + <Trigger Property="Orientation" Value="Horizontal"> + <Setter Property="ItemTemplate"> + <Setter.Value> + <DataTemplate DataType="{x:Type local:WpfGraphAxisTickData}"> + <DockPanel HorizontalAlignment="Left"> + <Rectangle DockPanel.Dock="Top" HorizontalAlignment="Center" Stroke="{Binding RelativeSource={RelativeSource AncestorType=local:WpfGraphAxisControl},Path=Foreground}" StrokeThickness="1"> + <Rectangle.Style> + <Style TargetType="Rectangle"> + <Setter Property="Height" Value="4"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding IsEven}" Value="True"> + <Setter Property="Height" Value="6"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </Rectangle.Style> + </Rectangle> + <TextBlock VerticalAlignment="Bottom" Text="{Binding DisplayText}" RenderTransformOrigin="0.5,0.5"> + <TextBlock.RenderTransform> + <RotateTransform Angle="-30" /> + </TextBlock.RenderTransform> + </TextBlock> + </DockPanel> + </DataTemplate> + </Setter.Value> + </Setter> + </Trigger> + </Style.Triggers> + </Style> + + <Style TargetType="{x:Type local:WpfGraphGridLines}"> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="{x:Type local:WpfGraphGridLines}"> + <Border Background="{TemplateBinding Background}" + BorderBrush="{TemplateBinding BorderBrush}" + BorderThickness="{TemplateBinding BorderThickness}"> + + <Grid> + <ItemsControl ItemsSource="{TemplateBinding HorizontalItems}"> + <ItemsControl.ItemsPanel> + <ItemsPanelTemplate> + <UniformGrid Columns="{Binding RelativeSource={RelativeSource AncestorType=local:WpfGraphGridLines},Path=Columns}"></UniformGrid> + </ItemsPanelTemplate> + </ItemsControl.ItemsPanel> + <ItemsControl.ItemTemplate> + <DataTemplate> + <Rectangle Stroke="{Binding RelativeSource={RelativeSource AncestorType=local:WpfGraphGridLines},Path=Foreground}" StrokeThickness="1" HorizontalAlignment="Left" VerticalAlignment="Stretch"></Rectangle> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> + + <ItemsControl ItemsSource="{TemplateBinding VerticalItems}"> + <ItemsControl.ItemsPanel> + <ItemsPanelTemplate> + <UniformGrid Rows="{Binding RelativeSource={RelativeSource AncestorType=local:WpfGraphGridLines},Path=Rows}"></UniformGrid> + </ItemsPanelTemplate> + </ItemsControl.ItemsPanel> + <ItemsControl.ItemTemplate> + <DataTemplate> + <Rectangle Stroke="{Binding RelativeSource={RelativeSource AncestorType=local:WpfGraphGridLines},Path=Foreground}" StrokeThickness="1" HorizontalAlignment="Stretch" VerticalAlignment="Top"></Rectangle> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> + + <Rectangle Stroke="{Binding RelativeSource={RelativeSource AncestorType=local:WpfGraphGridLines},Path=Foreground}" StrokeThickness="1" HorizontalAlignment="Right" VerticalAlignment="Stretch"></Rectangle> + <Rectangle Stroke="{Binding RelativeSource={RelativeSource AncestorType=local:WpfGraphGridLines},Path=Foreground}" StrokeThickness="1" HorizontalAlignment="Stretch" VerticalAlignment="Bottom"></Rectangle> + </Grid> + + </Border> + </ControlTemplate> + </Setter.Value> + </Setter> + </Style> +</ResourceDictionary> diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphAxisControl.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphAxisControl.cs new file mode 100644 index 000000000..23b831abe --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphAxisControl.cs @@ -0,0 +1,172 @@ +using RealTimeGraphX.EventArguments; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace RealTimeGraphX.WPF +{ + /// <summary> + /// Represents a horizontal/vertical graph axis component. + /// </summary> + /// <seealso cref="RealTimeGraphX.WPF.WpfGraphComponentBase" /> + public class WpfGraphAxisControl : WpfGraphComponentBase + { + private ItemsControl _items_control; + + /// <summary> + /// Initializes the <see cref="WpfGraphAxisControl"/> class. + /// </summary> + static WpfGraphAxisControl() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(WpfGraphAxisControl), new FrameworkPropertyMetadata(typeof(WpfGraphAxisControl))); + } + + /// <summary> + /// Gets or sets the control orientation. + /// </summary> + public Orientation Orientation + { + get { return (Orientation)GetValue(OrientationProperty); } + set { SetValue(OrientationProperty, value); } + } + public static readonly DependencyProperty OrientationProperty = + DependencyProperty.Register("Orientation", typeof(Orientation), typeof(WpfGraphAxisControl), new PropertyMetadata(Orientation.Vertical)); + + /// <summary> + /// Gets or sets the tick item template. + /// </summary> + public DataTemplate ItemTemplate + { + get { return (DataTemplate)GetValue(ItemTemplateProperty); } + set { SetValue(ItemTemplateProperty, value); } + } + public static readonly DependencyProperty ItemTemplateProperty = + DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(WpfGraphAxisControl), new PropertyMetadata(null)); + + /// <summary> + /// Gets or sets the tick items. + /// </summary> + internal ObservableCollection<WpfGraphAxisTickData> Items + { + get { return (ObservableCollection<WpfGraphAxisTickData>)GetValue(ItemsProperty); } + set { SetValue(ItemsProperty, value); } + } + public static readonly DependencyProperty ItemsProperty = + DependencyProperty.Register("Items", typeof(ObservableCollection<WpfGraphAxisTickData>), typeof(WpfGraphAxisControl), new PropertyMetadata(null)); + + /// <summary> + /// Gets or sets the number of ticks to display on the control. + /// </summary> + public int Ticks + { + get { return (int)GetValue(TicksProperty); } + set { SetValue(TicksProperty, value); } + } + public static readonly DependencyProperty TicksProperty = + DependencyProperty.Register("Ticks", typeof(int), typeof(WpfGraphAxisControl), new PropertyMetadata(9, (d, e) => (d as WpfGraphAxisControl).OnTicksChanged())); + + /// <summary> + /// Gets or sets the string format which is used to format the ticks value. + /// </summary> + public String StringFormat + { + get { return (String)GetValue(StringFormatProperty); } + set { SetValue(StringFormatProperty, value); } + } + public static readonly DependencyProperty StringFormatProperty = + DependencyProperty.Register("StringFormat", typeof(String), typeof(WpfGraphAxisControl), new PropertyMetadata(null)); + + /// <summary> + /// When overridden in a derived class, is invoked whenever application code or internal processes call <see cref="M:System.Windows.FrameworkElement.ApplyTemplate" />. + /// </summary> + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + _items_control = GetTemplateChild("PART_ItemsControl") as ItemsControl; + OnTicksChanged(); + } + + /// <summary> + /// Called when the <see cref="Ticks"/> property has changed. + /// </summary> + protected virtual void OnTicksChanged() + { + Items = new ObservableCollection<WpfGraphAxisTickData>(Enumerable.Range(0, Ticks).Select(x => new WpfGraphAxisTickData())); + + if (Controller != null) + { + Controller.RequestVirtualRangeChange(); + } + } + + protected override void OnControllerChanged(IGraphController oldController, IGraphController newController) + { + base.OnControllerChanged(oldController, newController); + + if (newController != null) + { + newController.RequestVirtualRangeChange(); + } + } + + /// <summary> + /// Handles the <see cref="IGraphController.VirtualRangeChanged"/> event. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The event arguments.</param> + protected override void OnVirtualRangeChanged(object sender, RangeChangedEventArgs e) + { + InvokeUI(() => + { + if (Orientation == Orientation.Vertical) + { + if (Items != null) + { + var steps = e.MinimumY.CreateRange(e.MinimumY, e.MaximumY, Ticks).Reverse().ToList(); + + for (int i = 0; i < steps.Count; i++) + { + var tick_data = Items[i]; + tick_data.Data = steps[i]; + tick_data.DisplayText = tick_data.Data.ToString(StringFormat); + tick_data.IsFirst = i == 0; + tick_data.IsLast = i == steps.Count - 1; + tick_data.IsEven = i % 2 == 0; + } + } + } + else + { + if (Items != null) + { + var steps = e.MinimumX.CreateRange(e.MinimumX, e.MaximumX, Ticks).ToList(); + + for (int i = 0; i < steps.Count; i++) + { + var tick_data = Items[i]; + tick_data.Data = steps[i]; + tick_data.DisplayText = tick_data.Data.ToString(StringFormat); + tick_data.IsFirst = i == 0; + tick_data.IsLast = i == steps.Count - 1; + tick_data.IsEven = i % 2 == 0; + } + } + } + }); + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphAxisPanel.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphAxisPanel.cs new file mode 100644 index 000000000..f10b583f4 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphAxisPanel.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; + +namespace RealTimeGraphX.WPF +{ + /// <summary> + /// Represents a panel that will align its children in an axis labels like arrangement. + /// </summary> + /// <seealso cref="System.Windows.Controls.Grid" /> + public class WpfGraphAxisPanel : Grid + { + /// <summary> + /// Gets or sets the panel orientation. + /// </summary> + public Orientation Orientation + { + get { return (Orientation)GetValue(OrientationProperty); } + set { SetValue(OrientationProperty, value); } + } + public static readonly DependencyProperty OrientationProperty = + DependencyProperty.Register("Orientation", typeof(Orientation), typeof(WpfGraphAxisPanel), new PropertyMetadata(Orientation.Vertical)); + + /// <summary> + /// Initializes a new instance of the <see cref="WpfGraphAxisPanel"/> class. + /// </summary> + public WpfGraphAxisPanel() + { + Loaded += VerticalAxisPanel_Loaded; + } + + /// <summary> + /// Handles the Loaded event of the VerticalAxisGrid control. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="RoutedEventArgs"/> instance containing the event data.</param> + private void VerticalAxisPanel_Loaded(object sender, RoutedEventArgs e) + { + UpdatePanel(); + } + + /// <summary> + /// Updates the panel. + /// </summary> + private void UpdatePanel() + { + RowDefinitions.Clear(); + ColumnDefinitions.Clear(); + + + if (Orientation == Orientation.Vertical) + { + for (int i = 0; i < InternalChildren.Count; i++) + { + FrameworkElement element = InternalChildren[i] as FrameworkElement; + + if (i < InternalChildren.Count - 1) + { + RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) }); + Grid.SetRow(element, i); + element.VerticalAlignment = VerticalAlignment.Top; + + element.SizeChanged += (_, __) => + { + element.Margin = new Thickness(0, (element.ActualHeight / 2) * -1, 0, 0); + }; + } + else + { + Grid.SetRow(element, i); + element.VerticalAlignment = VerticalAlignment.Bottom; + + element.SizeChanged += (_, __) => + { + element.Margin = new Thickness(0, 0, 0, (element.ActualHeight / 2) * -1); + }; + } + } + } + else + { + for (int i = 0; i < InternalChildren.Count; i++) + { + FrameworkElement element = InternalChildren[i] as FrameworkElement; + + if (i < InternalChildren.Count - 1) + { + ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) }); + Grid.SetColumn(element, i); + element.HorizontalAlignment = HorizontalAlignment.Left; + + element.SizeChanged += (_, __) => + { + element.Margin = new Thickness((element.ActualWidth / 2) * -1, 0, 0, 0); + }; + } + else + { + Grid.SetColumn(element, i); + element.HorizontalAlignment = HorizontalAlignment.Right; + + element.SizeChanged += (_, __) => + { + element.Margin = new Thickness(0, 0, (element.ActualWidth / 2) * -1, 0); + }; + } + } + } + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphAxisTickData.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphAxisTickData.cs new file mode 100644 index 000000000..08c0ae2fa --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphAxisTickData.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; + +namespace RealTimeGraphX.WPF +{ + /// <summary> + /// Represents a graph axis data point tick value wrapper. + /// </summary> + public class WpfGraphAxisTickData : DependencyObject + { + /// <summary> + /// Gets or sets a value indicating whether this tick is the first tick. + /// </summary> + public bool IsFirst + { + get { return (bool)GetValue(IsFirstProperty); } + set { SetValue(IsFirstProperty, value); } + } + public static readonly DependencyProperty IsFirstProperty = + DependencyProperty.Register("IsFirst", typeof(bool), typeof(WpfGraphAxisTickData), new PropertyMetadata(false)); + + /// <summary> + /// Gets or sets a value indicating whether this tick is the last tick. + /// </summary> + public bool IsLast + { + get { return (bool)GetValue(IsLastProperty); } + set { SetValue(IsLastProperty, value); } + } + public static readonly DependencyProperty IsLastProperty = + DependencyProperty.Register("IsLast", typeof(bool), typeof(WpfGraphAxisTickData), new PropertyMetadata(false)); + + /// <summary> + /// Gets or sets a value indicating whether this tick is not the first or last. + /// </summary> + public bool IsCenter + { + get { return !IsFirst && !IsLast; } + } + + /// <summary> + /// Gets or sets a value indicating whether this tick index is even. + /// </summary> + public bool IsEven + { + get { return (bool)GetValue(IsEvenProperty); } + set { SetValue(IsEvenProperty, value); } + } + public static readonly DependencyProperty IsEvenProperty = + DependencyProperty.Register("IsEven", typeof(bool), typeof(WpfGraphAxisTickData), new PropertyMetadata(false)); + + /// <summary> + /// Gets a value indicating whether this tick index is odd. + /// </summary> + public bool IsOdd + { + get { return !IsEven; } + } + + /// <summary> + /// Gets or sets the actual graph data point. + /// </summary> + public IGraphDataPoint Data + { + get { return (IGraphDataPoint)GetValue(DataProperty); } + set { SetValue(DataProperty, value); } + } + public static readonly DependencyProperty DataProperty = + DependencyProperty.Register("Data", typeof(IGraphDataPoint), typeof(WpfGraphAxisTickData), new PropertyMetadata(null)); + + /// <summary> + /// Gets or sets the display text. + /// </summary> + public String DisplayText + { + get { return (String)GetValue(DisplayTextProperty); } + set { SetValue(DisplayTextProperty, value); } + } + public static readonly DependencyProperty DisplayTextProperty = + DependencyProperty.Register("DisplayText", typeof(String), typeof(WpfGraphAxisTickData), new PropertyMetadata(null)); + + /// <summary> + /// Gets the <see cref="Data">Data Point</see> value. + /// </summary> + public object Value + { + get + { + return Data != null ? Data.GetValue() : null; + } + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphComponentBase.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphComponentBase.cs new file mode 100644 index 000000000..e48c18678 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphComponentBase.cs @@ -0,0 +1,66 @@ +using RealTimeGraphX.EventArguments; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; + +namespace RealTimeGraphX.WPF +{ + /// <summary> + /// Represents a graph component base class. + /// </summary> + /// <seealso cref="System.Windows.Controls.Control" /> + public abstract class WpfGraphComponentBase : Control + { + /// <summary> + /// Gets or sets the graph controller. + /// </summary> + public IGraphController Controller + { + get { return (IGraphController)GetValue(ControllerProperty); } + set { SetValue(ControllerProperty, value); } + } + public static readonly DependencyProperty ControllerProperty = + DependencyProperty.Register("Controller", typeof(IGraphController), typeof(WpfGraphComponentBase), new PropertyMetadata(null, (d, e) => (d as WpfGraphComponentBase).OnControllerChanged(e.OldValue as IGraphController, e.NewValue as IGraphController))); + + /// <summary> + /// Called when the controller has changed. + /// </summary> + /// <param name="oldController">The old controller.</param> + /// <param name="newController">The new controller.</param> + protected virtual void OnControllerChanged(IGraphController oldController, IGraphController newController) + { + if (oldController != null) + { + oldController.VirtualRangeChanged -= OnVirtualRangeChanged; + } + + if (newController != null) + { + newController.VirtualRangeChanged += OnVirtualRangeChanged; + } + } + + /// <summary> + /// Handles the <see cref="IGraphController.VirtualRangeChanged"/> event. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The event arguments.</param> + protected virtual void OnVirtualRangeChanged(object sender, RangeChangedEventArgs e) + { + //Optional + } + + /// <summary> + /// Invokes the specified method on the component dispatcher. + /// </summary> + /// <param name="action">The action.</param> + protected void InvokeUI(Action action) + { + Dispatcher.BeginInvoke(action); + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphController.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphController.cs new file mode 100644 index 000000000..6067a7e50 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphController.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media; + +namespace RealTimeGraphX.WPF +{ + /// <summary> + /// Represents a WPF <see cref="GraphController{TDataSeries, TXDataPoint, TYDataPoint}">graph controller</see>. + /// </summary> + /// <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.GraphController{RealTimeGraphX.WPF.WpfGraphDataSeries, TXDataPoint, TYDataPoint}" /> + public class WpfGraphController<TXDataPoint, TYDataPoint> : GraphController<WpfGraphDataSeries, TXDataPoint, TYDataPoint> + where TXDataPoint : GraphDataPoint + where TYDataPoint : GraphDataPoint + { + + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphDataSeries.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphDataSeries.cs new file mode 100644 index 000000000..15a99ab54 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphDataSeries.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media; + +namespace RealTimeGraphX.WPF +{ + /// <summary> + /// Represents a WPF <see cref="IGraphDataSeries">data series</see>. + /// </summary> + /// <seealso cref="RealTimeGraphX.GraphObject" /> + /// <seealso cref="RealTimeGraphX.IGraphDataSeries" /> + public class WpfGraphDataSeries : GraphObject, IGraphDataSeries + { + #region Internal Properties + + /// <summary> + /// Gets the GDI stroke color. + /// </summary> + internal System.Drawing.Color GdiStroke { get; private set; } + + /// <summary> + /// Gets the GDI fill brush. + /// </summary> + internal System.Drawing.Brush GdiFill { get; private set; } + + /// <summary> + /// Gets or sets the GDI pen. + /// </summary> + internal System.Drawing.Pen GdiPen { get; set; } + + #endregion + + private String _name; + /// <summary> + /// Gets or sets the series name. + /// </summary> + public String Name + { + get { return _name; } + set { _name = value; RaisePropertyChangedAuto(); } + } + + private float _strokeThickness; + /// <summary> + /// Gets or sets the stroke thickness. + /// </summary> + public float StrokeThickness + { + get + { + return _strokeThickness; + } + set + { + _strokeThickness = value; + GdiPen = new System.Drawing.Pen(GdiStroke, _strokeThickness); + RaisePropertyChangedAuto(); + } + } + + private bool _isVisible; + /// <summary> + /// Gets or sets a value indicating whether this series should be visible. + /// </summary> + public bool IsVisible + { + get { return _isVisible; } + set { _isVisible = value; RaisePropertyChangedAuto(); } + } + + private Color _stroke; + /// <summary> + /// Gets or sets the series stroke color. + /// </summary> + public Color Stroke + { + get { return _stroke; } + set + { + _stroke = value; + RaisePropertyChangedAuto(); + + if (_stroke != null) + { + GdiStroke = _stroke.ToGdiColor(); + GdiPen = new System.Drawing.Pen(GdiStroke, StrokeThickness); + } + else + { + GdiStroke = System.Drawing.Color.Transparent; + } + } + } + + private Brush _fill; + /// <summary> + /// Gets or sets the series fill brush. + /// </summary> + public Brush Fill + { + get { return _fill; } + set + { + _fill = value; + RaisePropertyChangedAuto(); + + if (_fill != null) + { + GdiFill = _fill.ToGdiBrush(); + } + else + { + GdiFill = null; + } + } + } + + /// <summary> + /// Initializes a new instance of the <see cref="WpfGraphDataSeries"/> class. + /// </summary> + public WpfGraphDataSeries() + { + StrokeThickness = 1; + IsVisible = true; + Stroke = Colors.DodgerBlue; + } + + /// <summary> + /// Gets or sets a value indicating whether to fill the series. + /// </summary> + public bool UseFill + { + get { return Fill != null; } + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphGridLines.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphGridLines.cs new file mode 100644 index 000000000..3eb25f3d8 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphGridLines.cs @@ -0,0 +1,92 @@ +using System.Collections.Generic; +using System.Linq; +using System.Windows; + +namespace RealTimeGraphX.WPF +{ + /// <summary> + /// Represents a graph grid lines component. + /// </summary> + /// <seealso cref="RealTimeGraphX.GraphSurfaceComponentBase" /> + public class WpfGraphGridLines : WpfGraphComponentBase + { + /// <summary> + /// Gets or sets the number of grid rows. + /// </summary> + public int Rows + { + get { return (int)GetValue(RowsProperty); } + set { SetValue(RowsProperty, value); } + } + public static readonly DependencyProperty RowsProperty = + DependencyProperty.Register("Rows", typeof(int), typeof(WpfGraphGridLines), new PropertyMetadata(8, (d, e) => (d as WpfGraphGridLines).UpdateGridLines())); + + /// <summary> + /// Gets or sets the number of grid columns. + /// </summary> + public int Columns + { + get { return (int)GetValue(ColumnsProperty); } + set { SetValue(ColumnsProperty, value); } + } + public static readonly DependencyProperty ColumnsProperty = + DependencyProperty.Register("Columns", typeof(int), typeof(WpfGraphGridLines), new PropertyMetadata(8, (d, e) => (d as WpfGraphGridLines).UpdateGridLines())); + + /// <summary> + /// Gets or sets the vertical items. + /// </summary> + internal IEnumerable<int> VerticalItems + { + get { return (IEnumerable<int>)GetValue(VerticalItemsProperty); } + set { SetValue(VerticalItemsProperty, value); } + } + internal static readonly DependencyProperty VerticalItemsProperty = + DependencyProperty.Register("VerticalItems", typeof(IEnumerable<int>), typeof(WpfGraphGridLines), new PropertyMetadata(null)); + + /// <summary> + /// Gets or sets the horizontal items. + /// </summary> + internal IEnumerable<int> HorizontalItems + { + get { return (IEnumerable<int>)GetValue(HorizontalItemsProperty); } + set { SetValue(HorizontalItemsProperty, value); } + } + internal static readonly DependencyProperty HorizontalItemsProperty = + DependencyProperty.Register("HorizontalItems", typeof(IEnumerable<int>), typeof(WpfGraphGridLines), new PropertyMetadata(null)); + + /// <summary> + /// Initializes the <see cref="WpfGraphGridLines"/> class. + /// </summary> + static WpfGraphGridLines() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(WpfGraphGridLines), new FrameworkPropertyMetadata(typeof(WpfGraphGridLines))); + } + + /// <summary> + /// Initializes a new instance of the <see cref="WpfGraphGridLines"/> class. + /// </summary> + public WpfGraphGridLines() + { + Loaded += GridLines_Loaded; + } + + /// <summary> + /// Handles the Loaded event of the GridLines control. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="RoutedEventArgs"/> instance containing the event data.</param> + private void GridLines_Loaded(object sender, RoutedEventArgs e) + { + UpdateGridLines(); + } + + /// <summary> + /// Updates the grid lines. + /// </summary> + private void UpdateGridLines() + { + VerticalItems = Enumerable.Range(0, Rows).ToList(); + HorizontalItems = Enumerable.Range(0, Columns).ToList(); + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphSurface.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphSurface.cs new file mode 100644 index 000000000..ebcff3472 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphSurface.cs @@ -0,0 +1,380 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using RealTimeGraphX.EventArguments; + +namespace RealTimeGraphX.WPF +{ + /// <summary> + /// Represents a WPF <see cref="IGraphSurface{TDataSeries}">graph surface</see>. + /// </summary> + /// <seealso cref="System.Windows.Controls.Control" /> + /// <seealso cref="RealTimeGraphX.IGraphSurface{RealTimeGraphX.WPF.WpfGraphDataSeries}" /> + public class WpfGraphSurface : Control, IGraphSurface<WpfGraphDataSeries> + { + private WriteableBitmap _writeable_bitmap; + private System.Drawing.Bitmap _gdi_bitmap; + private System.Drawing.Graphics _g; + + private bool _size_changed; + private System.Drawing.SizeF _size; + private System.Drawing.RectangleF _zoom_rect; + private Rectangle _selection_rectangle; + private Canvas _selection_canvas; + private bool _is_selection_mouse_down_zoom; + private bool _is_selection_mouse_down_pan; + private Point _selection_start_point; + private bool _is_scaled; + private Point _current_mouse_position; + private Point _last_mouse_position; + private Grid _grid; + + #region Properties + + /// <summary> + /// Gets or sets current graph rendered image. + /// </summary> + public BitmapSource Image + { + get { return (BitmapSource)GetValue(ImageProperty); } + private set { SetValue(ImageProperty, value); } + } + public static readonly DependencyProperty ImageProperty = + DependencyProperty.Register("Image", typeof(BitmapSource), typeof(WpfGraphSurface), new PropertyMetadata(null)); + + /// <summary> + /// Gets or sets the graph controller. + /// </summary> + public IGraphController<WpfGraphDataSeries> Controller + { + get { return (IGraphController<WpfGraphDataSeries>)GetValue(ControllerProperty); } + set { SetValue(ControllerProperty, value); } + } + public static readonly DependencyProperty ControllerProperty = + DependencyProperty.Register("Controller", typeof(IGraphController<WpfGraphDataSeries>), typeof(WpfGraphSurface), new PropertyMetadata(null, (d, e) => (d as WpfGraphSurface).OnControllerChanged(e.OldValue as IGraphController<WpfGraphDataSeries>, e.NewValue as IGraphController<WpfGraphDataSeries>))); + + #endregion + + #region Constructors + + /// <summary> + /// Initializes the <see cref="WpfGraphSurface"/> class. + /// </summary> + static WpfGraphSurface() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(WpfGraphSurface), new FrameworkPropertyMetadata(typeof(WpfGraphSurface))); + } + + /// <summary> + /// Initializes a new instance of the <see cref="WpfGraphSurface"/> class. + /// </summary> + public WpfGraphSurface() + { + SizeChanged += WpfGraphSurface_SizeChanged; + } + + #endregion + + #region Apply Template + + /// <summary> + /// When overridden in a derived class, is invoked whenever application code or internal processes call <see cref="M:System.Windows.FrameworkElement.ApplyTemplate" />. + /// </summary> + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + _selection_rectangle = GetTemplateChild("PART_SelectionRectangle") as Rectangle; + _selection_canvas = GetTemplateChild("PART_SelectionCanvas") as Canvas; + _grid = GetTemplateChild("PART_Grid") as Grid; + + _selection_canvas.MouseDown += OnSelectionCanvasMouseDown; + _selection_canvas.MouseUp += OnSelectionCanvasMouseUp; + _selection_canvas.MouseMove += OnSelectionCanvasMouseMove; + } + + #endregion + + #region Protected Methods + + /// <summary> + /// Called when the mouse moves over the zoom/pan selection canvas. + /// </summary> + /// <param name="sender">The sender.</param> + /// <param name="e">The <see cref="MouseEventArgs"/> instance containing the event data.</param> + protected virtual void OnSelectionCanvasMouseMove(object sender, MouseEventArgs e) + { + _current_mouse_position = e.GetPosition(_selection_canvas); + + if (_is_selection_mouse_down_zoom && Keyboard.IsKeyDown(Key.LeftCtrl)) + { + Canvas.SetLeft(_selection_rectangle, _selection_start_point.X); + Canvas.SetTop(_selection_rectangle, _selection_start_point.Y); + + Point _selection_current_point = e.GetPosition(_selection_canvas); + + if (_selection_current_point.X - _selection_start_point.X > 1) + { + _selection_rectangle.Width = _selection_current_point.X - _selection_start_point.X; + } + + if (_selection_current_point.Y - _selection_start_point.Y > 1) + { + _selection_rectangle.Height = _selection_current_point.Y - _selection_start_point.Y; + } + + if (_selection_current_point.X < _selection_start_point.X) + { + Canvas.SetLeft(_selection_rectangle, _selection_current_point.X); + _selection_rectangle.Width = _selection_start_point.X - _selection_current_point.X; + } + + if (_selection_current_point.Y < _selection_start_point.Y) + { + Canvas.SetTop(_selection_rectangle, _selection_current_point.Y); + _selection_rectangle.Height = _selection_start_point.Y - _selection_current_point.Y; + } + } + else if (_is_selection_mouse_down_pan && _is_scaled) + { + Point _selection_current_point = e.GetPosition(_selection_canvas); + + double delta_x = _current_mouse_position.X - _last_mouse_position.X; + double delta_y = _current_mouse_position.Y - _last_mouse_position.Y; + + double x = _zoom_rect.Left - delta_x; + double y = _zoom_rect.Top - delta_y; + + if (x < 0) + { + x = 0; + } + + if (y < 0) + { + y = 0; + } + + if (x + _zoom_rect.Width > _size.Width) + { + x = x - (x + _zoom_rect.Width - _size.Width); + } + + if (y + _zoom_rect.Height > _size.Height) + { + y = y - (y + _zoom_rect.Height - _size.Height); + } + + _zoom_rect = new System.Drawing.RectangleF((float)x, (float)y, _zoom_rect.Width, _zoom_rect.Height); + } + + _last_mouse_position = _current_mouse_position; + } + + /// <summary> + /// Called when the mouse released from the zoom/pan selection canvas. + /// </summary> + /// <param name="sender">The sender.</param> + /// <param name="e">The <see cref="MouseButtonEventArgs"/> instance containing the event data.</param> + protected virtual void OnSelectionCanvasMouseUp(object sender, MouseButtonEventArgs e) + { + _selection_canvas.ReleaseMouseCapture(); + + if (_is_selection_mouse_down_pan) + { + _is_selection_mouse_down_pan = false; + } + else if (_is_selection_mouse_down_zoom) + { + _is_selection_mouse_down_zoom = false; + + _zoom_rect = new System.Drawing.RectangleF((float)Canvas.GetLeft(_selection_rectangle), (float)Canvas.GetTop(_selection_rectangle), (float)_selection_rectangle.Width, (float)_selection_rectangle.Height); + _selection_rectangle.Visibility = Visibility.Hidden; + _is_scaled = true; + } + } + + /// <summary> + /// Called when the mouse pressed on the zoom/pan selection canvas. + /// </summary> + /// <param name="sender">The sender.</param> + /// <param name="e">The <see cref="MouseButtonEventArgs"/> instance containing the event data.</param> + protected virtual void OnSelectionCanvasMouseDown(object sender, MouseButtonEventArgs e) + { + Mouse.Capture(_selection_canvas); + + _selection_start_point = e.GetPosition(_selection_canvas); + _current_mouse_position = _selection_start_point; + _last_mouse_position = _current_mouse_position; + + if (e.ClickCount == 2) + { + _zoom_rect = new System.Drawing.RectangleF(); + _is_scaled = false; + } + else if (Keyboard.IsKeyDown(Key.LeftCtrl)) + { + _selection_rectangle.Width = 0; + _selection_rectangle.Height = 0; + _is_selection_mouse_down_zoom = true; + _is_selection_mouse_down_pan = false; + _selection_rectangle.Visibility = Visibility.Visible; + } + else + { + _is_selection_mouse_down_pan = true; + } + } + + /// <summary> + /// Called when the <see cref="Controller"/> property has changed. + /// </summary> + /// <param name="oldController">The old controller.</param> + /// <param name="newController">The new controller.</param> + protected virtual void OnControllerChanged(IGraphController<WpfGraphDataSeries> oldController, IGraphController<WpfGraphDataSeries> newController) + { + if (oldController != null) + { + oldController.Surface = null; + } + + if (newController != null) + { + newController.Surface = this; + } + } + + #endregion + + #region IGraphSurface + + /// <summary> + /// Called before drawing has started. + /// </summary> + public void BeginDraw() + { + if (_size_changed) + { + _writeable_bitmap = new WriteableBitmap((int)Math.Max(_size.Width, 1), (int)Math.Max(_size.Height, 1), 96.0, 96.0, PixelFormats.Pbgra32, null); + + _gdi_bitmap = new System.Drawing.Bitmap(_writeable_bitmap.PixelWidth, _writeable_bitmap.PixelHeight, + _writeable_bitmap.BackBufferStride, + System.Drawing.Imaging.PixelFormat.Format32bppPArgb, + _writeable_bitmap.BackBuffer); + + _size_changed = false; + } + + _writeable_bitmap.Lock(); + + _g = System.Drawing.Graphics.FromImage(_gdi_bitmap); + _g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + + _g.Clear(System.Drawing.Color.Transparent); + } + + /// <summary> + /// Applies transformation on the current pass. + /// </summary> + /// <param name="transform">The transform.</param> + public void SetTransform(GraphTransform transform) + { + _g.TranslateTransform((float)transform.TranslateX, (float)transform.TranslateY); + _g.ScaleTransform((float)transform.ScaleX, (float)transform.ScaleY); + } + + /// <summary> + /// Draws the stroke of the specified data series points. + /// </summary> + /// <param name="dataSeries">The data series.</param> + /// <param name="points">The points.</param> + public void DrawSeries(WpfGraphDataSeries dataSeries, IEnumerable<System.Drawing.PointF> points) + { + _g.DrawCurve(dataSeries.GdiPen, points.ToArray()); + } + + /// <summary> + /// Fills the specified data series points. + /// </summary> + /// <param name="dataSeries">The data series.</param> + /// <param name="points">The points.</param> + public void FillSeries(WpfGraphDataSeries dataSeries, IEnumerable<System.Drawing.PointF> points) + { + var brush = dataSeries.GdiFill; + + if (dataSeries.GdiFill is System.Drawing.Drawing2D.LinearGradientBrush) + { + var gradient = dataSeries.GdiFill as System.Drawing.Drawing2D.LinearGradientBrush; + gradient.ResetTransform(); + gradient.ScaleTransform((_size.Width / gradient.Rectangle.Width), (_size.Height / gradient.Rectangle.Height)); + } + + _g.FillPolygon(dataSeries.GdiFill, points.ToArray()); + } + + /// <summary> + /// Called when drawing has completed. + /// </summary> + public void EndDraw() + { + _writeable_bitmap.AddDirtyRect(new Int32Rect(0, 0, _writeable_bitmap.PixelWidth, _writeable_bitmap.PixelHeight)); + _writeable_bitmap.Unlock(); + + var cloned = _writeable_bitmap.Clone(); + cloned.Freeze(); + + Dispatcher.BeginInvoke(new Action((() => + { + Image = cloned; + }))); + + _g.Dispose(); + } + + /// <summary> + /// Returns the actual size of the surface. + /// </summary> + /// <returns></returns> + public System.Drawing.SizeF GetSize() + { + return _size; + } + + /// <summary> + /// Returns the current bounds of the zooming rectangle. + /// </summary> + /// <returns></returns> + public System.Drawing.RectangleF GetZoomRect() + { + return _zoom_rect; + } + + #endregion + + #region Event Handlers + + /// <summary> + /// Handles the WPF Graph Surface Size Changed event. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The event arguments.</param> + private void WpfGraphSurface_SizeChanged(object sender, SizeChangedEventArgs e) + { + _size = new System.Drawing.SizeF((float)e.NewSize.Width, (float)e.NewSize.Height); + _size_changed = true; + } + + #endregion + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/DataPoints/DoubleDataPoint.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/DataPoints/DoubleDataPoint.cs new file mode 100644 index 000000000..b4740fcfa --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/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/RealTimeGraphX-master/RealTimeGraphX/DataPoints/FloatDataPoint.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/DataPoints/FloatDataPoint.cs new file mode 100644 index 000000000..6e225a679 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/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/RealTimeGraphX-master/RealTimeGraphX/DataPoints/Int32DataPoint.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/DataPoints/Int32DataPoint.cs new file mode 100644 index 000000000..4bccdcb74 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/DataPoints/Int32DataPoint.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="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; + + 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) + { + int minimum = (int)min.GetValue(); + int maximum = (int)max.GetValue(); + + return Enumerable.Range(0, count). + Select(i => minimum + (maximum - minimum) * ((int)i / (count - 1))). + Select(x => new Int32DataPoint(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/RealTimeGraphX-master/RealTimeGraphX/DataPoints/TimeSpanDataPoint.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/DataPoints/TimeSpanDataPoint.cs new file mode 100644 index 000000000..737c93c81 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/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/RealTimeGraphX-master/RealTimeGraphX/EventArguments/RangeChangedEventArgs.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/EventArguments/RangeChangedEventArgs.cs new file mode 100644 index 000000000..15d5bb7ba --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/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/RealTimeGraphX-master/RealTimeGraphX/GraphCommand.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/GraphCommand.cs new file mode 100644 index 000000000..e16ecd675 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/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/RealTimeGraphX-master/RealTimeGraphX/GraphController.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/GraphController.cs new file mode 100644 index 000000000..9aabc649a --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/GraphController.cs @@ -0,0 +1,543 @@ +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; + +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; } + } + + #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 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 + { + _surface = value; + RequestVirtualRangeChange(); + } + } + + 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.Start(); + } + + #endregion + + #region Render Thread + + /// <summary> + /// The rendering thread method. + /// </summary> + private void RenderThreadMethod() + { + while (true) + { + if (!IsPaused) + { + var pending_list = _pending_series_collection.BlockDequeue(); + + foreach (var pending_series in pending_list) + { + if (pending_series.IsClearSeries) + { + _pending_series_collection = new GraphDataQueue<List<PendingSeries>>(); + _to_render.Clear(); + break; + } + + 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 (DateTime.Now > _last_render_time.AddMilliseconds(RefreshRate.TotalMilliseconds) && _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; + + min_x = _to_render.First().Value.XX.First(); + max_x = _to_render.First().Value.XX.Last(); + + 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) + { + 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); + } + } + else + { + Thread.Sleep(RefreshRate); + } + } + } + + #endregion + + #region Protected Methods + + /// <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 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/RealTimeGraphX-master/RealTimeGraphX/GraphDataPoint.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/GraphDataPoint.cs new file mode 100644 index 000000000..e069d8950 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/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/RealTimeGraphX-master/RealTimeGraphX/GraphDataPointHelper.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/GraphDataPointHelper.cs new file mode 100644 index 000000000..b28d7a501 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/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/RealTimeGraphX-master/RealTimeGraphX/GraphDataPointTypeConverter.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/GraphDataPointTypeConverter.cs new file mode 100644 index 000000000..edbd78cf1 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/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/RealTimeGraphX-master/RealTimeGraphX/GraphDataQueue.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/GraphDataQueue.cs new file mode 100644 index 000000000..cb28231ab --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/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/RealTimeGraphX-master/RealTimeGraphX/GraphObject.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/GraphObject.cs new file mode 100644 index 000000000..d37110c5c --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/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/RealTimeGraphX-master/RealTimeGraphX/GraphRange.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/GraphRange.cs new file mode 100644 index 000000000..521f9f0b6 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/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/RealTimeGraphX-master/RealTimeGraphX/GraphRenderer.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/GraphRenderer.cs new file mode 100644 index 000000000..c42fcb4ab --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/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/RealTimeGraphX-master/RealTimeGraphX/GraphTransform.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/GraphTransform.cs new file mode 100644 index 000000000..efcf4b052 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/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/RealTimeGraphX-master/RealTimeGraphX/IGraphComponent.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/IGraphComponent.cs new file mode 100644 index 000000000..dd8f4ee1d --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/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/RealTimeGraphX-master/RealTimeGraphX/IGraphController.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/IGraphController.cs new file mode 100644 index 000000000..0dbc49ccb --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/IGraphController.cs @@ -0,0 +1,185 @@ +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 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/RealTimeGraphX-master/RealTimeGraphX/IGraphDataPoint.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/IGraphDataPoint.cs new file mode 100644 index 000000000..9ecae4a8a --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/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/RealTimeGraphX-master/RealTimeGraphX/IGraphDataSeries.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/IGraphDataSeries.cs new file mode 100644 index 000000000..dd05da92b --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/IGraphDataSeries.cs @@ -0,0 +1,31 @@ +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; } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/IGraphRenderer.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/IGraphRenderer.cs new file mode 100644 index 000000000..fdd3b17e8 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/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/RealTimeGraphX-master/RealTimeGraphX/IGraphSurface.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/IGraphSurface.cs new file mode 100644 index 000000000..310bc7c3d --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/IGraphSurface.cs @@ -0,0 +1,64 @@ +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> + /// 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/RealTimeGraphX-master/RealTimeGraphX/RealTimeGraphX.csproj b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/RealTimeGraphX.csproj new file mode 100644 index 000000000..9f5c4f4ab --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/RealTimeGraphX.csproj @@ -0,0 +1,7 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <TargetFramework>netstandard2.0</TargetFramework> + </PropertyGroup> + +</Project> diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/Renderers/ScrollingLineRenderer.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/Renderers/ScrollingLineRenderer.cs new file mode 100644 index 000000000..82e80aa0f --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/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, points); + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX.WPF/RealTimeGraphX.WPF.csproj b/Software/Visual_Studio/SideChains/RealTimeGraphX.WPF/RealTimeGraphX.WPF.csproj index da7d14ce6..fa5852efa 100644 --- a/Software/Visual_Studio/SideChains/RealTimeGraphX.WPF/RealTimeGraphX.WPF.csproj +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX.WPF/RealTimeGraphX.WPF.csproj @@ -91,12 +91,6 @@ <LastGenOutput>Settings.Designer.cs</LastGenOutput> </None> </ItemGroup> - <ItemGroup> - <ProjectReference Include="..\RealTimeGraphX\RealTimeGraphX.csproj"> - <Project>{518eb7c5-9e1d-4c23-a9c1-02ee73c25406}</Project> - <Name>RealTimeGraphX</Name> - </ProjectReference> - </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <ProjectExtensions> <VisualStudio> |
