/// <summary> /// Draws a branch in a tree. This function is recursive. /// </summary> /// <param name="branch">the branch to draw</param> /// <param name="graphics">allows graphics to be drawn</param> /// <param name="pen">for drawing lines</param> /// <param name="nodeFill">for drawing nodes</param> /// <param name="direction">the side of the tree the node is drawn on</param> /// <param name="slotsUsed">the number of slots on this side of the tree that have already been used</param> /// <param name="pixelsPerSlot">the number of pixels in a slot</param> /// <param name="parentPositionX">the x-position of this branch's parent</param> private void drawBranch(TreeNode branch, Graphics graphics, Pen pen, Brush nodeFill, int direction, int slotsUsed, float pixelsPerSlot, float parentPositionX) { // calculate some useful numbers int slotsInThisBranch = branch.GetNumChildlessDescendents(); float nodeCenterX = (this.Width / 2) + (direction * (slotsUsed + ((slotsInThisBranch + 1) / 2)) * pixelsPerSlot); // draw this node graphics.FillEllipse(nodeFill, nodeCenterX - (NODE_DIAMETER / 2), ValueToYCoordinate(branch.value) - (NODE_DIAMETER / 2), NODE_DIAMETER, NODE_DIAMETER); // draw lines from the branch node back to its parent graphics.DrawLine(pen, parentPositionX, ValueToYCoordinate(branch.GetParents()[0].value), nodeCenterX, ValueToYCoordinate(branch.GetParents()[0].value)); graphics.DrawLine(pen, nodeCenterX, ValueToYCoordinate(branch.GetParents()[0].value), nodeCenterX, ValueToYCoordinate(branch.value)); int slotsUsedAfterChild = slotsUsed; foreach (TreeNode parent in branch.GetChildren()) { drawBranch(parent, graphics, pen, nodeFill, direction, slotsUsedAfterChild, pixelsPerSlot, nodeCenterX); slotsUsedAfterChild += parent.GetNumChildlessDescendents(); } }