private void SquarifyChildren(List <TreemapNode> children, List <TreemapNode> row, double containerWidth, double containerHeight)
        {
            double currentX       = 0;
            double currentY       = 0;
            double totalArea      = 0;
            double width          = 0;
            double height         = 0;
            double aspectRatio    = 0;
            bool   drawVertically = DrawVertically(containerWidth, containerHeight);

            // add next child to the current row
            row.Add(children.ElementAt(0));

            foreach (TreemapNode element in row)
            {
                totalArea += element.NormalisedArea;
            }

            if (drawVertically)
            {
                width  = totalArea / containerHeight;
                height = row.Last().NormalisedArea / width;
            }
            else
            {
                height = totalArea / containerWidth;
                width  = row.Last().NormalisedArea / height;
            }

            aspectRatio = AspectRatio(height, width);

            // Compare aspect ratios to decide whether to accept or reject the rectangle
            if (children.Count > 1 && _drawingArea.AspectRatio == 0 || aspectRatio < _drawingArea.AspectRatio)
            {
                // we have improved the aspect ratio, so update the latest accepted values and continue
                _drawingArea.AspectRatio = aspectRatio;

                if (drawVertically)
                {
                    _drawingArea.RowSize = width;
                }
                else
                {
                    _drawingArea.RowSize = height;
                }
                SquarifyChildren(children.Skip(1).ToList(), row, containerWidth, containerHeight);
            }
            else
            {
                // lockout row - remove last entry as it has been rejected, but
                // only if it is not the last element, which just takes up the remaining space
                if (children.Count > 1)
                {
                    int lastElement = row.Count - 1;
                    row.RemoveAt(lastElement);
                }
                else
                {
                    // This is the last data entry - update row size
                    if (drawVertically)
                    {
                        _drawingArea.RowSize = width;
                    }
                    else
                    {
                        _drawingArea.RowSize = height;
                    }
                }

                // Create a new row to add the nodes into
                TreemapRow lockoutRow = new TreemapRow();

                // create nodes for each element in the row and calculate the sizes
                foreach (TreemapNode element in row)
                {
                    double nodeSize = element.NormalisedArea / _drawingArea.RowSize;

                    if (drawVertically)
                    {
                        element.NodeWidth  = _drawingArea.RowSize;
                        element.NodeHeight = nodeSize;
                        element.XPos       = 0;
                        element.YPos       = 0;
                    }
                    else
                    {
                        element.NodeWidth  = nodeSize;
                        element.NodeHeight = _drawingArea.RowSize;
                        element.XPos       = 0;
                        element.YPos       = 0;
                    }

                    // assign event handlers
                    element.RightTapped += treemapNode_RightTapped;

                    element.XPos = currentX + _offsetChildX;
                    element.YPos = currentY + _offsetChildY;
                    lockoutRow.AddNodeToRow(element);

                    if (drawVertically)
                    {
                        currentY += nodeSize;
                    }
                    else
                    {
                        currentX += nodeSize;
                    }
                }

                // Add row to collection
                _childRows.Add(lockoutRow);

                // Update remaning screen width and offsets, reset aspect ratio ready for the new row
                if (drawVertically)
                {
                    containerWidth -= _drawingArea.RowSize;
                    _offsetChildX  += _drawingArea.RowSize;
                }
                else
                {
                    containerHeight -= _drawingArea.RowSize;
                    _offsetChildY   += _drawingArea.RowSize;
                }

                _drawingArea.AspectRatio = 0;
                row.Clear();

                // Continue if we have more than 1 data entry remaining
                if (children.Count > 1)
                {
                    SquarifyChildren(children, row, containerWidth, containerHeight);
                }
            }
        }
        // Squarified treemap algorithm implementation
        private void Squarify(List<TreemapNode> children, List<TreemapNode> row)
        {
            double currentX = 0;
            double currentY = 0;
            double totalArea = 0;
            double width = 0;
            double height = 0;
            double aspectRatio = 0;

            bool drawVertically = DrawVertically();

            // add next child to the current row
            row.Add(children.ElementAt(0));

            foreach (TreemapNode element in row)
            {
                totalArea += element.NormalisedArea;
            }

            if (drawVertically)
            {
                width = totalArea / _drawingArea.Height;
                height = row.Last().NormalisedArea / width;
            }
            else
            {
                height = totalArea / _drawingArea.Width;
                width = row.Last().NormalisedArea / height;
            }

            aspectRatio = AspectRatio(height, width);

            // Compare aspect ratios to decide whether to accept or reject the rectangle
            if (_drawingArea.AspectRatio == 0 || aspectRatio < _drawingArea.AspectRatio)
            {
                // we have improved the aspect ratio, so update the latest accepted values and continue
                _drawingArea.AspectRatio = aspectRatio;

                if (drawVertically)
                {
                    _drawingArea.RowSize = width;
                }
                else
                {
                    _drawingArea.RowSize = height;
                }
                Squarify(children.Skip(1).ToList(), row);
            }
            else
            {
                // lockout row - remove last entry as it has been rejected, but
                // only if it is not the last element, which just takes up the remaining space
                if (children.Count > 1)
                {
                    int lastElement = row.Count - 1;
                    row.RemoveAt(lastElement);
                }
                else
                {
                    // This is the last data entry - update row size
                    if (drawVertically)
                    {
                        _drawingArea.RowSize = width;
                    }
                    else
                    {
                        _drawingArea.RowSize = height;
                    }
                }

                // Create a new row to add the nodes into
                TreemapRow lockoutRow = new TreemapRow();

                // create nodes for each element in the row and calculate the sizes
                foreach (TreemapNode element in row)
                {
                    double nodeSize = element.NormalisedArea / _drawingArea.RowSize;

                    if (drawVertically)
                    {
                        element.NodeWidth = _drawingArea.RowSize;
                        element.NodeHeight = nodeSize;
                        element.XPos = 0;
                        element.YPos = 0;
                    }
                    else
                    {
                        element.NodeWidth = nodeSize;
                        element.NodeHeight = _drawingArea.RowSize;
                        element.XPos = 0;
                        element.YPos = 0;
                    }

                    element.XPos = currentX + _offsetX;
                    element.YPos = currentY + _offsetY;
                    lockoutRow.AddNodeToRow(element);

                    if (drawVertically)
                    {
                        currentY += nodeSize;
                    }
                    else
                    {
                        currentX += nodeSize;
                    }
                }

                // Add row to collection
                _rows.Add(lockoutRow);

                // Update remaning screen width and offsets, reset aspect ratio ready for the new row
                if (drawVertically)
                {
                    _drawingArea.Width -= _drawingArea.RowSize;
                    _offsetX += _drawingArea.RowSize;
                }
                else
                {
                    _drawingArea.Height -= _drawingArea.RowSize;
                    _offsetY += _drawingArea.RowSize;
                }

                _drawingArea.AspectRatio = 0;
                row.Clear();

                // Continue if we have more than 1 data entry remaining
                if (children.Count > 1)
                {
                    Squarify(children, row);
                }
            }
        }