Page Index Toggle Pages: 1 Send TopicPrint
Normal Topic TreeLayout Problem (Read 1641 times)
manu
YaBB Newbies
*
Offline


Manu bhai moter chale
pum pum pum...

Posts: 25
Location: Japan
Joined: May 25th, 2008
TreeLayout Problem
Jul 28th, 2008 at 1:12pm
Print Post  
Hi,
I am generating a diagram with tree layout.
where nodes that do not have grandchildren should be arranged vertically and those who have grandchildren should be arranged horizontally.

I was able to do this but some of horizontal nodes and vertical nodes are crossing each other.
How to layout this so that no nodes are crossed or overlapped. Please help?

I have used following code:


For Each item As DiagramItem In DG.Items
If TypeOf item Is TableNode Then
Dim tablenode As TableNode = CType(item, TableNode)

If tablenode.Tag IsNot Nothing Then
If tablenode.OutgoingLinks.Count <= 0 Then
Dim immidiateParentNode As TableNode = tablenode.IncomingLinks(0).Origin
'if immidiate parent have grand childrens then arrang horizontally else vertically
If Not HasGrandChildren(immidiateParentNode) Then
If Not m_VerticalItemParents.Contains(immidiateParentNode) Then
m_VerticalItemParents.Add(immidiateParentNode)
End If
Else
m_HorizontalItems.Add(tablenode)
End If
Else
m_HorizontalItems.Add(tablenode)
For Each tablelink As DiagramLink In tablenode.OutgoingLinks
m_HorizontalItems.Add(tablelink)
Next
End If
End If
End If

Next

tree.Arrange(DG, m_HorizontalItems)


If m_VerticalItemParents.Count > 0 Then
For Each item As DiagramNode In m_VerticalItemParents
For Each childlink As DiagramLink In item.OutgoingLinks
childlink.Destination.AnchorPattern = Diagramming.AnchorPattern.LeftInRightOut
Next

t.KeepRootPosition = True
t.Type = Diagramming.Layout.TreeLayoutType.Cascading
t.Direction = Diagramming.Layout.TreeLayoutDirection.LeftToRight
t.Root = item
t.Arrange(DG)
Next

End If
  

Regards&&Manoj
Back to top
 
IP Logged
 
Meppy
God Member
*****
Offline


MindFusion support

Posts: 1783
Joined: Jul 20th, 2005
Re: TreeLayout Problem
Reply #1 - Jul 30th, 2008 at 8:21am
Print Post  
Here is what you can try. I have tested this code for ShapeNode objects and it works fine. Make the appropriate modifications in order to match your node types if necessary.

First, add the following methods to your class:

Code
Select All
''' <summary>
''' Retrieves the bounds of the specified node and its children.
''' </summary>
Private Function GetBounds(ByRef n As DiagramNode) As RectangleF

      Dim r As RectangleF = n.Bounds

      For Each olink As DiagramLink In n.OutgoingLinks
          r = RectangleF.Union(olink.Destination.Bounds, r)
      Next

      Return r

End Function

''' <summary>
''' Flattens the tree defined by the specified root node into the specified list.
''' </summary>
Private Sub Flatten(ByRef n As DiagramNode, ByVal l As List(Of DiagramNode))

      If Not l.Contains(n) Then l.Add(n)

      For Each olink As DiagramLink In n.OutgoingLinks
            Flatten(olink.Destination, l)
      Next

End Sub

''' <summary>
''' Finds the root node in the specified diagram.
''' </summary>
Private Function FindRoot(ByRef diagram As Diagram) As DiagramNode

      For Each d As DiagramNode In diagram.Nodes
            If d.IncomingLinks.Count = 0 Then Return d
      Next

      Return Nothing

End Function 


Then, add the following code in the arrangement method once all tree layouts have finished:

Code
Select All
' Traverse all nodes. For those who have childrent and don't have
' grandchildren, calculate the bounds of their subtree and offset
' all subsequent nodes in the tree by the necessary amount

' Find the root
Dim root As DiagramNode = FindRoot(dg)
If root Is Nothing Then Return

' Build a flat list of the tree
Dim items As New List(Of DiagramNode)

Flatten(root, items)

For i As Integer = 0 To items.Count - 1

      Dim current As DiagramNode = items(i)

      If Not HasGrandChildren(current) And current.OutgoingLinks.Count > 0 Then

            ' This item doesn't have grandchildren, but has children.
            ' Obtain the total bounding rectangle of it and its children
            Dim r As RectangleF = GetBounds(current)

            ' Calculate the offset
            Dim offset As Single = r.Right - current.Bounds.Right

            ' Bypass the items' children
            i += current.OutgoingLinks.Count

            ' Offset the rest of the tree
            For j As Integer = i + 1 To items.Count - 1

                  Dim n As DiagramNode = items(j)
                  n.Move(n.Bounds.X + offset, n.Bounds.Y)

            Next

      End If

Next 



Let me know if it works.

Meppy
  
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint