@antv/layout 1.2.13 → 1.2.14-beta.1
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 +61 -0
- package/lib/antv-dagre/acyclic.js.map +1 -0
- package/lib/{dagre → antv-dagre}/add-border-segments.js +12 -12
- 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 +65 -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 +20 -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 +136 -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 +125 -127
- package/lib/antv-dagre/layout.js.map +1 -0
- package/lib/{dagre → antv-dagre}/nesting-graph.js +36 -37
- 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 +24 -24
- package/lib/antv-dagre/normalize.js.map +1 -0
- package/lib/{dagre → antv-dagre}/order/add-subgraph-constraints.js +9 -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/{dagre → antv-dagre}/order/barycenter.js +8 -8
- package/lib/antv-dagre/order/barycenter.js.map +1 -0
- package/lib/{dagre → antv-dagre}/order/build-layer-graph.js +18 -22
- 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 +17 -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/{dagre → antv-dagre}/order/index.js +35 -35
- package/lib/antv-dagre/order/index.js.map +1 -0
- package/lib/{dagre → antv-dagre}/order/init-data-order.js +8 -9
- package/lib/antv-dagre/order/init-data-order.js.map +1 -0
- package/lib/antv-dagre/order/init-order.js +47 -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 +32 -35
- package/lib/antv-dagre/order/resolve-conflicts.js.map +1 -0
- package/lib/{dagre → antv-dagre}/order/sort-subgraph.js +20 -20
- 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 +19 -19
- package/lib/antv-dagre/order/sort.js.map +1 -0
- package/lib/{dagre → antv-dagre}/parent-dummy-chains.js +28 -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 +140 -143
- 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 +51 -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 +32 -32
- 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 +10 -10
- 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 +70 -71
- 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 +31 -31
- 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 +2 -0
- package/lib/antv-dagre/types.js.map +1 -0
- package/lib/{dagre → antv-dagre}/util.d.ts +1 -1
- package/lib/{dagre → antv-dagre}/util.js +90 -98
- package/lib/antv-dagre/util.js.map +1 -0
- package/lib/antv-dagre.d.ts +50 -0
- package/lib/antv-dagre.js +538 -0
- package/lib/antv-dagre.js.map +1 -0
- package/lib/bundle-entry.d.ts +2 -18
- package/lib/bundle-entry.js +2 -18
- package/lib/bundle-entry.js.map +1 -1
- package/lib/bundle-supervisor.d.ts +4 -22
- package/lib/bundle-supervisor.js +54 -53
- package/lib/bundle-supervisor.js.map +1 -1
- package/lib/bundle-worker.d.ts +1 -1
- package/lib/bundle-worker.js +31 -33
- package/lib/bundle-worker.js.map +1 -1
- package/lib/circular.d.ts +1 -1
- package/lib/circular.js +124 -140
- package/lib/circular.js.map +1 -1
- package/lib/comboCombined.d.ts +1 -1
- package/lib/comboCombined.js +254 -284
- package/lib/comboCombined.js.map +1 -1
- package/lib/concentric.d.ts +1 -1
- package/lib/concentric.js +166 -176
- package/lib/concentric.js.map +1 -1
- package/lib/d3Force/forceInBox.js +75 -77
- package/lib/d3Force/forceInBox.js.map +1 -1
- package/lib/d3Force/index.d.ts +2 -2
- package/lib/d3Force/index.js +196 -222
- package/lib/d3Force/index.js.map +1 -1
- package/lib/dagre.d.ts +13 -24
- package/lib/dagre.js +57 -542
- package/lib/dagre.js.map +1 -1
- package/lib/exports.d.ts +17 -0
- package/lib/exports.js +17 -0
- package/lib/exports.js.map +1 -0
- package/lib/force/forceNBody.js +42 -45
- package/lib/force/forceNBody.js.map +1 -1
- package/lib/force/index.d.ts +1 -1
- package/lib/force/index.js +282 -309
- package/lib/force/index.js.map +1 -1
- package/lib/force/types.d.ts +5 -5
- package/lib/forceAtlas2/body.d.ts +1 -1
- package/lib/forceAtlas2/body.js +29 -31
- package/lib/forceAtlas2/body.js.map +1 -1
- package/lib/forceAtlas2/index.d.ts +1 -1
- package/lib/forceAtlas2/index.js +206 -218
- package/lib/forceAtlas2/index.js.map +1 -1
- package/lib/forceAtlas2/quad.d.ts +2 -2
- package/lib/forceAtlas2/quad.js +40 -42
- package/lib/forceAtlas2/quad.js.map +1 -1
- package/lib/forceAtlas2/quadTree.js +16 -17
- package/lib/forceAtlas2/quadTree.js.map +1 -1
- package/lib/fruchterman.d.ts +1 -1
- package/lib/fruchterman.js +185 -205
- package/lib/fruchterman.js.map +1 -1
- package/lib/grid.d.ts +1 -1
- package/lib/grid.js +197 -207
- package/lib/grid.js.map +1 -1
- package/lib/index.d.ts +1 -15
- package/lib/index.js +1 -15
- package/lib/index.js.map +1 -1
- package/lib/mds.d.ts +1 -1
- package/lib/mds.js +68 -78
- package/lib/mds.js.map +1 -1
- package/lib/radial/index.d.ts +1 -1
- package/lib/radial/index.js +177 -184
- package/lib/radial/index.js.map +1 -1
- package/lib/radial/mds.d.ts +1 -1
- package/lib/radial/mds.js +15 -13
- 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 +36 -37
- package/lib/radial/radial-nonoverlap-force.js.map +1 -1
- package/lib/random.d.ts +1 -1
- package/lib/random.js +53 -66
- package/lib/random.js.map +1 -1
- package/lib/registry.d.ts +2 -2
- package/lib/registry.js +3 -1
- package/lib/registry.js.map +1 -1
- package/lib/supervisor.d.ts +2 -3
- package/lib/supervisor.js +57 -56
- package/lib/supervisor.js.map +1 -1
- package/lib/types.d.ts +20 -75
- package/lib/types.js.map +1 -1
- package/lib/util/array.js +1 -1
- package/lib/util/array.js.map +1 -1
- package/lib/util/common.d.ts +1 -1
- package/lib/util/common.js +7 -8
- package/lib/util/common.js.map +1 -1
- package/lib/util/function.js +23 -25
- package/lib/util/function.js.map +1 -1
- package/lib/util/index.d.ts +0 -2
- package/lib/util/index.js +0 -2
- package/lib/util/index.js.map +1 -1
- package/lib/util/math.d.ts +1 -26
- package/lib/util/math.js +41 -149
- package/lib/util/math.js.map +1 -1
- package/lib/util/object.d.ts +1 -1
- package/lib/util/object.js +13 -13
- package/lib/util/object.js.map +1 -1
- package/lib/util/size.d.ts +3 -0
- package/lib/util/size.js +12 -0
- package/lib/util/size.js.map +1 -0
- package/lib/worker.js +30 -31
- package/lib/worker.js.map +1 -1
- package/package.json +9 -5
- 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.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.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.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.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/forceAtlas2/index.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { cloneFormatData, isArray } from
|
|
5
|
-
import { handleSingleNodeGraph } from
|
|
6
|
-
import Body from
|
|
7
|
-
import Quad from
|
|
8
|
-
import QuadTree from
|
|
9
|
-
|
|
1
|
+
import { __awaiter } from "tslib";
|
|
2
|
+
import { Graph as GGraph } from '@antv/graphlib';
|
|
3
|
+
import { isFunction, isNumber, isObject } from '@antv/util';
|
|
4
|
+
import { cloneFormatData, isArray } from '../util';
|
|
5
|
+
import { handleSingleNodeGraph } from '../util/common';
|
|
6
|
+
import Body from './body';
|
|
7
|
+
import Quad from './quad';
|
|
8
|
+
import QuadTree from './quadTree';
|
|
9
|
+
const DEFAULTS_LAYOUT_OPTIONS = {
|
|
10
10
|
center: [0, 0],
|
|
11
11
|
width: 300,
|
|
12
12
|
height: 300,
|
|
13
13
|
kr: 5,
|
|
14
14
|
kg: 1,
|
|
15
|
-
mode:
|
|
15
|
+
mode: 'normal',
|
|
16
16
|
preventOverlap: false,
|
|
17
17
|
dissuadeHubs: false,
|
|
18
18
|
maxIteration: 0,
|
|
@@ -35,87 +35,78 @@ var DEFAULTS_LAYOUT_OPTIONS = {
|
|
|
35
35
|
* // If you want to assign the positions directly to the nodes, use assign method.
|
|
36
36
|
* await layout.assign(graph, { center: [100, 100] });
|
|
37
37
|
*/
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (options === void 0) { options = {}; }
|
|
38
|
+
export class ForceAtlas2Layout {
|
|
39
|
+
constructor(options = {}) {
|
|
41
40
|
this.options = options;
|
|
42
|
-
this.id =
|
|
43
|
-
this.options =
|
|
41
|
+
this.id = 'forceAtlas2';
|
|
42
|
+
this.options = Object.assign(Object.assign({}, DEFAULTS_LAYOUT_OPTIONS), options);
|
|
44
43
|
}
|
|
45
44
|
/**
|
|
46
45
|
* Return the positions of nodes and edges(if needed).
|
|
47
46
|
*/
|
|
48
|
-
|
|
49
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
50
|
-
return
|
|
51
|
-
return [2 /*return*/, this.genericForceAtlas2Layout(false, graph, options)];
|
|
52
|
-
});
|
|
47
|
+
execute(graph, options) {
|
|
48
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
49
|
+
return this.genericForceAtlas2Layout(false, graph, options);
|
|
53
50
|
});
|
|
54
|
-
}
|
|
51
|
+
}
|
|
55
52
|
/**
|
|
56
53
|
* To directly assign the positions to the nodes.
|
|
57
54
|
*/
|
|
58
|
-
|
|
59
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
60
|
-
|
|
61
|
-
this.genericForceAtlas2Layout(true, graph, options);
|
|
62
|
-
return [2 /*return*/];
|
|
63
|
-
});
|
|
55
|
+
assign(graph, options) {
|
|
56
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
57
|
+
this.genericForceAtlas2Layout(true, graph, options);
|
|
64
58
|
});
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
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
|
-
targetNode
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
sourceNode
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
y: sourceNode.data.y,
|
|
106
|
-
});
|
|
107
|
-
}
|
|
59
|
+
}
|
|
60
|
+
genericForceAtlas2Layout(assign, graph, options) {
|
|
61
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
62
|
+
const edges = graph.getAllEdges();
|
|
63
|
+
const nodes = graph.getAllNodes();
|
|
64
|
+
const mergedOptions = this.formatOptions(options, nodes.length);
|
|
65
|
+
const { width, height, prune, maxIteration, nodeSize, center } = mergedOptions;
|
|
66
|
+
if (!(nodes === null || nodes === void 0 ? void 0 : nodes.length) || nodes.length === 1) {
|
|
67
|
+
return handleSingleNodeGraph(graph, assign, center);
|
|
68
|
+
}
|
|
69
|
+
const calcNodes = nodes.map((node) => cloneFormatData(node, [width, height]));
|
|
70
|
+
const calcEdges = edges.filter((edge) => {
|
|
71
|
+
const { source, target } = edge;
|
|
72
|
+
return source !== target;
|
|
73
|
+
});
|
|
74
|
+
const calcGraph = new GGraph({
|
|
75
|
+
nodes: calcNodes,
|
|
76
|
+
edges: calcEdges,
|
|
77
|
+
});
|
|
78
|
+
const sizes = this.getSizes(calcGraph, graph, nodeSize);
|
|
79
|
+
this.run(calcGraph, graph, maxIteration, sizes, assign, mergedOptions);
|
|
80
|
+
// if prune, place the leaves around their parents, and then re-layout for several iterations.
|
|
81
|
+
if (prune) {
|
|
82
|
+
for (let j = 0; j < calcEdges.length; j += 1) {
|
|
83
|
+
const { source, target } = calcEdges[j];
|
|
84
|
+
const sourceDegree = calcGraph.getDegree(source);
|
|
85
|
+
const targetDegree = calcGraph.getDegree(source);
|
|
86
|
+
if (sourceDegree <= 1) {
|
|
87
|
+
const targetNode = calcGraph.getNode(target);
|
|
88
|
+
calcGraph.mergeNodeData(source, {
|
|
89
|
+
x: targetNode.data.x,
|
|
90
|
+
y: targetNode.data.y,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
else if (targetDegree <= 1) {
|
|
94
|
+
const sourceNode = calcGraph.getNode(source);
|
|
95
|
+
calcGraph.mergeNodeData(target, {
|
|
96
|
+
x: sourceNode.data.x,
|
|
97
|
+
y: sourceNode.data.y,
|
|
98
|
+
});
|
|
108
99
|
}
|
|
109
|
-
postOptions = __assign(__assign({}, mergedOptions), { prune: false, barnesHut: false });
|
|
110
|
-
this.run(calcGraph, graph, 100, sizes, assign, postOptions);
|
|
111
100
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
101
|
+
const postOptions = Object.assign(Object.assign({}, mergedOptions), { prune: false, barnesHut: false });
|
|
102
|
+
this.run(calcGraph, graph, 100, sizes, assign, postOptions);
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
nodes: calcNodes,
|
|
106
|
+
edges,
|
|
107
|
+
};
|
|
117
108
|
});
|
|
118
|
-
}
|
|
109
|
+
}
|
|
119
110
|
/**
|
|
120
111
|
* Init the node positions if there is no initial positions.
|
|
121
112
|
* And pre-calculate the size (max of width and height) for each node.
|
|
@@ -124,11 +115,11 @@ var ForceAtlas2Layout = /** @class */ (function () {
|
|
|
124
115
|
* @param nodeSize node size config from layout options
|
|
125
116
|
* @returns {SizeMap} node'id mapped to max of its width and height
|
|
126
117
|
*/
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
for (
|
|
131
|
-
|
|
118
|
+
getSizes(calcGraph, graph, nodeSize) {
|
|
119
|
+
const nodes = calcGraph.getAllNodes();
|
|
120
|
+
const sizes = {};
|
|
121
|
+
for (let i = 0; i < nodes.length; i += 1) {
|
|
122
|
+
const { id, data } = nodes[i];
|
|
132
123
|
sizes[id] = 10;
|
|
133
124
|
if (isNumber(data.size)) {
|
|
134
125
|
sizes[id] = data.size;
|
|
@@ -144,38 +135,37 @@ var ForceAtlas2Layout = /** @class */ (function () {
|
|
|
144
135
|
sizes[id] = Math.max(data.size.width, data.size.height);
|
|
145
136
|
}
|
|
146
137
|
else if (isFunction(nodeSize)) {
|
|
147
|
-
|
|
148
|
-
|
|
138
|
+
const originNode = graph.getNode(id);
|
|
139
|
+
const size = nodeSize(originNode);
|
|
149
140
|
if (isArray(size)) {
|
|
150
|
-
sizes[id] = Math.max
|
|
141
|
+
sizes[id] = Math.max(...size);
|
|
151
142
|
}
|
|
152
143
|
else {
|
|
153
144
|
sizes[id] = size;
|
|
154
145
|
}
|
|
155
146
|
}
|
|
156
147
|
else if (isArray(nodeSize)) {
|
|
157
|
-
sizes[id] = Math.max
|
|
148
|
+
sizes[id] = Math.max(...nodeSize);
|
|
158
149
|
}
|
|
159
150
|
else if (isNumber(nodeSize)) {
|
|
160
151
|
sizes[id] = nodeSize;
|
|
161
152
|
}
|
|
162
153
|
}
|
|
163
154
|
return sizes;
|
|
164
|
-
}
|
|
155
|
+
}
|
|
165
156
|
/**
|
|
166
157
|
* Format the options.
|
|
167
158
|
* @param options input options
|
|
168
159
|
* @param nodeNum number of nodes
|
|
169
160
|
* @returns formatted options
|
|
170
161
|
*/
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
var center = mergedOptions.center, width = mergedOptions.width, height = mergedOptions.height, barnesHut = mergedOptions.barnesHut, prune = mergedOptions.prune, maxIteration = mergedOptions.maxIteration, kr = mergedOptions.kr, kg = mergedOptions.kg;
|
|
162
|
+
formatOptions(options = {}, nodeNum) {
|
|
163
|
+
const mergedOptions = Object.assign(Object.assign({}, this.options), options);
|
|
164
|
+
const { center, width, height, barnesHut, prune, maxIteration, kr, kg } = mergedOptions;
|
|
175
165
|
mergedOptions.width =
|
|
176
|
-
!width && typeof window !==
|
|
166
|
+
!width && typeof window !== 'undefined' ? window.innerWidth : width;
|
|
177
167
|
mergedOptions.height =
|
|
178
|
-
!height && typeof window !==
|
|
168
|
+
!height && typeof window !== 'undefined' ? window.innerHeight : height;
|
|
179
169
|
mergedOptions.center = !center
|
|
180
170
|
? [mergedOptions.width / 2, mergedOptions.height / 2]
|
|
181
171
|
: center;
|
|
@@ -213,7 +203,7 @@ var ForceAtlas2Layout = /** @class */ (function () {
|
|
|
213
203
|
mergedOptions.kg = 1;
|
|
214
204
|
}
|
|
215
205
|
return mergedOptions;
|
|
216
|
-
}
|
|
206
|
+
}
|
|
217
207
|
/**
|
|
218
208
|
* Loops for fa2.
|
|
219
209
|
* @param calcGraph graph for calculation
|
|
@@ -223,19 +213,19 @@ var ForceAtlas2Layout = /** @class */ (function () {
|
|
|
223
213
|
* @param options formatted layout options
|
|
224
214
|
* @returns
|
|
225
215
|
*/
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
for (
|
|
235
|
-
|
|
216
|
+
run(calcGraph, graph, iteration, sizes, assign, options) {
|
|
217
|
+
const { kr, barnesHut, onTick } = options;
|
|
218
|
+
const calcNodes = calcGraph.getAllNodes();
|
|
219
|
+
let sg = 0;
|
|
220
|
+
let iter = iteration;
|
|
221
|
+
const forces = {};
|
|
222
|
+
const preForces = {};
|
|
223
|
+
const bodies = {};
|
|
224
|
+
for (let i = 0; i < calcNodes.length; i += 1) {
|
|
225
|
+
const { data, id } = calcNodes[i];
|
|
236
226
|
forces[id] = [0, 0];
|
|
237
227
|
if (barnesHut) {
|
|
238
|
-
|
|
228
|
+
const params = {
|
|
239
229
|
id: i,
|
|
240
230
|
rx: data.x,
|
|
241
231
|
ry: data.y,
|
|
@@ -248,14 +238,14 @@ var ForceAtlas2Layout = /** @class */ (function () {
|
|
|
248
238
|
}
|
|
249
239
|
while (iter > 0) {
|
|
250
240
|
sg = this.oneStep(calcGraph, {
|
|
251
|
-
iter
|
|
241
|
+
iter,
|
|
252
242
|
preventOverlapIters: 50,
|
|
253
243
|
krPrime: 100,
|
|
254
|
-
sg
|
|
255
|
-
forces
|
|
256
|
-
preForces
|
|
257
|
-
bodies
|
|
258
|
-
sizes
|
|
244
|
+
sg,
|
|
245
|
+
forces,
|
|
246
|
+
preForces,
|
|
247
|
+
bodies,
|
|
248
|
+
sizes,
|
|
259
249
|
}, options);
|
|
260
250
|
iter--;
|
|
261
251
|
onTick === null || onTick === void 0 ? void 0 : onTick({
|
|
@@ -270,7 +260,7 @@ var ForceAtlas2Layout = /** @class */ (function () {
|
|
|
270
260
|
// }
|
|
271
261
|
}
|
|
272
262
|
return calcGraph;
|
|
273
|
-
}
|
|
263
|
+
}
|
|
274
264
|
/**
|
|
275
265
|
* One step for a loop.
|
|
276
266
|
* @param graph graph for calculation
|
|
@@ -278,14 +268,14 @@ var ForceAtlas2Layout = /** @class */ (function () {
|
|
|
278
268
|
* @param options formatted layout's input options
|
|
279
269
|
* @returns
|
|
280
270
|
*/
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
for (
|
|
287
|
-
|
|
288
|
-
preForces[id] =
|
|
271
|
+
oneStep(graph, params, options) {
|
|
272
|
+
const { iter, preventOverlapIters, krPrime, sg, preForces, bodies, sizes } = params;
|
|
273
|
+
let { forces } = params;
|
|
274
|
+
const { preventOverlap, barnesHut } = options;
|
|
275
|
+
const nodes = graph.getAllNodes();
|
|
276
|
+
for (let i = 0; i < nodes.length; i += 1) {
|
|
277
|
+
const { id } = nodes[i];
|
|
278
|
+
preForces[id] = [...forces[id]];
|
|
289
279
|
forces[id] = [0, 0];
|
|
290
280
|
}
|
|
291
281
|
// attractive forces, existing on every actual edge
|
|
@@ -301,7 +291,7 @@ var ForceAtlas2Layout = /** @class */ (function () {
|
|
|
301
291
|
}
|
|
302
292
|
// update the positions
|
|
303
293
|
return this.updatePos(graph, forces, preForces, sg, options);
|
|
304
|
-
}
|
|
294
|
+
}
|
|
305
295
|
/**
|
|
306
296
|
* Calculate the attract forces for nodes.
|
|
307
297
|
* @param graph graph for calculation
|
|
@@ -312,31 +302,31 @@ var ForceAtlas2Layout = /** @class */ (function () {
|
|
|
312
302
|
* @param options formatted layout's input options
|
|
313
303
|
* @returns
|
|
314
304
|
*/
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
for (
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
305
|
+
getAttrForces(graph, iter, preventOverlapIters, sizes, forces, options) {
|
|
306
|
+
const { preventOverlap, dissuadeHubs, mode, prune } = options;
|
|
307
|
+
const edges = graph.getAllEdges();
|
|
308
|
+
for (let i = 0; i < edges.length; i += 1) {
|
|
309
|
+
const { source, target } = edges[i];
|
|
310
|
+
const sourceNode = graph.getNode(source);
|
|
311
|
+
const targetNode = graph.getNode(target);
|
|
312
|
+
const sourceDegree = graph.getDegree(source);
|
|
313
|
+
const targetDegree = graph.getDegree(target);
|
|
324
314
|
if (prune && (sourceDegree <= 1 || targetDegree <= 1))
|
|
325
315
|
continue;
|
|
326
|
-
|
|
316
|
+
const dir = [
|
|
327
317
|
targetNode.data.x - sourceNode.data.x,
|
|
328
318
|
targetNode.data.y - sourceNode.data.y,
|
|
329
319
|
];
|
|
330
|
-
|
|
320
|
+
let eucliDis = Math.hypot(dir[0], dir[1]);
|
|
331
321
|
eucliDis = eucliDis < 0.0001 ? 0.0001 : eucliDis;
|
|
332
322
|
dir[0] = dir[0] / eucliDis;
|
|
333
323
|
dir[1] = dir[1] / eucliDis;
|
|
334
324
|
if (preventOverlap && iter < preventOverlapIters) {
|
|
335
325
|
eucliDis = eucliDis - sizes[source] - sizes[target];
|
|
336
326
|
}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
if (mode ===
|
|
327
|
+
let fa1 = eucliDis;
|
|
328
|
+
let fa2 = fa1;
|
|
329
|
+
if (mode === 'linlog') {
|
|
340
330
|
fa1 = Math.log(1 + eucliDis);
|
|
341
331
|
fa2 = fa1;
|
|
342
332
|
}
|
|
@@ -358,7 +348,7 @@ var ForceAtlas2Layout = /** @class */ (function () {
|
|
|
358
348
|
forces[target][1] -= fa2 * dir[1];
|
|
359
349
|
}
|
|
360
350
|
return forces;
|
|
361
|
-
}
|
|
351
|
+
}
|
|
362
352
|
/**
|
|
363
353
|
* Calculate the repulsive forces for nodes under barnesHut mode.
|
|
364
354
|
* @param graph graph for calculatiion
|
|
@@ -367,16 +357,16 @@ var ForceAtlas2Layout = /** @class */ (function () {
|
|
|
367
357
|
* @param options formatted layout's input options
|
|
368
358
|
* @returns
|
|
369
359
|
*/
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
for (
|
|
379
|
-
|
|
360
|
+
getOptRepGraForces(graph, forces, bodies, options) {
|
|
361
|
+
const { kg, center, prune } = options;
|
|
362
|
+
const nodes = graph.getAllNodes();
|
|
363
|
+
const nodeNum = nodes.length;
|
|
364
|
+
let minx = 9e10;
|
|
365
|
+
let maxx = -9e10;
|
|
366
|
+
let miny = 9e10;
|
|
367
|
+
let maxy = -9e10;
|
|
368
|
+
for (let i = 0; i < nodeNum; i += 1) {
|
|
369
|
+
const { id, data } = nodes[i];
|
|
380
370
|
if (prune && graph.getDegree(id) <= 1)
|
|
381
371
|
continue;
|
|
382
372
|
bodies[id].setPos(data.x, data.y);
|
|
@@ -389,28 +379,28 @@ var ForceAtlas2Layout = /** @class */ (function () {
|
|
|
389
379
|
if (data.y <= miny)
|
|
390
380
|
miny = data.y;
|
|
391
381
|
}
|
|
392
|
-
|
|
393
|
-
|
|
382
|
+
const width = Math.max(maxx - minx, maxy - miny);
|
|
383
|
+
const quadParams = {
|
|
394
384
|
xmid: (maxx + minx) / 2,
|
|
395
385
|
ymid: (maxy + miny) / 2,
|
|
396
386
|
length: width,
|
|
397
387
|
massCenter: center,
|
|
398
388
|
mass: nodeNum,
|
|
399
389
|
};
|
|
400
|
-
|
|
401
|
-
|
|
390
|
+
const quad = new Quad(quadParams);
|
|
391
|
+
const quadTree = new QuadTree(quad);
|
|
402
392
|
// build the tree, insert the nodes(quads) into the tree
|
|
403
|
-
for (
|
|
404
|
-
|
|
393
|
+
for (let i = 0; i < nodeNum; i += 1) {
|
|
394
|
+
const { id } = nodes[i];
|
|
405
395
|
if (prune && graph.getDegree(id) <= 1)
|
|
406
396
|
continue;
|
|
407
397
|
if (bodies[id].in(quad))
|
|
408
398
|
quadTree.insert(bodies[id]);
|
|
409
399
|
}
|
|
410
400
|
// update the repulsive forces and the gravity.
|
|
411
|
-
for (
|
|
412
|
-
|
|
413
|
-
|
|
401
|
+
for (let i = 0; i < nodeNum; i += 1) {
|
|
402
|
+
const { id, data } = nodes[i];
|
|
403
|
+
const degree = graph.getDegree(id);
|
|
414
404
|
if (prune && degree <= 1)
|
|
415
405
|
continue;
|
|
416
406
|
bodies[id].resetForce();
|
|
@@ -418,17 +408,17 @@ var ForceAtlas2Layout = /** @class */ (function () {
|
|
|
418
408
|
forces[id][0] -= bodies[id].fx;
|
|
419
409
|
forces[id][1] -= bodies[id].fy;
|
|
420
410
|
// gravity
|
|
421
|
-
|
|
422
|
-
|
|
411
|
+
const dir = [data.x - center[0], data.y - center[1]];
|
|
412
|
+
let eucliDis = Math.hypot(dir[0], dir[1]);
|
|
423
413
|
eucliDis = eucliDis < 0.0001 ? 0.0001 : eucliDis;
|
|
424
414
|
dir[0] = dir[0] / eucliDis;
|
|
425
415
|
dir[1] = dir[1] / eucliDis;
|
|
426
|
-
|
|
416
|
+
const fg = kg * (degree + 1); // tslint:disable-line
|
|
427
417
|
forces[id][0] -= fg * dir[0];
|
|
428
418
|
forces[id][1] -= fg * dir[1];
|
|
429
419
|
}
|
|
430
420
|
return forces;
|
|
431
|
-
}
|
|
421
|
+
}
|
|
432
422
|
/**
|
|
433
423
|
* Calculate the repulsive forces for nodes.
|
|
434
424
|
* @param graph graph for calculatiion
|
|
@@ -440,56 +430,56 @@ var ForceAtlas2Layout = /** @class */ (function () {
|
|
|
440
430
|
* @param options formatted layout's input options
|
|
441
431
|
* @returns
|
|
442
432
|
*/
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
for (
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
for (
|
|
451
|
-
|
|
452
|
-
|
|
433
|
+
getRepGraForces(graph, iter, preventOverlapIters, forces, krPrime, sizes, options) {
|
|
434
|
+
const { preventOverlap, kr, kg, center, prune } = options;
|
|
435
|
+
const nodes = graph.getAllNodes();
|
|
436
|
+
const nodeNum = nodes.length;
|
|
437
|
+
for (let i = 0; i < nodeNum; i += 1) {
|
|
438
|
+
const nodei = nodes[i];
|
|
439
|
+
const degreei = graph.getDegree(nodei.id);
|
|
440
|
+
for (let j = i + 1; j < nodeNum; j += 1) {
|
|
441
|
+
const nodej = nodes[j];
|
|
442
|
+
const degreej = graph.getDegree(nodej.id);
|
|
453
443
|
if (prune && (degreei <= 1 || degreej <= 1))
|
|
454
444
|
continue;
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
445
|
+
const dir = [nodej.data.x - nodei.data.x, nodej.data.y - nodei.data.y];
|
|
446
|
+
let eucliDis = Math.hypot(dir[0], dir[1]);
|
|
447
|
+
eucliDis = eucliDis < 0.0001 ? 0.0001 : eucliDis;
|
|
448
|
+
dir[0] = dir[0] / eucliDis;
|
|
449
|
+
dir[1] = dir[1] / eucliDis;
|
|
460
450
|
if (preventOverlap && iter < preventOverlapIters) {
|
|
461
|
-
|
|
451
|
+
eucliDis = eucliDis - sizes[nodei.id] - sizes[nodej.id];
|
|
462
452
|
}
|
|
463
|
-
|
|
464
|
-
if (preventOverlap && iter < preventOverlapIters &&
|
|
453
|
+
let fr = (kr * (degreei + 1) * (degreej + 1)) / eucliDis;
|
|
454
|
+
if (preventOverlap && iter < preventOverlapIters && eucliDis < 0) {
|
|
465
455
|
fr = krPrime * (degreei + 1) * (degreej + 1);
|
|
466
456
|
}
|
|
467
457
|
else if (preventOverlap &&
|
|
468
458
|
iter < preventOverlapIters &&
|
|
469
|
-
|
|
459
|
+
eucliDis === 0) {
|
|
470
460
|
fr = 0;
|
|
471
461
|
}
|
|
472
462
|
else if (preventOverlap &&
|
|
473
463
|
iter < preventOverlapIters &&
|
|
474
|
-
|
|
475
|
-
fr = (kr * (degreei + 1) * (degreej + 1)) /
|
|
464
|
+
eucliDis > 0) {
|
|
465
|
+
fr = (kr * (degreei + 1) * (degreej + 1)) / eucliDis;
|
|
476
466
|
}
|
|
477
|
-
forces[nodei.id][0] -= fr *
|
|
478
|
-
forces[nodej.id][0] += fr *
|
|
479
|
-
forces[nodei.id][1] -= fr *
|
|
480
|
-
forces[nodej.id][1] += fr *
|
|
467
|
+
forces[nodei.id][0] -= fr * dir[0];
|
|
468
|
+
forces[nodej.id][0] += fr * dir[0];
|
|
469
|
+
forces[nodei.id][1] -= fr * dir[1];
|
|
470
|
+
forces[nodej.id][1] += fr * dir[1];
|
|
481
471
|
}
|
|
482
472
|
// gravity
|
|
483
|
-
|
|
484
|
-
|
|
473
|
+
const dir = [nodei.data.x - center[0], nodei.data.y - center[1]];
|
|
474
|
+
const eucliDis = Math.hypot(dir[0], dir[1]);
|
|
485
475
|
dir[0] = dir[0] / eucliDis;
|
|
486
476
|
dir[1] = dir[1] / eucliDis;
|
|
487
|
-
|
|
477
|
+
const fg = kg * (degreei + 1); // tslint:disable-line
|
|
488
478
|
forces[nodei.id][0] -= fg * dir[0];
|
|
489
479
|
forces[nodei.id][1] -= fg * dir[1];
|
|
490
480
|
}
|
|
491
481
|
return forces;
|
|
492
|
-
}
|
|
482
|
+
}
|
|
493
483
|
/**
|
|
494
484
|
* Update node positions.
|
|
495
485
|
* @param graph graph for calculatiion
|
|
@@ -499,64 +489,62 @@ var ForceAtlas2Layout = /** @class */ (function () {
|
|
|
499
489
|
* @param options formatted layout's input options
|
|
500
490
|
* @returns
|
|
501
491
|
*/
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
492
|
+
updatePos(graph, forces, preForces, sg, options) {
|
|
493
|
+
const { ks, tao, prune, ksmax } = options;
|
|
494
|
+
const nodes = graph.getAllNodes();
|
|
495
|
+
const nodeNum = nodes.length;
|
|
496
|
+
const swgns = [];
|
|
497
|
+
const trans = [];
|
|
508
498
|
// swg(G) and tra(G)
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
for (
|
|
513
|
-
|
|
514
|
-
|
|
499
|
+
let swgG = 0;
|
|
500
|
+
let traG = 0;
|
|
501
|
+
let usingSg = sg;
|
|
502
|
+
for (let i = 0; i < nodeNum; i += 1) {
|
|
503
|
+
const { id } = nodes[i];
|
|
504
|
+
const degree = graph.getDegree(id);
|
|
515
505
|
if (prune && degree <= 1)
|
|
516
506
|
continue;
|
|
517
|
-
|
|
507
|
+
const minus = [
|
|
518
508
|
forces[id][0] - preForces[id][0],
|
|
519
509
|
forces[id][1] - preForces[id][1],
|
|
520
510
|
];
|
|
521
|
-
|
|
522
|
-
|
|
511
|
+
const minusNorm = Math.hypot(minus[0], minus[1]);
|
|
512
|
+
const add = [
|
|
523
513
|
forces[id][0] + preForces[id][0],
|
|
524
514
|
forces[id][1] + preForces[id][1],
|
|
525
515
|
];
|
|
526
|
-
|
|
516
|
+
const addNorm = Math.hypot(add[0], add[1]);
|
|
527
517
|
swgns[i] = minusNorm;
|
|
528
518
|
trans[i] = addNorm / 2;
|
|
529
519
|
swgG += (degree + 1) * swgns[i];
|
|
530
520
|
traG += (degree + 1) * trans[i];
|
|
531
521
|
}
|
|
532
|
-
|
|
522
|
+
const preSG = usingSg;
|
|
533
523
|
usingSg = (tao * traG) / swgG;
|
|
534
524
|
if (preSG !== 0) {
|
|
535
525
|
usingSg = usingSg > 1.5 * preSG ? 1.5 * preSG : usingSg;
|
|
536
526
|
}
|
|
537
527
|
// update the node positions
|
|
538
|
-
for (
|
|
539
|
-
|
|
540
|
-
|
|
528
|
+
for (let i = 0; i < nodeNum; i += 1) {
|
|
529
|
+
const { id, data } = nodes[i];
|
|
530
|
+
const degree = graph.getDegree(id);
|
|
541
531
|
if (prune && degree <= 1)
|
|
542
532
|
continue;
|
|
543
533
|
if (isNumber(data.fx) && isNumber(data.fy))
|
|
544
534
|
continue;
|
|
545
|
-
|
|
546
|
-
|
|
535
|
+
let sn = (ks * usingSg) / (1 + usingSg * Math.sqrt(swgns[i]));
|
|
536
|
+
let absForce = Math.hypot(forces[id][0], forces[id][1]);
|
|
547
537
|
absForce = absForce < 0.0001 ? 0.0001 : absForce;
|
|
548
|
-
|
|
538
|
+
const max = ksmax / absForce;
|
|
549
539
|
sn = sn > max ? max : sn;
|
|
550
|
-
|
|
551
|
-
|
|
540
|
+
const dnx = sn * forces[id][0];
|
|
541
|
+
const dny = sn * forces[id][1];
|
|
552
542
|
graph.mergeNodeData(id, {
|
|
553
543
|
x: data.x + dnx,
|
|
554
544
|
y: data.y + dny,
|
|
555
545
|
});
|
|
556
546
|
}
|
|
557
547
|
return usingSg;
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
}());
|
|
561
|
-
export { ForceAtlas2Layout };
|
|
548
|
+
}
|
|
549
|
+
}
|
|
562
550
|
//# sourceMappingURL=index.js.map
|