Esempio n. 1
0
        /// <summary>
        /// Returns a sequence of TreeMapNodes in breadth-first order.
        /// </summary>
        /// <returns>Sequence of TreeMapNodes.</returns>
        private IEnumerable <TreeMapNode> GetTreeMapNodes()
        {
            if (_getTreeMapNodesCache == null)
            {
                // Create a new list
                List <TreeMapNode> allNodes = new List <TreeMapNode>();

                // Seed the queue with the roots
                Queue <TreeMapNode> nodes = new Queue <TreeMapNode>();
                foreach (TreeMapNode node in _nodeRoots ?? Enumerable.Empty <TreeMapNode>())
                {
                    nodes.Enqueue(node);
                }
                // Process the queue in breadth-first order
                while (0 < nodes.Count)
                {
                    TreeMapNode node = nodes.Dequeue();
                    allNodes.Add(node);
                    foreach (TreeMapNode child in node.Children)
                    {
                        nodes.Enqueue(child);
                    }
                }

                // Cache the list
                _getTreeMapNodesCache = allNodes;
            }

            // Return the cached sequence
            return(_getTreeMapNodesCache);
        }
        public void NullChildrenReturnsEmptyEnumeration()
        {
            SquaringAlgorithm rect = new SquaringAlgorithm();
            TreeMapNode node = new TreeMapNode
            {
                Area = 1.0,
                Children = null
            };

            IEnumerable<Tuple<Rect, TreeMapNode>> result = rect.Split(new Rect(0, 0, 100, 100), node, NoThickness).ToArray();

            Assert.IsFalse(result.Any());
        }
        public void ZeroParentAreaReturnsEmptyEnumeration()
        {
            SquaringAlgorithm rect = new SquaringAlgorithm();
            TreeMapNode node = new TreeMapNode
            {
                Area = 0.0,
                Children = new List<TreeMapNode>
                {
                    new TreeMapNode { Area = 0.0, Children = null }
                }
            };

            IList<SWCDV::Tuple<Rect, TreeMapNode>> result = rect.Split(new Rect(0, 0, 100, 100), node, NoThickness).ToArray();

            Assert.IsFalse(result.Any());
        }
Esempio n. 4
0
        /// <summary>
        /// Performs the Arrange pass of the layout.
        /// </summary>
        /// <remarks>
        /// We round rectangles to snap to nearest pixels. We do that to avoid
        /// anti-aliasing which results in better appearance. Moreover to get
        /// correct layout we would need to use UseLayoutRounding=false which
        /// is Silverlight specific. A side effect is that areas for rectangles
        /// in the visual tree no longer can be used to compare them as dimensions
        /// are not rounded and therefore not precise.
        /// </remarks>
        /// <param name="finalSize">The final area within the parent that this element should use to arrange itself and its children.</param>
        /// <returns>The actual size used.</returns>
        protected override Size ArrangeOverride(Size finalSize)
        {
            // Sets ActualHeight & ActualWidth for the container
            finalSize = base.ArrangeOverride(finalSize);

            if (_nodeRoots != null && ContainerElement != null)
            {
                // Create a temporary pseudo-root node containing all the top-level nodes
                TreeMapNode root = new TreeMapNode()
                {
                    Area             = _nodeRoots.Sum(x => x.Area),
                    Children         = _nodeRoots,
                    ChildItemPadding = new Thickness(0)
                };

                // Calculate associated rectangles. We use ContainerElement,
                // not finalSize so all elements that are above it like border
                // (with padding and border) are taken into account
                IEnumerable <Tuple <Rect, TreeMapNode> > measuredRectangles = ComputeRectangles(
                    root,
                    new Rect(0, 0, ContainerElement.ActualWidth, ContainerElement.ActualHeight));

                // Position everything
                foreach (Tuple <Rect, TreeMapNode> rectangle in measuredRectangles)
                {
                    FrameworkElement element = rectangle.Item2.Element;
                    if (element != null)
                    {
                        double roundedTop  = Math.Round(rectangle.Item1.Top);
                        double roundedLeft = Math.Round(rectangle.Item1.Left);
                        double height      = Math.Round(rectangle.Item1.Height + rectangle.Item1.Top) - roundedTop;
                        double width       = Math.Round(rectangle.Item1.Width + rectangle.Item1.Left) - roundedLeft;

                        // Fully specify element location/size (setting size is required on WPF)
                        Canvas.SetLeft(element, roundedLeft);
                        Canvas.SetTop(element, roundedTop);
                        element.Width  = width;
                        element.Height = height;

                        element.Arrange(new Rect(roundedLeft, roundedTop, width, height));
                    }
                }
            }

            return(finalSize);
        }
Esempio n. 5
0
        /// <summary>
        ///     Subdivides the parent rectangle using squaring tree map algorithm into
        ///     rectangles with areas specified by the children. The areas must add up
        ///     to at most the area of the rectangle.
        /// </summary>
        /// <param name="parentRectangle">Total area being split.</param>
        /// <param name="parentNode">
        ///     The node associated with the total area. The
        ///     children of this node will be allocated small chunks of the parent rectangle.
        /// </param>
        /// <param name="margin">How much of a gap should be left between the parent rectangle and the children.</param>
        /// <returns>A list of RectangularArea objects describing areas associated with each of the children of parentNode.</returns>
        public IEnumerable <Tuple <Rect, TreeMapNode> > Split(Rect parentRectangle, TreeMapNode parentNode,
                                                              Thickness margin)
        {
            IEnumerable <Tuple <Rect, TreeMapNode> > retVal;

            double area = parentNode.Area;

            if (parentNode.Children == null || parentNode.Children.Count() == 0 || area == 0)
            {
                retVal = Enumerable.Empty <Tuple <Rect, TreeMapNode> >();
            }
            else
            {
                if (parentRectangle.Width - margin.Left - margin.Right <= 0 ||
                    parentRectangle.Height - margin.Top - margin.Bottom <= 0)
                {
                    // Margins too big, no more room for children. Returning
                    // zero sized rectangles for all children.
                    retVal = from child in parentNode.Children
                             select new Tuple <Rect, TreeMapNode>(new Rect(0, 0, 0, 0), child);
                }
                else
                {
                    // Leave as much room as specified by the margin
                    _currentRectangle = new Rect(
                        parentRectangle.X + margin.Left,
                        parentRectangle.Y + margin.Top,
                        parentRectangle.Width - margin.Left - margin.Right,
                        parentRectangle.Height - margin.Top - margin.Bottom);

                    _areas = (from child in parentNode.Children
                              where child.Area != 0
                              orderby child.Area descending
                              select child).ToArray();

                    // Factor is only computed once and used during the algorithm
                    _factor = _currentRectangle.Width * _currentRectangle.Height / area;

                    retVal = BuildTreeMap().ToArray();
                }
            }

            return(retVal);
        }
        /// <summary>
        /// Subdivides the parent rectangle using squaring tree map algorithm into
        /// rectangles with areas specified by the children. The areas must add up 
        /// to at most the area of the rectangle.
        /// </summary>
        /// <param name="parentRectangle">Total area being split.</param>
        /// <param name="parentNode">The node associated with the total area. The 
        /// children of this node will be allocated small chunks of the parent rectangle.</param>
        /// <param name="margin">How much of a gap should be left between the parent rectangle and the children.</param>
        /// <returns>A list of RectangularArea objects describing areas associated with each of the children of parentNode.</returns>
        public IEnumerable<Tuple<Rect, TreeMapNode>> Split(Rect parentRectangle, TreeMapNode parentNode, Thickness margin)
        {
            IEnumerable<Tuple<Rect, TreeMapNode>> retVal;

            double area = parentNode.Area;
            if (parentNode.Children == null || parentNode.Children.Count() == 0 || area == 0)
            {
                retVal = Enumerable.Empty<Tuple<Rect, TreeMapNode>>();
            }
            else
            {
                if (parentRectangle.Width - margin.Left - margin.Right <= 0 ||
                    parentRectangle.Height - margin.Top - margin.Bottom <= 0)
                {
                    // Margins too big, no more room for children. Returning
                    // zero sized rectangles for all children.
                    retVal = from child in parentNode.Children
                             select new Tuple<Rect, TreeMapNode>(new Rect(0, 0, 0, 0), child);
                }
                else
                {
                    // Leave as much room as specified by the margin
                    _currentRectangle = new Rect(
                        parentRectangle.X + margin.Left,
                        parentRectangle.Y + margin.Top,
                        parentRectangle.Width - margin.Left - margin.Right,
                        parentRectangle.Height - margin.Top - margin.Bottom);

                    _areas = (from child in parentNode.Children
                             where child.Area != 0
                             orderby child.Area descending
                             select child).ToArray();

                    // Factor is only computed once and used during the algorithm
                    _factor = _currentRectangle.Width * _currentRectangle.Height / area;

                    retVal = BuildTreeMap().ToArray();
                }
            }

            return retVal;
        }
Esempio n. 7
0
        /// <summary>
        /// Recursively computes TreeMap rectangles given the root node and the bounding rectangle as start.
        /// </summary>
        /// <param name="root">Root of the TreeMapNode tree.</param>
        /// <param name="boundingRectangle">Bounding rectangle which will be sub-divided.</param>
        /// <returns>A list of RectangularAreas containing a rectangle for each node in the tree.</returns>
        private IEnumerable <Tuple <Rect, TreeMapNode> > ComputeRectangles(TreeMapNode root, Rect boundingRectangle)
        {
            Queue <Tuple <Rect, TreeMapNode> > treeQueue = new Queue <Tuple <Rect, TreeMapNode> >();

            treeQueue.Enqueue(new Tuple <Rect, TreeMapNode>(boundingRectangle, root));

            // Perform a breadth-first traversal of the tree
            SquaringAlgorithm algorithm = new SquaringAlgorithm();

            while (treeQueue.Count > 0)
            {
                Tuple <Rect, TreeMapNode> currentParent = treeQueue.Dequeue();

                yield return(currentParent);

                foreach (Tuple <Rect, TreeMapNode> rectangle in
                         algorithm.Split(currentParent.Item1, currentParent.Item2, currentParent.Item2.ChildItemPadding))
                {
                    treeQueue.Enqueue(rectangle);
                }
            }
        }
        /// <summary>
        /// Recursively computes TreeMap rectangles given the root node and the bounding rectangle as start.
        /// </summary>
        /// <param name="root">Root of the TreeMapNode tree.</param>
        /// <param name="boundingRectangle">Bounding rectangle which will be sub-divided.</param>
        /// <returns>A list of RectangularAreas containing a rectangle for each node in the tree.</returns>
        private IEnumerable<Tuple<Rect, TreeMapNode>> ComputeRectangles(TreeMapNode root, Rect boundingRectangle)
        {
            Queue<Tuple<Rect, TreeMapNode>> treeQueue = new Queue<Tuple<Rect, TreeMapNode>>();
            treeQueue.Enqueue(new Tuple<Rect, TreeMapNode>(boundingRectangle, root));

            // Perform a breadth-first traversal of the tree
            SquaringAlgorithm algorithm = new SquaringAlgorithm();
            while (treeQueue.Count > 0)
            {
                Tuple<Rect, TreeMapNode> currentParent = treeQueue.Dequeue();

                yield return currentParent;

                foreach (Tuple<Rect, TreeMapNode> rectangle in
                    algorithm.Split(currentParent.Item1, currentParent.Item2, currentParent.Item2.ChildItemPadding))
                {
                    treeQueue.Enqueue(rectangle);
                }
            }
        }
        /// <summary>
        /// Performs the Arrange pass of the layout.
        /// </summary>
        /// <remarks>
        /// We round rectangles to snap to nearest pixels. We do that to avoid 
        /// anti-aliasing which results in better appearance. Moreover to get
        /// correct layout we would need to use UseLayoutRounding=false which
        /// is Silverlight specific. A side effect is that areas for rectangles 
        /// in the visual tree no longer can be used to compare them as dimensions
        /// are not rounded and therefore not precise. 
        /// </remarks>
        /// <param name="finalSize">The final area within the parent that this element should use to arrange itself and its children.</param>
        /// <returns>The actual size used.</returns>
        protected override Size ArrangeOverride(Size finalSize)
        {
            // Sets ActualHeight & ActualWidth for the container
            finalSize = base.ArrangeOverride(finalSize);

            if (_nodeRoots != null && ContainerElement != null)
            {
                // Create a temporary pseudo-root node containing all the top-level nodes
                TreeMapNode root = new TreeMapNode()
                {
                    Area = _nodeRoots.Sum(x => x.Area),
                    Children = _nodeRoots,
                    ChildItemPadding = new Thickness(0)
                };

                // Calculate associated rectangles. We use ContainerElement, 
                // not finalSize so all elements that are above it like border 
                // (with padding and border) are taken into account
                IEnumerable<Tuple<Rect, TreeMapNode>> measuredRectangles = ComputeRectangles(
                    root,
                    new Rect(0, 0, ContainerElement.ActualWidth, ContainerElement.ActualHeight));

                // Position everything
                foreach (Tuple<Rect, TreeMapNode> rectangle in measuredRectangles)
                {
                    FrameworkElement element = rectangle.Item2.Element;
                    if (element != null)
                    {
                        double roundedTop = Math.Round(rectangle.Item1.Top);
                        double roundedLeft = Math.Round(rectangle.Item1.Left);
                        double height = Math.Round(rectangle.Item1.Height + rectangle.Item1.Top) - roundedTop;
                        double width = Math.Round(rectangle.Item1.Width + rectangle.Item1.Left) - roundedLeft;

                        // Fully specify element location/size (setting size is required on WPF)
                        Canvas.SetLeft(element, roundedLeft);
                        Canvas.SetTop(element, roundedTop);
                        element.Width = width;
                        element.Height = height;

                        element.Arrange(new Rect(roundedLeft, roundedTop, width, height));
                    }
                }
            }

            return finalSize;
        }
        public void ZeroChildAreaReturnsNonemptyEnumeration()
        {
            SquaringAlgorithm rect = new SquaringAlgorithm();
            TreeMapNode node = new TreeMapNode
            {
                Area = 1.0,
                Children = new List<TreeMapNode>
                {
                    new TreeMapNode { Area = 1.0, Children = null },
                    new TreeMapNode { Area = 0.0, Children = null }
                }
            };

            IList<Tuple<Rect, TreeMapNode>> result = rect.Split(new Rect(0, 0, 80, 100), node, NoThickness).ToArray();

            Assert.AreEqual(1, result.Count);
        }
        public void CanSplitRectanglesWithThickness()
        {
            SquaringAlgorithm rect = new SquaringAlgorithm();
            TreeMapNode node = new TreeMapNode
            {
                Area = 10.0,
                Children = new List<TreeMapNode>
                {
                    new TreeMapNode { Area = 1.0, Children = null },
                    new TreeMapNode { Area = 9.0, Children = null }
                }
            };

            Thickness thickness = new Thickness(10, 30, 20, 40);
            IList<Tuple<Rect, TreeMapNode>> result = rect.Split(new Rect(40, 20, 110, 170), node, thickness).ToArray();

            Assert.AreEqual(50, result[0].Item1.Top, DELTA);
            Assert.AreEqual(140, result[0].Item1.Bottom, DELTA);
            Assert.AreEqual(140, result[1].Item1.Top, DELTA);
            Assert.AreEqual(150, result[1].Item1.Bottom, DELTA);
            Assert.AreEqual(50, result[0].Item1.Left, DELTA);
            Assert.AreEqual(130, result[0].Item1.Right, DELTA);
            Assert.AreEqual(50, result[1].Item1.Left, DELTA);
            Assert.AreEqual(130, result[1].Item1.Right, DELTA);
        }
Esempio n. 12
0
        /// <summary>
        /// Recursively computes TreeMap rectangles given the root node and the bounding rectangle as start.
        /// </summary>
        /// <param name="root">Root of the TreeMapNode tree.</param>
        /// <param name="boundingRectangle">Bounding rectangle which will be sub-divided.</param>
        /// <returns>A list of RectangularAreas containing a rectangle for each node in the tree.</returns>
        private IEnumerable <(Rect RectangularArea, TreeMapNode TreeMapNode)> ComputeRectangles(TreeMapNode root, Rect boundingRectangle)
        {
            Queue <(Rect RectangularArea, TreeMapNode TreeMapNode)> treeQueue = new Queue <(Rect RectangularArea, TreeMapNode TreeMapNode)>();

            treeQueue.Enqueue((boundingRectangle, root));

            // Perform a breadth-first traversal of the tree
            SquaringAlgorithm algorithm = new SquaringAlgorithm();

            while (treeQueue.Count > 0)
            {
                var currentParent = treeQueue.Dequeue();

                yield return(currentParent);

                foreach (var rectangle in algorithm.Split(currentParent.RectangularArea, currentParent.TreeMapNode, currentParent.TreeMapNode.ChildItemPadding))
                {
                    treeQueue.Enqueue(rectangle);
                }
            }
        }
        public void TwoReverseOrderedChildrenSplitAreaProperly()
        {
            SquaringAlgorithm rect = new SquaringAlgorithm();
            TreeMapNode node = new TreeMapNode
            {
                Area = 10.0,
                Children = new List<TreeMapNode>
                {
                    new TreeMapNode { Area = 1.0, Children = null },
                    new TreeMapNode { Area = 9.0, Children = null }
                }
            };

            IList<Tuple<Rect, TreeMapNode>> result = rect.Split(new Rect(0, 0, 100, 100), node, NoThickness).ToArray();

            Assert.AreEqual(2, result.Count);
            Assert.AreEqual(9000, result[0].Item1.Width * result[0].Item1.Height, DELTA);
            Assert.AreEqual(1000, result[1].Item1.Width * result[1].Item1.Height, DELTA);
        }
        public void MultipleVerticalChildrenTakeAllHorizontalSpace()
        {
            SquaringAlgorithm rect = new SquaringAlgorithm();
            TreeMapNode node = new TreeMapNode
            {
                Area = 10.0,
                Children = new List<TreeMapNode>
                {
                    new TreeMapNode { Area = 1.0, Children = null },
                    new TreeMapNode { Area = 9.0, Children = null }
                }
            };

            IList<Tuple<Rect, TreeMapNode>> result = rect.Split(new Rect(0, 0, 100, 150), node, NoThickness).ToArray();

            Assert.AreEqual(0, result[0].Item1.Left, DELTA);
            Assert.AreEqual(100, result[0].Item1.Right, DELTA);
            Assert.AreEqual(0, result[1].Item1.Left, DELTA);
            Assert.AreEqual(100, result[1].Item1.Right, DELTA);
        }
        public void RectanglesDoNotOverlap()
        {
            SquaringAlgorithm rect = new SquaringAlgorithm();
            TreeMapNode node = new TreeMapNode
            {
                Area = 10.0,
                Children = new List<TreeMapNode>
                {
                    new TreeMapNode { Area = 1.0, Children = null },
                    new TreeMapNode { Area = 9.0, Children = null }
                }
            };

            IList<Tuple<Rect, TreeMapNode>> result = rect.Split(new Rect(0, 0, 100, 100), node, NoThickness).ToArray();

            Assert.AreEqual(0, result[0].Item1.Top, DELTA);
            Assert.AreEqual(90, result[0].Item1.Bottom, DELTA);
            Assert.AreEqual(90, result[1].Item1.Top, DELTA);
            Assert.AreEqual(100, result[1].Item1.Bottom, DELTA);
        }
        public void TupleRectTreeMapNodeTakesCorrectNode()
        {
            SquaringAlgorithm rect = new SquaringAlgorithm();
            TreeMapNode node = new TreeMapNode
            {
                Area = 10.0,
                Children = new List<TreeMapNode>
                {
                    new TreeMapNode { Area = 1.0, Children = null },
                    new TreeMapNode { Area = 9.0, Children = null }
                }
            };

            IList<Tuple<Rect, TreeMapNode>> result = rect.Split(new Rect(0, 0, 100, 100), node, NoThickness).ToArray();

            Assert.IsTrue(Object.ReferenceEquals(node.Children.First(), result[1].Item2));
        }
        public void PlaceholderRectangleIsCorrect()
        {
            SquaringAlgorithm rect = new SquaringAlgorithm();
            TreeMapNode node = new TreeMapNode
            {
                Area = 10.0,
                Children = new List<TreeMapNode>
                {
                    new TreeMapNode
                    {
                        Area = 10.0,
                        Children = new List<TreeMapNode>
                        {
                            new TreeMapNode { Area = 2.0, Children = null },
                            new TreeMapNode { Area = 1.0, Children = null }
                        }
                    }
                }
            };

            IList<Tuple<Rect, TreeMapNode>> result = rect.Split(new Rect(0, 0, 100, 100), node, NoThickness).ToArray();
            Assert.AreEqual(new Rect(0, 0, 100, 100), result[0].Item1);
        }
        public void ChildrenNotAddingToParent()
        {
            SquaringAlgorithm rect = new SquaringAlgorithm();
            TreeMapNode node = new TreeMapNode
            {
                Area = 10.0,
                Children = new List<TreeMapNode>
                {
                    new TreeMapNode { Area = 1.0, Children = null },
                    new TreeMapNode { Area = 2.0, Children = null }
                }
            };

            IList<Tuple<Rect, TreeMapNode>> result = rect.Split(new Rect(0, 0, 100, 100), node, NoThickness).ToArray();

            Assert.AreEqual(2, result.Count);
            Assert.AreEqual(result[0].Item1.Width * result[0].Item1.Height, 1999, 2001);
            Assert.AreEqual(result[1].Item1.Width * result[1].Item1.Height, 999, 1001);
        }
        public void CanSplitRectanglesWithTranslatedViewport()
        {
            SquaringAlgorithm rect = new SquaringAlgorithm();
            TreeMapNode node = new TreeMapNode
            {
                Area = 10.0,
                Children = new List<TreeMapNode>
                {
                    new TreeMapNode { Area = 1.0, Children = null },
                    new TreeMapNode { Area = 9.0, Children = null }
                }
            };

            IList<Tuple<Rect, TreeMapNode>> result = rect.Split(new Rect(50, 50, 80, 100), node, NoThickness).ToArray();

            Assert.AreEqual(50, result[0].Item1.Top, DELTA);
            Assert.AreEqual(140, result[0].Item1.Bottom, DELTA);
            Assert.AreEqual(140, result[1].Item1.Top, DELTA);
            Assert.AreEqual(150, result[1].Item1.Bottom, DELTA);
            Assert.AreEqual(50, result[0].Item1.Left, DELTA);
            Assert.AreEqual(130, result[0].Item1.Right,  DELTA);
            Assert.AreEqual(50, result[1].Item1.Left, DELTA);
            Assert.AreEqual(130, result[1].Item1.Right, DELTA);
        }
        public void SingleChildTakesAllSpace()
        {
            SquaringAlgorithm rect = new SquaringAlgorithm();
            TreeMapNode node = new TreeMapNode
            {
                Area = 1.0,
                Children = new List<TreeMapNode>
                {
                    new TreeMapNode { Area = 1.0, Children = null }
                }
            };

            IList<Tuple<Rect, TreeMapNode>> result = rect.Split(new Rect(0, 0, 100, 100), node, NoThickness).ToArray();

            Assert.AreEqual(1, result.Count);
            Assert.AreEqual(100, result[0].Item1.Width, DELTA);
            Assert.AreEqual(100, result[0].Item1.Height, DELTA);
        }
Esempio n. 21
0
        /// <summary>
        /// Subdivides the parent rectangle using squaring tree map algorithm into
        /// rectangles with areas specified by the children. The areas must add up
        /// to at most the area of the rectangle.
        /// </summary>
        /// <param name="parentRectangle">Total area being split.</param>
        /// <param name="parentNode">The node associated with the total area. The
        /// children of this node will be allocated small chunks of the parent rectangle.</param>
        /// <param name="margin">How much of a gap should be left between the parent rectangle and the children.</param>
        /// <returns>A list of RectangularArea objects describing areas associated with each of the children of parentNode.</returns>
        public IEnumerable <(Rect RectangularArea, TreeMapNode TreeMapNode)> Split(Rect parentRectangle, TreeMapNode parentNode, Thickness margin)
        {
            IEnumerable <(Rect RectangularArea, TreeMapNode TreeMapNode)> retVal;

            double area = parentNode.Area;

            if (parentNode.Children == null || !parentNode.Children.Any() || area == 0)
            {
                retVal = Enumerable.Empty <(Rect RectangularArea, TreeMapNode TreeMapNode)>();
            }
            else
            {
                if (parentRectangle.Width - margin.Left - margin.Right <= 0 ||
                    parentRectangle.Height - margin.Top - margin.Bottom <= 0)
                {
                    // Margins too big, no more room for children. Returning
                    // zero sized rectangles for all children.
                    retVal = parentNode.Children.Select(child => (new Rect(0, 0, 0, 0), child));
                }
                else
                {
                    // Leave as much room as specified by the margin
                    _currentRectangle = new Rect(
                        parentRectangle.X + margin.Left,
                        parentRectangle.Y + margin.Top,
                        parentRectangle.Width - margin.Left - margin.Right,
                        parentRectangle.Height - margin.Top - margin.Bottom);

                    _areas = parentNode.Children.Where(child => child.Area != 0).OrderByDescending(child => child.Area).ToArray();

                    // Factor is only computed once and used during the algorithm
                    _factor = _currentRectangle.Width * _currentRectangle.Height / area;

                    retVal = BuildTreeMap().ToArray();
                }
            }

            return(retVal);
        }
        public void ThicknessIsSubtractedFromRectangleSize()
        {
            SquaringAlgorithm rect = new SquaringAlgorithm();
            TreeMapNode node = new TreeMapNode
            {
                Area = 10.0,
                Children = new List<TreeMapNode>
                {
                    new TreeMapNode { Area = 1.0, Children = null },
                    new TreeMapNode { Area = 9.0, Children = null }
                }
            };
            Thickness thickness = new Thickness(10, 30, 20, 40);
            IList<Tuple<Rect, TreeMapNode>> result = rect.Split(new Rect(10, 30, 130, 170), node, thickness).ToArray();

            Assert.AreEqual(2, result.Count);
            Assert.AreEqual(9000, result[0].Item1.Width * result[0].Item1.Height);
            Assert.AreEqual(1000, result[1].Item1.Width * result[1].Item1.Height);
        }