/Main/src/DynamicDataDisplay.Markers2/PointChartBase.cs

# · C# · 286 lines · 195 code · 53 blank · 38 comment · 12 complexity · 387122adf0e45e6f800acacda4501bec MD5 · raw file

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