2011-10-22 31 views
1

所以有一個很好的開源tutorial on creating TreeNode class。太好了。但我不知道如何改變其排列功能,使其繪製indented樹?如何讓所有者繪製的TreeNode類在縮進樹中排列項目?

這裏的功能:

// Arrange the node and its children in the allowed area. 
// Set xmin to indicate the right edge of our subtree. 
// Set ymin to indicate the bottom edge of our subtree. 
public void Arrange(Graphics gr, ref float xmin, ref float ymin) 
{ 
    // See how big this node is. 
    SizeF my_size = Data.GetSize(gr, MyFont); 

    // Recursively arrange our children, 
    // allowing room for this node. 
    float x = xmin; 
    float biggest_ymin = ymin + my_size.Height; 
    float subtree_ymin = ymin + my_size.Height + Voffset; 
    foreach (TreeNode<T> child in Children) 
    { 
     // Arrange this child's subtree. 
     float child_ymin = subtree_ymin; 
     child.Arrange(gr, ref x, ref child_ymin); 

     // See if this increases the biggest ymin value. 
     if (biggest_ymin < child_ymin) biggest_ymin = child_ymin; 

     // Allow room before the next sibling. 
     x += Hoffset; 
    } 

    // Remove the spacing after the last child. 
    if (Children.Count > 0) x -= Hoffset; 

    // See if this node is wider than the subtree under it. 
    float subtree_width = x - xmin; 
    if (my_size.Width > subtree_width) 
    { 
     // Center the subtree under this node. 
     // Make the children rearrange themselves 
     // moved to center their subtrees. 
     x = xmin + (my_size.Width - subtree_width)/2; 
     foreach (TreeNode<T> child in Children) 
     { 
      // Arrange this child's subtree. 
      child.Arrange(gr, ref x, ref subtree_ymin); 

      // Allow room before the next sibling. 
      x += Hoffset; 
     } 

     // The subtree's width is this node's width. 
     subtree_width = my_size.Width; 
    } 

    // Set this node's center position. 
    Center = new PointF(
     xmin + subtree_width/2, 
     ymin + my_size.Height/2); 

    // Increase xmin to allow room for 
    // the subtree before returning. 
    xmin += subtree_width; 

    // Set the return value for ymin. 
    ymin = biggest_ymin; 
} 

如何現在看起來:

enter image description here

樹看起來怎麼縮進像(基於DmitryG s grate answer圖像):

enter image description here

所以..我如何使它以縮進形式繪製圖形?

+1

爲什麼不使用內置的[TreeView控件](HTTP:// msdn.microsoft.com/en-us/library/system.windows.forms.treeview.aspx)可視化你的樹? –

+0

它的主點繪製=) – Rella

+1

@Kabumbus'它的主點繪製'這是一個家庭作業嗎?或者,您是否在尋找分包商? –

回答

1

我修改了縮進樹排列的TreeNode.Arrange()方法。
現在看起來是這樣的:

public void Arrange(Graphics gr, ref float xmin, ref float ymin) { 
    // See how big this node is. 
    SizeF my_size = Data.GetSize(gr, MyFont); 
    // Recursively arrange our children, 
    // allowing room for this node. 
    float y = ymin + my_size.Height; 
    float biggest_xmin = xmin + my_size.Width; 
    float subtree_xmin = xmin + my_size.Width + Hoffset; 
    foreach(TreeNode<T> child in Children) { 
     // Arrange this child's subtree. 
     float child_xmin = subtree_xmin; 
     child.Arrange(gr, ref child_xmin, ref y); 
     // See if this increases the biggest ymin value. 
     if(biggest_xmin < child_xmin) biggest_xmin = child_xmin; 
     // Allow room before the next sibling. 
     y += Voffset; 
    } 
    // Remove the spacing after the last child. 
    if(Children.Count > 0) y -= Voffset; 
    // See if this node is wider than the subtree under it. 
    float subtree_height = y - ymin; 
    if(my_size.Height > subtree_height) { 
     y = ymin + (my_size.Height - subtree_height)/2; 
     foreach(TreeNode<T> child in Children) { 
      // Arrange this child's subtree. 
      child.Arrange(gr, ref subtree_xmin, ref y); 
      y += Voffset; 
     } 
     subtree_height = my_size.Height; 
    } 
    // Set this node's center position. 
    Center = new PointF(xmin + my_size.Width/2, ymin + my_size.Height/2); 
    ymin += subtree_height; 
    xmin = biggest_xmin; 
} 

注意,該DrawSubtreLinks()方法也進行了修改:

private void DrawSubtreeLinks(Graphics gr) { 
    foreach(TreeNode<T> child in Children) { 
     PointF p = new PointF(Center.X, child.Center.Y); 
     gr.DrawLine(MyPen, Center, p); 
     gr.DrawLine(MyPen, p, child.Center); 
     child.DrawSubtreeLinks(gr); 
    } 
} 
+0

這個答案是正確的,經過測試,並會在5小時內收到獎金(由於授予時間限制)。 – Rella

+0

順便說一句:這裏是從原始TreeNode作者http://blog.csharphelper.com/2011/10/25/make-a-generic-treenode-class-that-c​​an-draw-trees-oriented-vertically-or-水平在-c.aspx?結果= 1 – Rella

0

實際縮進利潤率和東西會採取一些試驗和錯誤,但這應該工作的基本僞算法

創建存儲樹節點,深度和PrevSiblingIndex一類,然後用它來填充單所有樹節點的數組。所以,當你完成後,數組中的節點的索引是行號(y偏移量),深度是縮進(x偏移量),並且如果PrevSiblingIndex爲null,則只需將一條線連接到父母。如果它不爲空,則需要連接當前行中的一行,直到prevSibling。

1

您可以遞歸渲染樹,並跟蹤你在確定縮進級別的深度。

如:

rootNode.RenderTree(0, 0); // Recursively draw root node at (0,0) 
... 


void RenderTree(int depth, ref int y) 
{ 
    // Draw this Node at position (depth * indentAmount, y) 
    ... whatever you like here to get the style of items that you want... 

    depth++;    // Increase indent level (X pos) for all children 
    y += thisNode.Height; // After drawing each item, move down the page 

    // Now recurse to draw all children 
    foreach (Node childNode in Children) 
     childNode.RenderTree(depth, ref y); 
} 

有一點更多的工作要做,以繪製連接線(你需要使用深度級別來告訴你多少行繪製),但本質上它。

請注意,我們將y作爲ref,以便每個項目都順序地將繪圖位置向下移動到頁面上,但是我們將深度傳遞給值,因爲它對樹中同一級別的所有子項都是恆定的。 (請注意,這個僞代碼與您的Arrange方法非常相似 - 只需更改名稱並傳入Graphics對象,它幾乎是一個插件替代品。我將由您決定如何繪製每個項目的線條,圓圈和文本,但:-)

相關問題