コード例 #1
0
        private static void CenterNodesBetween(TreeNodeModel <T> leftNode, TreeNodeModel <T> rightNode)
        {
            var leftIndex  = leftNode.Parent.Children.IndexOf(rightNode);
            var rightIndex = leftNode.Parent.Children.IndexOf(leftNode);

            var numNodesBetween = (rightIndex - leftIndex) - 1;

            if (numNodesBetween > 0)
            {
                var distanceBetweenNodes = (leftNode.X - rightNode.X) / (numNodesBetween + 1);

                int count = 1;
                for (int i = leftIndex + 1; i < rightIndex; i++)
                {
                    var middleNode = leftNode.Parent.Children[i];

                    var desiredX = rightNode.X + (distanceBetweenNodes * count);
                    var offset   = desiredX - middleNode.X;
                    middleNode.X   += offset;
                    middleNode.Mod += offset;

                    count++;
                }

                CheckForConflicts(leftNode);
            }
        }
コード例 #2
0
        private static void CalculateInitialX(TreeNodeModel <T> node)
        {
            foreach (var child in node.Children)
            {
                CalculateInitialX(child);
            }

            // if no children
            if (node.IsLeaf())
            {
                // if there is a previous sibling in this set, set X to prevous sibling + designated distance
                if (!node.IsLeftMost())
                {
                    node.X = node.GetPreviousSibling().X + nodeSize + siblingDistance;
                }
                else
                {
                    // if this is the first node in a set, set X to 0
                    node.X = 0;
                }
            }
            // if there is only one child
            else if (node.Children.Count == 1)
            {
                // if this is the first node in a set, set it's X value equal to it's child's X value
                if (node.IsLeftMost())
                {
                    node.X = node.Children[0].X;
                }
                else
                {
                    node.X   = node.GetPreviousSibling().X + nodeSize + siblingDistance;
                    node.Mod = node.X - node.Children[0].X;
                }
            }
            else
            {
                var leftChild  = node.GetLeftMostChild();
                var rightChild = node.GetRightMostChild();
                var mid        = (leftChild.X + rightChild.X) / 2;

                if (node.IsLeftMost())
                {
                    node.X = mid;
                }
                else
                {
                    node.X   = node.GetPreviousSibling().X + nodeSize + siblingDistance;
                    node.Mod = node.X - mid;
                }
            }

            if (node.Children.Count > 0 && !node.IsLeftMost())
            {
                // Since subtrees can overlap, check for conflicts and shift tree right if needed
                CheckForConflicts(node);
            }
        }
コード例 #3
0
        // converts list of sample items to hierarchial list of TreeNodeModels
        private TreeNodeModel <SampleDataModel> GetSampleTree(List <SampleDataModel> data)
        {
            var root         = data.FirstOrDefault(p => p.ParentId == string.Empty);
            var rootTreeNode = new TreeNodeModel <SampleDataModel>(root, null);

            // add tree node children recursively
            rootTreeNode.Children = GetChildNodes(data, rootTreeNode);

            return(rootTreeNode);
        }
コード例 #4
0
        // recusrively initialize x, y, and mod values of nodes
        private static void InitializeNodes(TreeNodeModel <T> node, int depth)
        {
            node.X   = -1;
            node.Y   = depth;
            node.Mod = 0;

            foreach (var child in node.Children)
            {
                InitializeNodes(child, depth + 1);
            }
        }
コード例 #5
0
        private static List <TreeNodeModel <SampleDataModel> > GetChildNodes(List <SampleDataModel> data, TreeNodeModel <SampleDataModel> parent)
        {
            var nodes = new List <TreeNodeModel <SampleDataModel> >();

            foreach (var item in data.Where(p => p.ParentId == parent.Item.Id))
            {
                var treeNode = new TreeNodeModel <SampleDataModel>(item, parent);
                treeNode.Children = GetChildNodes(data, treeNode);
                nodes.Add(treeNode);
            }

            return(nodes);
        }
コード例 #6
0
        public static void CalculateNodePositions(TreeNodeModel <T> rootNode)
        {
            // initialize node x, y, and mod values
            InitializeNodes(rootNode, 0);

            // assign initial X and Mod values for nodes
            CalculateInitialX(rootNode);

            // ensure no node is being drawn off screen
            CheckAllChildrenOnScreen(rootNode);

            // assign final X values to nodes
            CalculateFinalPositions(rootNode, 0);
        }
コード例 #7
0
        public MainForm(Nod nods)
        {
            InitializeComponent();

            //_data = GetSampleData();
            _data = NodToData(nods, string.Empty);
            _tree = GetSampleTree(_data);
            TreeHelpers <SampleDataModel> .CalculateNodePositions(_tree);

            CalculateControlSize();

            DoubleBuffered   = true;
            treePanel.Paint += treePanel_Paint;
        }
コード例 #8
0
        private void DrawNode(TreeNodeModel <SampleDataModel> node, Graphics g)
        {
            // rectangle where node will be positioned
            var nodeRect = new Rectangle(
                Convert.ToInt32(NODE_MARGIN_X + (node.X * (NODE_WIDTH + NODE_MARGIN_X))),
                NODE_MARGIN_Y + (node.Y * (NODE_HEIGHT + NODE_MARGIN_Y))
                , NODE_WIDTH, NODE_HEIGHT);

            // draw box
            g.DrawRectangle(NODE_PEN, nodeRect);

            // draw content
            g.DrawString(node.ToString(), this.Font, Brushes.Black, nodeRect.X + 10, nodeRect.Y + 10);

            // draw line to parent
            if (node.Parent != null)
            {
                var nodeTopMiddle = new Point(nodeRect.X + (nodeRect.Width / 2), nodeRect.Y);
                g.DrawLine(NODE_PEN, nodeTopMiddle, new Point(nodeTopMiddle.X, nodeTopMiddle.Y - (NODE_MARGIN_Y / 2)));
            }

            // draw line to children
            if (node.Children.Count > 0)
            {
                var nodeBottomMiddle = new Point(nodeRect.X + (nodeRect.Width / 2), nodeRect.Y + nodeRect.Height);
                g.DrawLine(NODE_PEN, nodeBottomMiddle, new Point(nodeBottomMiddle.X, nodeBottomMiddle.Y + (NODE_MARGIN_Y / 2)));


                // draw line over children
                if (node.Children.Count > 1)
                {
                    var childrenLineStart = new Point(
                        Convert.ToInt32(NODE_MARGIN_X + (node.GetRightMostChild().X *(NODE_WIDTH + NODE_MARGIN_X)) + (NODE_WIDTH / 2)),
                        nodeBottomMiddle.Y + (NODE_MARGIN_Y / 2));
                    var childrenLineEnd = new Point(
                        Convert.ToInt32(NODE_MARGIN_X + (node.GetLeftMostChild().X *(NODE_WIDTH + NODE_MARGIN_X)) + (NODE_WIDTH / 2)),
                        nodeBottomMiddle.Y + (NODE_MARGIN_Y / 2));

                    g.DrawLine(NODE_PEN, childrenLineStart, childrenLineEnd);
                }
            }


            foreach (var item in node.Children)
            {
                DrawNode(item, g);
            }
        }
コード例 #9
0
        private static void GetRightContour(TreeNodeModel <T> node, float modSum, ref Dictionary <int, float> values)
        {
            if (!values.ContainsKey(node.Y))
            {
                values.Add(node.Y, node.X + modSum);
            }
            else
            {
                values[node.Y] = Math.Max(values[node.Y], node.X + modSum);
            }

            modSum += node.Mod;
            foreach (var child in node.Children)
            {
                GetRightContour(child, modSum, ref values);
            }
        }
コード例 #10
0
        private static void CalculateFinalPositions(TreeNodeModel <T> node, float modSum)
        {
            node.X += modSum;
            modSum += node.Mod;

            foreach (var child in node.Children)
            {
                CalculateFinalPositions(child, modSum);
            }

            if (node.Children.Count == 0)
            {
                node.Width  = node.X;
                node.Height = node.Y;
            }
            else
            {
                node.Width  = node.Children.OrderByDescending(p => p.Width).First().Width;
                node.Height = node.Children.OrderByDescending(p => p.Height).First().Height;
            }
        }
コード例 #11
0
        private static void CheckAllChildrenOnScreen(TreeNodeModel <T> node)
        {
            var nodeContour = new Dictionary <int, float>();

            GetLeftContour(node, 0, ref nodeContour);

            float shiftAmount = 0;

            foreach (var y in nodeContour.Keys)
            {
                if (nodeContour[y] + shiftAmount < 0)
                {
                    shiftAmount = (nodeContour[y] * -1);
                }
            }

            if (shiftAmount > 0)
            {
                node.X   += shiftAmount;
                node.Mod += shiftAmount;
            }
        }
コード例 #12
0
        private static void CheckForConflicts(TreeNodeModel <T> node)
        {
            var minDistance = treeDistance + nodeSize;
            var shiftValue  = 0F;

            var nodeContour = new Dictionary <int, float>();

            GetLeftContour(node, 0, ref nodeContour);

            var sibling = node.GetLeftMostSibling();

            while (sibling != null && sibling != node)
            {
                var siblingContour = new Dictionary <int, float>();
                GetRightContour(sibling, 0, ref siblingContour);

                for (int level = node.Y + 1; level <= Math.Min(siblingContour.Keys.Max(), nodeContour.Keys.Max()); level++)
                {
                    var distance = nodeContour[level] - siblingContour[level];
                    if (distance + shiftValue < minDistance)
                    {
                        shiftValue = minDistance - distance;
                    }
                }

                if (shiftValue > 0)
                {
                    node.X   += shiftValue;
                    node.Mod += shiftValue;

                    CenterNodesBetween(node, sibling);

                    shiftValue = 0;
                }

                sibling = sibling.GetNextSibling();
            }
        }
コード例 #13
0
 public TreeNodeModel(T item, TreeNodeModel <T> parent)
 {
     this.Item     = item;
     this.Parent   = parent;
     this.Children = new List <TreeNodeModel <T> >();
 }