using RealTimeGraphEx.DataSeries;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace RealTimeGraphEx.Controllers
{
public class GraphMultiController : GraphControllerBase
{
private readonly object _lock = new object();
#region Cross Thread Fields
internal ObservableCollection<DataYSeries> dataSeriesCollection;
#endregion
public int TotalPoints
{
get { return dataSeriesCollection.Count > 0 ? dataSeriesCollection[0].Points.Count : 0; }
}
internal bool IsAllSeriesEqual
{
get { return dataSeriesCollection.All(x => x.Points.Count == dataSeriesCollection[0].Points.Count); }
}
internal void TrimToLast()
{
lock (dataSeriesCollection)
{
if (dataSeriesCollection.Count > 1)
{
var min = dataSeriesCollection.FirstOrDefault(x => x.Points.Count == dataSeriesCollection.Min(y => y.Points.Count));
if (min != null)
{
lock (min.Points)
{
foreach (var series in dataSeriesCollection)
{
lock (series.Points)
{
if (series.Points.Count > min.Points.Count)
{
series.Points.RemoveRange(min.Points.Count, series.Points.Count - min.Points.Count);
}
}
}
}
}
}
}
}
public ObservableCollection<DataYSeries> DataSeriesCollection
{
get { return (ObservableCollection<DataSeries.DataYSeries>)GetValue(DataSeriesCollectionProperty); }
set { SetValue(DataSeriesCollectionProperty, value); }
}
public static readonly DependencyProperty DataSeriesCollectionProperty =
DependencyProperty.Register("Controller", typeof(ObservableCollection<DataYSeries>), typeof(GraphMultiController), new PropertyMetadata(null, new PropertyChangedCallback(SetCrossThreadFields)));
private static void SetCrossThreadFields(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as GraphMultiController).OnSetCrossModelFields();
}
protected virtual void OnSetCrossModelFields()
{
this.Dispatcher.Invoke(() =>
{
dataSeriesCollection = DataSeriesCollection;
}, System.Windows.Threading.DispatcherPriority.Send);
}
public GraphMultiController()
: base()
{
DataSeriesCollection = new ObservableCollection<DataSeries.DataYSeries>();
}
public override void Clear()
{
if (clearMethod != null)
{
clearMethod();
}
dataSeriesCollection.ToList().ForEach(x => x.ClearPoints());
}
internal override void ClearPoints()
{
dataSeriesCollection.ToList().ForEach(x => x.ClearPoints());
}
public virtual void PushData(List<double> values)
{
lock (_lock)
{
if (startThreadMethod != null)
{
startThreadMethod();
}
dataSeriesCollection.ToList().ForEach(x => x.PushData(values));
}
}
public virtual void PushData(double[] values)
{
lock (_lock)
{
if (startThreadMethod != null)
{
startThreadMethod();
}
dataSeriesCollection.ToList().ForEach(x => x.PushData(values));
}
}
public virtual void PushData(params List<double>[] arrays)
{
PushData(arrays.ToList());
}
public virtual void PushData(List<List<double>> arrays)
{
lock (_lock)
{
if (startThreadMethod != null)
{
startThreadMethod();
}
for (int i = 0; i < arrays.Count; i++)
{
dataSeriesCollection[i].PushData(arrays[i]);
}
}
}
public virtual void PushData(List<double> array, int dataSeriesIndex)
{
lock (_lock)
{
if (startThreadMethod != null)
{
startThreadMethod();
}
dataSeriesCollection[dataSeriesIndex].PushData(array);
}
}
public virtual void PushDataSingles(List<double> values)
{
lock (_lock)
{
if (startThreadMethod != null)
{
startThreadMethod();
}
for (int i = 0; i < values.Count; i++)
{
dataSeriesCollection[i].PushData(values[i]);
}
}
}
internal virtual List<List<double>> GetAndClearAllPoints()
{
List<List<double>> pointsCollection = new List<List<double>>();
lock (_lock)
{
foreach (var series in dataSeriesCollection)
{
pointsCollection.Add(series.Points.GetAndClearAllPoints());
}
}
return pointsCollection;
}
public void AddSeries(DataYSeries dataSeries)
{
DataSeriesCollection.Add(dataSeries);
}
}
}