@antv/layout 1.2.13 → 1.2.14-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/85db61ddc757dae66e04.worker.js +2 -0
- package/dist/85db61ddc757dae66e04.worker.js.map +1 -0
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/lib/{dagre → antv-dagre}/acyclic.d.ts +1 -1
- package/lib/antv-dagre/acyclic.js +65 -0
- package/lib/antv-dagre/acyclic.js.map +1 -0
- package/lib/antv-dagre/add-border-segments.js +41 -0
- package/lib/antv-dagre/add-border-segments.js.map +1 -0
- package/lib/{dagre → antv-dagre}/coordinate-system.d.ts +2 -1
- package/lib/antv-dagre/coordinate-system.js +69 -0
- package/lib/antv-dagre/coordinate-system.js.map +1 -0
- package/lib/{dagre → antv-dagre}/data/list.d.ts +1 -1
- package/lib/{dagre → antv-dagre}/data/list.js +23 -22
- package/lib/antv-dagre/data/list.js.map +1 -0
- package/lib/{dagre → antv-dagre}/greedy-fas.d.ts +2 -2
- package/lib/antv-dagre/greedy-fas.js +141 -0
- package/lib/antv-dagre/greedy-fas.js.map +1 -0
- package/lib/{dagre → antv-dagre}/layout.d.ts +2 -1
- package/lib/{dagre → antv-dagre}/layout.js +156 -154
- package/lib/antv-dagre/layout.js.map +1 -0
- package/lib/{dagre → antv-dagre}/nesting-graph.js +42 -39
- package/lib/antv-dagre/nesting-graph.js.map +1 -0
- package/lib/{dagre → antv-dagre}/normalize.d.ts +2 -2
- package/lib/{dagre → antv-dagre}/normalize.js +29 -25
- package/lib/antv-dagre/normalize.js.map +1 -0
- package/lib/{dagre → antv-dagre}/order/add-subgraph-constraints.js +13 -9
- package/lib/antv-dagre/order/add-subgraph-constraints.js.map +1 -0
- package/lib/{dagre → antv-dagre}/order/barycenter.d.ts +2 -2
- package/lib/antv-dagre/order/barycenter.js +27 -0
- package/lib/antv-dagre/order/barycenter.js.map +1 -0
- package/lib/{dagre → antv-dagre}/order/build-layer-graph.js +23 -23
- package/lib/antv-dagre/order/build-layer-graph.js.map +1 -0
- package/lib/antv-dagre/order/cross-count.d.ts +3 -0
- package/lib/{dagre → antv-dagre}/order/cross-count.js +21 -17
- package/lib/antv-dagre/order/cross-count.js.map +1 -0
- package/lib/{dagre → antv-dagre}/order/index.d.ts +1 -1
- package/lib/antv-dagre/order/index.js +95 -0
- package/lib/antv-dagre/order/index.js.map +1 -0
- package/lib/{dagre → antv-dagre}/order/init-data-order.js +12 -9
- package/lib/antv-dagre/order/init-data-order.js.map +1 -0
- package/lib/antv-dagre/order/init-order.js +51 -0
- package/lib/antv-dagre/order/init-order.js.map +1 -0
- package/lib/{dagre → antv-dagre}/order/resolve-conflicts.d.ts +3 -3
- package/lib/{dagre → antv-dagre}/order/resolve-conflicts.js +35 -36
- package/lib/antv-dagre/order/resolve-conflicts.js.map +1 -0
- package/lib/{dagre → antv-dagre}/order/sort-subgraph.js +28 -23
- package/lib/antv-dagre/order/sort-subgraph.js.map +1 -0
- package/lib/{dagre → antv-dagre}/order/sort.d.ts +2 -2
- package/lib/{dagre → antv-dagre}/order/sort.js +23 -19
- package/lib/antv-dagre/order/sort.js.map +1 -0
- package/lib/{dagre → antv-dagre}/parent-dummy-chains.js +32 -28
- package/lib/antv-dagre/parent-dummy-chains.js.map +1 -0
- package/lib/{dagre → antv-dagre}/position/bk.d.ts +5 -4
- package/lib/{dagre → antv-dagre}/position/bk.js +162 -148
- package/lib/antv-dagre/position/bk.js.map +1 -0
- package/lib/{dagre → antv-dagre}/position/index.d.ts +2 -1
- package/lib/antv-dagre/position/index.js +55 -0
- package/lib/antv-dagre/position/index.js.map +1 -0
- package/lib/{dagre → antv-dagre}/rank/feasible-tree.d.ts +2 -2
- package/lib/{dagre → antv-dagre}/rank/feasible-tree.js +42 -38
- package/lib/antv-dagre/rank/feasible-tree.js.map +1 -0
- package/lib/antv-dagre/rank/index.d.ts +2 -0
- package/lib/{dagre → antv-dagre}/rank/index.js +17 -13
- package/lib/antv-dagre/rank/index.js.map +1 -0
- package/lib/{dagre → antv-dagre}/rank/network-simplex.d.ts +2 -2
- package/lib/{dagre → antv-dagre}/rank/network-simplex.js +90 -81
- package/lib/antv-dagre/rank/network-simplex.js.map +1 -0
- package/lib/{dagre → antv-dagre}/rank/util.d.ts +2 -2
- package/lib/{dagre → antv-dagre}/rank/util.js +37 -32
- package/lib/antv-dagre/rank/util.js.map +1 -0
- package/lib/antv-dagre/types.d.ts +2 -0
- package/lib/antv-dagre/types.js +3 -0
- package/lib/antv-dagre/types.js.map +1 -0
- package/lib/{dagre → antv-dagre}/util.d.ts +1 -1
- package/lib/antv-dagre/util.js +299 -0
- package/lib/antv-dagre/util.js.map +1 -0
- package/lib/antv-dagre.d.ts +50 -0
- package/lib/antv-dagre.js +542 -0
- package/lib/antv-dagre.js.map +1 -0
- package/lib/bundle-entry.d.ts +2 -18
- package/lib/bundle-entry.js +5 -18
- package/lib/bundle-entry.js.map +1 -1
- package/lib/bundle-supervisor.d.ts +4 -22
- package/lib/bundle-supervisor.js +59 -54
- package/lib/bundle-supervisor.js.map +1 -1
- package/lib/bundle-worker.d.ts +1 -1
- package/lib/bundle-worker.js +38 -35
- package/lib/bundle-worker.js.map +1 -1
- package/lib/circular.d.ts +1 -1
- package/lib/circular.js +133 -145
- package/lib/circular.js.map +1 -1
- package/lib/comboCombined.d.ts +1 -1
- package/lib/comboCombined.js +273 -299
- package/lib/comboCombined.js.map +1 -1
- package/lib/concentric.d.ts +1 -1
- package/lib/concentric.js +173 -179
- package/lib/concentric.js.map +1 -1
- package/lib/d3Force/forceInBox.js +80 -78
- package/lib/d3Force/forceInBox.js.map +1 -1
- package/lib/d3Force/index.d.ts +2 -2
- package/lib/d3Force/index.js +207 -229
- package/lib/d3Force/index.js.map +1 -1
- package/lib/dagre.d.ts +13 -24
- package/lib/dagre.js +61 -542
- package/lib/dagre.js.map +1 -1
- package/lib/exports.d.ts +17 -0
- package/lib/exports.js +20 -0
- package/lib/exports.js.map +1 -0
- package/lib/force/forceNBody.js +48 -47
- package/lib/force/forceNBody.js.map +1 -1
- package/lib/force/index.d.ts +1 -1
- package/lib/force/index.js +301 -324
- package/lib/force/index.js.map +1 -1
- package/lib/force/types.d.ts +5 -5
- package/lib/force/types.js +2 -1
- package/lib/forceAtlas2/body.d.ts +1 -1
- package/lib/forceAtlas2/body.js +32 -31
- package/lib/forceAtlas2/body.js.map +1 -1
- package/lib/forceAtlas2/index.d.ts +1 -1
- package/lib/forceAtlas2/index.js +219 -227
- package/lib/forceAtlas2/index.js.map +1 -1
- package/lib/forceAtlas2/quad.d.ts +2 -2
- package/lib/forceAtlas2/quad.js +43 -42
- package/lib/forceAtlas2/quad.js.map +1 -1
- package/lib/forceAtlas2/quadTree.js +19 -17
- package/lib/forceAtlas2/quadTree.js.map +1 -1
- package/lib/fruchterman.d.ts +1 -1
- package/lib/fruchterman.js +203 -219
- package/lib/fruchterman.js.map +1 -1
- package/lib/grid.d.ts +1 -1
- package/lib/grid.js +201 -207
- package/lib/grid.js.map +1 -1
- package/lib/index.d.ts +1 -15
- package/lib/index.js +5 -16
- package/lib/index.js.map +1 -1
- package/lib/mds.d.ts +1 -1
- package/lib/mds.js +73 -79
- package/lib/mds.js.map +1 -1
- package/lib/radial/index.d.ts +1 -1
- package/lib/radial/index.js +183 -186
- package/lib/radial/index.js.map +1 -1
- package/lib/radial/mds.d.ts +1 -1
- package/lib/radial/mds.js +20 -14
- package/lib/radial/mds.js.map +1 -1
- package/lib/radial/radial-nonoverlap-force.d.ts +2 -2
- package/lib/radial/radial-nonoverlap-force.js +40 -37
- package/lib/radial/radial-nonoverlap-force.js.map +1 -1
- package/lib/random.d.ts +1 -1
- package/lib/random.js +57 -66
- package/lib/random.js.map +1 -1
- package/lib/registry.d.ts +2 -2
- package/lib/registry.js +30 -25
- package/lib/registry.js.map +1 -1
- package/lib/supervisor.d.ts +2 -3
- package/lib/supervisor.js +63 -58
- package/lib/supervisor.js.map +1 -1
- package/lib/types.d.ts +20 -75
- package/lib/types.js +5 -1
- package/lib/types.js.map +1 -1
- package/lib/util/array.js +4 -1
- package/lib/util/array.js.map +1 -1
- package/lib/util/common.d.ts +1 -1
- package/lib/util/common.js +11 -8
- package/lib/util/common.js.map +1 -1
- package/lib/util/function.js +41 -37
- package/lib/util/function.js.map +1 -1
- package/lib/util/index.d.ts +0 -2
- package/lib/util/index.js +7 -6
- package/lib/util/index.js.map +1 -1
- package/lib/util/math.d.ts +1 -26
- package/lib/util/math.js +55 -154
- package/lib/util/math.js.map +1 -1
- package/lib/util/object.d.ts +1 -1
- package/lib/util/object.js +20 -15
- package/lib/util/object.js.map +1 -1
- package/lib/util/size.d.ts +3 -0
- package/lib/util/size.js +16 -0
- package/lib/util/size.js.map +1 -0
- package/lib/worker.js +36 -35
- package/lib/worker.js.map +1 -1
- package/package.json +10 -6
- package/dist/aa1bb0ccc06b11cf79c1.worker.js +0 -2
- package/dist/aa1bb0ccc06b11cf79c1.worker.js.map +0 -1
- package/lib/dagre/acyclic.js +0 -62
- package/lib/dagre/acyclic.js.map +0 -1
- package/lib/dagre/add-border-segments.js +0 -37
- package/lib/dagre/add-border-segments.js.map +0 -1
- package/lib/dagre/coordinate-system.js +0 -65
- package/lib/dagre/coordinate-system.js.map +0 -1
- package/lib/dagre/data/list.js.map +0 -1
- package/lib/dagre/greedy-fas.js +0 -147
- package/lib/dagre/greedy-fas.js.map +0 -1
- package/lib/dagre/layout.js.map +0 -1
- package/lib/dagre/nesting-graph.js.map +0 -1
- package/lib/dagre/normalize.js.map +0 -1
- package/lib/dagre/order/add-subgraph-constraints.js.map +0 -1
- package/lib/dagre/order/barycenter.js +0 -23
- package/lib/dagre/order/barycenter.js.map +0 -1
- package/lib/dagre/order/build-layer-graph.js.map +0 -1
- package/lib/dagre/order/cross-count.d.ts +0 -3
- package/lib/dagre/order/cross-count.js.map +0 -1
- package/lib/dagre/order/index.js +0 -91
- package/lib/dagre/order/index.js.map +0 -1
- package/lib/dagre/order/init-data-order.js.map +0 -1
- package/lib/dagre/order/init-order.js +0 -50
- package/lib/dagre/order/init-order.js.map +0 -1
- package/lib/dagre/order/resolve-conflicts.js.map +0 -1
- package/lib/dagre/order/sort-subgraph.js.map +0 -1
- package/lib/dagre/order/sort.js.map +0 -1
- package/lib/dagre/parent-dummy-chains.js.map +0 -1
- package/lib/dagre/position/bk.js.map +0 -1
- package/lib/dagre/position/index.js +0 -54
- package/lib/dagre/position/index.js.map +0 -1
- package/lib/dagre/rank/feasible-tree.js.map +0 -1
- package/lib/dagre/rank/index.d.ts +0 -2
- package/lib/dagre/rank/index.js.map +0 -1
- package/lib/dagre/rank/network-simplex.js.map +0 -1
- package/lib/dagre/rank/util.js.map +0 -1
- package/lib/dagre/util.js +0 -289
- package/lib/dagre/util.js.map +0 -1
- package/lib/util/gpu.d.ts +0 -45
- package/lib/util/gpu.js +0 -214
- package/lib/util/gpu.js.map +0 -1
- package/lib/util/number.d.ts +0 -1
- package/lib/util/number.js +0 -5
- package/lib/util/number.js.map +0 -1
- package/lib/util/string.d.ts +0 -1
- package/lib/util/string.js +0 -15
- package/lib/util/string.js.map +0 -1
- /package/lib/{dagre → antv-dagre}/add-border-segments.d.ts +0 -0
- /package/lib/{dagre → antv-dagre}/nesting-graph.d.ts +0 -0
- /package/lib/{dagre → antv-dagre}/order/add-subgraph-constraints.d.ts +0 -0
- /package/lib/{dagre → antv-dagre}/order/build-layer-graph.d.ts +0 -0
- /package/lib/{dagre → antv-dagre}/order/init-data-order.d.ts +0 -0
- /package/lib/{dagre → antv-dagre}/order/init-order.d.ts +0 -0
- /package/lib/{dagre → antv-dagre}/order/sort-subgraph.d.ts +0 -0
- /package/lib/{dagre → antv-dagre}/parent-dummy-chains.d.ts +0 -0
package/lib/force/index.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ForceLayout = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const graphlib_1 = require("@antv/graphlib");
|
|
6
|
+
const util_1 = require("@antv/util");
|
|
7
|
+
const util_2 = require("../util");
|
|
8
|
+
const forceNBody_1 = require("./forceNBody");
|
|
9
|
+
const DEFAULTS_LAYOUT_OPTIONS = {
|
|
7
10
|
dimensions: 2,
|
|
8
11
|
maxIteration: 500,
|
|
9
12
|
gravity: 10,
|
|
@@ -35,9 +38,8 @@ var DEFAULTS_LAYOUT_OPTIONS = {
|
|
|
35
38
|
* // If you want to assign the positions directly to the nodes, use assign method.
|
|
36
39
|
* await layout.assign(graph, { center: [100, 100] });
|
|
37
40
|
*/
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (options === void 0) { options = {}; }
|
|
41
|
+
class ForceLayout {
|
|
42
|
+
constructor(options = {}) {
|
|
41
43
|
this.options = options;
|
|
42
44
|
this.id = 'force';
|
|
43
45
|
/**
|
|
@@ -49,162 +51,148 @@ var ForceLayout = /** @class */ (function () {
|
|
|
49
51
|
*/
|
|
50
52
|
this.judgingDistance = 0;
|
|
51
53
|
this.running = false;
|
|
52
|
-
this.options =
|
|
54
|
+
this.options = Object.assign(Object.assign({}, DEFAULTS_LAYOUT_OPTIONS), options);
|
|
53
55
|
}
|
|
54
56
|
/**
|
|
55
57
|
* Return the positions of nodes and edges(if needed).
|
|
56
58
|
*/
|
|
57
|
-
|
|
58
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
59
|
-
return
|
|
60
|
-
return [2 /*return*/, this.genericForceLayout(false, graph, options)];
|
|
61
|
-
});
|
|
59
|
+
execute(graph, options) {
|
|
60
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
61
|
+
return this.genericForceLayout(false, graph, options);
|
|
62
62
|
});
|
|
63
|
-
}
|
|
63
|
+
}
|
|
64
64
|
/**
|
|
65
65
|
* To directly assign the positions to the nodes.
|
|
66
66
|
*/
|
|
67
|
-
|
|
68
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
69
|
-
|
|
70
|
-
this.genericForceLayout(true, graph, options);
|
|
71
|
-
return [2 /*return*/];
|
|
72
|
-
});
|
|
67
|
+
assign(graph, options) {
|
|
68
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
69
|
+
this.genericForceLayout(true, graph, options);
|
|
73
70
|
});
|
|
74
|
-
}
|
|
71
|
+
}
|
|
75
72
|
/**
|
|
76
73
|
* Stop simulation immediately.
|
|
77
74
|
*/
|
|
78
|
-
|
|
75
|
+
stop() {
|
|
79
76
|
if (this.timeInterval && typeof window !== 'undefined') {
|
|
80
77
|
window.clearInterval(this.timeInterval);
|
|
81
78
|
}
|
|
82
79
|
this.running = false;
|
|
83
|
-
}
|
|
80
|
+
}
|
|
84
81
|
/**
|
|
85
82
|
* Manually steps the simulation by the specified number of iterations.
|
|
86
83
|
* @see https://github.com/d3/d3-force#simulation_tick
|
|
87
84
|
*/
|
|
88
|
-
|
|
89
|
-
var _this = this;
|
|
90
|
-
if (iterations === void 0) { iterations = this.options.maxIteration || 1; }
|
|
85
|
+
tick(iterations = this.options.maxIteration || 1) {
|
|
91
86
|
if (this.lastResult) {
|
|
92
87
|
return this.lastResult;
|
|
93
88
|
}
|
|
94
|
-
for (
|
|
89
|
+
for (let i = 0; (this.judgingDistance > this.lastOptions.minMovement || i < 1) &&
|
|
95
90
|
i < iterations; i++) {
|
|
96
91
|
this.runOneStep(this.lastCalcGraph, this.lastGraph, i, this.lastVelMap, this.lastOptions);
|
|
97
92
|
this.updatePosition(this.lastGraph, this.lastCalcGraph, this.lastVelMap, this.lastOptions);
|
|
98
93
|
}
|
|
99
|
-
|
|
94
|
+
const result = {
|
|
100
95
|
nodes: this.lastLayoutNodes,
|
|
101
96
|
edges: this.lastLayoutEdges,
|
|
102
97
|
};
|
|
103
98
|
if (this.lastAssign) {
|
|
104
|
-
result.nodes.forEach(
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
});
|
|
110
|
-
});
|
|
99
|
+
result.nodes.forEach((node) => this.lastGraph.mergeNodeData(node.id, {
|
|
100
|
+
x: node.data.x,
|
|
101
|
+
y: node.data.y,
|
|
102
|
+
z: this.options.dimensions === 3 ? node.data.z : undefined,
|
|
103
|
+
}));
|
|
111
104
|
}
|
|
112
105
|
return result;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
velMap = {
|
|
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
|
-
}, 0);
|
|
194
|
-
_this.running = true;
|
|
195
|
-
})];
|
|
106
|
+
}
|
|
107
|
+
genericForceLayout(assign, graph, options) {
|
|
108
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
109
|
+
const mergedOptions = Object.assign(Object.assign({}, this.options), options);
|
|
110
|
+
const nodes = graph.getAllNodes();
|
|
111
|
+
const edges = graph.getAllEdges();
|
|
112
|
+
const formattedOptions = this.formatOptions(mergedOptions, graph);
|
|
113
|
+
const { dimensions, width, height, nodeSize, getMass, nodeStrength, edgeStrength, linkDistance, } = formattedOptions;
|
|
114
|
+
// clones the original data and attaches calculation attributes for this layout algorithm
|
|
115
|
+
const layoutNodes = nodes.map((node, i) => {
|
|
116
|
+
return Object.assign(Object.assign({}, node), { data: Object.assign(Object.assign({}, node.data), {
|
|
117
|
+
// ...randomDistribution(node, dimensions, 30, i),
|
|
118
|
+
x: (0, util_1.isNumber)(node.data.x) ? node.data.x : Math.random() * width, y: (0, util_1.isNumber)(node.data.y) ? node.data.y : Math.random() * height, z: (0, util_1.isNumber)(node.data.z)
|
|
119
|
+
? node.data.z
|
|
120
|
+
: Math.random() * Math.sqrt(width * height), size: nodeSize(node) || 30, mass: getMass(node), nodeStrength: nodeStrength(node) }) });
|
|
121
|
+
});
|
|
122
|
+
const layoutEdges = edges.map((edge) => (Object.assign(Object.assign({}, edge), { data: Object.assign(Object.assign({}, edge.data), { edgeStrength: edgeStrength(edge), linkDistance: linkDistance(edge, graph.getNode(edge.source), graph.getNode(edge.target)) }) })));
|
|
123
|
+
if (!(nodes === null || nodes === void 0 ? void 0 : nodes.length)) {
|
|
124
|
+
this.lastResult = { nodes: [], edges };
|
|
125
|
+
return { nodes: [], edges };
|
|
126
|
+
}
|
|
127
|
+
const velMap = {};
|
|
128
|
+
nodes.forEach((node, i) => {
|
|
129
|
+
velMap[node.id] = {
|
|
130
|
+
x: 0,
|
|
131
|
+
y: 0,
|
|
132
|
+
z: 0,
|
|
133
|
+
};
|
|
134
|
+
});
|
|
135
|
+
const calcGraph = new graphlib_1.Graph({
|
|
136
|
+
nodes: layoutNodes,
|
|
137
|
+
edges: layoutEdges,
|
|
138
|
+
});
|
|
139
|
+
this.formatCentripetal(formattedOptions, calcGraph);
|
|
140
|
+
const { maxIteration, minMovement, onTick } = formattedOptions;
|
|
141
|
+
// Use them later in `tick`.
|
|
142
|
+
this.lastLayoutNodes = layoutNodes;
|
|
143
|
+
this.lastLayoutEdges = layoutEdges;
|
|
144
|
+
this.lastAssign = assign;
|
|
145
|
+
this.lastGraph = graph;
|
|
146
|
+
this.lastCalcGraph = calcGraph;
|
|
147
|
+
this.lastOptions = formattedOptions;
|
|
148
|
+
this.lastVelMap = velMap;
|
|
149
|
+
if (typeof window === 'undefined')
|
|
150
|
+
return;
|
|
151
|
+
let iter = 0;
|
|
152
|
+
return new Promise((resolve) => {
|
|
153
|
+
// interval for render the result after each iteration
|
|
154
|
+
this.timeInterval = window.setInterval(() => {
|
|
155
|
+
if (!nodes || !this.running) {
|
|
156
|
+
resolve({
|
|
157
|
+
nodes: formatOutNodes(graph, layoutNodes),
|
|
158
|
+
edges,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
this.runOneStep(calcGraph, graph, iter, velMap, formattedOptions);
|
|
162
|
+
this.updatePosition(graph, calcGraph, velMap, formattedOptions);
|
|
163
|
+
if (assign) {
|
|
164
|
+
layoutNodes.forEach((node) => graph.mergeNodeData(node.id, {
|
|
165
|
+
x: node.data.x,
|
|
166
|
+
y: node.data.y,
|
|
167
|
+
z: dimensions === 3 ? node.data.z : undefined,
|
|
168
|
+
}));
|
|
169
|
+
}
|
|
170
|
+
onTick === null || onTick === void 0 ? void 0 : onTick({
|
|
171
|
+
nodes: formatOutNodes(graph, layoutNodes),
|
|
172
|
+
edges,
|
|
173
|
+
});
|
|
174
|
+
iter++;
|
|
175
|
+
if (iter >= maxIteration || this.judgingDistance < minMovement) {
|
|
176
|
+
window.clearInterval(this.timeInterval);
|
|
177
|
+
resolve({
|
|
178
|
+
nodes: formatOutNodes(graph, layoutNodes),
|
|
179
|
+
edges,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}, 0);
|
|
183
|
+
this.running = true;
|
|
196
184
|
});
|
|
197
185
|
});
|
|
198
|
-
}
|
|
186
|
+
}
|
|
199
187
|
/**
|
|
200
188
|
* Format merged layout options.
|
|
201
189
|
* @param options merged layout options
|
|
202
190
|
* @param graph original graph
|
|
203
191
|
* @returns
|
|
204
192
|
*/
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
193
|
+
formatOptions(options, graph) {
|
|
194
|
+
const formattedOptions = Object.assign({}, options);
|
|
195
|
+
const { width: propsWidth, height: propsHeight, getMass, nodeSize, } = options;
|
|
208
196
|
// === formating width, height, and center =====
|
|
209
197
|
formattedOptions.width =
|
|
210
198
|
!propsWidth && typeof window !== 'undefined'
|
|
@@ -222,25 +210,25 @@ var ForceLayout = /** @class */ (function () {
|
|
|
222
210
|
}
|
|
223
211
|
// === formating node mass =====
|
|
224
212
|
if (!getMass) {
|
|
225
|
-
formattedOptions.getMass =
|
|
226
|
-
|
|
227
|
-
if (isNumber(d === null || d === void 0 ? void 0 : d.data.mass))
|
|
213
|
+
formattedOptions.getMass = (d) => {
|
|
214
|
+
let massWeight = 1;
|
|
215
|
+
if ((0, util_1.isNumber)(d === null || d === void 0 ? void 0 : d.data.mass))
|
|
228
216
|
massWeight = d === null || d === void 0 ? void 0 : d.data.mass;
|
|
229
|
-
|
|
217
|
+
const degree = graph.getDegree(d.id, 'both');
|
|
230
218
|
return !degree || degree < 5 ? massWeight : degree * 5 * massWeight;
|
|
231
219
|
};
|
|
232
220
|
}
|
|
233
221
|
// === formating node size =====
|
|
234
|
-
|
|
235
|
-
|
|
222
|
+
const nodeSpacingFunc = (0, util_2.formatNumberFn)(0, options.nodeSpacing);
|
|
223
|
+
let nodeSizeFn;
|
|
236
224
|
if (!nodeSize) {
|
|
237
|
-
nodeSizeFn =
|
|
238
|
-
|
|
225
|
+
nodeSizeFn = (d) => {
|
|
226
|
+
const { size } = (d === null || d === void 0 ? void 0 : d.data) || {};
|
|
239
227
|
if (size) {
|
|
240
|
-
if (isArray(size)) {
|
|
228
|
+
if ((0, util_2.isArray)(size)) {
|
|
241
229
|
return Math.max(size[0], size[1]) + nodeSpacingFunc(d);
|
|
242
230
|
}
|
|
243
|
-
if (isObject(size)) {
|
|
231
|
+
if ((0, util_1.isObject)(size)) {
|
|
244
232
|
return Math.max(size.width, size.height) + nodeSpacingFunc(d);
|
|
245
233
|
}
|
|
246
234
|
return size + nodeSpacingFunc(d);
|
|
@@ -248,47 +236,47 @@ var ForceLayout = /** @class */ (function () {
|
|
|
248
236
|
return 10 + nodeSpacingFunc(d);
|
|
249
237
|
};
|
|
250
238
|
}
|
|
251
|
-
else if (isFunction(nodeSize)) {
|
|
252
|
-
nodeSizeFn =
|
|
239
|
+
else if ((0, util_1.isFunction)(nodeSize)) {
|
|
240
|
+
nodeSizeFn = (d) => nodeSize(d) + nodeSpacingFunc(d);
|
|
253
241
|
}
|
|
254
|
-
else if (isArray(nodeSize)) {
|
|
255
|
-
nodeSizeFn =
|
|
256
|
-
|
|
242
|
+
else if ((0, util_2.isArray)(nodeSize)) {
|
|
243
|
+
nodeSizeFn = (d) => {
|
|
244
|
+
const nodeSizeArr = nodeSize;
|
|
257
245
|
return Math.max(nodeSizeArr[0], nodeSizeArr[1]) + nodeSpacingFunc(d);
|
|
258
246
|
};
|
|
259
247
|
}
|
|
260
248
|
else {
|
|
261
|
-
nodeSizeFn =
|
|
249
|
+
nodeSizeFn = (d) => nodeSize + nodeSpacingFunc(d);
|
|
262
250
|
}
|
|
263
251
|
formattedOptions.nodeSize = nodeSizeFn;
|
|
264
252
|
// === formating node / edge strengths =====
|
|
265
|
-
|
|
266
|
-
? formatNumberFn(1, options.linkDistance)
|
|
267
|
-
:
|
|
253
|
+
const linkDistanceFn = options.linkDistance
|
|
254
|
+
? (0, util_2.formatNumberFn)(1, options.linkDistance)
|
|
255
|
+
: (edge) => {
|
|
268
256
|
return (1 +
|
|
269
257
|
formattedOptions.nodeSize(graph.getNode(edge.source)) +
|
|
270
258
|
formattedOptions.nodeSize(graph.getNode(edge.target)));
|
|
271
259
|
};
|
|
272
260
|
formattedOptions.linkDistance = linkDistanceFn;
|
|
273
|
-
formattedOptions.nodeStrength = formatNumberFn(1, options.nodeStrength);
|
|
274
|
-
formattedOptions.edgeStrength = formatNumberFn(1, options.edgeStrength);
|
|
261
|
+
formattedOptions.nodeStrength = (0, util_2.formatNumberFn)(1, options.nodeStrength);
|
|
262
|
+
formattedOptions.edgeStrength = (0, util_2.formatNumberFn)(1, options.edgeStrength);
|
|
275
263
|
return formattedOptions;
|
|
276
|
-
}
|
|
264
|
+
}
|
|
277
265
|
/**
|
|
278
266
|
* Format centripetalOption in the option.
|
|
279
267
|
* @param options merged layout options
|
|
280
268
|
* @param calcGraph calculation graph
|
|
281
269
|
*/
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
270
|
+
formatCentripetal(options, calcGraph) {
|
|
271
|
+
const { dimensions, centripetalOptions, center, clusterNodeStrength, leafCluster, clustering, nodeClusterBy, } = options;
|
|
272
|
+
const calcNodes = calcGraph.getAllNodes();
|
|
285
273
|
// === formating centripetalOptions =====
|
|
286
|
-
|
|
274
|
+
const basicCentripetal = centripetalOptions || {
|
|
287
275
|
leaf: 2,
|
|
288
276
|
single: 2,
|
|
289
277
|
others: 1,
|
|
290
278
|
// eslint-disable-next-line
|
|
291
|
-
center:
|
|
279
|
+
center: (n) => {
|
|
292
280
|
return {
|
|
293
281
|
x: center[0],
|
|
294
282
|
y: center[1],
|
|
@@ -297,22 +285,20 @@ var ForceLayout = /** @class */ (function () {
|
|
|
297
285
|
},
|
|
298
286
|
};
|
|
299
287
|
if (typeof clusterNodeStrength !== 'function') {
|
|
300
|
-
options.clusterNodeStrength =
|
|
301
|
-
return clusterNodeStrength;
|
|
302
|
-
};
|
|
288
|
+
options.clusterNodeStrength = (node) => clusterNodeStrength;
|
|
303
289
|
}
|
|
304
|
-
|
|
305
|
-
|
|
290
|
+
let sameTypeLeafMap;
|
|
291
|
+
let clusters;
|
|
306
292
|
if (leafCluster && nodeClusterBy) {
|
|
307
293
|
sameTypeLeafMap = getSameTypeLeafMap(calcGraph, nodeClusterBy);
|
|
308
294
|
clusters =
|
|
309
|
-
Array.from(new Set(calcNodes === null || calcNodes === void 0 ? void 0 : calcNodes.map(
|
|
295
|
+
Array.from(new Set(calcNodes === null || calcNodes === void 0 ? void 0 : calcNodes.map((node) => node.data[nodeClusterBy]))) || [];
|
|
310
296
|
// @ts-ignore
|
|
311
297
|
options.centripetalOptions = Object.assign(basicCentripetal, {
|
|
312
298
|
single: 100,
|
|
313
|
-
leaf:
|
|
299
|
+
leaf: (node) => {
|
|
314
300
|
// 找出与它关联的边的起点或终点出发的所有一度节点中同类型的叶子节点
|
|
315
|
-
|
|
301
|
+
const { siblingLeaves, sameTypeLeaves } = sameTypeLeafMap[node.id] || {};
|
|
316
302
|
// 如果都是同一类型或者每种类型只有1个,则施加默认向心力
|
|
317
303
|
if ((sameTypeLeaves === null || sameTypeLeaves === void 0 ? void 0 : sameTypeLeaves.length) === (siblingLeaves === null || siblingLeaves === void 0 ? void 0 : siblingLeaves.length) ||
|
|
318
304
|
(clusters === null || clusters === void 0 ? void 0 : clusters.length) === 1) {
|
|
@@ -321,8 +307,8 @@ var ForceLayout = /** @class */ (function () {
|
|
|
321
307
|
return options.clusterNodeStrength(node);
|
|
322
308
|
},
|
|
323
309
|
others: 1,
|
|
324
|
-
center:
|
|
325
|
-
|
|
310
|
+
center: (node) => {
|
|
311
|
+
const degree = calcGraph.getDegree(node.id, 'both');
|
|
326
312
|
// 孤点默认给1个远离的中心点
|
|
327
313
|
if (!degree) {
|
|
328
314
|
return {
|
|
@@ -331,11 +317,11 @@ var ForceLayout = /** @class */ (function () {
|
|
|
331
317
|
z: 0,
|
|
332
318
|
};
|
|
333
319
|
}
|
|
334
|
-
|
|
320
|
+
let centerPos;
|
|
335
321
|
if (degree === 1) {
|
|
336
322
|
// 如果为叶子节点
|
|
337
323
|
// 找出与它关联的边的起点出发的所有一度节点中同类型的叶子节点
|
|
338
|
-
|
|
324
|
+
const { sameTypeLeaves = [] } = sameTypeLeafMap[node.id] || {};
|
|
339
325
|
if (sameTypeLeaves.length === 1) {
|
|
340
326
|
// 如果同类型的叶子节点只有1个,中心位置为undefined
|
|
341
327
|
centerPos = undefined;
|
|
@@ -361,24 +347,24 @@ var ForceLayout = /** @class */ (function () {
|
|
|
361
347
|
sameTypeLeafMap = getSameTypeLeafMap(calcGraph, nodeClusterBy);
|
|
362
348
|
}
|
|
363
349
|
if (!clusters) {
|
|
364
|
-
clusters = Array.from(new Set(calcNodes.map(
|
|
350
|
+
clusters = Array.from(new Set(calcNodes.map((node) => node.data[nodeClusterBy])));
|
|
365
351
|
}
|
|
366
|
-
clusters = clusters.filter(
|
|
367
|
-
|
|
368
|
-
clusters.forEach(
|
|
369
|
-
|
|
370
|
-
.filter(
|
|
371
|
-
.map(
|
|
352
|
+
clusters = clusters.filter((item) => item !== undefined);
|
|
353
|
+
const centerInfo = {};
|
|
354
|
+
clusters.forEach((cluster) => {
|
|
355
|
+
const sameTypeNodes = calcNodes
|
|
356
|
+
.filter((node) => node.data[nodeClusterBy] === cluster)
|
|
357
|
+
.map((node) => calcGraph.getNode(node.id));
|
|
372
358
|
// 找出同类型节点平均位置节点的距离最近的节点作为中心节点
|
|
373
|
-
|
|
359
|
+
centerInfo[cluster] = getAvgNodePosition(sameTypeNodes);
|
|
374
360
|
});
|
|
375
361
|
options.centripetalOptions = Object.assign(basicCentripetal, {
|
|
376
|
-
single:
|
|
377
|
-
leaf:
|
|
378
|
-
others:
|
|
379
|
-
center:
|
|
362
|
+
single: (node) => options.clusterNodeStrength(node),
|
|
363
|
+
leaf: (node) => options.clusterNodeStrength(node),
|
|
364
|
+
others: (node) => options.clusterNodeStrength(node),
|
|
365
|
+
center: (node) => {
|
|
380
366
|
// 找出同类型节点平均位置节点的距离最近的节点作为中心节点
|
|
381
|
-
|
|
367
|
+
const centerPos = centerInfo[node.data[nodeClusterBy]];
|
|
382
368
|
return {
|
|
383
369
|
x: centerPos === null || centerPos === void 0 ? void 0 : centerPos.x,
|
|
384
370
|
y: centerPos === null || centerPos === void 0 ? void 0 : centerPos.y,
|
|
@@ -387,17 +373,17 @@ var ForceLayout = /** @class */ (function () {
|
|
|
387
373
|
},
|
|
388
374
|
});
|
|
389
375
|
}
|
|
390
|
-
|
|
376
|
+
const { leaf, single, others } = options.centripetalOptions || {};
|
|
391
377
|
if (leaf && typeof leaf !== 'function') {
|
|
392
|
-
options.centripetalOptions.leaf =
|
|
378
|
+
options.centripetalOptions.leaf = () => leaf;
|
|
393
379
|
}
|
|
394
380
|
if (single && typeof single !== 'function') {
|
|
395
|
-
options.centripetalOptions.single =
|
|
381
|
+
options.centripetalOptions.single = () => single;
|
|
396
382
|
}
|
|
397
383
|
if (others && typeof others !== 'function') {
|
|
398
|
-
options.centripetalOptions.others =
|
|
384
|
+
options.centripetalOptions.others = () => others;
|
|
399
385
|
}
|
|
400
|
-
}
|
|
386
|
+
}
|
|
401
387
|
/**
|
|
402
388
|
* One iteration.
|
|
403
389
|
* @param calcGraph calculation graph
|
|
@@ -407,13 +393,13 @@ var ForceLayout = /** @class */ (function () {
|
|
|
407
393
|
* @param options formatted layout options
|
|
408
394
|
* @returns
|
|
409
395
|
*/
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
396
|
+
runOneStep(calcGraph, graph, iter, velMap, options) {
|
|
397
|
+
const accMap = {};
|
|
398
|
+
const calcNodes = calcGraph.getAllNodes();
|
|
399
|
+
const calcEdges = calcGraph.getAllEdges();
|
|
414
400
|
if (!(calcNodes === null || calcNodes === void 0 ? void 0 : calcNodes.length))
|
|
415
401
|
return;
|
|
416
|
-
|
|
402
|
+
const { monitor } = options;
|
|
417
403
|
this.calRepulsive(calcGraph, accMap, options);
|
|
418
404
|
if (calcEdges)
|
|
419
405
|
this.calAttractive(calcGraph, accMap, options);
|
|
@@ -421,62 +407,61 @@ var ForceLayout = /** @class */ (function () {
|
|
|
421
407
|
this.updateVelocity(calcGraph, accMap, velMap, options);
|
|
422
408
|
/** 如果需要监控信息,则提供给用户 */
|
|
423
409
|
if (monitor) {
|
|
424
|
-
|
|
410
|
+
const energy = this.calTotalEnergy(accMap, calcNodes);
|
|
425
411
|
monitor({
|
|
426
|
-
energy
|
|
412
|
+
energy,
|
|
427
413
|
nodes: graph.getAllNodes(),
|
|
428
414
|
edges: graph.getAllEdges(),
|
|
429
415
|
iterations: iter,
|
|
430
416
|
});
|
|
431
417
|
}
|
|
432
|
-
}
|
|
418
|
+
}
|
|
433
419
|
/**
|
|
434
420
|
* Calculate graph energy for monitoring convergence.
|
|
435
421
|
* @param accMap acceleration map
|
|
436
422
|
* @param nodes calculation nodes
|
|
437
423
|
* @returns energy
|
|
438
424
|
*/
|
|
439
|
-
|
|
440
|
-
var _this = this;
|
|
425
|
+
calTotalEnergy(accMap, nodes) {
|
|
441
426
|
if (!(nodes === null || nodes === void 0 ? void 0 : nodes.length))
|
|
442
427
|
return 0;
|
|
443
|
-
|
|
444
|
-
nodes.forEach(
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
428
|
+
let energy = 0.0;
|
|
429
|
+
nodes.forEach((node, i) => {
|
|
430
|
+
const vx = accMap[node.id].x;
|
|
431
|
+
const vy = accMap[node.id].y;
|
|
432
|
+
const vz = this.options.dimensions === 3 ? accMap[node.id].z : 0;
|
|
433
|
+
const speed2 = vx * vx + vy * vy + vz * vz;
|
|
434
|
+
const { mass = 1 } = node.data;
|
|
450
435
|
energy += mass * speed2 * 0.5; // p = 1/2*(mv^2)
|
|
451
436
|
});
|
|
452
437
|
return energy;
|
|
453
|
-
}
|
|
438
|
+
}
|
|
454
439
|
/**
|
|
455
440
|
* Calculate the repulsive forces according to coulombs law.
|
|
456
441
|
* @param calcGraph calculation graph
|
|
457
442
|
* @param accMap acceleration map
|
|
458
443
|
* @param options formatted layout options
|
|
459
444
|
*/
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
forceNBody(calcGraph, factor, coulombDisScale * coulombDisScale, accMap, dimensions);
|
|
463
|
-
}
|
|
445
|
+
calRepulsive(calcGraph, accMap, options) {
|
|
446
|
+
const { dimensions, factor, coulombDisScale } = options;
|
|
447
|
+
(0, forceNBody_1.forceNBody)(calcGraph, factor, coulombDisScale * coulombDisScale, accMap, dimensions);
|
|
448
|
+
}
|
|
464
449
|
/**
|
|
465
450
|
* Calculate the attractive forces according to hooks law.
|
|
466
451
|
* @param calcGraph calculation graph
|
|
467
452
|
* @param accMap acceleration map
|
|
468
453
|
*/
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
calcGraph.getAllEdges().forEach(
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
454
|
+
calAttractive(calcGraph, accMap, options) {
|
|
455
|
+
const { dimensions, nodeSize } = options;
|
|
456
|
+
calcGraph.getAllEdges().forEach((edge, i) => {
|
|
457
|
+
const { source, target } = edge;
|
|
458
|
+
const sourceNode = calcGraph.getNode(source);
|
|
459
|
+
const targetNode = calcGraph.getNode(target);
|
|
475
460
|
if (!sourceNode || !targetNode)
|
|
476
461
|
return;
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
462
|
+
let vecX = targetNode.data.x - sourceNode.data.x;
|
|
463
|
+
let vecY = targetNode.data.y - sourceNode.data.y;
|
|
464
|
+
let vecZ = dimensions === 3 ? targetNode.data.z - sourceNode.data.z : 0;
|
|
480
465
|
if (!vecX && !vecY) {
|
|
481
466
|
vecX = Math.random() * 0.01;
|
|
482
467
|
vecY = Math.random() * 0.01;
|
|
@@ -484,23 +469,23 @@ var ForceLayout = /** @class */ (function () {
|
|
|
484
469
|
vecZ = Math.random() * 0.01;
|
|
485
470
|
}
|
|
486
471
|
}
|
|
487
|
-
|
|
472
|
+
const vecLength = Math.sqrt(vecX * vecX + vecY * vecY + vecZ * vecZ);
|
|
488
473
|
if (vecLength < nodeSize(sourceNode) + nodeSize(targetNode))
|
|
489
474
|
return;
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
475
|
+
const direX = vecX / vecLength;
|
|
476
|
+
const direY = vecY / vecLength;
|
|
477
|
+
const direZ = vecZ / vecLength;
|
|
478
|
+
const { linkDistance = 200, edgeStrength = 200 } = edge.data || {};
|
|
479
|
+
const diff = linkDistance - vecLength;
|
|
480
|
+
const param = diff * edgeStrength;
|
|
481
|
+
const massSource = sourceNode.data.mass || 1;
|
|
482
|
+
const massTarget = targetNode.data.mass || 1;
|
|
498
483
|
// 质量占比越大,对另一端影响程度越大
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
484
|
+
const sourceMassRatio = 1 / massSource;
|
|
485
|
+
const targetMassRatio = 1 / massTarget;
|
|
486
|
+
const disX = direX * param;
|
|
487
|
+
const disY = direY * param;
|
|
488
|
+
const disZ = direZ * param;
|
|
504
489
|
accMap[source].x -= disX * sourceMassRatio;
|
|
505
490
|
accMap[source].y -= disY * sourceMassRatio;
|
|
506
491
|
accMap[source].z -= disZ * sourceMassRatio;
|
|
@@ -508,7 +493,7 @@ var ForceLayout = /** @class */ (function () {
|
|
|
508
493
|
accMap[target].y += disY * targetMassRatio;
|
|
509
494
|
accMap[target].z += disZ * targetMassRatio;
|
|
510
495
|
});
|
|
511
|
-
}
|
|
496
|
+
}
|
|
512
497
|
/**
|
|
513
498
|
* Calculate the gravity forces toward center.
|
|
514
499
|
* @param calcGraph calculation graph
|
|
@@ -516,28 +501,28 @@ var ForceLayout = /** @class */ (function () {
|
|
|
516
501
|
* @param accMap acceleration map
|
|
517
502
|
* @param options formatted layout options
|
|
518
503
|
*/
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
504
|
+
calGravity(calcGraph, graph, accMap, options) {
|
|
505
|
+
const { getCenter } = options;
|
|
506
|
+
const calcNodes = calcGraph.getAllNodes();
|
|
507
|
+
const nodes = graph.getAllNodes();
|
|
508
|
+
const edges = graph.getAllEdges();
|
|
509
|
+
const { width, height, center, gravity: defaultGravity, centripetalOptions, } = options;
|
|
525
510
|
if (!calcNodes)
|
|
526
511
|
return;
|
|
527
|
-
calcNodes.forEach(
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
512
|
+
calcNodes.forEach((calcNode) => {
|
|
513
|
+
const { id, data } = calcNode;
|
|
514
|
+
const { mass, x, y, z } = data;
|
|
515
|
+
const node = graph.getNode(id);
|
|
516
|
+
let vecX = 0;
|
|
517
|
+
let vecY = 0;
|
|
518
|
+
let vecZ = 0;
|
|
519
|
+
let gravity = defaultGravity;
|
|
520
|
+
const inDegree = calcGraph.getDegree(id, 'in');
|
|
521
|
+
const outDegree = calcGraph.getDegree(id, 'out');
|
|
522
|
+
const degree = calcGraph.getDegree(id, 'both');
|
|
523
|
+
const forceCenter = getCenter === null || getCenter === void 0 ? void 0 : getCenter(node, degree);
|
|
539
524
|
if (forceCenter) {
|
|
540
|
-
|
|
525
|
+
const [centerX, centerY, strength] = forceCenter;
|
|
541
526
|
vecX = x - centerX;
|
|
542
527
|
vecY = y - centerY;
|
|
543
528
|
gravity = strength;
|
|
@@ -553,18 +538,18 @@ var ForceLayout = /** @class */ (function () {
|
|
|
553
538
|
accMap[id].z -= (gravity * vecZ) / mass;
|
|
554
539
|
}
|
|
555
540
|
if (centripetalOptions) {
|
|
556
|
-
|
|
557
|
-
|
|
541
|
+
const { leaf, single, others, center: centriCenter, } = centripetalOptions;
|
|
542
|
+
const { x: centriX, y: centriY, z: centriZ, centerStrength, } = (centriCenter === null || centriCenter === void 0 ? void 0 : centriCenter(node, nodes, edges, width, height)) || {
|
|
558
543
|
x: 0,
|
|
559
544
|
y: 0,
|
|
560
545
|
z: 0,
|
|
561
546
|
centerStrength: 0,
|
|
562
|
-
}
|
|
563
|
-
if (!isNumber(centriX) || !isNumber(centriY))
|
|
547
|
+
};
|
|
548
|
+
if (!(0, util_1.isNumber)(centriX) || !(0, util_1.isNumber)(centriY))
|
|
564
549
|
return;
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
550
|
+
const vx = (x - centriX) / mass;
|
|
551
|
+
const vy = (y - centriY) / mass;
|
|
552
|
+
const vz = (z - centriZ) / mass;
|
|
568
553
|
if (centerStrength) {
|
|
569
554
|
accMap[id].x -= centerStrength * vx;
|
|
570
555
|
accMap[id].y -= centerStrength * vy;
|
|
@@ -572,7 +557,7 @@ var ForceLayout = /** @class */ (function () {
|
|
|
572
557
|
}
|
|
573
558
|
// 孤点
|
|
574
559
|
if (degree === 0) {
|
|
575
|
-
|
|
560
|
+
const singleStrength = single(node);
|
|
576
561
|
if (!singleStrength)
|
|
577
562
|
return;
|
|
578
563
|
accMap[id].x -= singleStrength * vx;
|
|
@@ -582,7 +567,7 @@ var ForceLayout = /** @class */ (function () {
|
|
|
582
567
|
}
|
|
583
568
|
// 没有出度或没有入度,都认为是叶子节点
|
|
584
569
|
if (inDegree === 0 || outDegree === 0) {
|
|
585
|
-
|
|
570
|
+
const leafStrength = leaf(node, nodes, edges);
|
|
586
571
|
if (!leafStrength)
|
|
587
572
|
return;
|
|
588
573
|
accMap[id].x -= leafStrength * vx;
|
|
@@ -591,7 +576,7 @@ var ForceLayout = /** @class */ (function () {
|
|
|
591
576
|
return;
|
|
592
577
|
}
|
|
593
578
|
/** others */
|
|
594
|
-
|
|
579
|
+
const othersStrength = others(node);
|
|
595
580
|
if (!othersStrength)
|
|
596
581
|
return;
|
|
597
582
|
accMap[id].x -= othersStrength * vx;
|
|
@@ -599,7 +584,7 @@ var ForceLayout = /** @class */ (function () {
|
|
|
599
584
|
accMap[id].z -= othersStrength * vz;
|
|
600
585
|
}
|
|
601
586
|
});
|
|
602
|
-
}
|
|
587
|
+
}
|
|
603
588
|
/**
|
|
604
589
|
* Update the velocities for nodes.
|
|
605
590
|
* @param calcGraph calculation graph
|
|
@@ -608,21 +593,21 @@ var ForceLayout = /** @class */ (function () {
|
|
|
608
593
|
* @param options formatted layout options
|
|
609
594
|
* @returns
|
|
610
595
|
*/
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
596
|
+
updateVelocity(calcGraph, accMap, velMap, options) {
|
|
597
|
+
const { damping, maxSpeed, interval, dimensions } = options;
|
|
598
|
+
const calcNodes = calcGraph.getAllNodes();
|
|
614
599
|
if (!(calcNodes === null || calcNodes === void 0 ? void 0 : calcNodes.length))
|
|
615
600
|
return;
|
|
616
|
-
calcNodes.forEach(
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
601
|
+
calcNodes.forEach((calcNode) => {
|
|
602
|
+
const { id } = calcNode;
|
|
603
|
+
let vx = (velMap[id].x + accMap[id].x * interval) * damping || 0.01;
|
|
604
|
+
let vy = (velMap[id].y + accMap[id].y * interval) * damping || 0.01;
|
|
605
|
+
let vz = dimensions === 3
|
|
621
606
|
? (velMap[id].z + accMap[id].z * interval) * damping || 0.01
|
|
622
607
|
: 0.0;
|
|
623
|
-
|
|
608
|
+
const vLength = Math.sqrt(vx * vx + vy * vy + vz * vz);
|
|
624
609
|
if (vLength > maxSpeed) {
|
|
625
|
-
|
|
610
|
+
const param2 = maxSpeed / vLength;
|
|
626
611
|
vx = param2 * vx;
|
|
627
612
|
vy = param2 * vy;
|
|
628
613
|
vz = param2 * vz;
|
|
@@ -633,7 +618,7 @@ var ForceLayout = /** @class */ (function () {
|
|
|
633
618
|
z: vz,
|
|
634
619
|
};
|
|
635
620
|
});
|
|
636
|
-
}
|
|
621
|
+
}
|
|
637
622
|
/**
|
|
638
623
|
* Update nodes' positions.
|
|
639
624
|
* @param graph origin graph
|
|
@@ -642,23 +627,22 @@ var ForceLayout = /** @class */ (function () {
|
|
|
642
627
|
* @param options formatted layou options
|
|
643
628
|
* @returns
|
|
644
629
|
*/
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
var calcNodes = calcGraph.getAllNodes();
|
|
630
|
+
updatePosition(graph, calcGraph, velMap, options) {
|
|
631
|
+
const { distanceThresholdMode, interval, dimensions } = options;
|
|
632
|
+
const calcNodes = calcGraph.getAllNodes();
|
|
649
633
|
if (!(calcNodes === null || calcNodes === void 0 ? void 0 : calcNodes.length)) {
|
|
650
634
|
this.judgingDistance = 0;
|
|
651
635
|
return;
|
|
652
636
|
}
|
|
653
|
-
|
|
637
|
+
let sum = 0;
|
|
654
638
|
if (distanceThresholdMode === 'max')
|
|
655
639
|
this.judgingDistance = -Infinity;
|
|
656
640
|
else if (distanceThresholdMode === 'min')
|
|
657
641
|
this.judgingDistance = Infinity;
|
|
658
|
-
calcNodes.forEach(
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
if (isNumber(node.data.fx) && isNumber(node.data.fy)) {
|
|
642
|
+
calcNodes.forEach((calcNode) => {
|
|
643
|
+
const { id } = calcNode;
|
|
644
|
+
const node = graph.getNode(id);
|
|
645
|
+
if ((0, util_1.isNumber)(node.data.fx) && (0, util_1.isNumber)(node.data.fy)) {
|
|
662
646
|
calcGraph.mergeNodeData(id, {
|
|
663
647
|
x: node.data.fx,
|
|
664
648
|
y: node.data.fy,
|
|
@@ -666,24 +650,24 @@ var ForceLayout = /** @class */ (function () {
|
|
|
666
650
|
});
|
|
667
651
|
return;
|
|
668
652
|
}
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
653
|
+
const distX = velMap[id].x * interval;
|
|
654
|
+
const distY = velMap[id].y * interval;
|
|
655
|
+
const distZ = dimensions === 3 ? velMap[id].z * interval : 0.0;
|
|
672
656
|
calcGraph.mergeNodeData(id, {
|
|
673
657
|
x: calcNode.data.x + distX,
|
|
674
658
|
y: calcNode.data.y + distY,
|
|
675
659
|
z: calcNode.data.z + distZ,
|
|
676
660
|
});
|
|
677
|
-
|
|
661
|
+
const distanceMagnitude = Math.sqrt(distX * distX + distY * distY + distZ * distZ);
|
|
678
662
|
switch (distanceThresholdMode) {
|
|
679
663
|
case 'max':
|
|
680
|
-
if (
|
|
681
|
-
|
|
664
|
+
if (this.judgingDistance < distanceMagnitude) {
|
|
665
|
+
this.judgingDistance = distanceMagnitude;
|
|
682
666
|
}
|
|
683
667
|
break;
|
|
684
668
|
case 'min':
|
|
685
|
-
if (
|
|
686
|
-
|
|
669
|
+
if (this.judgingDistance > distanceMagnitude) {
|
|
670
|
+
this.judgingDistance = distanceMagnitude;
|
|
687
671
|
}
|
|
688
672
|
break;
|
|
689
673
|
default:
|
|
@@ -694,23 +678,22 @@ var ForceLayout = /** @class */ (function () {
|
|
|
694
678
|
if (!distanceThresholdMode || distanceThresholdMode === 'mean') {
|
|
695
679
|
this.judgingDistance = sum / calcNodes.length;
|
|
696
680
|
}
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
export { ForceLayout };
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
exports.ForceLayout = ForceLayout;
|
|
701
684
|
/**
|
|
702
685
|
* Group the leaf nodes according to nodeClusterBy field.
|
|
703
686
|
* @param calcGraph calculation graph
|
|
704
687
|
* @param nodeClusterBy the field name in node.data to ditinguish different node clusters
|
|
705
688
|
* @returns related same group leaf nodes for each leaf node
|
|
706
689
|
*/
|
|
707
|
-
|
|
708
|
-
|
|
690
|
+
const getSameTypeLeafMap = (calcGraph, nodeClusterBy) => {
|
|
691
|
+
const calcNodes = calcGraph.getAllNodes();
|
|
709
692
|
if (!(calcNodes === null || calcNodes === void 0 ? void 0 : calcNodes.length))
|
|
710
693
|
return {};
|
|
711
|
-
|
|
712
|
-
calcNodes.forEach(
|
|
713
|
-
|
|
694
|
+
const sameTypeLeafMap = {};
|
|
695
|
+
calcNodes.forEach((node, i) => {
|
|
696
|
+
const degree = calcGraph.getDegree(node.id, 'both');
|
|
714
697
|
if (degree === 1) {
|
|
715
698
|
sameTypeLeafMap[node.id] = getCoreNodeAndSiblingLeaves(calcGraph, 'leaf', node, nodeClusterBy);
|
|
716
699
|
}
|
|
@@ -725,12 +708,12 @@ var getSameTypeLeafMap = function (calcGraph, nodeClusterBy) {
|
|
|
725
708
|
* @param nodeClusterBy the field name in node.data to ditinguish different node clusters
|
|
726
709
|
* @returns coreNode, sibling leaf nodes, and grouped sibling leaf nodes
|
|
727
710
|
*/
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
711
|
+
const getCoreNodeAndSiblingLeaves = (calcGraph, type, node, nodeClusterBy) => {
|
|
712
|
+
const inDegree = calcGraph.getDegree(node.id, 'in');
|
|
713
|
+
const outDegree = calcGraph.getDegree(node.id, 'out');
|
|
731
714
|
// node is not a leaf, coreNode is itself, siblingLeaves is empty
|
|
732
|
-
|
|
733
|
-
|
|
715
|
+
let coreNode = node;
|
|
716
|
+
let siblingLeaves = [];
|
|
734
717
|
if (inDegree === 0) {
|
|
735
718
|
// node is a leaf node without out edges, its related(successor) node is coreNode, siblingLeaves is the neighbors of its related node
|
|
736
719
|
coreNode = calcGraph.getSuccessors(node.id)[0];
|
|
@@ -742,12 +725,10 @@ var getCoreNodeAndSiblingLeaves = function (calcGraph, type, node, nodeClusterBy
|
|
|
742
725
|
siblingLeaves = calcGraph.getNeighbors(coreNode.id);
|
|
743
726
|
}
|
|
744
727
|
// siblingLeaves are leaf nodes
|
|
745
|
-
siblingLeaves = siblingLeaves.filter(
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
}
|
|
749
|
-
var sameTypeLeaves = getSameTypeNodes(calcGraph, type, nodeClusterBy, node, siblingLeaves);
|
|
750
|
-
return { coreNode: coreNode, siblingLeaves: siblingLeaves, sameTypeLeaves: sameTypeLeaves };
|
|
728
|
+
siblingLeaves = siblingLeaves.filter((node) => calcGraph.getDegree(node.id, 'in') === 0 ||
|
|
729
|
+
calcGraph.getDegree(node.id, 'out') === 0);
|
|
730
|
+
const sameTypeLeaves = getSameTypeNodes(calcGraph, type, nodeClusterBy, node, siblingLeaves);
|
|
731
|
+
return { coreNode, siblingLeaves, sameTypeLeaves };
|
|
751
732
|
};
|
|
752
733
|
/**
|
|
753
734
|
* Find the same type (according to nodeClusterBy field) of node in relativeNodes.
|
|
@@ -758,15 +739,13 @@ var getCoreNodeAndSiblingLeaves = function (calcGraph, type, node, nodeClusterBy
|
|
|
758
739
|
* @param relativeNodes node's related ndoes to be filtered
|
|
759
740
|
* @returns related nodes that meet the filtering conditions
|
|
760
741
|
*/
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
742
|
+
const getSameTypeNodes = (calcGraph, type, nodeClusterBy, node, relativeNodes) => {
|
|
743
|
+
const typeName = node.data[nodeClusterBy] || '';
|
|
744
|
+
let sameTypeNodes = (relativeNodes === null || relativeNodes === void 0 ? void 0 : relativeNodes.filter((item) => item.data[nodeClusterBy] === typeName)) ||
|
|
764
745
|
[];
|
|
765
746
|
if (type === 'leaf') {
|
|
766
|
-
sameTypeNodes = sameTypeNodes.filter(
|
|
767
|
-
|
|
768
|
-
calcGraph.getDegree(item.id, 'out') === 0;
|
|
769
|
-
});
|
|
747
|
+
sameTypeNodes = sameTypeNodes.filter((item) => calcGraph.getDegree(item.id, 'in') === 0 ||
|
|
748
|
+
calcGraph.getDegree(item.id, 'out') === 0);
|
|
770
749
|
}
|
|
771
750
|
return sameTypeNodes;
|
|
772
751
|
};
|
|
@@ -775,15 +754,15 @@ var getSameTypeNodes = function (calcGraph, type, nodeClusterBy, node, relativeN
|
|
|
775
754
|
* @param nodes nodes set
|
|
776
755
|
* @returns average ppsition
|
|
777
756
|
*/
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
nodes.forEach(
|
|
781
|
-
|
|
757
|
+
const getAvgNodePosition = (nodes) => {
|
|
758
|
+
const totalNodes = { x: 0, y: 0 };
|
|
759
|
+
nodes.forEach((node) => {
|
|
760
|
+
const { x, y } = node.data;
|
|
782
761
|
totalNodes.x += x || 0;
|
|
783
762
|
totalNodes.y += y || 0;
|
|
784
763
|
});
|
|
785
764
|
// 获取均值向量
|
|
786
|
-
|
|
765
|
+
const length = nodes.length || 1;
|
|
787
766
|
return {
|
|
788
767
|
x: totalNodes.x / length,
|
|
789
768
|
y: totalNodes.y / length,
|
|
@@ -795,11 +774,9 @@ var getAvgNodePosition = function (nodes) {
|
|
|
795
774
|
* @param layoutNodes calculation nodes
|
|
796
775
|
* @returns output nodes
|
|
797
776
|
*/
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
});
|
|
804
|
-
};
|
|
777
|
+
const formatOutNodes = (graph, layoutNodes) => layoutNodes.map((calcNode) => {
|
|
778
|
+
const { id, data } = calcNode;
|
|
779
|
+
const node = graph.getNode(id);
|
|
780
|
+
return Object.assign(Object.assign({}, node), { data: Object.assign(Object.assign({}, node.data), { x: data.x, y: data.y, z: data.z }) });
|
|
781
|
+
});
|
|
805
782
|
//# sourceMappingURL=index.js.map
|