diff options
| author | Roy Ben-Shabat <Roy@Twine-s.com> | 2018-01-16 12:17:10 +0200 |
|---|---|---|
| committer | Roy Ben-Shabat <Roy@Twine-s.com> | 2018-01-16 12:17:10 +0200 |
| commit | 0fda2ba3ff49bdc1ffc6833f658e2164af187008 (patch) | |
| tree | 6f3a24d0671ebda50debb8511ab40e0bda0a0df0 /Software/Visual_Studio/SideChains/RealTimeGraphEx/Components | |
| parent | 28103646681686bf1b58275d5dbccb92d2b26f9f (diff) | |
| download | Tango-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')
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); + } + } + } +} |
