/Main/src/DynamicDataDisplay/Charts/Axes/StackCanvas.cs
C# | 237 lines | 199 code | 36 blank | 2 comment | 33 complexity | 527dc53f9e38897aacccf9efabc881c5 MD5 | raw file
Possible License(s): CC-BY-SA-3.0
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Windows.Controls;
- using System.Windows;
- using System.Windows.Media;
- using System.Diagnostics;
- using Microsoft.Research.DynamicDataDisplay.Common.Auxiliary;
-
- namespace Microsoft.Research.DynamicDataDisplay.Charts
- {
- public class StackCanvas : Panel
- {
- public StackCanvas()
- {
- }
-
- #region EndCoordinate attached property
-
- [AttachedPropertyBrowsableForChildren]
- public static double GetEndCoordinate(DependencyObject obj)
- {
- return (double)obj.GetValue(EndCoordinateProperty);
- }
-
- public static void SetEndCoordinate(DependencyObject obj, double value)
- {
- obj.SetValue(EndCoordinateProperty, value);
- }
-
- public static readonly DependencyProperty EndCoordinateProperty = DependencyProperty.RegisterAttached(
- "EndCoordinate",
- typeof(double),
- typeof(StackCanvas),
- new PropertyMetadata(Double.NaN, OnCoordinateChanged));
-
- #endregion
-
- #region Coordinate attached property
-
- [AttachedPropertyBrowsableForChildren]
- public static double GetCoordinate(DependencyObject obj)
- {
- return (double)obj.GetValue(CoordinateProperty);
- }
-
- public static void SetCoordinate(DependencyObject obj, double value)
- {
- obj.SetValue(CoordinateProperty, value);
- }
-
- public static readonly DependencyProperty CoordinateProperty = DependencyProperty.RegisterAttached(
- "Coordinate",
- typeof(double),
- typeof(StackCanvas),
- new PropertyMetadata(0.0, OnCoordinateChanged));
-
- private static void OnCoordinateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- UIElement reference = d as UIElement;
- if (reference != null)
- {
- StackCanvas parent = VisualTreeHelper.GetParent(reference) as StackCanvas;
- if (parent != null)
- {
- parent.InvalidateArrange();
- }
- }
- }
- #endregion
-
- #region AxisPlacement property
-
- public AxisPlacement Placement
- {
- get { return (AxisPlacement)GetValue(PlacementProperty); }
- set { SetValue(PlacementProperty, value); }
- }
-
- public static readonly DependencyProperty PlacementProperty =
- DependencyProperty.Register(
- "Placement",
- typeof(AxisPlacement),
- typeof(StackCanvas),
- new FrameworkPropertyMetadata(
- AxisPlacement.Bottom,
- FrameworkPropertyMetadataOptions.AffectsArrange));
-
- #endregion
-
- private bool IsHorizontal
- {
- get { return Placement == AxisPlacement.Top || Placement == AxisPlacement.Bottom; }
- }
-
- protected override Size MeasureOverride(Size constraint)
- {
- Size availableSize = constraint;
- Size size = new Size();
-
- bool isHorizontal = IsHorizontal;
-
- if (isHorizontal)
- {
- availableSize.Width = Double.PositiveInfinity;
- size.Width = constraint.Width;
- }
- else
- {
- availableSize.Height = Double.PositiveInfinity;
- size.Height = constraint.Height;
- }
-
- // measuring all children and determining self width and height
- foreach (UIElement element in base.Children)
- {
- if (element != null)
- {
- Size childSize = GetChildSize(element, availableSize);
- element.Measure(childSize);
- Size desiredSize = element.DesiredSize;
-
- if (isHorizontal)
- {
- size.Height = Math.Max(size.Height, desiredSize.Height);
- }
- else
- {
- size.Width = Math.Max(size.Width, desiredSize.Width);
- }
- }
- }
-
- if (Double.IsPositiveInfinity(size.Width)) size.Width = 0;
- if (Double.IsPositiveInfinity(size.Height)) size.Height = 0;
-
- return size;
- }
-
- private Size GetChildSize(UIElement element, Size availableSize)
- {
- var coordinate = GetCoordinate(element);
- var endCoordinate = GetEndCoordinate(element);
-
- if (coordinate.IsNotNaN() && endCoordinate.IsNotNaN())
- {
- if (Placement.IsBottomOrTop())
- {
- availableSize.Width = Math.Abs(endCoordinate - coordinate);
- }
- else
- {
- availableSize.Height = Math.Abs(endCoordinate - coordinate);
- }
- }
-
- return availableSize;
- }
-
- protected override Size ArrangeOverride(Size finalSize)
- {
- bool isHorizontal = IsHorizontal;
-
- foreach (FrameworkElement element in base.Children)
- {
- if (element == null)
- {
- continue;
- }
-
- Size elementSize = element.DesiredSize;
- double x = 0.0;
- double y = 0.0;
-
- switch (Placement)
- {
- case AxisPlacement.Left:
- x = finalSize.Width - elementSize.Width;
- break;
- case AxisPlacement.Right:
- x = 0;
- break;
- case AxisPlacement.Top:
- y = finalSize.Height - elementSize.Height;
- break;
- case AxisPlacement.Bottom:
- y = 0;
- break;
- default:
- break;
- }
-
- double coordinate = GetCoordinate(element);
-
- if (!Double.IsNaN(GetEndCoordinate(element)))
- {
- double endCoordinate = GetEndCoordinate(element);
- double size = endCoordinate - coordinate;
- if (size < 0)
- {
- size = -size;
- coordinate -= size;
- }
- if (isHorizontal)
- elementSize.Width = size;
- else
- elementSize.Height = size;
- }
-
-
- // shift for common tick labels, not for major ones.
- if (isHorizontal)
- {
- x = coordinate;
- if (element.HorizontalAlignment == HorizontalAlignment.Center)
- x = coordinate - elementSize.Width / 2;
- }
- else
- {
- y = coordinate;
- if (element.VerticalAlignment == VerticalAlignment.Center)
- y = coordinate - elementSize.Height / 2;
- else if (element.VerticalAlignment == VerticalAlignment.Bottom)
- y = coordinate - elementSize.Height;
- else if (element.VerticalAlignment == VerticalAlignment.Top)
- y = coordinate;
- }
-
- Rect bounds = new Rect(new Point(x, y), elementSize);
- element.Arrange(bounds);
- }
-
- return finalSize;
- }
- }
- }