using System; using System.Windows; using Microsoft.Research.DynamicDataDisplay.DataSources; using System.Collections.Generic; using System.Collections.ObjectModel; using Microsoft.Research.DynamicDataDisplay.Common; using Microsoft.Research.DynamicDataDisplay.Charts; namespace Microsoft.Research.DynamicDataDisplay { public abstract class PointsGraphBase : ViewportElement2D, IOneDimensionalChart { /// /// Initializes a new instance of the class. /// protected PointsGraphBase() { Viewport2D.SetIsContentBoundsHost(this, true); } #region DataSource public IPointDataSource DataSource { get { return (IPointDataSource)GetValue(DataSourceProperty); } set { SetValue(DataSourceProperty, value); } } public static readonly DependencyProperty DataSourceProperty = DependencyProperty.Register( "DataSource", typeof(IPointDataSource), typeof(PointsGraphBase), new FrameworkPropertyMetadata { AffectsRender = true, DefaultValue = null, PropertyChangedCallback = OnDataSourceChangedCallback } ); private static void OnDataSourceChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { PointsGraphBase graph = (PointsGraphBase)d; if (e.NewValue != e.OldValue) { graph.DetachDataSource(e.OldValue as IPointDataSource); graph.AttachDataSource(e.NewValue as IPointDataSource); } graph.OnDataSourceChanged(e); } private void AttachDataSource(IPointDataSource source) { if (source != null) { source.DataChanged += OnDataChanged; } } private void DetachDataSource(IPointDataSource source) { if (source != null) { source.DataChanged -= OnDataChanged; } } private void OnDataChanged(object sender, EventArgs e) { OnDataChanged(); } protected virtual void OnDataChanged() { UpdateBounds(DataSource); RaiseDataChanged(); Update(); } private void RaiseDataChanged() { if (DataChanged != null) { DataChanged(this, EventArgs.Empty); } } public event EventHandler DataChanged; protected virtual void OnDataSourceChanged(DependencyPropertyChangedEventArgs args) { IPointDataSource newDataSource = (IPointDataSource)args.NewValue; if (newDataSource != null) { UpdateBounds(newDataSource); } Update(); } private void UpdateBounds(IPointDataSource dataSource) { if (Plotter2D != null) { var transform = GetTransform(); DataRect bounds = BoundsHelper.GetViewportBounds(dataSource.GetPoints(), transform.DataTransform); Viewport2D.SetContentBounds(this, bounds); } } #endregion #region DataTransform private DataTransform dataTransform = null; public DataTransform DataTransform { get { return dataTransform; } set { if (dataTransform != value) { dataTransform = value; Update(); } } } protected CoordinateTransform GetTransform() { if (Plotter == null) return null; var transform = Plotter2D.Viewport.Transform; if (dataTransform != null) transform = transform.WithDataTransform(dataTransform); return transform; } #endregion #region VisiblePoints public ReadOnlyCollection VisiblePoints { get { return GetVisiblePoints(this); } protected set { SetVisiblePoints(this, value); } } public static ReadOnlyCollection GetVisiblePoints(DependencyObject obj) { return (ReadOnlyCollection)obj.GetValue(VisiblePointsProperty); } public static void SetVisiblePoints(DependencyObject obj, ReadOnlyCollection value) { obj.SetValue(VisiblePointsProperty, value); } public static readonly DependencyProperty VisiblePointsProperty = DependencyProperty.RegisterAttached( "VisiblePoints", typeof(ReadOnlyCollection), typeof(PointsGraphBase), new FrameworkPropertyMetadata(null, OnVisiblePointsChanged)); private static void OnVisiblePointsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { PointsGraphBase graph = d as PointsGraphBase; if (graph != null) { graph.RaiseVisiblePointsChanged(); } } public event EventHandler VisiblePointsChanged; protected void RaiseVisiblePointsChanged() { VisiblePointsChanged.Raise(this); } private bool provideVisiblePoints = false; public bool ProvideVisiblePoints { get { return provideVisiblePoints; } set { provideVisiblePoints = value; UpdateCore(); } } #endregion protected IEnumerable GetPoints() { return DataSource.GetPoints(GetContext()); } private readonly DataSource2dContext context = new DataSource2dContext(); protected DependencyObject GetContext() { //context.VisibleRect = Plotter2D.Viewport.Visible; //context.ScreenRect = Plotter2D.Viewport.Output; return context; } } }