/Main/src/DynamicDataDisplay.Markers2/PointChartBase.cs
C# | 286 lines | 195 code | 53 blank | 38 comment | 12 complexity | 387122adf0e45e6f800acacda4501bec MD5 | raw file
Possible License(s): CC-BY-SA-3.0
1using System; 2using System.Collections.Generic; 3using System.Linq; 4using System.Text; 5using System.Windows; 6using DynamicDataDisplay.Markers.DataSources; 7using DynamicDataDisplay.Markers.DataSources.DataSourceFactories; 8using System.Diagnostics.Contracts; 9using Microsoft.Research.DynamicDataDisplay.Common.Auxiliary; 10using Microsoft.Research.DynamicDataDisplay.Charts; 11using System.Collections.Specialized; 12using System.Windows.Threading; 13using Microsoft.Research.DynamicDataDisplay.Filters; 14 15namespace Microsoft.Research.DynamicDataDisplay.Markers2 16{ 17 /// <summary> 18 /// Represents a base class for creating marker or line charts. 19 /// </summary> 20 public abstract class PointChartBase : FrameworkElement, IPlotterElement 21 { 22 private Plotter2D plotter = null; 23 private EnvironmentPlugin environmentPlugin = new DefaultLineChartEnvironmentPlugin(); 24 private DataRect visibleWhileCreation; 25 private Rect outputWhileCreation; 26 protected const double rectanglesEps = 0.0005; 27 28 /// <summary> 29 /// Initializes a new instance of the <see cref="PointChartBase"/> class. 30 /// </summary> 31 public PointChartBase() 32 { 33 Viewport2D.SetIsContentBoundsHost(this, true); 34 } 35 36 /// <summary> 37 /// Gets the visible rectangle while creation of points to draw. 38 /// </summary> 39 /// <value>The visible while creation.</value> 40 protected DataRect VisibleWhileCreation 41 { 42 get { return visibleWhileCreation; } 43 } 44 45 /// <summary> 46 /// Gets the output rectangle while creation of points to draw. 47 /// </summary> 48 /// <value>The output while creation.</value> 49 protected Rect OutputWhileCreation 50 { 51 get { return outputWhileCreation; } 52 } 53 54 #region Helpers 55 56 /// <summary> 57 /// Gets or sets the environment plugin. 58 /// </summary> 59 /// <value>The environment plugin.</value> 60 [NotNull] 61 public EnvironmentPlugin EnvironmentPlugin 62 { 63 get { return environmentPlugin; } 64 set 65 { 66 if (value == null) 67 throw new ArgumentNullException("value"); 68 69 environmentPlugin = value; 70 } 71 } 72 73 /// <summary> 74 /// Creates the environment. 75 /// </summary> 76 /// <returns></returns> 77 protected DataSourceEnvironment CreateEnvironment() 78 { 79 if (plotter == null) 80 throw new InvalidOperationException(); 81 82 Viewport2D viewport = plotter.Viewport; 83 DataSourceEnvironment result = environmentPlugin.CreateEnvironment(viewport); 84 85 visibleWhileCreation = result.Visible; 86 outputWhileCreation = result.Output; 87 88 return result; 89 } 90 91 #endregion 92 93 #region ItemsSource 94 95 /// <summary> 96 /// Gets or sets the items source. This is a DependencyProperty. 97 /// </summary> 98 /// <value>The items source.</value> 99 public object ItemsSource 100 { 101 get { return (object)GetValue(ItemsSourceProperty); } 102 set { SetValue(ItemsSourceProperty, value); } 103 } 104 105 public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register( 106 "ItemsSource", 107 typeof(object), 108 typeof(PointChartBase), 109 new FrameworkPropertyMetadata(null, OnItemsSourceReplaced)); 110 111 private static void OnItemsSourceReplaced(DependencyObject d, DependencyPropertyChangedEventArgs e) 112 { 113 PointChartBase owner = (PointChartBase)d; 114 owner.OnItemsSourceReplacedCore(e.OldValue, e.NewValue); 115 } 116 117 protected virtual void OnItemsSourceReplacedCore(object oldValue, object newValue) 118 { 119 object itemsSource = newValue; 120 121 if (itemsSource != null) 122 { 123 var store = DataSourceFactoryStore.Current; 124 var dataSource = store.BuildDataSource(itemsSource); 125 126 if (dataSource != null) 127 { 128 DataSource = dataSource; 129 } 130 else 131 { 132 throw new ArgumentException("Cannot create a DataSource of given ItemsSource. Look into a list of DataSource types to determine what data can be passed."); 133 } 134 } 135 else 136 { 137 DataSource = null; 138 } 139 } 140 141 #endregion 142 143 #region DataSource 144 145 /// <summary> 146 /// Gets or sets the data source. This is a DependencyProperty. 147 /// </summary> 148 /// <value>The data source.</value> 149 public PointDataSourceBase DataSource 150 { 151 get { return (PointDataSourceBase)GetValue(DataSourceProperty); } 152 set { SetValue(DataSourceProperty, value); } 153 } 154 155 public static readonly DependencyProperty DataSourceProperty = DependencyProperty.Register( 156 "DataSource", 157 typeof(PointDataSourceBase), 158 typeof(PointChartBase), 159 new FrameworkPropertyMetadata(null, OnDataSourceReplaced)); 160 161 private static void OnDataSourceReplaced(DependencyObject d, DependencyPropertyChangedEventArgs e) 162 { 163 PointChartBase owner = (PointChartBase)d; 164 owner.OnDataSourceReplaced((PointDataSourceBase)e.OldValue, (PointDataSourceBase)e.NewValue); 165 } 166 167 protected virtual void OnDataSourceReplaced(PointDataSourceBase oldDataSource, PointDataSourceBase newDataSource) 168 { 169 if (oldDataSource != null) 170 oldDataSource.CollectionChanged -= OnDataSource_CollectionChanged; 171 172 if (newDataSource != null) 173 newDataSource.CollectionChanged += OnDataSource_CollectionChanged; 174 } 175 176 private void OnDataSource_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 177 { 178 OnCollectionChanged(e); 179 } 180 181 protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e) { } 182 183 #endregion 184 185 #region IPlotterElement Members 186 187 public virtual void OnPlotterAttached(Plotter plotter) 188 { 189 this.plotter = (Plotter2D)plotter; 190 this.plotter.Viewport.PropertyChanged += new EventHandler<ExtendedPropertyChangedEventArgs>(Viewport_PropertyChanged); 191 } 192 193 private void Viewport_PropertyChanged(object sender, ExtendedPropertyChangedEventArgs e) 194 { 195 OnViewportPropertyChanged(e); 196 } 197 198 protected virtual void OnViewportPropertyChanged(ExtendedPropertyChangedEventArgs e) { } 199 200 public virtual void OnPlotterDetaching(Plotter plotter) 201 { 202 this.plotter.Viewport.PropertyChanged -= Viewport_PropertyChanged; 203 this.plotter = null; 204 } 205 206 Plotter IPlotterElement.Plotter 207 { 208 get { return plotter; } 209 } 210 211 protected Plotter2D Plotter 212 { 213 get { return plotter; } 214 } 215 216 #endregion 217 218 #region Description property 219 220 /// <summary> 221 /// Gets or sets the description of this chart in the legend. 222 /// </summary> 223 /// <value>The description.</value> 224 public string Description 225 { 226 get { return (string)GetValue(Legend.DescriptionProperty); } 227 set { SetValue(Legend.DescriptionProperty, value); } 228 } 229 230 #endregion 231 232 #region DetailedDescription property 233 234 /// <summary> 235 /// Gets or sets the detailed description of this chart in the legend. 236 /// </summary> 237 /// <value>The detailed description.</value> 238 public string DetailedDescription 239 { 240 get { return (string)GetValue(Legend.DetailedDescriptionProperty); } 241 set { SetValue(Legend.DetailedDescriptionProperty, value); } 242 } 243 244 #endregion 245 246 #region IndexRange property 247 248 public static Range<int> GetIndexRange(DependencyObject obj) 249 { 250 return (Range<int>)obj.GetValue(IndexRangeProperty); 251 } 252 253 public static void SetIndexRange(DependencyObject obj, Range<int> value) 254 { 255 obj.SetValue(IndexRangeProperty, value); 256 } 257 258 public static readonly DependencyProperty IndexRangeProperty = DependencyProperty.RegisterAttached( 259 "IndexRange", 260 typeof(Range<int>), 261 typeof(PointChartBase), 262 new FrameworkPropertyMetadata(new Range<int>(IndexWrapper.Empty, IndexWrapper.Empty))); 263 264 #endregion 265 266 #region ContentBounds property 267 268 public static DataRect GetContentBounds(DependencyObject obj) 269 { 270 return (DataRect)obj.GetValue(ContentBoundsProperty); 271 } 272 273 public static void SetContentBounds(DependencyObject obj, DataRect value) 274 { 275 obj.SetValue(ContentBoundsProperty, value); 276 } 277 278 public static readonly DependencyProperty ContentBoundsProperty = DependencyProperty.RegisterAttached( 279 "ContentBounds", 280 typeof(DataRect), 281 typeof(PointChartBase), 282 new FrameworkPropertyMetadata(DataRect.Empty)); 283 284 #endregion 285 } 286}