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

/V1/trunk/Source/ChartControls/DiscreteAxisPanel.cs

#
C# | 265 lines | 209 code | 36 blank | 20 comment | 22 complexity | 74856e5cf05d493f42236d2ba4e39c63 MD5 | raw file
  1. //===============================================================================
  2. // Microsoft patterns & practices
  3. // Composite Application Guidance for Windows Presentation Foundation
  4. //===============================================================================
  5. // Copyright (c) Microsoft Corporation. All rights reserved.
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
  7. // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
  8. // LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  9. // FITNESS FOR A PARTICULAR PURPOSE.
  10. //===============================================================================
  11. // The example companies, organizations, products, domain names,
  12. // e-mail addresses, logos, people, places, and events depicted
  13. // herein are fictitious. No association with any real company,
  14. // organization, product, domain name, email address, logo, person,
  15. // places, or events is intended or should be inferred.
  16. //===============================================================================
  17. using System.Windows.Controls;
  18. using System.Windows;
  19. using System.Windows.Media;
  20. using System.Collections.ObjectModel;
  21. using System.Windows.Data;
  22. using System;
  23. namespace StockTraderRI.ChartControls
  24. {
  25. public class DiscreteAxisPanel : Panel
  26. {
  27. public DiscreteAxisPanel()
  28. {
  29. TickPositions = new ObservableCollection<double>();
  30. _largestLabelSize = new Size();
  31. }
  32. protected override void OnInitialized(System.EventArgs e)
  33. {
  34. base.OnInitialized(e);
  35. _parentControl = ((ItemsControl)((FrameworkElement)VisualTreeHelper.GetParent(this)).TemplatedParent);
  36. Binding tickBinding = new Binding();
  37. tickBinding.Path = new PropertyPath(DiscreteAxisPanel.TickPositionsProperty);
  38. tickBinding.Source = this;
  39. _parentControl.SetBinding(DiscreteAxis.TickPositionsProperty, tickBinding);
  40. Binding originBinding = new Binding();
  41. originBinding.Path = new PropertyPath(DiscreteAxisPanel.OriginProperty);
  42. originBinding.Source = this;
  43. _parentControl.SetBinding(DiscreteAxis.OriginProperty, originBinding);
  44. }
  45. protected override Size MeasureOverride(Size availableSize)
  46. {
  47. _largestLabelSize.Height = 0.0;
  48. _largestLabelSize.Width = 0.0;
  49. UIElementCollection tempInternalChildren = InternalChildren;
  50. for (int i = 0; i < tempInternalChildren.Count; i++)
  51. {
  52. tempInternalChildren[i].Measure(availableSize);
  53. _largestLabelSize.Height = _largestLabelSize.Height > tempInternalChildren[i].DesiredSize.Height
  54. ? _largestLabelSize.Height : tempInternalChildren[i].DesiredSize.Height;
  55. _largestLabelSize.Width = _largestLabelSize.Width > tempInternalChildren[i].DesiredSize.Width
  56. ? _largestLabelSize.Width : tempInternalChildren[i].DesiredSize.Width;
  57. }
  58. if (Orientation.Equals(Orientation.Vertical))
  59. {
  60. double fitAllLabelSize = _largestLabelSize.Height * InternalChildren.Count;
  61. availableSize.Height = fitAllLabelSize < availableSize.Height ? fitAllLabelSize : availableSize.Height;
  62. availableSize.Width = _largestLabelSize.Width;
  63. }
  64. else
  65. {
  66. double fitAllLabelsSize = _largestLabelSize.Width * InternalChildren.Count;
  67. availableSize.Width = fitAllLabelsSize < availableSize.Width ? fitAllLabelsSize : availableSize.Width;
  68. availableSize.Height = _largestLabelSize.Height;
  69. }
  70. return availableSize;
  71. }
  72. protected override Size ArrangeOverride(Size finalSize)
  73. {
  74. if (InternalChildren.Count > 0)
  75. {
  76. if (Orientation.Equals(Orientation.Horizontal))
  77. {
  78. Origin = TickMarksLength / 2;
  79. ArrangeHorizontalLabels(finalSize);
  80. }
  81. else
  82. {
  83. Origin = finalSize.Height - TickMarksLength / 2;
  84. ArrangeVerticalLabels(finalSize);
  85. }
  86. }
  87. return base.ArrangeOverride(finalSize);
  88. }
  89. private void ArrangeHorizontalLabels(Size constraint)
  90. {
  91. double rectHeight = _largestLabelSize.Height;
  92. double rectWidth = _largestLabelSize.Width;
  93. TickPositions.Clear();
  94. double availableWidth = constraint.Width - TickMarksLength / 2;
  95. int skipfactor;
  96. if (availableWidth < rectWidth)
  97. skipfactor = InternalChildren.Count + 1;
  98. else
  99. skipfactor = (int)Math.Ceiling(InternalChildren.Count/Math.Floor(availableWidth / rectWidth));
  100. skipfactor = Math.Min(skipfactor, (int)Math.Ceiling((double)InternalChildren.Count/2.0));
  101. bool canDisplayAllLabels = true;
  102. if (skipfactor > 1)
  103. {
  104. canDisplayAllLabels = false;
  105. }
  106. double sections = availableWidth / InternalChildren.Count;
  107. double startCord = TickMarksLength/2;
  108. TickPositions.Add(startCord);
  109. for (int i = 0; i < InternalChildren.Count; i++)
  110. {
  111. if (TickPositions.Count - 1 <= i)
  112. TickPositions.Add(startCord + (i + 1) * sections);
  113. else
  114. TickPositions[i + 1] = startCord + (i + 1) * sections;
  115. if (canDisplayAllLabels)
  116. {
  117. Rect r = new Rect(i * sections + sections / 2 - rectWidth / 2, 0, rectWidth, InternalChildren[i].DesiredSize.Height);
  118. InternalChildren[i].Arrange(r);
  119. }
  120. else
  121. {
  122. if((i+1)%skipfactor == 0)
  123. {
  124. double x = i * sections + sections / 2 - rectWidth / 2;
  125. if (x < 0 || x + rectWidth > availableWidth)
  126. {
  127. Rect r1 = new Rect(0, 0, 0, 0);
  128. InternalChildren[i].Arrange(r1);
  129. continue;
  130. }
  131. Rect r = new Rect(i * sections + sections / 2 - rectWidth / 2, 0, rectWidth, InternalChildren[i].DesiredSize.Height);
  132. InternalChildren[i].Arrange(r);
  133. }
  134. else
  135. {
  136. Rect r = new Rect(0, 0, 0, 0);
  137. InternalChildren[i].Arrange(r);
  138. }
  139. }
  140. }
  141. }
  142. private void ArrangeVerticalLabels(Size constraint)
  143. {
  144. double rectHeight = _largestLabelSize.Height;
  145. double rectWidth = _largestLabelSize.Width;
  146. TickPositions.Clear();
  147. double availableHeight = constraint.Height - TickMarksLength / 2;
  148. int skipfactor;
  149. if (availableHeight < rectHeight)
  150. skipfactor = InternalChildren.Count + 1;
  151. else
  152. skipfactor = (int)Math.Ceiling(InternalChildren.Count / Math.Floor(availableHeight / rectHeight));
  153. skipfactor = Math.Min(skipfactor, (int)Math.Ceiling((double)InternalChildren.Count / 2.0));
  154. bool canDisplayAllLabels = true;
  155. if (skipfactor > 1)
  156. {
  157. canDisplayAllLabels = false;
  158. }
  159. double sections = availableHeight / InternalChildren.Count;
  160. for (int i = 0; i < InternalChildren.Count; i++)
  161. {
  162. if (TickPositions.Count <= i)
  163. TickPositions.Add(i * sections);
  164. else
  165. TickPositions[i] = i * sections;
  166. if (canDisplayAllLabels)
  167. {
  168. Rect r = new Rect(0, i * sections + sections / 2 - rectHeight / 2, InternalChildren[i].DesiredSize.Width, InternalChildren[i].DesiredSize.Height);
  169. InternalChildren[i].Arrange(r);
  170. }
  171. else
  172. {
  173. if ((i + 1) % skipfactor == 0)
  174. {
  175. double x = i * sections + sections / 2 - rectHeight / 2;
  176. if (x < 0 || x + rectHeight > availableHeight)
  177. {
  178. Rect r1 = new Rect(0, 0, 0, 0);
  179. InternalChildren[i].Arrange(r1);
  180. continue;
  181. }
  182. Rect r = new Rect(0, i * sections + sections / 2 - rectHeight / 2, InternalChildren[i].DesiredSize.Width, InternalChildren[i].DesiredSize.Height);
  183. InternalChildren[i].Arrange(r);
  184. }
  185. else
  186. {
  187. Rect r = new Rect(0, 0, 0, 0);
  188. InternalChildren[i].Arrange(r);
  189. }
  190. }
  191. }
  192. TickPositions.Add(availableHeight);
  193. }
  194. public double TickMarksLength
  195. {
  196. get { return (double)GetValue(TickMarksLengthProperty); }
  197. set { SetValue(TickMarksLengthProperty, value); }
  198. }
  199. // Using a DependencyProperty as the backing store for TickMarksLength. This enables animation, styling, binding, etc...
  200. public static readonly DependencyProperty TickMarksLengthProperty =
  201. DependencyProperty.Register("TickMarksLength", typeof(double), typeof(DiscreteAxisPanel), new UIPropertyMetadata(null));
  202. public ObservableCollection<double> TickPositions
  203. {
  204. get { return (ObservableCollection<double>)GetValue(TickPositionsProperty); }
  205. set { SetValue(TickPositionsProperty, value); }
  206. }
  207. // Using a DependencyProperty as the backing store for HorizontalAxisTickPositions. This enables animation, styling, binding, etc...
  208. public static readonly DependencyProperty TickPositionsProperty =
  209. DependencyProperty.Register("TickPositions", typeof(ObservableCollection<double>), typeof(DiscreteAxisPanel), new UIPropertyMetadata(null));
  210. public Orientation Orientation
  211. {
  212. get { return (Orientation)GetValue(OrientationProperty); }
  213. set { SetValue(OrientationProperty, value); }
  214. }
  215. // Using a DependencyProperty as the backing store for Orientation. This enables animation, styling, binding, etc...
  216. public static readonly DependencyProperty OrientationProperty =
  217. DependencyProperty.Register("Orientation", typeof(Orientation), typeof(DiscreteAxisPanel), new UIPropertyMetadata(Orientation.Horizontal));
  218. public double Origin
  219. {
  220. get { return (double)GetValue(OriginProperty); }
  221. set { SetValue(OriginProperty, value); }
  222. }
  223. // Using a DependencyProperty as the backing store for Origin. This enables animation, styling, binding, etc...
  224. public static readonly DependencyProperty OriginProperty =
  225. DependencyProperty.Register("Origin", typeof(double), typeof(DiscreteAxisPanel), new UIPropertyMetadata(0.0));
  226. private ItemsControl _parentControl;
  227. private Size _largestLabelSize;
  228. }
  229. }