Skip to content

Commit 4ee4182

Browse files
Extracted branch alignment logic
1 parent e9ba272 commit 4ee4182

File tree

10 files changed

+1774
-1074
lines changed

10 files changed

+1774
-1074
lines changed

src/tasks/transformations/VisualTreeTask.js

Lines changed: 33 additions & 1074 deletions
Large diffs are not rendered by default.
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
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

Comments
 (0)