1+ import Tree from '../../../algorithms/Tree' ;
2+ import { RowType , GroupType , RowTypeToGroupTypeMap } from './enums' ;
3+
4+ function RowKeyGenerator ( ) {
5+ var _rowsHash = { } ;
6+ var _rowIndex = 1 ;
7+
8+ function find ( parentId , rowType , index ) {
9+ var key = parentId + '-' + rowType + '-' + index ;
10+ if ( ! _rowsHash . hasOwnProperty ( key ) ) {
11+ _rowsHash [ key ] = _rowIndex ;
12+ _rowIndex += 1 ;
13+ }
14+ return _rowsHash [ key ] ;
15+ }
16+
17+ function get ( ) {
18+ var result = _rowIndex ;
19+ _rowIndex += 1 ;
20+ return result ;
21+ }
22+
23+ return {
24+ find : find ,
25+ get : get
26+ }
27+ }
28+
29+ function Row ( id ) {
30+ this . id = id ;
31+ this . index = 0 ;
32+ this . offset = 0 ;
33+ this . extend = true ; /* indicates that we need to keep branches of this row children above subsequent rows */
34+ this . nodes = [ ] ;
35+ this . depth = 0 ;
36+
37+ this . groups = [ ] ;
38+ this . groups [ GroupType . Items ] = [ [ 1 , 1 ] ] ;
39+
40+ this . getDepth = function ( ) {
41+ var [ currExtend , currDepth ] = this . groups . reduce ( ( acc , row ) => {
42+ return row . reduce ( ( [ currExtend , currDepth ] , item ) => {
43+ var [ extend , depth ] = item || [ 1 , 1 ] ;
44+ return [ currExtend + extend , Math . max ( currDepth , currExtend + depth ) ] ;
45+ } , acc )
46+ } , [ 0 , 0 ] ) ;
47+ return Math . max ( currExtend , currDepth ) || 1 ;
48+ } ;
49+
50+
51+ this . addRowDepth = function ( rowType , extend , index , depth ) {
52+ var groupIndex = RowTypeToGroupTypeMap [ rowType ] ;
53+ if ( ! this . groups [ groupIndex ] ) {
54+ this . groups [ groupIndex ] = [ ] ;
55+ }
56+ var rows = this . groups [ groupIndex ] ;
57+ var [ currExtend , currDepth ] = rows [ index ] || [ 1 , 1 ] ;
58+ rows [ index ] = [ Math . max ( currExtend , extend ? depth : 1 ) , Math . max ( currDepth , depth ) ] ;
59+ }
60+ }
61+
62+ function BranchAligner ( ) {
63+ var _rowsTree = Tree ( ) ;
64+ var _rowKeyGenerator = RowKeyGenerator ( ) ;
65+ var _rowHash = { } ; // rowHash[nodeId] = rowKey;
66+
67+ function _createParentRow ( parentNodeId ) {
68+ var parentRowId = _rowKeyGenerator . find ( null , RowType . Children , 0 ) ;
69+ var parentRow = new Row ( parentRowId ) ;
70+ parentRow . rowType = RowType . Items ;
71+ parentRow . index = 0 ;
72+ parentRow . offset = 0 ;
73+ parentRow . extend = false ;
74+ _rowsTree . add ( null , parentRowId , parentRow ) ;
75+ _rowHash [ parentNodeId ] = parentRowId ;
76+ return parentRowId ;
77+ }
78+
79+ function mergeToParent ( parentNodeId , nodes ) {
80+ var parentRowId = _rowHash [ parentNodeId ] || _createParentRow ( parentNodeId ) ;
81+ nodes . forEach ( child => {
82+ _rowHash [ child . id ] = parentRowId ;
83+ } ) ;
84+ }
85+
86+ function mergeToChild ( parentNodeId , nodes , rowType , index , offset , extendChildren ) {
87+ var parentRowId = _rowHash [ parentNodeId ] || _createParentRow ( parentNodeId ) ;
88+ var rowId = _rowKeyGenerator . find ( parentRowId , rowType , index ) ;
89+ _add ( parentRowId , rowId , nodes , rowType , index , offset , extendChildren ) ;
90+ }
91+
92+ function addChild ( parentNodeId , nodes , rowType , index , offset , extendChildren ) {
93+ var parentRowId = _rowHash [ parentNodeId ] || _createParentRow ( parentNodeId ) ;
94+ var rowId = _rowKeyGenerator . get ( ) ;
95+ _add ( parentRowId , rowId , nodes , rowType , index , offset , extendChildren ) ;
96+ }
97+
98+ function addSplitChildren ( parentNodeId , nodes , rowType , index , offset ) {
99+ var parentRowId = _rowHash [ parentNodeId ] || _createParentRow ( parentNodeId ) ;
100+ nodes . forEach ( child => {
101+ var rowId = _rowKeyGenerator . get ( ) ;
102+ var row = new Row ( rowId ) ;
103+ row . extend = false ;
104+ row . index = index || 0 ;
105+ row . offset = offset || 0 ;
106+ row . rowType = rowType ;
107+ _rowsTree . add ( parentRowId , rowId , row ) ;
108+ _rowHash [ child . id ] = rowId ;
109+ } )
110+ }
111+
112+ function _add ( parentRowId , rowId , nodes , rowType , index , offset , extendChildren ) {
113+ var row = _rowsTree . node ( rowId ) ;
114+ if ( ! row ) {
115+ row = new Row ( rowId ) ;
116+ row . extend = extendChildren ;
117+ row . index = index || 0 ;
118+ row . offset = offset || 0 ;
119+ row . rowType = rowType ;
120+ _rowsTree . add ( parentRowId , rowId , row ) ;
121+ } ;
122+ nodes . forEach ( child => {
123+ _rowHash [ child . id ] = rowId ;
124+ } ) ;
125+ }
126+
127+ /* measure depth of rows in rowsTree, count number of assistants and child rows, find depth of partner's branches */
128+ function align ( debug ) {
129+ _rowsTree . loopPostOrder ( this , function ( rowId , row , parentRowId , parentRow ) {
130+ // console.log(rowId + " " + Object.entries(RowType).filter(([name, value]) => value == row.rowType)[0][0] + " parent=" + parentRowId + " extend=" + row.extend);
131+ row . depth = row . getDepth ( ) + row . offset ;
132+ if ( parentRow != null ) {
133+ //console.log(rowId + " depth = " + row.depth);
134+ parentRow . addRowDepth ( row . rowType , row . extend , row . index , row . depth ) ;
135+ }
136+ } ) ;
137+ }
138+
139+ // function loopGroupTypes(rowType, len)
140+ function loopGroupTypes ( thisArg , nodeId , onGroupType ) {
141+ var rowId = _rowHash [ nodeId ] ;
142+ var row = _rowsTree . node ( rowId ) ;
143+ for ( var index = 0 , len = row . groups . length ; index < len ; index += 1 ) {
144+ if ( row . groups [ index ] ) {
145+ if ( onGroupType . call ( thisArg , index , len ) ) {
146+ break ;
147+ }
148+ }
149+ }
150+ }
151+
152+ function getRowDepth ( nodeId , groupType , index ) {
153+ var rowId = _rowHash [ nodeId ] ;
154+ var row = _rowsTree . node ( rowId ) ;
155+ var childRow = ( row . groups [ groupType ] || [ ] ) [ index ] ;
156+ return ( childRow && childRow [ 0 ] ) || 1 ;
157+ }
158+
159+ function getRowsDepth ( nodeId , groupType ) {
160+ var rowId = _rowHash [ nodeId ] ;
161+ var row = _rowsTree . node ( rowId ) ;
162+ var children = row . groups [ groupType ] || [ ] ;
163+ return children . map ( item => item [ 0 ] ) ;
164+ }
165+
166+ // function onRow(rowDepth, index)
167+ function loopRows ( thisArg , nodeId , rowType , onRow ) {
168+ var rowId = _rowHash [ nodeId ] ;
169+ var row = _rowsTree . node ( rowId ) ;
170+ var groupIndex = RowTypeToGroupTypeMap [ rowType ] ;
171+ var children = row . groups [ groupIndex ] || [ ] ;
172+ for ( var index = 0 ; index < children . length ; index += 1 ) {
173+ var childRow = children [ index ] ;
174+ if ( childRow ) {
175+ if ( onRow . call ( thisArg , childRow [ 0 ] , index ) ) {
176+ break ;
177+ }
178+ }
179+ }
180+ }
181+
182+ return {
183+ mergeToParent : mergeToParent ,
184+ mergeToChild : mergeToChild ,
185+ addChild : addChild ,
186+ addSplitChildren : addSplitChildren ,
187+ align : align ,
188+ loopGroupTypes : loopGroupTypes ,
189+ getRowDepth : getRowDepth ,
190+ getRowsDepth : getRowsDepth ,
191+ loopRows : loopRows
192+ }
193+ }
194+
195+ export default BranchAligner ;
0 commit comments