/// <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="childPositionX">the x-position of this branch's child</param> private void drawBranch(TreeNode branch, Graphics graphics, Pen pen, Brush nodeFill, int direction, int slotsUsed, float pixelsPerSlot, float childPositionX) { // calculate some useful numbers int slotsInThisBranch = branch.GetNumParentlessAncestors(); 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 child graphics.DrawLine(pen, childPositionX, ValueToYCoordinate(branch.GetChildren()[0].value), nodeCenterX, ValueToYCoordinate(branch.GetChildren()[0].value)); graphics.DrawLine(pen, nodeCenterX, ValueToYCoordinate(branch.GetChildren()[0].value), nodeCenterX, ValueToYCoordinate(branch.value)); int slotsUsedAfterParent = slotsUsed; foreach (TreeNode parent in branch.GetParents()) { drawBranch(parent, graphics, pen, nodeFill, direction, slotsUsedAfterParent, pixelsPerSlot, nodeCenterX); slotsUsedAfterParent += parent.GetNumParentlessAncestors(); } }