aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/SideChains/RealTimeGraphEx/Components
diff options
context:
space:
mode:
authorRoy Ben-Shabat <Roy@Twine-s.com>2018-01-16 12:17:10 +0200
committerRoy Ben-Shabat <Roy@Twine-s.com>2018-01-16 12:17:10 +0200
commit0fda2ba3ff49bdc1ffc6833f658e2164af187008 (patch)
tree6f3a24d0671ebda50debb8511ab40e0bda0a0df0 /Software/Visual_Studio/SideChains/RealTimeGraphEx/Components
parent28103646681686bf1b58275d5dbccb92d2b26f9f (diff)
downloadTango-0fda2ba3ff49bdc1ffc6833f658e2164af187008.tar.gz
Tango-0fda2ba3ff49bdc1ffc6833f658e2164af187008.zip
Embedded RealTimeGraphEx library to solution.
Added graphs to technician view. Implemented simple sensors data test using Machine Emulator.
Diffstat (limited to 'Software/Visual_Studio/SideChains/RealTimeGraphEx/Components')
-rw-r--r--Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/ComponentBase.cs101
-rw-r--r--Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/ComponentLocationEnum.cs17
-rw-r--r--Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/GridLines.cs121
-rw-r--r--Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/MouseValueToolTip.cs73
-rw-r--r--Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/YAxisLegends.cs61
-rw-r--r--Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/YAxisScroll.cs205
-rw-r--r--Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/YAxisTicks.cs192
-rw-r--r--Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/YAxisWave.cs107
8 files changed, 877 insertions, 0 deletions
diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/ComponentBase.cs b/Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/ComponentBase.cs
new file mode 100644
index 000000000..3e2294068
--- /dev/null
+++ b/Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/ComponentBase.cs
@@ -0,0 +1,101 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace RealTimeGraphEx.Components
+{
+ public abstract class ComponentBase : UserControl
+ {
+ public ComponentLocationEnum Location
+ {
+ get { return (ComponentLocationEnum)GetValue(LocationProperty); }
+ set { SetValue(LocationProperty, value); }
+ }
+ public static readonly DependencyProperty LocationProperty =
+ DependencyProperty.Register("Location", typeof(ComponentLocationEnum), typeof(ComponentBase), new PropertyMetadata(ComponentLocationEnum.None));
+
+ public RealTimeGraphExBase Graph
+ {
+ get { return (RealTimeGraphExBase)GetValue(GraphProperty); }
+ set { SetValue(GraphProperty, value); }
+ }
+ public static readonly DependencyProperty GraphProperty =
+ DependencyProperty.Register("Graph", typeof(RealTimeGraphExBase), typeof(ComponentBase), new PropertyMetadata(null));
+
+ public ComponentBase()
+ {
+ this.Loaded += ComponentBase_Loaded;
+ }
+
+ private void ComponentBase_Loaded(object sender, RoutedEventArgs e)
+ {
+ if (Graph != null)
+ {
+ Graph.ZoomComplete += OnGraphZoomComplete;
+ Graph.PanningComplete += OnGraphPanningComplete;
+ Render(Graph);
+ }
+ }
+
+ public abstract void Render(RealTimeGraphExBase graph, bool animate = false);
+
+ public void RemoveFromParent()
+ {
+ var parent = this.Parent;
+ var child = this;
+
+ var panel = parent as Panel;
+ if (panel != null)
+ {
+ panel.Children.Remove(child);
+ return;
+ }
+
+ var decorator = parent as Decorator;
+ if (decorator != null)
+ {
+ if (decorator.Child == child)
+ {
+ decorator.Child = null;
+ }
+ return;
+ }
+
+ var contentPresenter = parent as ContentPresenter;
+ if (contentPresenter != null)
+ {
+ if (contentPresenter.Content == child)
+ {
+ contentPresenter.Content = null;
+ }
+ return;
+ }
+
+ var contentControl = parent as ContentControl;
+ if (contentControl != null)
+ {
+ if (contentControl.Content == child)
+ {
+ contentControl.Content = null;
+ }
+ return;
+ }
+
+ // maybe more
+ }
+
+ protected virtual void OnGraphZoomComplete(Point transformOrigin, double scaleX, double scaleY)
+ {
+
+ }
+
+ protected virtual void OnGraphPanningComplete(Point translate)
+ {
+
+ }
+ }
+}
diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/ComponentLocationEnum.cs b/Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/ComponentLocationEnum.cs
new file mode 100644
index 000000000..1cadae25c
--- /dev/null
+++ b/Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/ComponentLocationEnum.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace RealTimeGraphEx.Components
+{
+ public enum ComponentLocationEnum
+ {
+ None,
+ Front,
+ Back,
+ Left,
+ Right
+ }
+}
diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/GridLines.cs b/Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/GridLines.cs
new file mode 100644
index 000000000..ce49f1efd
--- /dev/null
+++ b/Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/GridLines.cs
@@ -0,0 +1,121 @@
+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.Media;
+using System.Windows.Shapes;
+
+namespace RealTimeGraphEx.Components
+{
+ public class GridLines : ComponentBase
+ {
+ private RealTimeGraphExBase lastGraph;
+
+ #region Properties
+
+ public int Rows
+ {
+ get { return (int)GetValue(RowsProperty); }
+ set { SetValue(RowsProperty, value); }
+ }
+ public static readonly DependencyProperty RowsProperty =
+ DependencyProperty.Register("Rows", typeof(int), typeof(GridLines), new PropertyMetadata(5));
+
+ public int Columns
+ {
+ get { return (int)GetValue(ColumnsProperty); }
+ set { SetValue(ColumnsProperty, value); }
+ }
+ public static readonly DependencyProperty ColumnsProperty =
+ DependencyProperty.Register("Columns", typeof(int), typeof(GridLines), new PropertyMetadata(9));
+
+ public Brush GridBrush
+ {
+ get { return (Brush)GetValue(GridBrushProperty); }
+ set { SetValue(GridBrushProperty, value); }
+ }
+ public static readonly DependencyProperty GridBrushProperty =
+ DependencyProperty.Register("GridBrush", typeof(Brush), typeof(GridLines), new PropertyMetadata(Brushes.Silver));
+
+ #endregion
+
+ public GridLines()
+ {
+ Location = ComponentLocationEnum.Back;
+ this.SizeChanged += (x, y) => { Render(Graph); };
+ }
+
+ public void Render()
+ {
+ Render(lastGraph);
+ }
+
+ public override void Render(RealTimeGraphExBase graph, bool animate = false)
+ {
+ if (graph == null) return;
+
+ lastGraph = graph;
+
+ Grid grid = new Grid();
+
+ grid.Children.Clear();
+ grid.ColumnDefinitions.Clear();
+ grid.RowDefinitions.Clear();
+
+ for (int i = 0; i < Rows; i++)
+ {
+ RowDefinition row = new RowDefinition();
+ row.Height = new GridLength(1, GridUnitType.Star);
+ grid.RowDefinitions.Add(row);
+
+ RowDefinition rowLabels = new RowDefinition();
+ row.Height = new GridLength(1, GridUnitType.Star);
+ }
+
+ for (int i = 0; i < Columns; i++)
+ {
+ ColumnDefinition column = new ColumnDefinition();
+ column.Width = new GridLength(1, GridUnitType.Star);
+ grid.ColumnDefinitions.Add(column);
+ }
+
+ for (int i = 0; i < grid.RowDefinitions.Count - 1; i++)
+ {
+ Rectangle rec = new Rectangle();
+ rec.Height = 1;
+ rec.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
+ rec.VerticalAlignment = System.Windows.VerticalAlignment.Bottom;
+ rec.Fill = GridBrush;
+ Grid.SetRow(rec, i);
+ Grid.SetColumn(rec, 0);
+ Grid.SetColumnSpan(rec, grid.ColumnDefinitions.Count);
+ grid.Children.Add(rec);
+ }
+
+ for (int i = 0; i < grid.ColumnDefinitions.Count - 1; i++)
+ {
+ Rectangle rec = new Rectangle();
+ rec.Width = 1;
+ rec.HorizontalAlignment = System.Windows.HorizontalAlignment.Right;
+ rec.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
+ rec.Fill = GridBrush;
+ Grid.SetColumn(rec, i);
+ Grid.SetRow(rec, 0);
+ Grid.SetRowSpan(rec, grid.RowDefinitions.Count);
+
+ grid.Children.Add(rec);
+ }
+
+ this.Content = grid;
+
+ //if (!graph.gridBack.Children.Contains(this))
+ //{
+ // this.RemoveFromParent();
+ // graph.gridBack.Children.Add(this);
+ //}
+ }
+ }
+}
diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/MouseValueToolTip.cs b/Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/MouseValueToolTip.cs
new file mode 100644
index 000000000..115f84b34
--- /dev/null
+++ b/Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/MouseValueToolTip.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+
+namespace RealTimeGraphEx.Components
+{
+ public class MouseValueToolTip : ComponentBase
+ {
+
+ /// <summary>
+ /// Gets or sets the tool tip template.
+ /// </summary>
+ /// <value>
+ /// The tool tip template.
+ /// </value>
+ public DataTemplate ToolTipTemplate
+ {
+ get { return (DataTemplate)GetValue(ToolTipTemplateProperty); }
+ set { SetValue(ToolTipTemplateProperty, value); }
+ }
+ public static readonly DependencyProperty ToolTipTemplateProperty =
+ DependencyProperty.Register("ToolTipTemplate", typeof(DataTemplate), typeof(MouseValueToolTip), new PropertyMetadata(null));
+
+
+ public override void Render(RealTimeGraphExBase graph, bool animate = false)
+ {
+ graph.gridInnerContentWrapper.Children.Remove(this);
+ graph.gridInnerContentWrapper.Children.Add(this);
+
+ if (ToolTipTemplate != null)
+ {
+ this.ContentTemplate = ToolTipTemplate;
+ }
+
+ this.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
+ this.VerticalAlignment = System.Windows.VerticalAlignment.Top;
+ this.Visibility = System.Windows.Visibility.Hidden;
+ graph.MouseMove += graph_MouseMove;
+ graph.MouseLeave += graph_MouseLeave;
+ }
+
+ private void graph_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
+ {
+ this.Visibility = System.Windows.Visibility.Hidden;
+ }
+
+ private void graph_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
+ {
+ this.Visibility = System.Windows.Visibility.Visible;
+
+ double x = e.GetPosition(Graph.gridInnerContentWrapper).X;
+ double y = e.GetPosition(Graph.gridInnerContentWrapper).Y;
+
+ if (y > Graph.gridInnerContentWrapper.ActualHeight / 2)
+ {
+ y -= this.ActualHeight + 1;
+ }
+ if (x > Graph.gridInnerContentWrapper.ActualWidth / 2)
+ {
+ x -= this.ActualWidth + 1;
+ }
+
+ this.Margin = new System.Windows.Thickness(x, y, 0, 0);
+ this.Content = Graph.MouseValue;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/YAxisLegends.cs b/Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/YAxisLegends.cs
new file mode 100644
index 000000000..d5f5b6d54
--- /dev/null
+++ b/Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/YAxisLegends.cs
@@ -0,0 +1,61 @@
+using RealTimeGraphEx.Components.ComponentsItems;
+using RealTimeGraphEx.FastGraphs;
+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.Media;
+using System.Windows.Shapes;
+
+namespace RealTimeGraphEx.Components
+{
+ public class YAxisLegends : ComponentBase
+ {
+ public DataTemplate LegendTemplate
+ {
+ get { return (DataTemplate)GetValue(LegendTemplateProperty); }
+ set { SetValue(LegendTemplateProperty, value); }
+ }
+ public static readonly DependencyProperty LegendTemplateProperty =
+ DependencyProperty.Register("LegendTemplate", typeof(DataTemplate), typeof(YAxisLegends), new PropertyMetadata(null));
+
+
+ public YAxisLegends()
+ {
+ Location = ComponentLocationEnum.Right;
+ Width = 30;
+ }
+
+ public override void Render(RealTimeGraphExBase graph, bool animate = false)
+ {
+ var multiGraph = graph as RealTimeGraphExMultiBase;
+
+ if (multiGraph == null)
+ {
+ throw new InvalidCastException("The YAxisLegends component can only be used with multi series graphs.");
+ }
+
+ if (multiGraph.Controller == null) return;
+
+ WrapPanel stack = new WrapPanel() { Orientation = Orientation.Vertical };
+ this.Content = stack;
+
+ for (int i = 0; i < multiGraph.Controller.DataSeriesCollection.Count; i++)
+ {
+ YAxisLegend legend = new YAxisLegend();
+
+ legend.Content = multiGraph.Controller.DataSeriesCollection[i];
+
+ if (LegendTemplate != null)
+ {
+ legend.ContentTemplate = LegendTemplate;
+ }
+
+ stack.Children.Add(legend);
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/YAxisScroll.cs b/Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/YAxisScroll.cs
new file mode 100644
index 000000000..40a6ca5cb
--- /dev/null
+++ b/Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/YAxisScroll.cs
@@ -0,0 +1,205 @@
+using RealTimeGraphEx.Components.ComponentsItems;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Diagnostics;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+
+namespace RealTimeGraphEx.Components
+{
+ public class YAxisScroll : ComponentBase
+ {
+ private Grid innerGrid;
+
+ #region Properties
+
+ public int Interval
+ {
+ get { return (int)GetValue(IntervalProperty); }
+ set { SetValue(IntervalProperty, value); }
+ }
+ public static readonly DependencyProperty IntervalProperty =
+ DependencyProperty.Register("Interval", typeof(int), typeof(YAxisScroll), new PropertyMetadata(4));
+
+ public double VerticalOffset
+ {
+ get { return (double)GetValue(VerticalOffsetProperty); }
+ set { SetValue(VerticalOffsetProperty, value); }
+ }
+ public static readonly DependencyProperty VerticalOffsetProperty =
+ DependencyProperty.Register("VerticalOffset", typeof(double), typeof(YAxisScroll), new PropertyMetadata(0.0));
+
+ public double HorizontalOffset
+ {
+ get { return (double)GetValue(HorizontalOffsetProperty); }
+ set { SetValue(HorizontalOffsetProperty, value); }
+ }
+ public static readonly DependencyProperty HorizontalOffsetProperty =
+ DependencyProperty.Register("HorizontalOffset", typeof(double), typeof(YAxisScroll), new PropertyMetadata(0.0));
+
+ public DataTemplate LabelTemplate
+ {
+ get { return (DataTemplate)GetValue(LabelTemplateProperty); }
+ set { SetValue(LabelTemplateProperty, value); }
+ }
+ public static readonly DependencyProperty LabelTemplateProperty =
+ DependencyProperty.Register("LabelTemplate", typeof(DataTemplate), typeof(YAxisScroll), new PropertyMetadata(null));
+
+ public ObservableCollection<YAxisLabel> Labels
+ {
+ get { return (ObservableCollection<YAxisLabel>)GetValue(LabelsProperty); }
+ set { SetValue(LabelsProperty, value); }
+ }
+ public static readonly DependencyProperty LabelsProperty =
+ DependencyProperty.Register("Labels", typeof(ObservableCollection<YAxisLabel>), typeof(YAxisScroll), new PropertyMetadata(null));
+
+ public String StringFormat
+ {
+ get { return (String)GetValue(StringFormatProperty); }
+ set { SetValue(StringFormatProperty, value); }
+ }
+ public static readonly DependencyProperty StringFormatProperty =
+ DependencyProperty.Register("StringFormat", typeof(String), typeof(YAxisScroll), new PropertyMetadata("#0.0"));
+
+
+
+ #endregion
+
+ public YAxisScroll()
+ {
+ Labels = new ObservableCollection<YAxisLabel>();
+ Location = ComponentLocationEnum.Left;
+ this.SizeChanged += (x, y) => { Render(Graph); };
+ }
+
+ public override void Render(RealTimeGraphExBase graph, bool animate = false)
+ {
+ if (graph == null) return;
+
+ if (Interval < 2) return;
+
+ if (innerGrid == null)
+ {
+ innerGrid = new Grid();
+ }
+
+ var grid = innerGrid;
+
+ double animationTime = animate ? 0.2 : 0;
+
+ DoubleAnimation heightAnimation = new DoubleAnimation() { Duration = new Duration(TimeSpan.FromSeconds(animationTime)) };
+ heightAnimation.To = double.IsNaN(Graph.gridLinesAndImageWrapperGrid.Height) ? Graph.gridLinesAndImageWrapperGrid.ActualHeight : Graph.gridLinesAndImageWrapperGrid.Height;
+
+ if (!double.IsNaN(grid.Height))
+ {
+ grid.BeginAnimation(Grid.HeightProperty, heightAnimation);
+ }
+ else
+ {
+ grid.Height = Graph.gridLinesAndImageWrapperGrid.ActualHeight;
+ }
+ grid.VerticalAlignment = System.Windows.VerticalAlignment.Top;
+
+ ThicknessAnimation marginAni = new ThicknessAnimation() { Duration = new Duration(TimeSpan.FromSeconds(animationTime)) };
+ marginAni.To = new Thickness(0, Graph.gridLinesAndImageWrapperGrid.Margin.Top, 0, 0);
+
+ if (!double.IsNaN(grid.Height))
+ {
+ grid.BeginAnimation(MarginProperty, marginAni);
+ }
+ else
+ {
+ grid.Margin = new Thickness(0, Graph.gridLinesAndImageWrapperGrid.Margin.Top, 0, 0);
+ }
+
+ double height = double.IsNaN(Graph.gridLinesAndImageWrapperGrid.Height) ? Graph.gridLinesAndImageWrapperGrid.ActualHeight : Graph.gridLinesAndImageWrapperGrid.Height;
+
+ int interval = (int)Math.Round((Interval * (((height * 100) / Graph.gridMain.ActualHeight) / 100)), MidpointRounding.ToEven);
+
+ this.Content = grid;
+ this.ClipToBounds = true;
+
+ grid.RowDefinitions.Clear();
+ grid.Children.Clear();
+
+ if (Labels != null && Labels.Count > 0)
+ {
+ for (int i = 0; i < Labels.Count - 1; i++)
+ {
+ RowDefinition rowLabels = new RowDefinition();
+ rowLabels.Height = new GridLength(1, GridUnitType.Star);
+ grid.RowDefinitions.Add(rowLabels);
+ AddLabel(Labels[i], graph, grid, i, System.Windows.VerticalAlignment.Top);
+ }
+
+ AddLabel(Labels.Last(), graph, grid, interval - 1, System.Windows.VerticalAlignment.Bottom);
+ }
+ else
+ {
+ for (int i = 0; i < interval; i++)
+ {
+ RowDefinition rowLabels = new RowDefinition();
+ rowLabels.Height = new GridLength(1, GridUnitType.Star);
+ grid.RowDefinitions.Add(rowLabels);
+ }
+
+ for (int i = 0; i < interval; i++)
+ {
+ double value = graph.Maximum - (i * ((graph.Maximum - graph.Minimum) / interval));
+ AddLabel(value.ToString(StringFormat), graph, grid, i, System.Windows.VerticalAlignment.Top);
+ }
+
+ AddLabel(graph.Minimum.ToString(StringFormat), graph, grid, interval - 1, System.Windows.VerticalAlignment.Bottom);
+ }
+
+ grid.InvalidateArrange();
+ grid.InvalidateMeasure();
+ grid.UpdateLayout();
+ grid.InvalidateVisual();
+ }
+
+ protected void AddLabel(Object content, RealTimeGraphExBase graph, Grid grid, int row, VerticalAlignment align)
+ {
+ //Add Labels
+ YAxisLabel label = new YAxisLabel();
+ label.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
+ label.VerticalAlignment = align;
+ label.Content = content;
+
+ if (row > 0 || VerticalOffset > 0)
+ {
+ label.Margin = new Thickness(HorizontalOffset, VerticalOffset, 0, 0);
+ }
+
+ Grid.SetRow(label, row);
+ grid.Children.Add(label);
+
+ if (LabelTemplate != null)
+ {
+ label.ContentTemplate = LabelTemplate;
+ }
+ }
+
+ protected override void OnGraphZoomComplete(Point transformOrigin, double scaleX, double scaleY)
+ {
+ Render(Graph, true);
+ }
+
+ protected override void OnGraphPanningComplete(Point translate)
+ {
+ if (innerGrid != null)
+ {
+ var renderBounds = Graph.GetGraphRenderBounds();
+ innerGrid.BeginAnimation(MarginProperty, null);
+ innerGrid.Margin = new Thickness(0, Graph.gridLinesAndImageWrapperGrid.Margin.Top, 0, 0);
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/YAxisTicks.cs b/Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/YAxisTicks.cs
new file mode 100644
index 000000000..e340aac8a
--- /dev/null
+++ b/Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/YAxisTicks.cs
@@ -0,0 +1,192 @@
+using RealTimeGraphEx.Components.ComponentsItems;
+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.Media.Animation;
+using System.Windows.Shapes;
+
+namespace RealTimeGraphEx.Components
+{
+ public class YAxisTicks : ComponentBase
+ {
+ private Grid innerGrid;
+
+ #region Constructors
+
+ public YAxisTicks()
+ {
+ Width = 4;
+ Location = ComponentLocationEnum.Left;
+ this.SizeChanged += (x, y) => { Render(Graph); };
+ }
+
+ #endregion
+
+ #region Properties
+
+ public int SmallTicks
+ {
+ get { return (int)GetValue(SmallTicksProperty); }
+ set { SetValue(SmallTicksProperty, value); }
+ }
+ public static readonly DependencyProperty SmallTicksProperty =
+ DependencyProperty.Register("SmallTicks", typeof(int), typeof(YAxisTicks), new PropertyMetadata(20));
+
+ public int BigTicks
+ {
+ get { return (int)GetValue(BigTicksProperty); }
+ set { SetValue(BigTicksProperty, value); }
+ }
+ public static readonly DependencyProperty BigTicksProperty =
+ DependencyProperty.Register("BigTicks", typeof(int), typeof(YAxisTicks), new PropertyMetadata(2));
+
+ public DataTemplate SmallTickTemplate
+ {
+ get { return (DataTemplate)GetValue(SmallTickTemplateProperty); }
+ set { SetValue(SmallTickTemplateProperty, value); }
+ }
+ public static readonly DependencyProperty SmallTickTemplateProperty =
+ DependencyProperty.Register("SmallTickTemplate", typeof(DataTemplate), typeof(YAxisTicks), new PropertyMetadata(null));
+
+ public DataTemplate BigTickTemplate
+ {
+ get { return (DataTemplate)GetValue(BigTickTemplateProperty); }
+ set { SetValue(BigTickTemplateProperty, value); }
+ }
+ public static readonly DependencyProperty BigTickTemplateProperty =
+ DependencyProperty.Register("BigTickTemplate", typeof(DataTemplate), typeof(YAxisTicks), new PropertyMetadata(null));
+
+ #endregion
+
+ public override void Render(RealTimeGraphExBase graph, bool animate = false)
+ {
+ if (graph == null) return;
+
+ if (SmallTicks < 2) return;
+
+
+ if (innerGrid == null)
+ {
+ innerGrid = new Grid();
+ }
+
+ double animationTime = animate ? 0.2 : 0;
+
+ Grid grid = innerGrid;
+
+ DoubleAnimation heightAnimation = new DoubleAnimation() { Duration = new Duration(TimeSpan.FromSeconds(animationTime)) };
+ heightAnimation.To = double.IsNaN(Graph.gridLinesAndImageWrapperGrid.Height) ? Graph.gridLinesAndImageWrapperGrid.ActualHeight : Graph.gridLinesAndImageWrapperGrid.Height;
+
+
+ if (!double.IsNaN(grid.Height))
+ {
+ grid.BeginAnimation(Grid.HeightProperty, heightAnimation);
+ }
+ else
+ {
+ grid.Height = Graph.gridLinesAndImageWrapperGrid.ActualHeight;
+ }
+
+ grid.VerticalAlignment = System.Windows.VerticalAlignment.Top;
+
+ ThicknessAnimation marginAni = new ThicknessAnimation() { Duration = new Duration(TimeSpan.FromSeconds(animationTime)) };
+ marginAni.To = new Thickness(0, Graph.gridLinesAndImageWrapperGrid.Margin.Top, 0, 0);
+
+ if (!double.IsNaN(grid.Height))
+ {
+ grid.BeginAnimation(MarginProperty, marginAni);
+ }
+ else
+ {
+ grid.Margin = new Thickness(0, Graph.gridLinesAndImageWrapperGrid.Margin.Top, 0, 0);
+ }
+
+ double height = double.IsNaN(Graph.gridLinesAndImageWrapperGrid.Height) ? Graph.gridLinesAndImageWrapperGrid.ActualHeight : Graph.gridLinesAndImageWrapperGrid.Height;
+
+ int smallTicks = (int)Math.Round((SmallTicks * (((height * 100) / Graph.gridMain.ActualHeight) / 100)), MidpointRounding.ToEven);
+
+
+
+
+ this.Content = grid;
+ this.ClipToBounds = true;
+
+
+ grid.RowDefinitions.Clear();
+ grid.Children.Clear();
+
+ int bigTickCounter = BigTicks;
+
+ for (int i = 0; i < smallTicks; i++)
+ {
+ RowDefinition rowTick = new RowDefinition();
+ rowTick.Height = new GridLength(1, GridUnitType.Star);
+ grid.RowDefinitions.Add(rowTick);
+
+ if (i == bigTickCounter)
+ {
+ YAxisBigTick bigTick = new YAxisBigTick();
+ bigTick.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
+ bigTick.VerticalAlignment = System.Windows.VerticalAlignment.Top;
+
+ if (BigTickTemplate != null)
+ {
+ bigTick.ContentTemplate = BigTickTemplate;
+ }
+
+ bigTickCounter += BigTicks;
+
+ grid.Children.Add(bigTick);
+ Grid.SetRow(bigTick, i);
+ }
+ else
+ {
+
+ YAxisSmallTick smallTick = new YAxisSmallTick();
+ smallTick.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
+ smallTick.VerticalAlignment = System.Windows.VerticalAlignment.Top;
+
+ if (SmallTickTemplate != null)
+ {
+ smallTick.ContentTemplate = SmallTickTemplate;
+ }
+
+ grid.Children.Add(smallTick);
+ Grid.SetRow(smallTick, i);
+ }
+ }
+
+ //Add last tick
+ YAxisSmallTick lastTick = new YAxisSmallTick();
+ lastTick.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
+ lastTick.VerticalAlignment = System.Windows.VerticalAlignment.Bottom;
+
+ if (SmallTickTemplate != null)
+ {
+ lastTick.ContentTemplate = SmallTickTemplate;
+ }
+
+ grid.Children.Add(lastTick);
+ Grid.SetRow(lastTick, smallTicks - 1);
+ }
+
+ protected override void OnGraphZoomComplete(Point transformOrigin, double scaleX, double scaleY)
+ {
+ Render(Graph, true);
+ }
+
+ protected override void OnGraphPanningComplete(Point translate)
+ {
+ if (innerGrid != null)
+ {
+ var renderBounds = Graph.GetGraphRenderBounds();
+ innerGrid.BeginAnimation(MarginProperty, null);
+ innerGrid.Margin = new Thickness(0, Graph.gridLinesAndImageWrapperGrid.Margin.Top, 0, 0);
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/YAxisWave.cs b/Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/YAxisWave.cs
new file mode 100644
index 000000000..1e6229b15
--- /dev/null
+++ b/Software/Visual_Studio/SideChains/RealTimeGraphEx/Components/YAxisWave.cs
@@ -0,0 +1,107 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+
+namespace RealTimeGraphEx.Components
+{
+ public class YAxisWave : YAxisScroll
+ {
+ private Grid innerGrid;
+
+ public YAxisWave()
+ : base()
+ {
+
+ }
+
+ public override void Render(RealTimeGraphExBase graph, bool animate = false)
+ {
+ if (graph == null) return;
+
+ if (innerGrid == null)
+ {
+ innerGrid = new Grid();
+ }
+
+ if (Interval == 0) return;
+ if (Interval % 2 != 0) Interval += 1;
+
+ var grid = innerGrid;
+
+ var renderBounds = Graph.GetGraphRenderBounds();
+
+ double animationTime = animate ? 0.2 : 0;
+
+ DoubleAnimation heightAnimation = new DoubleAnimation() { Duration = new Duration(TimeSpan.FromSeconds(animationTime)) };
+ heightAnimation.To = double.IsNaN(Graph.gridLinesAndImageWrapperGrid.Height) ? Graph.gridLinesAndImageWrapperGrid.ActualHeight : Graph.gridLinesAndImageWrapperGrid.Height;
+
+
+ if (!double.IsNaN(grid.Height))
+ {
+ grid.BeginAnimation(Grid.HeightProperty, heightAnimation);
+ }
+ else
+ {
+ grid.Height = Graph.gridLinesAndImageWrapperGrid.ActualHeight;
+ }
+ grid.VerticalAlignment = System.Windows.VerticalAlignment.Top;
+
+ ThicknessAnimation marginAni = new ThicknessAnimation() { Duration = new Duration(TimeSpan.FromSeconds(animationTime)) };
+ marginAni.To = new Thickness(0, Graph.gridLinesAndImageWrapperGrid.Margin.Top, 0, 0);
+
+ if (!double.IsNaN(grid.Height))
+ {
+ grid.BeginAnimation(MarginProperty, marginAni);
+ }
+ else
+ {
+ grid.Margin = new Thickness(0, Graph.gridLinesAndImageWrapperGrid.Margin.Top, 0, 0);
+ }
+
+ this.ClipToBounds = true;
+ this.Content = grid;
+
+ double height = double.IsNaN(Graph.gridLinesAndImageWrapperGrid.Height) ? Graph.gridLinesAndImageWrapperGrid.ActualHeight : Graph.gridLinesAndImageWrapperGrid.Height;
+ int interval = (int)Math.Round((Interval * (((height * 100) / Graph.gridMain.ActualHeight) / 100)), MidpointRounding.ToEven);
+
+ grid.RowDefinitions.Clear();
+ grid.Children.Clear();
+
+ for (int i = 0; i < interval; i++)
+ {
+ RowDefinition rowLabels = new RowDefinition();
+ rowLabels.Height = new GridLength(1, GridUnitType.Star);
+ grid.RowDefinitions.Add(rowLabels);
+ }
+
+ for (int i = 0; i < interval; i++)
+ {
+ AddLabel(Math.Abs((graph.Maximum - (i * ((graph.Maximum + Math.Abs(graph.Minimum)) / (interval / 2))))).ToString(StringFormat), graph, grid, i, System.Windows.VerticalAlignment.Top);
+ }
+
+ AddLabel(graph.Maximum.ToString(StringFormat), graph, grid, interval - 1, System.Windows.VerticalAlignment.Bottom);
+ }
+
+ protected override void OnGraphZoomComplete(Point transformOrigin, double scaleX, double scaleY)
+ {
+ Render(Graph, true);
+ }
+
+ protected override void OnGraphPanningComplete(Point translate)
+ {
+ if (innerGrid != null)
+ {
+ var renderBounds = Graph.GetGraphRenderBounds();
+ innerGrid.BeginAnimation(MarginProperty, null);
+ innerGrid.Margin = new Thickness(0, renderBounds.Top, 0, 0);
+ }
+ }
+ }
+}