diff options
Diffstat (limited to 'Software/Visual_Studio/SideChains/RealTimeGraphX/GraphControllerBase.cs')
| -rw-r--r-- | Software/Visual_Studio/SideChains/RealTimeGraphX/GraphControllerBase.cs | 315 |
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 + } +} |
