PageRenderTime 39ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/Diplom/DynamicDataDisplay/Main/src/DynamicDataDisplay/Charts/Legend.xaml.cs

#
C# | 301 lines | 234 code | 47 blank | 20 comment | 28 complexity | 425b18cfb70a623be3e20702dfa0e07b MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. using System.Collections.Generic;
  2. using System.Collections.Specialized;
  3. using System.ComponentModel;
  4. using System.Linq;
  5. using System.Windows;
  6. using System.Windows.Controls;
  7. using System.Windows.Media.Effects;
  8. using System;
  9. namespace Microsoft.Research.DynamicDataDisplay
  10. {
  11. /// <summary>
  12. /// Legend - shows list of annotations to charts.
  13. /// </summary>
  14. public partial class Legend : ContentControl, IPlotterElement
  15. {
  16. /// <summary>
  17. /// Initializes a new instance of the <see cref="Legend"/> class.
  18. /// </summary>
  19. public Legend()
  20. {
  21. InitializeComponent();
  22. #if !RELEASEXBAP
  23. shadowRect.Effect = new DropShadowEffect { Direction = 300, ShadowDepth = 3, Opacity = 0.4 };
  24. #endif
  25. }
  26. #region Position properties
  27. public double LegendLeft
  28. {
  29. get { return (double)GetValue(LegendLeftProperty); }
  30. set { SetValue(LegendLeftProperty, value); }
  31. }
  32. public static readonly DependencyProperty LegendLeftProperty = DependencyProperty.Register(
  33. "LegendLeft",
  34. typeof(double),
  35. typeof(Legend),
  36. new FrameworkPropertyMetadata(Double.NaN));
  37. public double LegendRight
  38. {
  39. get { return (double)GetValue(LegendRightProperty); }
  40. set { SetValue(LegendRightProperty, value); }
  41. }
  42. public static readonly DependencyProperty LegendRightProperty = DependencyProperty.Register(
  43. "LegendRight",
  44. typeof(double),
  45. typeof(Legend),
  46. new FrameworkPropertyMetadata(10.0));
  47. public double LegendBottom
  48. {
  49. get { return (double)GetValue(LegendBottomProperty); }
  50. set { SetValue(LegendBottomProperty, value); }
  51. }
  52. public static readonly DependencyProperty LegendBottomProperty = DependencyProperty.Register(
  53. "LegendBottom",
  54. typeof(double),
  55. typeof(Legend),
  56. new FrameworkPropertyMetadata(Double.NaN));
  57. public double LegendTop
  58. {
  59. get { return (double)GetValue(LegendTopProperty); }
  60. set { SetValue(LegendTopProperty, value); }
  61. }
  62. public static readonly DependencyProperty LegendTopProperty = DependencyProperty.Register(
  63. "LegendTop",
  64. typeof(double),
  65. typeof(Legend),
  66. new FrameworkPropertyMetadata(10.0));
  67. #endregion
  68. public override bool ShouldSerializeContent()
  69. {
  70. return false;
  71. }
  72. #region Plotter attached & detached
  73. private Plotter plotter;
  74. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  75. public Plotter Plotter
  76. {
  77. get { return plotter; }
  78. }
  79. void IPlotterElement.OnPlotterAttached(Plotter plotter)
  80. {
  81. this.plotter = plotter;
  82. plotter.Children.CollectionChanged += OnPlotterChildrenChanged;
  83. plotter.CentralGrid.Children.Add(this);
  84. SubscribeOnEvents();
  85. PopulateLegend();
  86. }
  87. private void SubscribeOnEvents()
  88. {
  89. foreach (var item in plotter.Children.OfType<INotifyPropertyChanged>())
  90. {
  91. item.PropertyChanged += OnChartPropertyChanged;
  92. }
  93. }
  94. private void OnPlotterChildrenChanged(object sender, NotifyCollectionChangedEventArgs e)
  95. {
  96. ManageEvents(e);
  97. PopulateLegend();
  98. }
  99. private void ManageEvents(NotifyCollectionChangedEventArgs e)
  100. {
  101. if (e.OldItems != null)
  102. {
  103. foreach (var item in e.OldItems.OfType<INotifyPropertyChanged>())
  104. {
  105. item.PropertyChanged -= OnChartPropertyChanged;
  106. }
  107. }
  108. if (e.NewItems != null)
  109. {
  110. foreach (var item in e.NewItems.OfType<INotifyPropertyChanged>())
  111. {
  112. item.PropertyChanged += OnChartPropertyChanged;
  113. }
  114. }
  115. }
  116. private void OnChartPropertyChanged(object sender, PropertyChangedEventArgs e)
  117. {
  118. if (e.PropertyName == "Description")
  119. {
  120. ViewportElement2D chart = sender as ViewportElement2D;
  121. if (chart != null && cachedLegendItems.ContainsKey(chart))
  122. {
  123. // todo dirty, but quick to code.
  124. PopulateLegend();
  125. }
  126. }
  127. }
  128. void IPlotterElement.OnPlotterDetaching(Plotter plotter)
  129. {
  130. UnsubscribeFromEvents();
  131. plotter.CentralGrid.Children.Remove(this);
  132. plotter.Children.CollectionChanged -= OnPlotterChildrenChanged;
  133. this.plotter = null;
  134. PopulateLegend();
  135. }
  136. private void UnsubscribeFromEvents()
  137. {
  138. foreach (var item in plotter.Children.OfType<INotifyPropertyChanged>())
  139. {
  140. item.PropertyChanged -= OnChartPropertyChanged;
  141. }
  142. }
  143. #endregion
  144. public Grid ContentGrid
  145. {
  146. get { return grid; }
  147. }
  148. public Panel ContentPanel
  149. {
  150. get { return stackPanel; }
  151. }
  152. private bool autoShowAndHide = true;
  153. /// <summary>
  154. /// Gets or sets a value indicating whether legend automatically shows or hides itself
  155. /// when chart collection changes.
  156. /// </summary>
  157. /// <value><c>true</c> if legend automatically shows and hides itself when chart collection changes; otherwise, <c>false</c>.</value>
  158. public bool AutoShowAndHide
  159. {
  160. get { return autoShowAndHide; }
  161. set { autoShowAndHide = value; }
  162. }
  163. /// <summary>
  164. /// Adds new legend item.
  165. /// </summary>
  166. /// <param name="legendItem">The legend item.</param>
  167. public void AddLegendItem(LegendItem legendItem)
  168. {
  169. stackPanel.Children.Add(legendItem);
  170. UpdateVisibility();
  171. }
  172. /// <summary>
  173. /// Removes the legend item.
  174. /// </summary>
  175. /// <param name="legendItem">The legend item.</param>
  176. public void RemoveLegendItem(LegendItem legendItem)
  177. {
  178. stackPanel.Children.Remove(legendItem);
  179. UpdateVisibility();
  180. }
  181. private void UpdateVisibility()
  182. {
  183. if (stackPanel.Children.Count > 0 && ReadLocalValue(VisibilityProperty) == DependencyProperty.UnsetValue && autoShowAndHide == true)
  184. {
  185. Visibility = Visibility.Visible;
  186. }
  187. else if (stackPanel.Children.Count == 0 && ReadLocalValue(VisibilityProperty) != DependencyProperty.UnsetValue && autoShowAndHide == true)
  188. {
  189. Visibility = Visibility.Hidden;
  190. }
  191. }
  192. private readonly Dictionary<ViewportElement2D, LegendItem> cachedLegendItems = new Dictionary<ViewportElement2D, LegendItem>();
  193. private void ParentChartPlotter_CollectionChanged(object sender, CollectionChangeEventArgs e)
  194. {
  195. stackPanel.Children.Clear();
  196. PopulateLegend();
  197. }
  198. private void graph_PropertyChanged(object sender, PropertyChangedEventArgs e)
  199. {
  200. if (e.PropertyName == "Description")
  201. {
  202. ViewportElement2D graph = (ViewportElement2D)sender;
  203. LegendItem oldLegendItem = cachedLegendItems[graph];
  204. int index = stackPanel.Children.IndexOf(oldLegendItem);
  205. stackPanel.Children.RemoveAt(index);
  206. LegendItem newLegendItem = graph.Description.LegendItem;
  207. cachedLegendItems[graph] = newLegendItem;
  208. stackPanel.Children.Insert(index, newLegendItem);
  209. }
  210. }
  211. public void PopulateLegend()
  212. {
  213. stackPanel.Children.Clear();
  214. if (plotter == null)
  215. {
  216. return;
  217. }
  218. cachedLegendItems.Clear();
  219. foreach (var graph in plotter.Children.OfType<ViewportElement2D>())
  220. {
  221. if (GetVisibleInLegend(graph))
  222. {
  223. LegendItem legendItem = graph.Description.LegendItem;
  224. cachedLegendItems.Add(graph, legendItem);
  225. AddLegendItem(legendItem);
  226. }
  227. }
  228. UpdateVisibility();
  229. }
  230. #region VisibleInLegend attached dependency property
  231. public static bool GetVisibleInLegend(DependencyObject obj)
  232. {
  233. return (bool)obj.GetValue(VisibleInLegendProperty);
  234. }
  235. public static void SetVisibleInLegend(DependencyObject obj, bool value)
  236. {
  237. obj.SetValue(VisibleInLegendProperty, value);
  238. }
  239. public static readonly DependencyProperty VisibleInLegendProperty =
  240. DependencyProperty.RegisterAttached(
  241. "VisibleInLegend",
  242. typeof(bool),
  243. typeof(Legend), new FrameworkPropertyMetadata(false, OnVisibleInLegendChanged));
  244. private static void OnVisibleInLegendChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  245. {
  246. ChartPlotter plotter = Plotter.GetPlotter(d) as ChartPlotter;
  247. if (plotter != null)
  248. {
  249. plotter.Legend.PopulateLegend();
  250. }
  251. }
  252. #endregion
  253. }
  254. }