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 previous 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); } }
private static void DrawNode(TreeNodeModel <NodeModel> node, Graphics graphic) { // Set the pen var nodePen = node.Item.Colour; // rectangle where node will be positioned var nodeRect = new Rectangle(Convert.ToInt32(NodeMarginX + node.X * (NodeWidth + NodeMarginX)), NodeMarginY + node.Y * (NodeHeight + NodeMarginY), NodeWidth, NodeHeight); // draw box if (!node.Item.IsCompressed) { graphic.DrawRectangle(nodePen, nodeRect); } // draw content var font = new Font(FontFamily.GenericMonospace, 8); var stringSize = graphic.MeasureString(node.ToString(), font); graphic.DrawString(node.ToString(), font, nodePen.Brush, nodeRect.X + NodeWidth / 2 - stringSize.Width / 2, nodeRect.Y + NodeHeight / 2 - stringSize.Height / 2); // draw line to parent if (node.Parent != null) { var nodeTopMiddle = new Point(nodeRect.X + nodeRect.Width / 2, nodeRect.Y); var nodeBottomMiddle = new Point(nodeTopMiddle.X, nodeTopMiddle.Y - NodeMarginY / 2); graphic.DrawLine(nodePen, nodeTopMiddle, nodeBottomMiddle); } // draw line to children if (node.Children.Count > 0) { var nodeBottomMiddle = new Point(nodeRect.X + nodeRect.Width / 2, nodeRect.Y + nodeRect.Height); var nodeTopMiddle = new Point(nodeBottomMiddle.X, nodeBottomMiddle.Y + NodeMarginY / 2); graphic.DrawLine(nodePen, nodeBottomMiddle, nodeTopMiddle); // draw line over children if (node.Children.Count > 1) { var childrenLineStartX = Convert.ToInt32(NodeMarginX + node.GetRightMostChild().X * // ReSharper disable once PossibleLossOfFraction (NodeWidth + NodeMarginX) + NodeWidth / 2); var childrenLineStartY = nodeBottomMiddle.Y + NodeMarginY / 2; var childrenLineStart = new Point(childrenLineStartX, childrenLineStartY); var childrenLineEndX = Convert.ToInt32(NodeMarginX + node.GetLeftMostChild().X *(NodeWidth + NodeMarginX) + // ReSharper disable once PossibleLossOfFraction NodeWidth / 2); var childrenLineEndY = nodeBottomMiddle.Y + NodeMarginY / 2; var childrenLineEnd = new Point(childrenLineEndX, childrenLineEndY); graphic.DrawLine(Pens.Black, childrenLineStart, childrenLineEnd); } } foreach (var item in node.Children) { DrawNode(item, graphic); } }