1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216 | 1×
1×
1×
1×
1×
1×
46813×
1×
13×
13×
1×
13×
13×
87×
87×
86×
86×
13×
13×
1×
12×
11×
11×
13×
12×
12×
12×
12×
12×
12×
1×
85×
85×
85×
85×
85×
85×
73×
73×
73×
73×
1×
85×
85×
85×
18×
18×
73×
73×
73×
18×
55×
18×
18×
18×
18×
18×
18×
18×
18×
18×
18×
18×
18×
18×
18×
67×
67×
67×
67×
67×
85×
1×
12×
85×
12×
85×
12×
12×
12×
26×
195×
85×
110×
26×
59×
26×
26×
26×
26×
26×
85×
26×
85×
85×
59×
26×
26×
26×
26×
26×
26×
4×
4×
26×
85×
85×
26×
12×
26×
1×
12×
12×
12×
12×
14×
73×
73×
73×
73×
73×
1×
12×
12×
1×
85×
85×
85×
85×
85×
85×
73×
73×
1×
86×
86×
86×
86×
86×
86×
86×
86×
86×
86×
86×
86×
86×
1×
1×
| define(["require", "exports"], function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var RadialTree = (function () {
function RadialTree() {
}
RadialTree.prototype.destroy = function () {
};
RadialTree.prototype.getModuleName = function () {
return 'RadialTree';
};
RadialTree.prototype.updateLayout = function (nodes, nameTable, layoutProp, viewport) {
var layout = {
type: layoutProp.type,
nameTable: nameTable, anchorX: 0, anchorY: 0,
firstLevelNodes: [], centerNode: null, levels: [], maxLevel: 0, graphNodes: {}, layoutNodes: [],
orientation: layoutProp.orientation,
horizontalSpacing: layoutProp.horizontalSpacing, verticalSpacing: layoutProp.verticalSpacing,
verticalAlignment: layoutProp.verticalAlignment, horizontalAlignment: layoutProp.horizontalAlignment,
fixedNode: layoutProp.fixedNode, margin: layoutProp.margin,
bounds: layoutProp.bounds, objects: [], root: layoutProp.root
};
this.doLayout(layout, nodes, nameTable, viewport);
};
RadialTree.prototype.doLayout = function (layout, nodes, nameTable, viewport) {
var node;
for (var i = 0; i < nodes.length; i++) {
node = nodes[parseInt(i.toString(), 10)];
if (!node.excludeFromLayout) {
layout.graphNodes[node.id] = this.setUpLayoutInfo(layout, node);
if (!node.inEdges || !node.inEdges.length) {
layout.firstLevelNodes.push(node);
}
}
}
if (layout.root && nameTable[layout.root]) {
layout.centerNode = nameTable[layout.root];
}
else if (layout.firstLevelNodes.length) {
layout.centerNode = layout.firstLevelNodes[0];
layout.root = layout.centerNode.id;
}
if (layout.centerNode) {
this.updateEdges(layout, layout.centerNode, 0, nameTable);
this.depthFirstAllignment(layout, layout.centerNode, 0, 0);
this.populateLevels(layout);
this.transformToCircleLayout(layout);
this.updateAnchor(layout, viewport);
this.updateNodes(layout, layout.centerNode, nameTable);
}
};
RadialTree.prototype.updateEdges = function (layout, node, depth, nameTable) {
var nodeInfo = layout.graphNodes[node.id];
layout.layoutNodes.push(nodeInfo);
nodeInfo.level = depth;
nodeInfo.visited = true;
layout.maxLevel = Math.max(layout.maxLevel, depth);
for (var j = 0; j < node.outEdges.length; j++) {
var edge = nameTable[nameTable[node.outEdges[parseInt(j.toString(), 10)]].targetID];
Eif (!edge.excludeFromLayout && !edge.visited) {
nodeInfo.children.push(edge);
this.updateEdges(layout, edge, depth + 1, nameTable);
}
}
};
RadialTree.prototype.depthFirstAllignment = function (layout, node, x, y) {
var newValue;
var nodeInfo = layout.graphNodes[node.id];
if (nodeInfo.children.length) {
y += 300;
for (var i = 0; i < nodeInfo.children.length; i++) {
newValue = this.depthFirstAllignment(layout, nodeInfo.children[parseInt(i.toString(), 10)], x, y);
x = newValue.x;
y = newValue.y;
}
nodeInfo.children = nodeInfo.children.sort(function (obj1, obj2) {
return layout.graphNodes[obj1.id].x - layout.graphNodes[obj2.id].x;
});
var min = layout.graphNodes[nodeInfo.children[0].id].min;
var max = layout.graphNodes[nodeInfo.children[nodeInfo.children.length - 1].id].max;
nodeInfo.x = min + (max - min) / 2;
x = max + layout.horizontalSpacing;
nodeInfo.segmentOffset = max + layout.horizontalSpacing;
nodeInfo.x -= nodeInfo.width / 2;
nodeInfo.y -= nodeInfo.height / 2;
nodeInfo.min = min;
nodeInfo.max = max;
Iif (nodeInfo.x < min && nodeInfo.visited) {
nodeInfo.x = min;
x = nodeInfo.x + nodeInfo.width / 2 - (max - min) / 2;
nodeInfo.visited = false;
for (var i = 0; i < nodeInfo.children.length; i++) {
newValue = this.depthFirstAllignment(layout, nodeInfo.children[parseInt(i.toString(), 10)], x, y);
}
nodeInfo.visited = true;
x = nodeInfo.x + nodeInfo.width + layout.horizontalSpacing;
}
max = layout.graphNodes[nodeInfo.children[nodeInfo.children.length - 1].id].segmentOffset;
x = x < max ? max : x;
y -= 300;
nodeInfo.y = y;
}
else {
nodeInfo.x = x;
nodeInfo.y = y;
nodeInfo.min = x;
nodeInfo.max = x + nodeInfo.width;
x += nodeInfo.width + layout.horizontalSpacing;
}
return { x: x, y: y };
};
RadialTree.prototype.populateLevels = function (layout) {
var stages = [];
var min = Math.min.apply(Math, layout.layoutNodes.map(function (nodeInfo) { return nodeInfo.x; }));
var max = Math.max.apply(Math, layout.layoutNodes.map(function (nodeInfo) {
return nodeInfo.x + nodeInfo.width + layout.horizontalSpacing;
}));
var full = max - min;
layout.levels = [];
var _loop_1 = function (i) {
stages = layout.layoutNodes.filter(function (nodeInfo) {
if (nodeInfo.level === i) {
return nodeInfo;
}
else {
return null;
}
});
var newlevel = {};
stages = stages.sort(function (nodeInfo1, nodeInfo2) { return nodeInfo1.x - nodeInfo2.x; });
newlevel.min = stages[0].x;
newlevel.max = stages[stages.length - 1].x + stages[stages.length - 1].width + layout.horizontalSpacing;
newlevel.actualCircumference = 0;
newlevel.height = 0;
for (var k = 0; k < stages.length; k++) {
if (stages[parseInt(k.toString(), 10)].height > newlevel.height) {
newlevel.height = stages[parseInt(k.toString(), 10)].height;
}
newlevel.actualCircumference += Math.max(stages[parseInt(k.toString(), 10)].width, stages[parseInt(k.toString(), 10)].height);
if (k !== stages.length - 1) {
newlevel.actualCircumference += layout.horizontalSpacing;
}
}
newlevel.circumference = newlevel.max - newlevel.min;
Eif (newlevel.actualCircumference < newlevel.circumference) {
newlevel.circumference = (newlevel.circumference + newlevel.actualCircumference) / 2;
}
newlevel.radius = newlevel.circumference / (2 * Math.PI) + newlevel.height;
newlevel.nodes = [];
if (i > 1) {
Eif (layout.levels[i - 1].radius + layout.levels[i - 1].height >= newlevel.radius) {
newlevel.radius = layout.levels[i - 1].radius + layout.levels[i - 1].height;
}
}
for (var j = 0; j < stages.length; j++) {
stages[parseInt(j.toString(), 10)].ratio = Math.abs(stages[parseInt(j.toString(), 10)].x
+ stages[parseInt(j.toString(), 10)].width / 2 - min) / full;
newlevel.nodes.push(stages[parseInt(j.toString(), 10)]);
}
layout.levels.push(newlevel);
};
for (var i = 0; i <= layout.maxLevel; i++) {
_loop_1(i);
}
};
RadialTree.prototype.transformToCircleLayout = function (layout) {
var root = layout.graphNodes[layout.centerNode.id];
root.x = 0;
root.y = 0;
for (var i = 1; i < layout.levels.length; i++) {
for (var j = 0; j < layout.levels[parseInt(i.toString(), 10)].nodes.length; j++) {
var nodeInfo = layout.levels[parseInt(i.toString(), 10)].nodes[parseInt(j.toString(), 10)];
nodeInfo.x = Math.cos(nodeInfo.ratio * 360 * Math.PI / 180)
* (layout.levels[parseInt(i.toString(), 10)].radius + layout.verticalSpacing * i);
nodeInfo.y = Math.sin(nodeInfo.ratio * 360 * Math.PI / 180)
* (layout.levels[parseInt(i.toString(), 10)].radius + layout.verticalSpacing * i);
layout.anchorX = Math.min(layout.anchorX, nodeInfo.x);
layout.anchorY = Math.min(layout.anchorY, nodeInfo.y);
}
}
};
RadialTree.prototype.updateAnchor = function (layout, viewPort) {
layout.anchorX = layout.centerNode.offsetX || viewPort.x / 2;
layout.anchorY = layout.centerNode.offsetY || viewPort.y / 2;
};
RadialTree.prototype.updateNodes = function (layout, node, nameTable) {
var nodeInfo = layout.graphNodes[node.id];
var offsetX = nodeInfo.x + layout.anchorX;
var offsetY = nodeInfo.y + layout.anchorY;
node.offsetX = offsetX;
node.offsetY = offsetY;
for (var i = 0; i < nodeInfo.children.length; i++) {
var childInfo = nodeInfo.children[parseInt(i.toString(), 10)];
this.updateNodes(layout, nameTable[childInfo.id], nameTable);
}
};
RadialTree.prototype.setUpLayoutInfo = function (layout, item) {
var info = {};
info.name = item.id;
info.x = 0;
info.y = 0;
info.min = 0;
info.max = 0;
info.width = item.actualSize.width;
info.height = item.actualSize.height;
info.children = [];
info.level = 0;
info.ratio = 0;
info.visited = false;
return info;
};
return RadialTree;
}());
exports.RadialTree = RadialTree;
});
|