aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/SideChains/RealTimeGraphX/GraphControllerBase.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Software/Visual_Studio/SideChains/RealTimeGraphX/GraphControllerBase.cs')
-rw-r--r--Software/Visual_Studio/SideChains/RealTimeGraphX/GraphControllerBase.cs315
1 files changed, 315 insertions, 0 deletions
diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX/GraphControllerBase.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX/GraphControllerBase.cs
new file mode 100644
index 000000000..a39fce366
--- /dev/null
+++ b/Software/Visual_Studio/SideChains/RealTimeGraphX/GraphControllerBase.cs
@@ -0,0 +1,315 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using RealTimeGraphX.EventArguments;
+
+namespace RealTimeGraphX
+{
+ /// <summary>
+ /// Represents an <see cref="IGraphController{XDataPoint, YDataPoint}"/> base class.
+ /// </summary>
+ /// <typeparam name="TDataSeries">The type of the graph data series.</typeparam>
+ /// <typeparam name="XDataPoint">The type of the x-axis data point.</typeparam>
+ /// <typeparam name="YDataPoint">The type of the y-axis data point.</typeparam>
+ /// <seealso cref="RealTimeGraphX.GraphOutputComponentBase{RealTimeGraphX.IGraphRenderer{XDataPoint, YDataPoint}}" />
+ /// <seealso cref="RealTimeGraphX.IGraphController{XDataPoint, YDataPoint}" />
+ public abstract class GraphControllerBase<TDataSeries, XDataPoint, YDataPoint> :
+ GraphOutputComponentBase<IGraphRenderer<TDataSeries, XDataPoint, YDataPoint>>,
+ IGraphController<TDataSeries, XDataPoint, YDataPoint>
+ where XDataPoint : GraphDataPointBase
+ where YDataPoint : GraphDataPointBase
+ where TDataSeries : IGraphDataSeries
+ {
+ #region Events
+
+ /// <summary>
+ /// Occurs when one of the <see cref="P:RealTimeGraphX.IGraphController`2.Range" /> properties was modified.
+ /// </summary>
+ public event EventHandler<GraphRange<XDataPoint, YDataPoint>> RangeChanged;
+
+ /// <summary>
+ /// Occurs when one of the <see cref="Range" /> properties was modified.
+ /// </summary>
+ event EventHandler<IGraphRange> IGraphController<TDataSeries>.RangeChanged
+ {
+ add
+ {
+ RangeChanged += new EventHandler<GraphRange<XDataPoint, YDataPoint>>((sender, range) => { value.Invoke(sender, Range); });
+ }
+
+ remove
+ {
+ RangeChanged -= new EventHandler<GraphRange<XDataPoint, YDataPoint>>((sender, range) => { value.Invoke(sender, Range); });
+ }
+ }
+
+ /// <summary>
+ /// Occurs when the connected <see cref="IGraphRenderer"/> has changed.
+ /// </summary>
+ event EventHandler<OutputChangedEventArgs<IGraphRenderer<TDataSeries>>> IGraphOutputComponent<IGraphRenderer<TDataSeries>>.OutputChanged
+ {
+ add
+ {
+ OutputChanged += new EventHandler<OutputChangedEventArgs<IGraphRenderer<TDataSeries,XDataPoint, YDataPoint>>>((sender, output) => { value.Invoke(sender, new OutputChangedEventArgs<IGraphRenderer<TDataSeries>>(output.Output)); });
+ }
+
+ remove
+ {
+ OutputChanged -= new EventHandler<OutputChangedEventArgs<IGraphRenderer<TDataSeries,XDataPoint, YDataPoint>>>((sender, output) => { value.Invoke(sender, new OutputChangedEventArgs<IGraphRenderer<TDataSeries>>(output.Output)); });
+ }
+ }
+
+ #endregion
+
+ #region Properties
+
+
+
+ /// <summary>
+ /// Gets the data series collection.
+ /// </summary>
+ public ReadOnlyObservableCollection<TDataSeries> DataSeriesCollection { get; private set; }
+
+ /// <summary>
+ /// Gets the graph range (limits).
+ /// </summary>
+ public GraphRange<XDataPoint, YDataPoint> Range { get; private set; }
+
+ /// <summary>
+ /// Gets the graph range (limits).
+ /// </summary>
+ IGraphRange IGraphController<TDataSeries>.Range
+ {
+ get
+ {
+ return Range;
+ }
+ }
+
+ /// <summary>
+ /// Gets the connected output <see cref="IGraphRenderer"/>.
+ /// </summary>
+ IGraphRenderer<TDataSeries> IGraphOutputComponent<IGraphRenderer<TDataSeries>>.Output
+ {
+ get
+ {
+ return Output;
+ }
+ }
+
+ private bool _isPaused;
+ /// <summary>
+ /// Gets or sets a value indicating whether to pause the graph movement.
+ /// </summary>
+ public bool IsPaused
+ {
+ get { return _isPaused; }
+ set
+ {
+ _isPaused = value; RaisePropertyChangedAuto();
+
+ if (Output != null)
+ {
+ Output.IsPaused = value;
+ }
+ }
+ }
+
+ #endregion
+
+ #region Constructors
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="GraphControllerBase{XDataPoint, YDataPoint}"/> class.
+ /// </summary>
+ public GraphControllerBase()
+ {
+ DataSeriesCollection = new ReadOnlyObservableCollection<TDataSeries>(new ObservableCollection<TDataSeries>());
+ Range = new GraphRange<XDataPoint, YDataPoint>();
+ Range.PropertyChanged += (x, e) => OnRangeChanged();
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ /// <summary>
+ /// Clears the graph data.
+ /// </summary>
+ public void Clear()
+ {
+ if (Output != null)
+ {
+ Output.Clear();
+ }
+ }
+
+ /// <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<XDataPoint>> xxxx, IEnumerable<IEnumerable<YDataPoint>> yyyy)
+ {
+ if (DataSeriesCollection.Count == 0) return;
+
+ Output.Render(DataSeriesCollection, 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<XDataPoint> xx, IEnumerable<YDataPoint> yy)
+ {
+ if (DataSeriesCollection.Count == 0) return;
+
+ var xList = xx.ToList();
+ var yList = yy.ToList();
+
+ List<List<XDataPoint>> xxList = new List<List<XDataPoint>>();
+ List<List<YDataPoint>> yyList = new List<List<YDataPoint>>();
+
+ foreach (var series in DataSeriesCollection.ToList())
+ {
+ xxList.Add(new List<XDataPoint>());
+ yyList.Add(new List<YDataPoint>());
+ }
+
+ int counter = 0;
+
+ for (int i = 0; i < xList.Count; i++)
+ {
+ xxList[counter].Add(xList[i]);
+ yyList[counter].Add(yList[i]);
+
+ counter++;
+
+ if (counter >= xxList.Count)
+ {
+ counter = 0;
+ }
+ }
+
+ Output.Render(DataSeriesCollection, xxList, yyList);
+ }
+
+ /// <summary>
+ /// Submits the specified x and y data points the controller.
+ /// 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(XDataPoint x, YDataPoint y)
+ {
+ if (DataSeriesCollection.Count == 0) return;
+
+ List<List<XDataPoint>> xxList = new List<List<XDataPoint>>();
+ List<List<YDataPoint>> yyList = new List<List<YDataPoint>>();
+
+ foreach (var series in DataSeriesCollection.ToList())
+ {
+ xxList.Add(new List<XDataPoint>() { x });
+ yyList.Add(new List<YDataPoint>() { y });
+ }
+
+ Output.Render(DataSeriesCollection, xxList, yyList);
+ }
+
+ /// <summary>
+ /// Adds a new data series.
+ /// </summary>
+ /// <param name="series">The series.</param>
+ public void AddDataSeries(TDataSeries series)
+ {
+ var current_collection = DataSeriesCollection.ToList();
+ current_collection.Add(series);
+ DataSeriesCollection = new ReadOnlyObservableCollection<TDataSeries>(new ObservableCollection<TDataSeries>(current_collection));
+ }
+
+ /// <summary>
+ /// Removed the specified data series
+ /// </summary>
+ /// <param name="series">The series.</param>
+ public void RemoveDataSeries(TDataSeries series)
+ {
+ var current_collection = DataSeriesCollection.ToList();
+ current_collection.Remove(series);
+ DataSeriesCollection = new ReadOnlyObservableCollection<TDataSeries>(new ObservableCollection<TDataSeries>(current_collection));
+ }
+
+ /// <summary>
+ /// Connects this controller to the specified <see cref="IGraphRenderer{XDataPoint, YDataPoint}"/>.
+ /// </summary>
+ /// <param name="renderer">The renderer.</param>
+ /// <param name="fromOutput">Specifies whether this call was made from an <see cref="IGraphRenderer{XDataPoint, YDataPoint}"/> component.</param>
+ public override void ConnectOutput(IGraphRenderer<TDataSeries, XDataPoint, YDataPoint> renderer, bool fromOutput = false)
+ {
+ renderer.ThrowIfNull("Cannot connect a null renderer.");
+
+ Output = renderer;
+
+ if (!fromOutput)
+ {
+ Output.ConnectInput(this, true);
+ }
+ }
+
+ /// <summary>
+ /// Disconnects this component from the connected <see cref="P:RealTimeGraphX.IGraphOutputComponent`1.Output" /><see cref="T:RealTimeGraphX.IGraphComponent" />.
+ /// </summary>
+ /// <param name="fromOutput">Specifies whether this call was made from an <see cref="IGraphRenderer{XDataPoint, YDataPoint}"/> component.</param>
+ public override void DisconnectOutput(bool fromOutput = false)
+ {
+ if (Output != null)
+ {
+ if (!fromOutput)
+ {
+ (Output as IGraphInputComponent<IGraphController<TDataSeries, XDataPoint, YDataPoint>>).DisconnectInput(true);
+ }
+
+ Output = null;
+ }
+ }
+
+ /// <summary>
+ /// Connects this controller to the specified <see cref="IGraphRenderer"/>.
+ /// </summary>
+ /// <param name="renderer">The renderer.</param>
+ /// <param name="fromOutput">Specifies whether this call was made from the output <see cref="IGraphRenderer"/>.</param>
+ void IGraphOutputComponent<IGraphRenderer<TDataSeries>>.ConnectOutput(IGraphRenderer<TDataSeries> renderer, bool fromOutput)
+ {
+ ConnectOutput(renderer as IGraphRenderer<TDataSeries,XDataPoint, YDataPoint>);
+ }
+
+ /// <summary>
+ /// Disconnects the current connected output <see cref="IGraphRenderer"/>.
+ /// </summary>
+ /// <param name="fromOutput">Specifies whether this call was made from the output <see cref="IGraphRenderer"/>.</param>
+ void IGraphOutputComponent<IGraphRenderer<TDataSeries>>.DisconnectOutput(bool fromOutput)
+ {
+ DisconnectOutput();
+ }
+
+ #endregion
+
+ #region Protected Methods
+
+ /// <summary>
+ /// Raises the <see cref="RangeChanged"/> event.
+ /// </summary>
+ protected virtual void OnRangeChanged()
+ {
+ RangeChanged?.Invoke(this, Range);
+ }
+
+
+
+
+
+ #endregion
+ }
+}