init
This commit is contained in:
102
Backup/DataSources/OneDimensional/CompositeDataSource.cs
Normal file
102
Backup/DataSources/OneDimensional/CompositeDataSource.cs
Normal file
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Collections;
|
||||
|
||||
namespace Microsoft.Research.DynamicDataDisplay.DataSources
|
||||
{
|
||||
/// <summary>Data source that is a composer from several other data sources.</summary>
|
||||
public class CompositeDataSource : IPointDataSource {
|
||||
/// <summary>Initializes a new instance of the <see cref="CompositeDataSource"/> class</summary>
|
||||
public CompositeDataSource() { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CompositeDataSource"/> class.
|
||||
/// </summary>
|
||||
/// <param name="dataSources">Data sources.</param>
|
||||
public CompositeDataSource(params IPointDataSource[] dataSources) {
|
||||
if (dataSources == null)
|
||||
throw new ArgumentNullException("dataSources");
|
||||
|
||||
foreach (var dataSource in dataSources) {
|
||||
AddDataPart(dataSource);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly List<IPointDataSource> dataParts = new List<IPointDataSource>();
|
||||
|
||||
public IEnumerable<IPointDataSource> DataParts {
|
||||
get { return dataParts; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds data part.
|
||||
/// </summary>
|
||||
/// <param name="dataPart">The data part.</param>
|
||||
public void AddDataPart(IPointDataSource dataPart) {
|
||||
if (dataPart == null)
|
||||
throw new ArgumentNullException("dataPart");
|
||||
|
||||
dataParts.Add(dataPart);
|
||||
dataPart.DataChanged += OnPartDataChanged;
|
||||
}
|
||||
|
||||
private void OnPartDataChanged(object sender, EventArgs e) {
|
||||
RaiseDataChanged();
|
||||
}
|
||||
|
||||
#region IPointSource Members
|
||||
|
||||
public event EventHandler DataChanged;
|
||||
protected void RaiseDataChanged() {
|
||||
if (DataChanged != null) {
|
||||
DataChanged(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
public IPointEnumerator GetEnumerator(DependencyObject context) {
|
||||
return new CompositeEnumerator(this, context);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private sealed class CompositeEnumerator : IPointEnumerator {
|
||||
private readonly IEnumerable<IPointEnumerator> enumerators;
|
||||
|
||||
public CompositeEnumerator(CompositeDataSource dataSource, DependencyObject context) {
|
||||
enumerators = dataSource.dataParts.Select(part => part.GetEnumerator(context)).ToList();
|
||||
}
|
||||
|
||||
#region IChartPointEnumerator Members
|
||||
|
||||
public bool MoveNext() {
|
||||
bool res = false;
|
||||
foreach (var enumerator in enumerators) {
|
||||
res |= enumerator.MoveNext();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public void ApplyMappings(DependencyObject glyph) {
|
||||
foreach (var enumerator in enumerators) {
|
||||
enumerator.ApplyMappings(glyph);
|
||||
}
|
||||
}
|
||||
|
||||
public void GetCurrent(ref Point p) {
|
||||
foreach (var enumerator in enumerators) {
|
||||
enumerator.GetCurrent(ref p);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
foreach (var enumerator in enumerators) {
|
||||
enumerator.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
92
Backup/DataSources/OneDimensional/DataSourceExtensions.cs
Normal file
92
Backup/DataSources/OneDimensional/DataSourceExtensions.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
|
||||
namespace Microsoft.Research.DynamicDataDisplay.DataSources
|
||||
{
|
||||
public static class DataSourceExtensions
|
||||
{
|
||||
public static RawDataSource AsDataSource(this IEnumerable<Point> points)
|
||||
{
|
||||
return new RawDataSource(points);
|
||||
}
|
||||
|
||||
public static EnumerableDataSource<T> AsDataSource<T>(this IEnumerable<T> collection)
|
||||
{
|
||||
return new EnumerableDataSource<T>(collection);
|
||||
}
|
||||
|
||||
public static EnumerableDataSource<T> AsXDataSource<T>(this IEnumerable<T> collection)
|
||||
{
|
||||
if (typeof(T) == typeof(double))
|
||||
{
|
||||
return ((IEnumerable<double>)collection).AsXDataSource() as EnumerableDataSource<T>;
|
||||
}
|
||||
else if (typeof(T) == typeof(float))
|
||||
{
|
||||
return ((IEnumerable<float>)collection).AsXDataSource() as EnumerableDataSource<T>;
|
||||
}
|
||||
|
||||
return new EnumerableXDataSource<T>(collection);
|
||||
}
|
||||
|
||||
public static EnumerableDataSource<float> AsXDataSource(this IEnumerable<float> collection)
|
||||
{
|
||||
EnumerableXDataSource<float> ds = new EnumerableXDataSource<float>(collection);
|
||||
ds.SetXMapping(f => (double)f);
|
||||
return ds;
|
||||
}
|
||||
|
||||
public static EnumerableDataSource<T> AsYDataSource<T>(this IEnumerable<T> collection)
|
||||
{
|
||||
if (typeof(T) == typeof(double))
|
||||
{
|
||||
return ((IEnumerable<double>)collection).AsYDataSource() as EnumerableDataSource<T>;
|
||||
}
|
||||
else if (typeof(T) == typeof(float))
|
||||
{
|
||||
return ((IEnumerable<float>)collection).AsYDataSource() as EnumerableDataSource<T>;
|
||||
}
|
||||
|
||||
return new EnumerableYDataSource<T>(collection);
|
||||
}
|
||||
|
||||
public static EnumerableDataSource<double> AsXDataSource(this IEnumerable<double> collection)
|
||||
{
|
||||
EnumerableXDataSource<double> ds = new EnumerableXDataSource<double>(collection);
|
||||
ds.SetXMapping(x => x);
|
||||
return ds;
|
||||
}
|
||||
|
||||
public static EnumerableDataSource<double> AsYDataSource(this IEnumerable<double> collection)
|
||||
{
|
||||
EnumerableYDataSource<double> ds = new EnumerableYDataSource<double>(collection);
|
||||
ds.SetYMapping(y => y);
|
||||
return ds;
|
||||
}
|
||||
|
||||
public static EnumerableDataSource<float> AsYDataSource(this IEnumerable<float> collection)
|
||||
{
|
||||
EnumerableYDataSource<float> ds = new EnumerableYDataSource<float>(collection);
|
||||
ds.SetYMapping(f => (double)f);
|
||||
return ds;
|
||||
}
|
||||
|
||||
public static CompositeDataSource Join(this IPointDataSource ds1, IPointDataSource ds2)
|
||||
{
|
||||
return new CompositeDataSource(ds1, ds2);
|
||||
}
|
||||
|
||||
public static IEnumerable<Point> GetPoints(this IPointDataSource dataSource)
|
||||
{
|
||||
return DataSourceHelper.GetPoints(dataSource);
|
||||
}
|
||||
|
||||
public static IEnumerable<Point> GetPoints(this IPointDataSource dataSource, DependencyObject context)
|
||||
{
|
||||
return DataSourceHelper.GetPoints(dataSource, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
35
Backup/DataSources/OneDimensional/DataSourceHelper.cs
Normal file
35
Backup/DataSources/OneDimensional/DataSourceHelper.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
using Microsoft.Research.DynamicDataDisplay.Charts;
|
||||
|
||||
namespace Microsoft.Research.DynamicDataDisplay.DataSources
|
||||
{
|
||||
public static class DataSourceHelper
|
||||
{
|
||||
public static IEnumerable<Point> GetPoints(IPointDataSource dataSource)
|
||||
{
|
||||
return GetPoints(dataSource, null);
|
||||
}
|
||||
|
||||
public static IEnumerable<Point> GetPoints(IPointDataSource dataSource, DependencyObject context)
|
||||
{
|
||||
if (dataSource == null)
|
||||
throw new ArgumentNullException("dataSource");
|
||||
|
||||
if (context == null)
|
||||
context = new DataSource2dContext();
|
||||
|
||||
using (IPointEnumerator enumerator = dataSource.GetEnumerator(context))
|
||||
{
|
||||
Point p = new Point();
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
enumerator.GetCurrent(ref p);
|
||||
yield return p;
|
||||
p = new Point();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
55
Backup/DataSources/OneDimensional/EmptyDataSource.cs
Normal file
55
Backup/DataSources/OneDimensional/EmptyDataSource.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Microsoft.Research.DynamicDataDisplay.DataSources
|
||||
{
|
||||
/// <summary>
|
||||
/// Empty data source - for testing purposes, represents data source with 0 points inside.
|
||||
/// </summary>
|
||||
public class EmptyDataSource : IPointDataSource
|
||||
{
|
||||
#region IPointDataSource Members
|
||||
|
||||
public IPointEnumerator GetEnumerator(DependencyObject context)
|
||||
{
|
||||
return new EmptyPointEnumerator();
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
private void RaiseDataChanged()
|
||||
{
|
||||
if (DataChanged != null)
|
||||
{
|
||||
DataChanged(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler DataChanged;
|
||||
|
||||
#endregion
|
||||
|
||||
private sealed class EmptyPointEnumerator : IPointEnumerator
|
||||
{
|
||||
public bool MoveNext()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void GetCurrent(ref Point p)
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
public void ApplyMappings(DependencyObject target)
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
public void Dispose() { }
|
||||
}
|
||||
}
|
||||
}
|
||||
109
Backup/DataSources/OneDimensional/EnumerableDataSource.cs
Normal file
109
Backup/DataSources/OneDimensional/EnumerableDataSource.cs
Normal file
@@ -0,0 +1,109 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
|
||||
namespace Microsoft.Research.DynamicDataDisplay.DataSources
|
||||
{
|
||||
public class EnumerableDataSource<T> : EnumerableDataSourceBase<T>
|
||||
{
|
||||
public EnumerableDataSource(IEnumerable<T> data) : base(data) { }
|
||||
|
||||
public EnumerableDataSource(IEnumerable data) : base(data) { }
|
||||
|
||||
private readonly List<Mapping<T>> mappings = new List<Mapping<T>>();
|
||||
private Func<T, double> xMapping;
|
||||
private Func<T, double> yMapping;
|
||||
private Func<T, Point> xyMapping;
|
||||
|
||||
public Func<T, double> XMapping
|
||||
{
|
||||
get { return xMapping; }
|
||||
set { SetXMapping(value); }
|
||||
}
|
||||
|
||||
public Func<T, double> YMapping
|
||||
{
|
||||
get { return yMapping; }
|
||||
set { SetYMapping(value); }
|
||||
}
|
||||
|
||||
public Func<T, Point> XYMapping
|
||||
{
|
||||
get { return xyMapping; }
|
||||
set { SetXYMapping(value); }
|
||||
}
|
||||
|
||||
public void SetXMapping(Func<T, double> mapping)
|
||||
{
|
||||
if (mapping == null)
|
||||
throw new ArgumentNullException("mapping");
|
||||
|
||||
this.xMapping = mapping;
|
||||
RaiseDataChanged();
|
||||
}
|
||||
|
||||
public void SetYMapping(Func<T, double> mapping)
|
||||
{
|
||||
if (mapping == null)
|
||||
throw new ArgumentNullException("mapping");
|
||||
|
||||
this.yMapping = mapping;
|
||||
RaiseDataChanged();
|
||||
}
|
||||
|
||||
public void SetXYMapping(Func<T, Point> mapping)
|
||||
{
|
||||
if (mapping == null)
|
||||
throw new ArgumentNullException("mapping");
|
||||
|
||||
this.xyMapping = mapping;
|
||||
RaiseDataChanged();
|
||||
}
|
||||
|
||||
public void AddMapping(DependencyProperty property, Func<T, object> mapping)
|
||||
{
|
||||
if (property == null)
|
||||
throw new ArgumentNullException("property");
|
||||
if (mapping == null)
|
||||
throw new ArgumentNullException("mapping");
|
||||
|
||||
mappings.Add(new Mapping<T> { Property = property, F = mapping });
|
||||
}
|
||||
|
||||
public override IPointEnumerator GetEnumerator(DependencyObject context)
|
||||
{
|
||||
return new EnumerablePointEnumerator<T>(this);
|
||||
}
|
||||
|
||||
internal void FillPoint(T elem, ref Point point)
|
||||
{
|
||||
if (xyMapping != null)
|
||||
{
|
||||
point = xyMapping(elem);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (xMapping != null)
|
||||
{
|
||||
point.X = xMapping(elem);
|
||||
}
|
||||
if (yMapping != null)
|
||||
{
|
||||
point.Y = yMapping(elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void ApplyMappings(DependencyObject target, T elem)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
foreach (var mapping in mappings)
|
||||
{
|
||||
target.SetValue(mapping.Property, mapping.F(elem));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
|
||||
namespace Microsoft.Research.DynamicDataDisplay.DataSources
|
||||
{
|
||||
/// <summary>Base class for all sources who receive data for charting
|
||||
/// from any IEnumerable of T</summary>
|
||||
/// <typeparam name="T">Type of items in IEnumerable</typeparam>
|
||||
public abstract class EnumerableDataSourceBase<T> : IPointDataSource {
|
||||
private IEnumerable data;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the data.
|
||||
/// </summary>
|
||||
/// <value>The data.</value>
|
||||
public IEnumerable Data {
|
||||
get { return data; }
|
||||
set {
|
||||
if (value == null)
|
||||
throw new ArgumentNullException("value");
|
||||
|
||||
data = value;
|
||||
|
||||
var observableCollection = data as INotifyCollectionChanged;
|
||||
if (observableCollection != null) {
|
||||
observableCollection.CollectionChanged += observableCollection_CollectionChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected EnumerableDataSourceBase(IEnumerable<T> data) : this((IEnumerable)data) { }
|
||||
|
||||
protected EnumerableDataSourceBase(IEnumerable data) {
|
||||
if (data == null)
|
||||
throw new ArgumentNullException("data");
|
||||
Data = data;
|
||||
}
|
||||
|
||||
private void observableCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) {
|
||||
RaiseDataChanged();
|
||||
}
|
||||
|
||||
public event EventHandler DataChanged;
|
||||
public void RaiseDataChanged() {
|
||||
if (DataChanged != null) {
|
||||
DataChanged(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract IPointEnumerator GetEnumerator(DependencyObject context);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System.Collections;
|
||||
using System.Windows;
|
||||
|
||||
namespace Microsoft.Research.DynamicDataDisplay.DataSources
|
||||
{
|
||||
/// <summary>This enumerator enumerates given enumerable object as sequence of points</summary>
|
||||
/// <typeparam name="T">Type parameter of source IEnumerable</typeparam>
|
||||
public sealed class EnumerablePointEnumerator<T> : IPointEnumerator {
|
||||
private readonly EnumerableDataSource<T> dataSource;
|
||||
private readonly IEnumerator enumerator;
|
||||
|
||||
public EnumerablePointEnumerator(EnumerableDataSource<T> dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
enumerator = dataSource.Data.GetEnumerator();
|
||||
}
|
||||
|
||||
public bool MoveNext() {
|
||||
return enumerator.MoveNext();
|
||||
}
|
||||
|
||||
public void GetCurrent(ref Point p) {
|
||||
dataSource.FillPoint((T)enumerator.Current, ref p);
|
||||
}
|
||||
|
||||
public void ApplyMappings(DependencyObject target) {
|
||||
dataSource.ApplyMappings(target, (T)enumerator.Current);
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
//enumerator.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Backup/DataSources/OneDimensional/EnumerableXDataSource.cs
Normal file
12
Backup/DataSources/OneDimensional/EnumerableXDataSource.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.Research.DynamicDataDisplay.DataSources
|
||||
{
|
||||
internal sealed class EnumerableXDataSource<T> : EnumerableDataSource<T>
|
||||
{
|
||||
public EnumerableXDataSource(IEnumerable<T> data) : base(data) { }
|
||||
}
|
||||
}
|
||||
12
Backup/DataSources/OneDimensional/EnumerableYDataSource.cs
Normal file
12
Backup/DataSources/OneDimensional/EnumerableYDataSource.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.Research.DynamicDataDisplay.DataSources
|
||||
{
|
||||
internal sealed class EnumerableYDataSource<T> : EnumerableDataSource<T>
|
||||
{
|
||||
public EnumerableYDataSource(IEnumerable<T> data) : base(data) { }
|
||||
}
|
||||
}
|
||||
16
Backup/DataSources/OneDimensional/IPointDataSource.cs
Normal file
16
Backup/DataSources/OneDimensional/IPointDataSource.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
|
||||
namespace Microsoft.Research.DynamicDataDisplay.DataSources
|
||||
{
|
||||
/// <summary>Data source that returns sequence of 2D points.</summary>
|
||||
public interface IPointDataSource
|
||||
{
|
||||
|
||||
/// <summary>Returns object to enumerate points in source.</summary>
|
||||
IPointEnumerator GetEnumerator(DependencyObject context);
|
||||
|
||||
/// <summary>This event is raised when contents of source are changed.</summary>
|
||||
event EventHandler DataChanged;
|
||||
}
|
||||
}
|
||||
21
Backup/DataSources/OneDimensional/IPointEnumerator.cs
Normal file
21
Backup/DataSources/OneDimensional/IPointEnumerator.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
|
||||
namespace Microsoft.Research.DynamicDataDisplay.DataSources
|
||||
{
|
||||
public interface IPointEnumerator : IDisposable {
|
||||
/// <summary>Move to next point in sequence</summary>
|
||||
/// <returns>True if successfully moved to next point
|
||||
/// or false if end of sequence is reached</returns>
|
||||
bool MoveNext();
|
||||
|
||||
/// <summary>Stores current value(s) in given point.</summary>
|
||||
/// <param name="p">Reference to store value</param>
|
||||
/// <remarks>Depending on implementing class this method may set only X or Y
|
||||
/// fields in specified point. That's why GetCurrent is a regular method and
|
||||
/// not a property as in standard enumerators</remarks>
|
||||
void GetCurrent(ref Point p);
|
||||
|
||||
void ApplyMappings(DependencyObject target);
|
||||
}
|
||||
}
|
||||
15
Backup/DataSources/OneDimensional/Mapping.cs
Normal file
15
Backup/DataSources/OneDimensional/Mapping.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
|
||||
namespace Microsoft.Research.DynamicDataDisplay.DataSources
|
||||
{
|
||||
/// <summary>Mapping class holds information about mapping of TSource type
|
||||
/// to some DependencyProperty.</summary>
|
||||
/// <typeparam name="TSource">Mapping source type.</typeparam>
|
||||
internal sealed class Mapping<TSource> {
|
||||
/// <summary>Property that will be set.</summary>
|
||||
internal DependencyProperty Property { get; set; }
|
||||
/// <summary>Function that computes value for property from TSource type.</summary>
|
||||
internal Func<TSource, object> F { get; set; }
|
||||
}
|
||||
}
|
||||
220
Backup/DataSources/OneDimensional/ObservableDataSource.cs
Normal file
220
Backup/DataSources/OneDimensional/ObservableDataSource.cs
Normal file
@@ -0,0 +1,220 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.Windows;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace Microsoft.Research.DynamicDataDisplay.DataSources
|
||||
{
|
||||
// todo I don't think that we should create data source which supports
|
||||
// suspending its DataChanged event - it is better to create
|
||||
// collection with the same functionality - then it would be able to be used
|
||||
// as a source in many data sources.
|
||||
public class ObservableDataSource<T> : IPointDataSource
|
||||
{
|
||||
|
||||
/// <summary>True if collection was changed between SuspendUpdate and ResumeUpdate
|
||||
/// or false otherwise</summary>
|
||||
private bool collectionChanged = false;
|
||||
|
||||
/// <summary>True if event should be raised on each collection change
|
||||
/// or false otherwise</summary>
|
||||
private bool updatesEnabled = true;
|
||||
|
||||
public ObservableDataSource()
|
||||
{
|
||||
collection.CollectionChanged += OnCollectionChanged;
|
||||
|
||||
// todo this is hack
|
||||
if (typeof(T) == typeof(Point))
|
||||
{
|
||||
xyMapping = t => (Point)(object)t;
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableDataSource(IEnumerable<T> data)
|
||||
: this()
|
||||
{
|
||||
if (data == null)
|
||||
throw new ArgumentNullException("data");
|
||||
|
||||
foreach (T item in data)
|
||||
{
|
||||
collection.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
public void SuspendUpdate()
|
||||
{
|
||||
updatesEnabled = false;
|
||||
}
|
||||
|
||||
public void ResumeUpdate()
|
||||
{
|
||||
updatesEnabled = true;
|
||||
if (collectionChanged)
|
||||
{
|
||||
collectionChanged = false;
|
||||
RaiseDataChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
if (updatesEnabled)
|
||||
{
|
||||
RaiseDataChanged();
|
||||
}
|
||||
else
|
||||
{
|
||||
collectionChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly ObservableCollection<T> collection = new ObservableCollection<T>();
|
||||
|
||||
public ObservableCollection<T> Collection
|
||||
{
|
||||
get { return collection; }
|
||||
}
|
||||
|
||||
public void AppendMany(IEnumerable<T> data)
|
||||
{
|
||||
if (data == null)
|
||||
throw new ArgumentNullException("data");
|
||||
|
||||
updatesEnabled = false;
|
||||
foreach (var p in data)
|
||||
{
|
||||
collection.Add(p);
|
||||
}
|
||||
updatesEnabled = true;
|
||||
RaiseDataChanged();
|
||||
}
|
||||
|
||||
public void AppendAsync(Dispatcher dispatcher, T item)
|
||||
{
|
||||
dispatcher.Invoke(DispatcherPriority.Normal,
|
||||
new Action(() =>
|
||||
{
|
||||
collection.Add(item);
|
||||
RaiseDataChanged();
|
||||
}));
|
||||
}
|
||||
|
||||
private readonly List<Mapping<T>> mappings = new List<Mapping<T>>();
|
||||
private Func<T, double> xMapping;
|
||||
private Func<T, double> yMapping;
|
||||
private Func<T, Point> xyMapping;
|
||||
|
||||
public void SetXMapping(Func<T, double> mapping)
|
||||
{
|
||||
if (mapping == null)
|
||||
throw new ArgumentNullException("mapping");
|
||||
|
||||
this.xMapping = mapping;
|
||||
}
|
||||
|
||||
public void SetYMapping(Func<T, double> mapping)
|
||||
{
|
||||
if (mapping == null)
|
||||
throw new ArgumentNullException("mapping");
|
||||
|
||||
this.yMapping = mapping;
|
||||
}
|
||||
|
||||
public void SetXYMapping(Func<T, Point> mapping)
|
||||
{
|
||||
if (mapping == null)
|
||||
throw new ArgumentNullException("mapping");
|
||||
|
||||
this.xyMapping = mapping;
|
||||
}
|
||||
|
||||
#region IChartDataSource Members
|
||||
|
||||
private class ObservableIterator : IPointEnumerator
|
||||
{
|
||||
private readonly ObservableDataSource<T> dataSource;
|
||||
private readonly IEnumerator<T> enumerator;
|
||||
|
||||
public ObservableIterator(ObservableDataSource<T> dataSource)
|
||||
{
|
||||
this.dataSource = dataSource;
|
||||
enumerator = dataSource.collection.GetEnumerator();
|
||||
}
|
||||
|
||||
#region IChartPointEnumerator Members
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
return enumerator.MoveNext();
|
||||
}
|
||||
|
||||
public void GetCurrent(ref Point p)
|
||||
{
|
||||
dataSource.FillPoint(enumerator.Current, ref p);
|
||||
}
|
||||
|
||||
public void ApplyMappings(DependencyObject target)
|
||||
{
|
||||
dataSource.ApplyMappings(target, enumerator.Current);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
enumerator.Dispose();
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
private void FillPoint(T elem, ref Point point)
|
||||
{
|
||||
if (xyMapping != null)
|
||||
{
|
||||
point = xyMapping(elem);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (xMapping != null)
|
||||
{
|
||||
point.X = xMapping(elem);
|
||||
}
|
||||
if (yMapping != null)
|
||||
{
|
||||
point.Y = yMapping(elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyMappings(DependencyObject target, T elem)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
foreach (var mapping in mappings)
|
||||
{
|
||||
target.SetValue(mapping.Property, mapping.F(elem));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IPointEnumerator GetEnumerator(DependencyObject context)
|
||||
{
|
||||
return new ObservableIterator(this);
|
||||
}
|
||||
|
||||
public event EventHandler DataChanged;
|
||||
private void RaiseDataChanged()
|
||||
{
|
||||
if (DataChanged != null)
|
||||
{
|
||||
DataChanged(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
14
Backup/DataSources/OneDimensional/RawDataSource.cs
Normal file
14
Backup/DataSources/OneDimensional/RawDataSource.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
|
||||
namespace Microsoft.Research.DynamicDataDisplay.DataSources
|
||||
{
|
||||
public sealed class RawDataSource : EnumerableDataSourceBase<Point> {
|
||||
public RawDataSource(params Point[] data) : base(data) { }
|
||||
public RawDataSource(IEnumerable<Point> data) : base(data) { }
|
||||
|
||||
public override IPointEnumerator GetEnumerator(DependencyObject context) {
|
||||
return new RawPointEnumerator(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
29
Backup/DataSources/OneDimensional/RawPointEnumerator.cs
Normal file
29
Backup/DataSources/OneDimensional/RawPointEnumerator.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System.Collections;
|
||||
using System.Windows;
|
||||
|
||||
namespace Microsoft.Research.DynamicDataDisplay.DataSources
|
||||
{
|
||||
public sealed class RawPointEnumerator : IPointEnumerator {
|
||||
private readonly IEnumerator enumerator;
|
||||
|
||||
public RawPointEnumerator(RawDataSource dataSource) {
|
||||
this.enumerator = dataSource.Data.GetEnumerator();
|
||||
}
|
||||
|
||||
public bool MoveNext() {
|
||||
return enumerator.MoveNext();
|
||||
}
|
||||
|
||||
public void GetCurrent(ref Point p) {
|
||||
p = (Point)enumerator.Current;
|
||||
}
|
||||
|
||||
public void ApplyMappings(DependencyObject target) {
|
||||
// do nothing here - no mapping supported
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
// do nothing here
|
||||
}
|
||||
}
|
||||
}
|
||||
32
Backup/DataSources/OneDimensional/TableDataSource.cs
Normal file
32
Backup/DataSources/OneDimensional/TableDataSource.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.Research.DynamicDataDisplay.DataSources
|
||||
{
|
||||
/// <summary>Data source that extracts sequence of points and their attributes from DataTable</summary>
|
||||
public class TableDataSource : EnumerableDataSource<DataRow>
|
||||
{
|
||||
public TableDataSource(DataTable table)
|
||||
: base(table.Rows)
|
||||
{
|
||||
// Subscribe to DataTable events
|
||||
table.TableNewRow += NewRowInsertedHandler;
|
||||
table.RowChanged += RowChangedHandler;
|
||||
table.RowDeleted += RowChangedHandler;
|
||||
}
|
||||
|
||||
private void RowChangedHandler(object sender, DataRowChangeEventArgs e)
|
||||
{
|
||||
RaiseDataChanged();
|
||||
}
|
||||
|
||||
private void NewRowInsertedHandler(object sender, DataTableNewRowEventArgs e)
|
||||
{
|
||||
// Raise DataChanged event. ChartPlotter should redraw graph.
|
||||
// This will be done automatically when rows are added to table.
|
||||
RaiseDataChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user