private static double PaintTree(Tree t, Point2D start, Graphics2D g2, FontMetrics fM) { if (t == null) { return(0.0); } string nodeStr = NodeToString(t); double nodeWidth = fM.StringWidth(nodeStr); double nodeHeight = fM.GetHeight(); double nodeAscent = fM.GetAscent(); TreeJPanel.WidthResult wr = WidthResult(t, fM); double treeWidth = wr.width; double nodeTab = wr.nodeTab; double childTab = wr.childTab; double nodeCenter = wr.nodeCenter; //double treeHeight = height(t, fM); // draw root g2.DrawString(nodeStr, (float)(nodeTab + start.GetX()), (float)(start.GetY() + nodeAscent)); if (t.IsLeaf()) { return(nodeWidth); } double layerMultiplier = (1.0 + belowLineSkip + aboveLineSkip + parentSkip); double layerHeight = nodeHeight * layerMultiplier; double childStartX = start.GetX() + childTab; double childStartY = start.GetY() + layerHeight; double lineStartX = start.GetX() + nodeCenter; double lineStartY = start.GetY() + nodeHeight * (1.0 + belowLineSkip); double lineEndY = lineStartY + nodeHeight * parentSkip; // recursively draw children for (int i = 0; i < t.Children().Length; i++) { Tree child = t.Children()[i]; double cWidth = PaintTree(child, new Point2D.Double(childStartX, childStartY), g2, fM); // draw connectors wr = WidthResult(child, fM); double lineEndX = childStartX + wr.nodeCenter; g2.Draw(new Line2D.Double(lineStartX, lineStartY, lineEndX, lineEndY)); childStartX += cWidth; if (i < t.Children().Length - 1) { childStartX += sisterSkip * fM.StringWidth(" "); } } return(treeWidth); }
protected internal static TreeJPanel.WidthResult WidthResult(Tree tree, FontMetrics fM) { if (tree == null) { return(new TreeJPanel.WidthResult(0.0, 0.0, 0.0, 0.0)); } double local = fM.StringWidth(NodeToString(tree)); if (tree.IsLeaf()) { return(new TreeJPanel.WidthResult(local, 0.0, local / 2.0, 0.0)); } double sub = 0.0; double nodeCenter = 0.0; //double childTab = 0.0; for (int i = 0; i < numKids; i++) { TreeJPanel.WidthResult subWR = WidthResult(tree.GetChild(i), fM); if (i == 0) { nodeCenter += (sub + subWR.nodeCenter) / 2.0; } if (i == numKids - 1) { nodeCenter += (sub + subWR.nodeCenter) / 2.0; } sub += subWR.width; if (i < numKids - 1) { sub += sisterSkip * fM.StringWidth(" "); } } double localLeft = local / 2.0; double subLeft = nodeCenter; double totalLeft = Math.Max(localLeft, subLeft); double localRight = local / 2.0; double subRight = sub - nodeCenter; double totalRight = Math.Max(localRight, subRight); return(new TreeJPanel.WidthResult(totalLeft + totalRight, totalLeft - localLeft, nodeCenter + totalLeft - subLeft, totalLeft - subLeft)); }