OpenNTF.org - K-way tree structure for repre
My Links (Not logged in)
Code Bin Search
 
Hosted by Prominic.NET
Rate This Code
5 - brilliant stuff
4 - very nice
3 - average
2 - needs work
1 - bad
   OpenNTF Code Bin
About This Code
Brief Description:
K-way tree structure for representing hierarchy of docs in a view 
Rating:
Not Rated Yet 
Contributor:
Marko Bonaci 
Category:
Lotusscript 
Type:
Miscellaneous 
Notes Version:
R6.x, R5.x, R7.x 
Last Modified:
06 Apr 2006 
OpenNTF Disclaimer

All of the program code and information presented in the OpenNTF.org Code Bin are provided "as-is", and should be used at your own risk. OpenNTF.org make no express or implied warranty about anything in the Code Bin, and OpenNTF.org will not be responsible or liable for any damage caused by the use or misuse of anything from this site. OpenNTF.org makes no guarantees about anything. Please thoroughly test all of the knowledge and code you find here before you attempt to use them in your production environment.

Code / Description
Dim rtf As NotesRichTextItem 'Static hack

%REM ÷פߧ ___________________| Mb¤, 25.06.2005. |___________________ §ß¤×÷
---
--- Marko Bonaci, IBM PCLP Application developer
---
--- #### Multiway Tree ####
--- Also: n-ary tree, k-ary (k-way) tree
---
--- Script Library "libTree"
---
--- Script Library containing a n-ary tree implementation, which is used to represent a
--- hierarchy of NotesDocuments on the hierarchical view.
------------------------------------------------------------------------------------------------------------------

--- Definition: --- a multiway tree - is a tree with any number of children for each node.
--- --- a k-ary tree - is a tree with no more than k children for each node.
---
--- A k-ary tree may be thought of as a multiway tree limited to k children.
--- We can say our tree is a k-ary tree, cuz Lotus supports only 31 deep view level hierarchy.
---
--- Implementation is to have an array of child nodes at each node, rather than a fixed
--- number of children.
--- Class "Tree" represents tree structure whose every node is carrier of class "Container",
--- which is the data container and can be customized.
--- Class Container is pulled out from class TreeNode, although it could've been omitted
--- and data put directly in TreeNode. That was done to be able to customize data carrier
--- more easely (for a wide set of possibilities). I didn't want to restrict the fact that now any
--- data type can be represented potentialy, all considering what is the content of the
--- NotesDocument.
------------------------------------------------------------------------------------------------------------------
i.e.
O ( 1, 1 ) - this is the root - main tree node
| \
O O ( 2, 1 ), ( 2, 2 ) - two root's children
|
O____ ( 3, 1 ) - one grandchild
| \ \ \
O O O O ( 4, 1 ), ( 4, 2 ), ( 4, 3 ), ( 4, 4 ) - four grand-grandchildren
------------------------------------------------------------------------------------------------------------------
--- To succesfuly use this class you have to change only the following two lines of
--- private method processNode:
---
--- Call rtf.AppendText( Format$( iterator.n_data.doc.Created, "dd.mm.yyyy" ) & " " )
--- Call rtf.AppendText( iterator.n_data.doc.strDocType(0) )
---
--- Instead of "Created" place the name of the field that contains creation date
--- Instead of "strDocType" place the Form or other field that contains document type
--- Of course you're free to change this method to fit your specific needs.
%ENDREM ÷פߧ __________________________________________________________ §ß¤×÷


'-------------------------------------------------------------------------------------------------------------------------------------
Public Class Container
'-------------------------------------------------------------------------------------------------------------------------------------
Public doc As NotesDocument 'Document which the node represents

Public Sub New( doc As NotesDocument )
Set Me.doc = doc
End Sub
End Class


'-------------------------------------------------------------------------------------------------------------------------------------
Public Class TreeNode
'-------------------------------------------------------------------------------------------------------------------------------------
Public n_data As Container 'Structure - data carier
Public n_level As Integer 'Node's level in the tree
Public n_parent As TreeNode 'Pointer on parent node
Public n_children( ) As TreeNode 'Array of pointers on child nodes

Public Function isEqual( other As TreeNode ) As Integer
'We are establishing the rule that the nodes are equal if they point on the same NotesDocument
isEqual = ( Me.n_data.doc.UniversalID = other.n_data.doc.UniversalID )
End Function
End Class


'-------------------------------------------------------------------------------------------------------------------------------------
Public Class Tree
'-------------------------------------------------------------------------------------------------------------------------------------
Private t_db As NotesDatabase 'This db
Private t_root As TreeNode 'Reference on root - main tree node ( node at level 1 )
Private t_levelsCount As Integer 'Number of levels in the tree
Private t_nodesCount As Integer 'Number of nodes in the tree
Private t_nodesAtLevel( ) As Integer 'Number of nodes on every tree level

Declare Public Sub New( mainParent As NotesDocument )
Declare Public Sub printToRTItem( rt As NotesRichTextItem )
Declare Public Property Get nodesCount As Long
Declare Public Property Get nodesOnLevelCount( level As Integer ) As Long

Declare Private Sub initializeNode( curNode As TreeNode )
Declare Private Sub processNode( iterator As TreeNode )
Declare Private Sub sortLevel( level As Integer )
Declare Private Function isTheSameNode( tn1 As TreeNode, tn2 As TreeNode ) As Integer
'-------------------------------------------------------------------------------------------------------------------------------------

Public Sub New( mainParent As NotesDocument )
'Here we create tree and fill it with data
Dim i As Integer
Set t_db = mainParent.ParentDatabase
Set t_root = New TreeNode
Set t_root.n_data = New Container( mainParent ) '//// Root's Data
t_root.n_level = 1 'root's level is 1
t_nodesCount = 1

Dim c As NotesDocumentCollection
Dim tmpDoc As NotesDocument
Dim countChildren As Integer

'Children:
Set c = mainParent.Responses
If c Is Nothing Then Exit Sub
countChildren = c.Count
If countChildren = 0 Then Exit Sub

'Array-a initialization and data for root (level 1)
Redim t_nodesAtLevel( 1 To 2 )
t_nodesAtLevel( 1 ) = 1
t_nodesAtLevel( 2 ) = countChildren

Redim t_root.n_children( 1 To countChildren )
For i = 1 To countChildren
Set tmpDoc = c.GetNthDocument( i )
Dim tn As New TreeNode

Set tn.n_data = New Container( tmpDoc ) '//// Data of Root's Child
Set tn.n_parent = t_root '//// Parent of Root's Child's
tn.n_level = 2 '//// Level of Root's Child

Set t_root.n_children( i ) = tn '//// Root's Child
Call initializeNode( tn )
Next
End Sub
'-------------------------------------------------------------------------------------------------------------------------------------
Private Sub initializeNode( curNode As TreeNode )
%REM Recursively fill the tree nodes with elements ( all descendants )
For every node:
¤ Create temporary TreeNode in memory,
¤ Tell him who is his parent
¤ Tell him who is his document
¤ Tell him on which level he is
¤ Assign his children to him
%ENDREM

'current node has the level higher by 1 in relation to his parent
curNode.n_level = curNode.n_parent.n_level + 1
'number of levels is the current level (always max because of recursion)
t_levelsCount = curNode.n_level
'increment number of nodes
t_nodesCount = t_nodesCount + 1

Dim c As NotesDocumentCollection
Dim tmpDoc As NotesDocument
Dim countChildren As Integer, i As Integer

'Children:
Set tmpDoc = curNode.n_data.doc
Set c = tmpDoc.Responses
If c Is Nothing Then Exit Sub
countChildren = c.Count
If countChildren = 0 Then Exit Sub

'Levels:
If Ubound( t_nodesAtLevel ) <> curNode.n_level + 1 Then
Redim Preserve t_nodesAtLevel( 1 To curNode.n_level + 1 )
End If
t_nodesAtLevel( curNode.n_level + 1 ) = countChildren

Redim curNode.n_children( 1 To countChildren )
For i = 1 To countChildren
Set tmpDoc = c.GetNthDocument( i )

Dim tn As New TreeNode
Set tn.n_data = New Container( tmpDoc ) '//// Child's Data
Set tn.n_parent = curNode '//// Child's Parent
Set curNode.n_children( i ) = tn '//// Child's Child

Call initializeNode( tn )
Next

End Sub
'-------------------------------------------------------------------------------------------------------------------------------------
Private Function areNodesSame( tn1 As TreeNode, tn2 As TreeNode ) As Integer
'We are establishing the rule that the nodes are equal if they point on the same NotesDocument
areNodesSame = tn1.n_data.doc.UniversalID = tn2.n_data.doc.UniversalID
End Function
'-------------------------------------------------------------------------------------------------------------------------------------
Public Property Get nodesCount As Long
'Returns total number of nodes in the tree
nodesCount = t_nodesCount
End Property
'-------------------------------------------------------------------------------------------------------------------------------------
Public Property Get nodesOnLevelCount( level As Integer ) As Long
'Returns number of nodes on level
nodesOnLevelCount = t_nodesAtLevel( level )
End Property
'-------------------------------------------------------------------------------------------------------------------------------------
Public Sub printToRTItem( rt As NotesRichTextItem )
Dim iterator As TreeNode
Set rtf = rt

Set iterator = t_root
Call processNode( iterator )
End Sub
'-------------------------------------------------------------------------------------------------------------------------------------
Private Sub processNode( iterator As TreeNode )
Dim i As Integer

'Start writing to RTF **************************************************
Call rtf.AddNewline( 1 )
' Call rtf.AppendText( "|" )
' Call rtf.AddTab( iterator.n_level )
Call rtf.AppendText( Space$( 4 * ( iterator.n_level - 1 ) ) )
' Call rtf.AppendText( String$( 4 * ( iterator.n_level - 1 ), Asc( "-" ) ) )
Call rtf.AppendText( Format$( iterator.n_data.doc.Created, "dd.mm.yyyy" ) & " " )
Call rtf.AppendText( iterator.n_data.doc.strDocType(0) )
Call rtf.AppendText( " ----> " )
Call rtf.AppendDocLink( iterator.n_data.doc, "Link na dokument" )
'End writing to RTF **************************************************

If iterator.n_data.doc.Responses.Count = 0 Then Exit Sub

For i = 1 To Ubound( iterator.n_children )
Call processNode( iterator.n_children( i ) )
Next

End Sub
'-------------------------------------------------------------------------------------------------------------------------------------
End Class

Usage / Example
Script Library containing a n-ary tree implementation, which is used to represent a hierarchy of NotesDocuments on the hierarchical view.

This class can be expanded with more methods, but this was enough for my purpose.

Usage example:
Sub PrintToRTF( rtf As NotesRichTextItem, doc As NotesDocument )
Dim tree As New Tree( doc )

Call rtf.AppendText( "Book of content:" )
Call tree.printToRTItem( rtf )
End Sub

rtf is Rich text item on document where the tree will be placed.
doc is NotesDocument - main parent doc in the view.
 Comments

No documents found

 Add your comment!