From 755f37e3e3e553a91dd2c5a7f0ddad8359287a3b Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Thu, 12 Mar 2020 17:15:11 +0200 Subject: Working on FSE/PPC monitoring/system info. --- .../RealTimeGraphX.WPF/Themes/Generic.xaml | 2 +- .../RealTimeGraphX.WPF/WpfGraphAxisControl.cs | 38 ++++- .../RealTimeGraphX.WPF/WpfGraphAxisPanel.cs | 2 +- .../RealTimeGraphX.WPF/WpfGraphDataSeries.cs | 10 ++ .../RealTimeGraphX.WPF/WpfGraphSurface.cs | 21 ++- .../RealTimeGraphX/DataPoints/DateTimeDataPoint.cs | 178 +++++++++++++++++++++ .../RealTimeGraphX/DataPoints/Int32DataPoint.cs | 13 +- .../RealTimeGraphX/GraphController.cs | 114 +++++++++++-- .../RealTimeGraphX/IGraphDataSeries.cs | 5 + .../RealTimeGraphX/IGraphSurface.cs | 10 ++ .../Renderers/ScrollingLineRenderer.cs | 2 +- 11 files changed, 366 insertions(+), 29 deletions(-) create mode 100644 Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/DataPoints/DateTimeDataPoint.cs (limited to 'Software/Visual_Studio/SideChains') 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 index 1070736ef..64145bcfa 100644 --- a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/Themes/Generic.xaml +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/Themes/Generic.xaml @@ -34,7 +34,7 @@ - + diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphAxisControl.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphAxisControl.cs index 23b831abe..aa738b203 100644 --- a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphAxisControl.cs +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphAxisControl.cs @@ -25,6 +25,7 @@ namespace RealTimeGraphX.WPF public class WpfGraphAxisControl : WpfGraphComponentBase { private ItemsControl _items_control; + private WpfGraphAxisPanel _axisPanel; /// /// Initializes the class. @@ -97,9 +98,37 @@ namespace RealTimeGraphX.WPF base.OnApplyTemplate(); _items_control = GetTemplateChild("PART_ItemsControl") as ItemsControl; + + _items_control.Loaded += (x, e) => + { + ItemsPresenter itemsPresenter = GetVisualChild(_items_control); + _axisPanel = VisualTreeHelper.GetChild(itemsPresenter, 0) as WpfGraphAxisPanel; + }; + OnTicksChanged(); } + private static T GetVisualChild(DependencyObject parent) where T : Visual + { + T child = default(T); + + int numVisuals = VisualTreeHelper.GetChildrenCount(parent); + for (int i = 0; i < numVisuals; i++) + { + Visual v = (Visual)VisualTreeHelper.GetChild(parent, i); + child = v as T; + if (child == null) + { + child = GetVisualChild(v); + } + if (child != null) + { + break; + } + } + return child; + } + /// /// Called when the property has changed. /// @@ -107,16 +136,15 @@ namespace RealTimeGraphX.WPF { Items = new ObservableCollection(Enumerable.Range(0, Ticks).Select(x => new WpfGraphAxisTickData())); - if (Controller != null) - { - Controller.RequestVirtualRangeChange(); - } + Controller?.RequestVirtualRangeChange(); + + _axisPanel?.UpdatePanel(); } protected override void OnControllerChanged(IGraphController oldController, IGraphController newController) { base.OnControllerChanged(oldController, newController); - + if (newController != null) { newController.RequestVirtualRangeChange(); diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphAxisPanel.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphAxisPanel.cs index f10b583f4..4fb6d94bc 100644 --- a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphAxisPanel.cs +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphAxisPanel.cs @@ -46,7 +46,7 @@ namespace RealTimeGraphX.WPF /// /// Updates the panel. /// - private void UpdatePanel() + public void UpdatePanel() { RowDefinitions.Clear(); ColumnDefinitions.Clear(); diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphDataSeries.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphDataSeries.cs index 15a99ab54..8eab3eabe 100644 --- a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphDataSeries.cs +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphDataSeries.cs @@ -135,5 +135,15 @@ namespace RealTimeGraphX.WPF { get { return Fill != null; } } + + private object _currentValue; + /// + /// Gets the current value. + /// + public object CurrentValue + { + get { return _currentValue; } + set { _currentValue = value; RaisePropertyChangedAuto(); } + } } } diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphSurface.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphSurface.cs index ebcff3472..1a3015728 100644 --- a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphSurface.cs +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX.WPF/WpfGraphSurface.cs @@ -40,6 +40,20 @@ namespace RealTimeGraphX.WPF private Point _last_mouse_position; private Grid _grid; + #region Events + + /// + /// Occurs when the surface size has changed. + /// + public event EventHandler SurfaceSizeChanged; + + /// + /// Occurs when the surface zoom rectangle has changed. + /// + public event EventHandler ZoomRectChanged; + + #endregion + #region Properties /// @@ -177,6 +191,8 @@ namespace RealTimeGraphX.WPF } _zoom_rect = new System.Drawing.RectangleF((float)x, (float)y, _zoom_rect.Width, _zoom_rect.Height); + + ZoomRectChanged?.Invoke(this, new EventArgs()); } _last_mouse_position = _current_mouse_position; @@ -202,6 +218,7 @@ namespace RealTimeGraphX.WPF _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; + ZoomRectChanged?.Invoke(this, new EventArgs()); } } @@ -222,6 +239,7 @@ namespace RealTimeGraphX.WPF { _zoom_rect = new System.Drawing.RectangleF(); _is_scaled = false; + ZoomRectChanged?.Invoke(this, new EventArgs()); } else if (Keyboard.IsKeyDown(Key.LeftCtrl)) { @@ -301,7 +319,7 @@ namespace RealTimeGraphX.WPF /// The points. public void DrawSeries(WpfGraphDataSeries dataSeries, IEnumerable points) { - _g.DrawCurve(dataSeries.GdiPen, points.ToArray()); + _g.DrawPolygon(dataSeries.GdiPen, points.ToArray()); } /// @@ -373,6 +391,7 @@ namespace RealTimeGraphX.WPF { _size = new System.Drawing.SizeF((float)e.NewSize.Width, (float)e.NewSize.Height); _size_changed = true; + SurfaceSizeChanged?.Invoke(this, new EventArgs()); } #endregion diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/DataPoints/DateTimeDataPoint.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/DataPoints/DateTimeDataPoint.cs new file mode 100644 index 000000000..9ec750af9 --- /dev/null +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/DataPoints/DateTimeDataPoint.cs @@ -0,0 +1,178 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace RealTimeGraphX.DataPoints +{ + public class DateTimeDataPoint : GraphDataPoint + { + /// + /// Initializes a new instance of the class. + /// + public DateTimeDataPoint() : base() + { + + } + + /// + /// Initializes a new instance of the class. + /// + /// The value. + public DateTimeDataPoint(DateTime value) : base(value) + { + + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value. + /// + /// The result of the conversion. + /// + public static implicit operator DateTimeDataPoint(DateTime value) + { + return new DateTimeDataPoint(value); + } + + /// + /// Implements the operator -. + /// + /// a. + /// The b. + /// + /// The result of the operator. + /// + public static DateTimeDataPoint operator -(DateTimeDataPoint a, DateTimeDataPoint b) + { + return new DateTimeDataPoint(new DateTime(a.Value.Ticks - b.Value.Ticks)); + } + + /// + /// Implements the operator +. + /// + /// a. + /// The b. + /// + /// The result of the operator. + /// + public static DateTimeDataPoint operator +(DateTimeDataPoint a, DateTimeDataPoint b) + { + return new DateTimeDataPoint(new DateTime(a.Value.Ticks + b.Value.Ticks)); + } + + /// + /// Sums the value of this instance with another instance value and returns the result. + /// + /// The other instance. + /// + public override IGraphDataPoint Add(IGraphDataPoint other) + { + return new DateTimeDataPoint(new DateTime(this.Value.Ticks + (other as DateTimeDataPoint).Value.Ticks)); + } + + /// + /// Subtract the value of another instance from this instance and returns the result. + /// + /// The other instance. + /// + public override IGraphDataPoint Subtract(IGraphDataPoint other) + { + return new DateTimeDataPoint(new DateTime(this.Value.Ticks - (other as DateTimeDataPoint).Value.Ticks)); + } + + /// + /// Multiplies the value of this instance with another instance value and returns the result. + /// + /// The other instance. + /// + public override IGraphDataPoint Multiply(IGraphDataPoint other) + { + return new DateTimeDataPoint(new DateTime(this.Value.Ticks * (other as DateTimeDataPoint).Value.Ticks)); + } + + /// + /// Divides the value of this instance with another instance value and returns the result. + /// + /// The other instance. + /// + public override IGraphDataPoint Divide(IGraphDataPoint other) + { + return new DateTimeDataPoint(new DateTime(this.Value.Ticks / (other as DateTimeDataPoint).Value.Ticks)); + } + + /// + /// Returns the percentage value of this instance between the specified minimum and maximum values. + /// + /// The minimum. + /// The maximum. + /// + public override double ComputeRelativePosition(IGraphDataPoint min, IGraphDataPoint max) + { + DateTime dMin = min as DateTimeDataPoint; + DateTime dMax = max as DateTimeDataPoint; + + if (dMax.Ticks - dMin.Ticks == 0) //Prevent divide by zero + { + return dMin.Ticks; + } + + var result = ((Value.Ticks - dMin.Ticks) * 100) / (dMax.Ticks - dMin.Ticks); + + return double.IsNaN(result) ? dMin.Ticks : result; + } + + /// + /// Returns the absolute value of the specified percentage value between the specified minimum and maximum values. + /// + /// The minimum. + /// The maximum. + /// The percentage. + /// + public override IGraphDataPoint ComputeAbsolutePosition(IGraphDataPoint min, IGraphDataPoint max, double percentage) + { + double minimum = ((DateTime)min.GetValue()).Ticks; + double maximum = ((DateTime)max.GetValue()).Ticks; + + return new DateTimeDataPoint(new DateTime((long)(minimum + (maximum - minimum) * percentage))); + } + + /// + /// Creates a range of values from the specified minimum and maximum. + /// + /// The minimum. + /// The maximum. + /// The count. + /// + public override IEnumerable CreateRange(IGraphDataPoint min, IGraphDataPoint max, int count) + { + double minimum = ((DateTime)min.GetValue()).Ticks; + double maximum = ((DateTime)max.GetValue()).Ticks; + + return Enumerable.Range(0, count). + Select(i => minimum + (maximum - minimum) * ((double)i / (count - 1))). + Select(x => new DateTimeDataPoint(new DateTime((long)x))); + } + + /// + /// Returns a formated string of this data point. + /// + /// The format. + /// + public override string ToString(string format) + { + return Value.ToString(format); + } + + /// + /// Parses the specified value and returns a new instance of data point. + /// + /// The value. + /// + public override IGraphDataPoint Parse(string value) + { + return new DateTimeDataPoint(DateTime.Parse(value)); + } + } +} diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/DataPoints/Int32DataPoint.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/DataPoints/Int32DataPoint.cs index 4bccdcb74..787e59aae 100644 --- a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/DataPoints/Int32DataPoint.cs +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/DataPoints/Int32DataPoint.cs @@ -118,6 +118,11 @@ namespace RealTimeGraphX.DataPoints Int32DataPoint dMin = min as Int32DataPoint; Int32DataPoint dMax = max as Int32DataPoint; + if (dMax - dMin == 0) //Prevent divide by zero + { + return dMin; + } + var result = ((Value - dMin) * 100) / (dMax - dMin); return result; @@ -147,12 +152,12 @@ namespace RealTimeGraphX.DataPoints /// public override IEnumerable CreateRange(IGraphDataPoint min, IGraphDataPoint max, int count) { - int minimum = (int)min.GetValue(); - int maximum = (int)max.GetValue(); + double minimum = (int)min.GetValue(); + double maximum = (int)max.GetValue(); return Enumerable.Range(0, count). - Select(i => minimum + (maximum - minimum) * ((int)i / (count - 1))). - Select(x => new Int32DataPoint(x)); + Select(i => minimum + (maximum - minimum) * ((double)i / (count - 1))). + Select(x => new Int32DataPoint((int)x)); } /// diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/GraphController.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/GraphController.cs index 328f0736e..1b452df57 100644 --- a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/GraphController.cs +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/GraphController.cs @@ -47,6 +47,8 @@ namespace RealTimeGraphX public int RenderedItems { get; set; } public bool IsClearSeries { get; set; } + + public bool IsUpdateSeries { get; set; } } #endregion @@ -113,8 +115,10 @@ namespace RealTimeGraphX get { return _surface; } set { + var previous = _surface; _surface = value; RequestVirtualRangeChange(); + OnSurfaceChanged(previous, _surface); } } @@ -227,11 +231,8 @@ namespace RealTimeGraphX { List> pending_lists = new List>(); - if (_pending_series_collection.Count == 0) - { - Thread.Sleep(TimeSpan.FromSeconds(1)); - continue; - } + var pending_list_first = _pending_series_collection.BlockDequeue(); + pending_lists.Add(pending_list_first); while (_pending_series_collection.Count > 0) { @@ -247,24 +248,24 @@ namespace RealTimeGraphX { _pending_series_collection = new GraphDataQueue>(); _to_render.Clear(); - break; } - - if (_to_render.ContainsKey(pending_series.Series)) + else if (!pending_series.IsUpdateSeries) { - var s = _to_render[pending_series.Series]; - s.XX.AddRange(pending_series.XX); - s.YY.AddRange(pending_series.YY); - } - else - { - _to_render[pending_series.Series] = pending_series; + if (_to_render.ContainsKey(pending_series.Series)) + { + var s = _to_render[pending_series.Series]; + s.XX.AddRange(pending_series.XX); + s.YY.AddRange(pending_series.YY); + } + else + { + _to_render[pending_series.Series] = pending_series; + } } } } if (_to_render.Count > 0) - //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; @@ -346,6 +347,11 @@ namespace RealTimeGraphX foreach (var item in to_render) { + if (item.YY.Count > 0) + { + item.Series.CurrentValue = item.YY.Last().GetValue(); + } + var points = Renderer.Render(Surface, item.Series, _range, item.XX, item.YY, min_x, max_x, min_y, max_y); to_draw.Add(new Tuple>(item.Series, points)); } @@ -384,6 +390,26 @@ namespace RealTimeGraphX #region Protected Methods + /// + /// Called when the surface has changed. + /// + /// The previous. + /// The surface. + protected virtual void OnSurfaceChanged(IGraphSurface previous, IGraphSurface surface) + { + if (previous != null) + { + previous.SurfaceSizeChanged += Surface_SurfaceSizeChanged; + previous.ZoomRectChanged += Surface_ZoomRectChanged; + } + + if (surface != null) + { + surface.SurfaceSizeChanged += Surface_SurfaceSizeChanged; + surface.ZoomRectChanged += Surface_ZoomRectChanged; + } + } + /// /// Raises the event. /// @@ -431,6 +457,62 @@ namespace RealTimeGraphX #endregion + #region Surface Event Handlers + + /// + /// Handles the ZoomRectChanged event of the Surface control. + /// + /// The source of the event. + /// The instance containing the event data. + private void Surface_ZoomRectChanged(object sender, EventArgs e) + { + if (!_pending_series_collection.ToList().SelectMany(x => x).ToList().Exists(x => x.IsUpdateSeries)) + { + List updateSeries = new List(); + + foreach (var pending_Series in _to_render) + { + updateSeries.Add(new PendingSeries() + { + IsUpdateSeries = true, + Series = pending_Series.Value.Series, + XX = new List(), + YY = new List(), + }); + } + + _pending_series_collection.BlockEnqueue(updateSeries); + } + } + + /// + /// Handles the SurfaceSizeChanged event of the Surface control. + /// + /// The source of the event. + /// The instance containing the event data. + private void Surface_SurfaceSizeChanged(object sender, EventArgs e) + { + if (!_pending_series_collection.ToList().SelectMany(x => x).ToList().Exists(x => x.IsUpdateSeries)) + { + List updateSeries = new List(); + + foreach (var pending_Series in _to_render) + { + updateSeries.Add(new PendingSeries() + { + IsUpdateSeries = true, + Series = pending_Series.Value.Series, + XX = new List(), + YY = new List(), + }); + } + + _pending_series_collection.BlockEnqueue(updateSeries); + } + } + + #endregion + #region Public Methods /// diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/IGraphDataSeries.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/IGraphDataSeries.cs index dd05da92b..03640e44a 100644 --- a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/IGraphDataSeries.cs +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/IGraphDataSeries.cs @@ -27,5 +27,10 @@ namespace RealTimeGraphX /// Gets or sets a value indicating whether this series should be visible. /// bool IsVisible { get; set; } + + /// + /// Gets the current value. + /// + Object CurrentValue { get; set; } } } diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/IGraphSurface.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/IGraphSurface.cs index 310bc7c3d..a3aeb90d9 100644 --- a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/IGraphSurface.cs +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/IGraphSurface.cs @@ -11,6 +11,16 @@ namespace RealTimeGraphX /// public interface IGraphSurface : IGraphComponent { + /// + /// Occurs when the surface size has changed. + /// + event EventHandler SurfaceSizeChanged; + + /// + /// Occurs when the surface zoom rectangle has changed. + /// + event EventHandler ZoomRectChanged; + /// /// Returns the actual size of the surface. /// diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/Renderers/ScrollingLineRenderer.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/Renderers/ScrollingLineRenderer.cs index 82e80aa0f..0a4ac8368 100644 --- a/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/Renderers/ScrollingLineRenderer.cs +++ b/Software/Visual_Studio/SideChains/RealTimeGraphX-master/RealTimeGraphX/Renderers/ScrollingLineRenderer.cs @@ -78,7 +78,7 @@ namespace RealTimeGraphX.Renderers surface.FillSeries(series, GetFillPoints(surface, points)); } - surface.DrawSeries(series, points); + surface.DrawSeries(series, GetFillPoints(surface, points)); } } } -- cgit v1.3.1