@deck.gl-community/graph-layers 9.2.0-beta.2 → 9.2.0-beta.3
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/core/graph-engine.d.ts +63 -21
- package/dist/core/graph-engine.d.ts.map +1 -1
- package/dist/core/graph-engine.js +155 -75
- package/dist/core/graph-engine.js.map +1 -1
- package/dist/core/graph-layout.d.ts +22 -18
- package/dist/core/graph-layout.d.ts.map +1 -1
- package/dist/core/graph-layout.js +33 -18
- package/dist/core/graph-layout.js.map +1 -1
- package/dist/core/interaction-manager.d.ts +2 -2
- package/dist/core/interaction-manager.d.ts.map +1 -1
- package/dist/core/interaction-manager.js +7 -5
- package/dist/core/interaction-manager.js.map +1 -1
- package/dist/graph/arrow-graph.d.ts +69 -0
- package/dist/graph/arrow-graph.d.ts.map +1 -0
- package/dist/graph/arrow-graph.js +513 -0
- package/dist/graph/arrow-graph.js.map +1 -0
- package/dist/graph/classic-graph.d.ts +169 -0
- package/dist/graph/classic-graph.d.ts.map +1 -0
- package/dist/graph/classic-graph.js +390 -0
- package/dist/graph/classic-graph.js.map +1 -0
- package/dist/graph/edge.d.ts +6 -6
- package/dist/graph/edge.d.ts.map +1 -1
- package/dist/graph/edge.js.map +1 -1
- package/dist/graph/functions/arrow-utils.d.ts +6 -0
- package/dist/graph/functions/arrow-utils.d.ts.map +1 -0
- package/dist/graph/functions/arrow-utils.js +67 -0
- package/dist/graph/functions/arrow-utils.js.map +1 -0
- package/dist/graph/functions/create-graph-from-data.d.ts +3 -0
- package/dist/graph/functions/create-graph-from-data.d.ts.map +1 -0
- package/dist/graph/functions/create-graph-from-data.js +12 -0
- package/dist/graph/functions/create-graph-from-data.js.map +1 -0
- package/dist/graph/graph-normalization.d.ts +10 -0
- package/dist/graph/graph-normalization.d.ts.map +1 -0
- package/dist/graph/graph-normalization.js +65 -0
- package/dist/graph/graph-normalization.js.map +1 -0
- package/dist/graph/graph.d.ts +62 -155
- package/dist/graph/graph.d.ts.map +1 -1
- package/dist/graph/graph.js +11 -300
- package/dist/graph/graph.js.map +1 -1
- package/dist/graph/node.d.ts +6 -6
- package/dist/graph/node.d.ts.map +1 -1
- package/dist/graph/node.js +2 -2
- package/dist/graph/node.js.map +1 -1
- package/dist/graph-data/arrow-graph-data-builder.d.ts +21 -0
- package/dist/graph-data/arrow-graph-data-builder.d.ts.map +1 -0
- package/dist/graph-data/arrow-graph-data-builder.js +105 -0
- package/dist/graph-data/arrow-graph-data-builder.js.map +1 -0
- package/dist/graph-data/graph-data-builder.d.ts +6 -0
- package/dist/graph-data/graph-data-builder.d.ts.map +1 -0
- package/dist/graph-data/graph-data-builder.js +1 -0
- package/dist/graph-data/graph-data-builder.js.map +1 -0
- package/dist/graph-data/graph-data.d.ts +40 -0
- package/dist/graph-data/graph-data.d.ts.map +1 -0
- package/dist/graph-data/graph-data.js +11 -0
- package/dist/graph-data/graph-data.js.map +1 -0
- package/dist/graph-data/plain-graph-data-builder.d.ts +20 -0
- package/dist/graph-data/plain-graph-data-builder.d.ts.map +1 -0
- package/dist/graph-data/plain-graph-data-builder.js +105 -0
- package/dist/graph-data/plain-graph-data-builder.js.map +1 -0
- package/dist/graph-style-schema.cdn.js +1 -1
- package/dist/graph-style-schema.json +1 -1
- package/dist/index.cjs +6905 -4576
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +14 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -11
- package/dist/index.js.map +1 -1
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer.d.ts.map +1 -1
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer.js +1 -2
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer.js.map +1 -1
- package/dist/layers/common-layers/grid-layer/grid-layer.d.ts +83 -0
- package/dist/layers/common-layers/grid-layer/grid-layer.d.ts.map +1 -0
- package/dist/layers/common-layers/grid-layer/grid-layer.js +133 -0
- package/dist/layers/common-layers/grid-layer/grid-layer.js.map +1 -0
- package/dist/layers/edge-attachment-helper.d.ts.map +1 -1
- package/dist/layers/edge-attachment-helper.js +1 -2
- package/dist/layers/edge-attachment-helper.js.map +1 -1
- package/dist/layers/graph-layer.d.ts +68 -11
- package/dist/layers/graph-layer.d.ts.map +1 -1
- package/dist/layers/graph-layer.js +435 -50
- package/dist/layers/graph-layer.js.map +1 -1
- package/dist/layouts/d3-dag/collapsable-d3-dag-layout.d.ts +24 -0
- package/dist/layouts/d3-dag/collapsable-d3-dag-layout.d.ts.map +1 -0
- package/dist/layouts/d3-dag/collapsable-d3-dag-layout.js +251 -0
- package/dist/layouts/d3-dag/collapsable-d3-dag-layout.js.map +1 -0
- package/dist/layouts/d3-dag/d3-dag-layout.d.ts +46 -61
- package/dist/layouts/d3-dag/d3-dag-layout.d.ts.map +1 -1
- package/dist/layouts/d3-dag/d3-dag-layout.js +85 -270
- package/dist/layouts/d3-dag/d3-dag-layout.js.map +1 -1
- package/dist/layouts/d3-force/d3-force-layout.d.ts +20 -8
- package/dist/layouts/d3-force/d3-force-layout.d.ts.map +1 -1
- package/dist/layouts/d3-force/d3-force-layout.js +39 -20
- package/dist/layouts/d3-force/d3-force-layout.js.map +1 -1
- package/dist/layouts/experimental/force-multi-graph-layout.d.ts +19 -15
- package/dist/layouts/experimental/force-multi-graph-layout.d.ts.map +1 -1
- package/dist/layouts/experimental/force-multi-graph-layout.js +47 -38
- package/dist/layouts/experimental/force-multi-graph-layout.js.map +1 -1
- package/dist/layouts/experimental/hive-plot-layout.d.ts +18 -15
- package/dist/layouts/experimental/hive-plot-layout.d.ts.map +1 -1
- package/dist/layouts/experimental/hive-plot-layout.js +33 -34
- package/dist/layouts/experimental/hive-plot-layout.js.map +1 -1
- package/dist/layouts/experimental/radial-layout.d.ts +12 -7
- package/dist/layouts/experimental/radial-layout.d.ts.map +1 -1
- package/dist/layouts/experimental/radial-layout.js +31 -14
- package/dist/layouts/experimental/radial-layout.js.map +1 -1
- package/dist/layouts/gpu-force/gpu-force-layout.d.ts +11 -8
- package/dist/layouts/gpu-force/gpu-force-layout.d.ts.map +1 -1
- package/dist/layouts/gpu-force/gpu-force-layout.js +59 -56
- package/dist/layouts/gpu-force/gpu-force-layout.js.map +1 -1
- package/dist/layouts/simple-layout.d.ts +8 -25
- package/dist/layouts/simple-layout.d.ts.map +1 -1
- package/dist/layouts/simple-layout.js +13 -17
- package/dist/layouts/simple-layout.js.map +1 -1
- package/dist/loaders/dot-graph-loader.d.ts +25 -0
- package/dist/loaders/dot-graph-loader.d.ts.map +1 -0
- package/dist/loaders/dot-graph-loader.js +668 -0
- package/dist/loaders/dot-graph-loader.js.map +1 -0
- package/dist/loaders/json-graph-loader.d.ts +6 -0
- package/dist/loaders/json-graph-loader.d.ts.map +1 -0
- package/dist/loaders/json-graph-loader.js +31 -0
- package/dist/loaders/json-graph-loader.js.map +1 -0
- package/dist/loaders/{edge-parsers.d.ts → parsers/edge-parsers.d.ts} +1 -1
- package/dist/loaders/parsers/edge-parsers.d.ts.map +1 -0
- package/dist/loaders/{edge-parsers.js → parsers/edge-parsers.js} +1 -1
- package/dist/loaders/parsers/edge-parsers.js.map +1 -0
- package/dist/loaders/{node-parsers.d.ts → parsers/node-parsers.d.ts} +1 -1
- package/dist/loaders/parsers/node-parsers.d.ts.map +1 -0
- package/dist/loaders/{node-parsers.js → parsers/node-parsers.js} +1 -1
- package/dist/loaders/parsers/node-parsers.js.map +1 -0
- package/dist/loaders/parsers/parse-json-graph.d.ts +29 -0
- package/dist/loaders/parsers/parse-json-graph.d.ts.map +1 -0
- package/dist/loaders/parsers/parse-json-graph.js +78 -0
- package/dist/loaders/parsers/parse-json-graph.js.map +1 -0
- package/dist/style/graph-style-engine.d.ts +4 -2
- package/dist/style/graph-style-engine.d.ts.map +1 -1
- package/dist/style/graph-style-engine.js +3 -2
- package/dist/style/graph-style-engine.js.map +1 -1
- package/dist/style/{style-engine.d.ts → stylesheet-engine.d.ts} +3 -3
- package/dist/style/stylesheet-engine.d.ts.map +1 -0
- package/dist/style/{style-engine.js → stylesheet-engine.js} +1 -1
- package/dist/style/stylesheet-engine.js.map +1 -0
- package/dist/utils/collapsed-chains.d.ts +8 -8
- package/dist/utils/collapsed-chains.d.ts.map +1 -1
- package/dist/utils/collapsed-chains.js +1 -6
- package/dist/utils/collapsed-chains.js.map +1 -1
- package/dist/utils/rank-grid.d.ts +30 -0
- package/dist/utils/rank-grid.d.ts.map +1 -0
- package/dist/utils/rank-grid.js +306 -0
- package/dist/utils/rank-grid.js.map +1 -0
- package/package.json +4 -8
- package/src/_disabled/arrow-graph-data.ts.disabled +18 -0
- package/src/_disabled/columnar-graph-data-builder.ts.disabled +250 -0
- package/src/_disabled/graph-runtime-layout.ts.disabled +29 -0
- package/src/core/graph-engine.ts +201 -84
- package/src/core/graph-layout.ts +52 -29
- package/src/core/interaction-manager.ts +20 -20
- package/src/graph/arrow-graph.ts +648 -0
- package/src/graph/classic-graph.ts +447 -0
- package/src/graph/edge.ts +7 -7
- package/src/graph/functions/arrow-utils.ts +72 -0
- package/src/graph/functions/convert-arrow-graph-to-classic-graph.ts.disabled +47 -0
- package/src/graph/functions/convert-plain-graph-to-arrow-graph.ts.disabled +119 -0
- package/src/graph/functions/create-graph-from-data.ts +16 -0
- package/src/graph/functions/create-plain-graph-from-data.ts.disabled +176 -0
- package/src/graph/graph-normalization.ts +87 -0
- package/src/graph/graph.ts +68 -339
- package/src/graph/node.ts +9 -9
- package/src/graph/tabular-graph.ts.disabled +761 -0
- package/src/graph-data/arrow-graph-data-builder.ts +165 -0
- package/src/graph-data/graph-data-builder.ts +7 -0
- package/src/graph-data/graph-data.ts +57 -0
- package/src/graph-data/plain-graph-data-builder.ts +132 -0
- package/src/index.ts +53 -13
- package/src/layers/common-layers/flow-path-layer/flow-path-layer.ts +1 -2
- package/src/layers/common-layers/grid-layer/grid-layer.ts +237 -0
- package/src/layers/edge-attachment-helper.ts +22 -16
- package/src/layers/graph-layer.ts +642 -62
- package/src/layouts/d3-dag/collapsable-d3-dag-layout.ts +330 -0
- package/src/layouts/d3-dag/d3-dag-layout.ts +166 -396
- package/src/layouts/d3-force/d3-force-layout.ts +52 -30
- package/src/layouts/experimental/force-multi-graph-layout.ts +55 -49
- package/src/layouts/experimental/hive-plot-layout.ts +41 -42
- package/src/layouts/experimental/radial-layout.ts +39 -20
- package/src/layouts/gpu-force/gpu-force-layout.ts +72 -70
- package/src/layouts/simple-layout.ts +20 -44
- package/src/loaders/{create-graph.ts → deprecated/create-graph.ts.disabled} +6 -6
- package/src/loaders/deprecated/json-classic-graph-loader.ts.disabled +33 -0
- package/src/loaders/{simple-json-graph-loader.ts → deprecated/simple-json-graph-loader.ts.disabled} +3 -3
- package/src/loaders/{table-graph-loader.ts → deprecated/table-graph-loader.ts.disabled} +8 -8
- package/src/loaders/dot-graph-loader.ts +860 -0
- package/src/loaders/json-graph-loader.ts +48 -0
- package/src/loaders/parsers/create-graph-data.ts.disabled +45 -0
- package/src/loaders/{edge-parsers.ts → parsers/edge-parsers.ts} +2 -2
- package/src/loaders/{node-parsers.ts → parsers/node-parsers.ts} +2 -2
- package/src/loaders/parsers/parse-json-graph.ts +134 -0
- package/src/style/graph-style-engine.ts +5 -2
- package/src/style/{style-engine.ts → stylesheet-engine.ts} +3 -3
- package/src/utils/collapsed-chains.ts +11 -17
- package/src/utils/rank-grid.ts +426 -0
- package/dist/loaders/create-graph.d.ts +0 -12
- package/dist/loaders/create-graph.d.ts.map +0 -1
- package/dist/loaders/create-graph.js +0 -38
- package/dist/loaders/create-graph.js.map +0 -1
- package/dist/loaders/edge-parsers.d.ts.map +0 -1
- package/dist/loaders/edge-parsers.js.map +0 -1
- package/dist/loaders/json-loader.d.ts +0 -7
- package/dist/loaders/json-loader.d.ts.map +0 -1
- package/dist/loaders/json-loader.js +0 -16
- package/dist/loaders/json-loader.js.map +0 -1
- package/dist/loaders/node-parsers.d.ts.map +0 -1
- package/dist/loaders/node-parsers.js.map +0 -1
- package/dist/loaders/simple-json-graph-loader.d.ts +0 -11
- package/dist/loaders/simple-json-graph-loader.d.ts.map +0 -1
- package/dist/loaders/simple-json-graph-loader.js +0 -20
- package/dist/loaders/simple-json-graph-loader.js.map +0 -1
- package/dist/loaders/table-graph-loader.d.ts +0 -16
- package/dist/loaders/table-graph-loader.d.ts.map +0 -1
- package/dist/loaders/table-graph-loader.js +0 -91
- package/dist/loaders/table-graph-loader.js.map +0 -1
- package/dist/style/style-engine.d.ts.map +0 -1
- package/dist/style/style-engine.js.map +0 -1
- package/dist/widgets/long-press-button.d.ts +0 -12
- package/dist/widgets/long-press-button.d.ts.map +0 -1
- package/dist/widgets/long-press-button.js +0 -31
- package/dist/widgets/long-press-button.js.map +0 -1
- package/dist/widgets/view-control-widget.d.ts +0 -77
- package/dist/widgets/view-control-widget.d.ts.map +0 -1
- package/dist/widgets/view-control-widget.js +0 -197
- package/dist/widgets/view-control-widget.js.map +0 -1
- package/src/loaders/json-loader.ts +0 -19
- package/src/widgets/long-press-button.tsx +0 -50
- package/src/widgets/view-control-widget.tsx +0 -339
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
5
|
import {GraphLayout, GraphLayoutProps} from '../../core/graph-layout';
|
|
6
|
+
import type {Graph, NodeInterface, EdgeInterface} from '../../graph/graph';
|
|
6
7
|
import {log} from '../../utils/log';
|
|
7
8
|
|
|
8
9
|
export type D3ForceLayoutOptions = GraphLayoutProps & {
|
|
@@ -15,39 +16,38 @@ export type D3ForceLayoutOptions = GraphLayoutProps & {
|
|
|
15
16
|
};
|
|
16
17
|
|
|
17
18
|
export class D3ForceLayout extends GraphLayout<D3ForceLayoutOptions> {
|
|
18
|
-
static defaultProps
|
|
19
|
+
static defaultProps = {
|
|
20
|
+
...GraphLayout.defaultProps,
|
|
19
21
|
alpha: 0.3,
|
|
20
22
|
resumeAlpha: 0.1,
|
|
21
23
|
nBodyStrength: -900,
|
|
22
24
|
nBodyDistanceMin: 100,
|
|
23
25
|
nBodyDistanceMax: 400,
|
|
24
26
|
getCollisionRadius: 0
|
|
25
|
-
}
|
|
27
|
+
} as const satisfies Readonly<Required<D3ForceLayoutOptions>>;
|
|
26
28
|
|
|
27
29
|
protected readonly _name = 'D3';
|
|
28
|
-
private _positionsByNodeId = new Map();
|
|
29
|
-
private _graph:
|
|
30
|
-
private _worker:
|
|
31
|
-
|
|
32
|
-
constructor(options?: D3ForceLayoutOptions) {
|
|
33
|
-
super(options);
|
|
30
|
+
private _positionsByNodeId = new Map<string | number, any>();
|
|
31
|
+
private _graph: Graph | null = null;
|
|
32
|
+
private _worker: Worker | null = null;
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
...options
|
|
38
|
-
};
|
|
34
|
+
constructor(props?: D3ForceLayoutOptions) {
|
|
35
|
+
super(props, D3ForceLayout.defaultProps);
|
|
39
36
|
}
|
|
40
37
|
|
|
41
|
-
initializeGraph(graph) {
|
|
38
|
+
initializeGraph(graph: Graph) {
|
|
42
39
|
this._graph = graph;
|
|
43
40
|
}
|
|
44
41
|
|
|
45
42
|
// for streaming new data on the same graph
|
|
46
|
-
updateGraph(graph) {
|
|
43
|
+
updateGraph(graph: Graph) {
|
|
47
44
|
this._graph = graph;
|
|
48
45
|
|
|
49
46
|
this._positionsByNodeId = new Map(
|
|
50
|
-
this._graph.getNodes()
|
|
47
|
+
Array.from(this._graph.getNodes(), (node) => {
|
|
48
|
+
const id = node.getId();
|
|
49
|
+
return [id, this._positionsByNodeId.get(id)];
|
|
50
|
+
})
|
|
51
51
|
);
|
|
52
52
|
}
|
|
53
53
|
|
|
@@ -69,17 +69,30 @@ export class D3ForceLayout extends GraphLayout<D3ForceLayoutOptions> {
|
|
|
69
69
|
|
|
70
70
|
this._worker = new Worker(new URL('./worker.js', import.meta.url).href);
|
|
71
71
|
|
|
72
|
+
if (!this._graph) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const options = {...this.props};
|
|
77
|
+
delete options.onLayoutStart;
|
|
78
|
+
delete options.onLayoutChange;
|
|
79
|
+
delete options.onLayoutDone;
|
|
80
|
+
delete options.onLayoutError;
|
|
81
|
+
|
|
72
82
|
this._worker.postMessage({
|
|
73
|
-
nodes: this._graph.getNodes()
|
|
74
|
-
id
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
83
|
+
nodes: Array.from(this._graph.getNodes(), (node) => {
|
|
84
|
+
const id = node.getId();
|
|
85
|
+
return {
|
|
86
|
+
id,
|
|
87
|
+
...this._positionsByNodeId.get(id)
|
|
88
|
+
};
|
|
89
|
+
}),
|
|
90
|
+
edges: Array.from(this._graph.getEdges(), (edge) => ({
|
|
91
|
+
id: edge.getId(),
|
|
79
92
|
source: edge.getSourceNodeId(),
|
|
80
93
|
target: edge.getTargetNodeId()
|
|
81
94
|
})),
|
|
82
|
-
options
|
|
95
|
+
options
|
|
83
96
|
});
|
|
84
97
|
|
|
85
98
|
this._worker.onmessage = (event) => {
|
|
@@ -112,7 +125,11 @@ export class D3ForceLayout extends GraphLayout<D3ForceLayoutOptions> {
|
|
|
112
125
|
}
|
|
113
126
|
}
|
|
114
127
|
|
|
115
|
-
getEdgePosition = (edge) => {
|
|
128
|
+
getEdgePosition = (edge: EdgeInterface) => {
|
|
129
|
+
if (!this._graph) {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
|
|
116
133
|
const sourceNode = this._graph.findNode(edge.getSourceNodeId());
|
|
117
134
|
const targetNode = this._graph.findNode(edge.getTargetNodeId());
|
|
118
135
|
if (!sourceNode || !targetNode) {
|
|
@@ -134,12 +151,12 @@ export class D3ForceLayout extends GraphLayout<D3ForceLayoutOptions> {
|
|
|
134
151
|
};
|
|
135
152
|
};
|
|
136
153
|
|
|
137
|
-
getNodePosition = (node) => {
|
|
154
|
+
getNodePosition = (node: NodeInterface | null) => {
|
|
138
155
|
if (!node) {
|
|
139
156
|
return null;
|
|
140
157
|
}
|
|
141
158
|
|
|
142
|
-
const d3Node = this._positionsByNodeId.get(node.
|
|
159
|
+
const d3Node = this._positionsByNodeId.get(node.getId());
|
|
143
160
|
if (d3Node) {
|
|
144
161
|
return d3Node.coordinates;
|
|
145
162
|
}
|
|
@@ -147,9 +164,10 @@ export class D3ForceLayout extends GraphLayout<D3ForceLayoutOptions> {
|
|
|
147
164
|
return null;
|
|
148
165
|
};
|
|
149
166
|
|
|
150
|
-
lockNodePosition = (node, x, y) => {
|
|
151
|
-
const
|
|
152
|
-
this._positionsByNodeId.
|
|
167
|
+
lockNodePosition = (node: NodeInterface, x: number, y: number) => {
|
|
168
|
+
const id = node.getId();
|
|
169
|
+
const d3Node = this._positionsByNodeId.get(id);
|
|
170
|
+
this._positionsByNodeId.set(id, {
|
|
153
171
|
...d3Node,
|
|
154
172
|
x,
|
|
155
173
|
y,
|
|
@@ -161,8 +179,12 @@ export class D3ForceLayout extends GraphLayout<D3ForceLayoutOptions> {
|
|
|
161
179
|
this._onLayoutDone();
|
|
162
180
|
};
|
|
163
181
|
|
|
164
|
-
unlockNodePosition = (node) => {
|
|
165
|
-
const
|
|
182
|
+
unlockNodePosition = (node: NodeInterface) => {
|
|
183
|
+
const id = node.getId();
|
|
184
|
+
const d3Node = this._positionsByNodeId.get(id);
|
|
185
|
+
if (!d3Node) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
166
188
|
d3Node.fx = null;
|
|
167
189
|
d3Node.fy = null;
|
|
168
190
|
};
|
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
5
|
import {GraphLayout, GraphLayoutProps} from '../../core/graph-layout';
|
|
6
|
-
import {
|
|
7
|
-
import {Graph} from '../../graph/graph';
|
|
6
|
+
import type {Graph, NodeInterface, EdgeInterface} from '../../graph/graph';
|
|
8
7
|
import * as d3 from 'd3-force';
|
|
9
8
|
|
|
10
9
|
export type ForceMultiGraphLayoutProps = GraphLayoutProps & {
|
|
@@ -16,28 +15,25 @@ export type ForceMultiGraphLayoutProps = GraphLayoutProps & {
|
|
|
16
15
|
|
|
17
16
|
export class ForceMultiGraphLayout extends GraphLayout<ForceMultiGraphLayoutProps> {
|
|
18
17
|
static defaultProps = {
|
|
18
|
+
...GraphLayout.defaultProps,
|
|
19
19
|
alpha: 3,
|
|
20
20
|
nBodyStrength: -1200,
|
|
21
21
|
nBodyDistanceMin: 100,
|
|
22
22
|
nBodyDistanceMax: 1400
|
|
23
|
-
}
|
|
23
|
+
} as const satisfies Readonly<Required<ForceMultiGraphLayoutProps>>;
|
|
24
24
|
|
|
25
25
|
_name = 'ForceMultiGraphLayout';
|
|
26
|
-
_graph: Graph;
|
|
26
|
+
_graph: Graph | null = null;
|
|
27
27
|
|
|
28
28
|
// d3 part
|
|
29
29
|
// custom graph data
|
|
30
|
-
_d3Graph = {nodes: [], edges: []};
|
|
31
|
-
_nodeMap =
|
|
32
|
-
_edgeMap =
|
|
33
|
-
_simulator;
|
|
30
|
+
_d3Graph: {nodes: any[]; edges: any[]} = {nodes: [], edges: []};
|
|
31
|
+
_nodeMap = new Map<string | number, any>();
|
|
32
|
+
_edgeMap = new Map<string | number, any>();
|
|
33
|
+
_simulator: d3.Simulation<any, undefined> | null = null;
|
|
34
34
|
|
|
35
|
-
constructor(
|
|
36
|
-
super(
|
|
37
|
-
this._options = {
|
|
38
|
-
...ForceMultiGraphLayout.defaultProps,
|
|
39
|
-
...options
|
|
40
|
-
};
|
|
35
|
+
constructor(props: ForceMultiGraphLayoutProps = {}) {
|
|
36
|
+
super(props, ForceMultiGraphLayout.defaultProps);
|
|
41
37
|
}
|
|
42
38
|
|
|
43
39
|
initializeGraph(graph: Graph): void {
|
|
@@ -48,8 +44,10 @@ export class ForceMultiGraphLayout extends GraphLayout<ForceMultiGraphLayoutProp
|
|
|
48
44
|
if (d3Edge.isVirtual) {
|
|
49
45
|
return 1 / d3Edge.edgeCount;
|
|
50
46
|
}
|
|
51
|
-
const
|
|
52
|
-
const
|
|
47
|
+
const sourceNode = this._graph?.findNode(d3Edge.source.id);
|
|
48
|
+
const targetNode = this._graph?.findNode(d3Edge.target.id);
|
|
49
|
+
const sourceDegree = sourceNode?.getDegree() ?? 0;
|
|
50
|
+
const targetDegree = targetNode?.getDegree() ?? 0;
|
|
53
51
|
return 1 / Math.min(sourceDegree, targetDegree);
|
|
54
52
|
};
|
|
55
53
|
|
|
@@ -58,7 +56,7 @@ export class ForceMultiGraphLayout extends GraphLayout<ForceMultiGraphLayoutProp
|
|
|
58
56
|
this._simulator.on('tick', null).on('end', null);
|
|
59
57
|
this._simulator = null;
|
|
60
58
|
}
|
|
61
|
-
const {alpha, nBodyStrength, nBodyDistanceMin, nBodyDistanceMax} = this.
|
|
59
|
+
const {alpha, nBodyStrength, nBodyDistanceMin, nBodyDistanceMax} = this.props;
|
|
62
60
|
|
|
63
61
|
const g = this._d3Graph;
|
|
64
62
|
this._simulator = d3
|
|
@@ -100,25 +98,28 @@ export class ForceMultiGraphLayout extends GraphLayout<ForceMultiGraphLayoutProp
|
|
|
100
98
|
|
|
101
99
|
update(): void {}
|
|
102
100
|
|
|
103
|
-
updateGraph(graph) {
|
|
101
|
+
updateGraph(graph: Graph) {
|
|
104
102
|
this._graph = graph;
|
|
105
103
|
|
|
106
104
|
// nodes
|
|
107
|
-
const newNodeMap =
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
const
|
|
111
|
-
|
|
105
|
+
const newNodeMap = new Map<string | number, any>();
|
|
106
|
+
const nodes = Array.from(graph.getNodes());
|
|
107
|
+
const newD3Nodes = nodes.map((node) => {
|
|
108
|
+
const id = node.getId();
|
|
109
|
+
const oldD3Node = this._nodeMap.get(id);
|
|
110
|
+
const newD3Node = oldD3Node ? oldD3Node : {id};
|
|
111
|
+
newNodeMap.set(id, newD3Node);
|
|
112
112
|
return newD3Node;
|
|
113
113
|
});
|
|
114
114
|
|
|
115
115
|
// edges
|
|
116
116
|
// bucket edges between the same source/target node pairs.
|
|
117
|
-
const
|
|
118
|
-
|
|
117
|
+
const edges = Array.from(graph.getEdges());
|
|
118
|
+
const nodePairs = edges.reduce((res, edge) => {
|
|
119
|
+
const endpoints = [edge.getSourceNodeId(), edge.getTargetNodeId()];
|
|
119
120
|
// sort the node ids to count the edges with the same pair
|
|
120
121
|
// but different direction (a -> b or b -> a)
|
|
121
|
-
const pairId =
|
|
122
|
+
const pairId = endpoints.sort().toString();
|
|
122
123
|
// push this edge into the bucket
|
|
123
124
|
if (!res[pairId]) {
|
|
124
125
|
res[pairId] = [edge];
|
|
@@ -131,8 +132,8 @@ export class ForceMultiGraphLayout extends GraphLayout<ForceMultiGraphLayoutProp
|
|
|
131
132
|
// go through each pair of edges,
|
|
132
133
|
// if only one edge between two nodes, create a straight line
|
|
133
134
|
// otherwise, create one virtual node and two edges for each edge
|
|
134
|
-
const newD3Edges = [];
|
|
135
|
-
const newEdgeMap =
|
|
135
|
+
const newD3Edges: any[] = [];
|
|
136
|
+
const newEdgeMap = new Map<string | number, any>();
|
|
136
137
|
|
|
137
138
|
Object.keys(nodePairs).forEach((pairId) => {
|
|
138
139
|
const betweenEdges = nodePairs[pairId];
|
|
@@ -142,11 +143,11 @@ export class ForceMultiGraphLayout extends GraphLayout<ForceMultiGraphLayoutProp
|
|
|
142
143
|
const newD3Edge = {
|
|
143
144
|
type: 'line',
|
|
144
145
|
id: firstEdge.getId(),
|
|
145
|
-
source: newNodeMap
|
|
146
|
-
target: newNodeMap
|
|
146
|
+
source: newNodeMap.get(firstEdge.getSourceNodeId()),
|
|
147
|
+
target: newNodeMap.get(firstEdge.getTargetNodeId()),
|
|
147
148
|
isVirtual: false
|
|
148
149
|
};
|
|
149
|
-
newEdgeMap
|
|
150
|
+
newEdgeMap.set(firstEdge.getId(), newD3Edge);
|
|
150
151
|
newD3Edges.push(newD3Edge);
|
|
151
152
|
return;
|
|
152
153
|
}
|
|
@@ -155,24 +156,25 @@ export class ForceMultiGraphLayout extends GraphLayout<ForceMultiGraphLayoutProp
|
|
|
155
156
|
const newD3Edge = {
|
|
156
157
|
type: 'line',
|
|
157
158
|
id: pairId,
|
|
158
|
-
source: newNodeMap
|
|
159
|
-
target: newNodeMap
|
|
159
|
+
source: newNodeMap.get(firstEdge.getSourceNodeId()),
|
|
160
|
+
target: newNodeMap.get(firstEdge.getTargetNodeId()),
|
|
160
161
|
isVirtual: true,
|
|
161
162
|
edgeCount: betweenEdges.length
|
|
162
163
|
};
|
|
163
|
-
newEdgeMap
|
|
164
|
+
newEdgeMap.set(pairId, newD3Edge);
|
|
164
165
|
newD3Edges.push(newD3Edge);
|
|
165
166
|
|
|
166
167
|
betweenEdges.forEach((e, idx) => {
|
|
167
|
-
|
|
168
|
+
const edgeId = e.getId();
|
|
169
|
+
newEdgeMap.set(edgeId, {
|
|
168
170
|
type: 'spline-curve',
|
|
169
|
-
id:
|
|
170
|
-
source: newNodeMap
|
|
171
|
-
target: newNodeMap
|
|
171
|
+
id: edgeId,
|
|
172
|
+
source: newNodeMap.get(e.getSourceNodeId()),
|
|
173
|
+
target: newNodeMap.get(e.getTargetNodeId()),
|
|
172
174
|
virtualEdgeId: pairId,
|
|
173
175
|
isVirtual: true,
|
|
174
176
|
index: idx
|
|
175
|
-
};
|
|
177
|
+
});
|
|
176
178
|
});
|
|
177
179
|
});
|
|
178
180
|
|
|
@@ -182,8 +184,8 @@ export class ForceMultiGraphLayout extends GraphLayout<ForceMultiGraphLayoutProp
|
|
|
182
184
|
this._d3Graph.edges = newD3Edges;
|
|
183
185
|
}
|
|
184
186
|
|
|
185
|
-
getNodePosition = (node:
|
|
186
|
-
const d3Node = this._nodeMap
|
|
187
|
+
getNodePosition = (node: NodeInterface): [number, number] => {
|
|
188
|
+
const d3Node = this._nodeMap.get(node.getId());
|
|
187
189
|
if (d3Node) {
|
|
188
190
|
return [d3Node.x, d3Node.y];
|
|
189
191
|
}
|
|
@@ -191,8 +193,8 @@ export class ForceMultiGraphLayout extends GraphLayout<ForceMultiGraphLayoutProp
|
|
|
191
193
|
return [0, 0];
|
|
192
194
|
};
|
|
193
195
|
|
|
194
|
-
getEdgePosition = (edge) => {
|
|
195
|
-
const d3Edge = this._edgeMap
|
|
196
|
+
getEdgePosition = (edge: EdgeInterface) => {
|
|
197
|
+
const d3Edge = this._edgeMap.get(edge.getId());
|
|
196
198
|
if (d3Edge) {
|
|
197
199
|
if (!d3Edge.isVirtual) {
|
|
198
200
|
return {
|
|
@@ -203,7 +205,10 @@ export class ForceMultiGraphLayout extends GraphLayout<ForceMultiGraphLayoutProp
|
|
|
203
205
|
};
|
|
204
206
|
}
|
|
205
207
|
// else, check the referenced virtual edge
|
|
206
|
-
const virtualEdge = this._edgeMap
|
|
208
|
+
const virtualEdge = this._edgeMap.get(d3Edge.virtualEdgeId);
|
|
209
|
+
if (!virtualEdge) {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
207
212
|
const edgeCount = virtualEdge.edgeCount;
|
|
208
213
|
// get the position of source and target nodes
|
|
209
214
|
const sourcePosition = [virtualEdge.source.x, virtualEdge.source.y];
|
|
@@ -239,8 +244,11 @@ export class ForceMultiGraphLayout extends GraphLayout<ForceMultiGraphLayoutProp
|
|
|
239
244
|
};
|
|
240
245
|
};
|
|
241
246
|
|
|
242
|
-
lockNodePosition = (node, x, y) => {
|
|
243
|
-
const d3Node = this._nodeMap
|
|
247
|
+
lockNodePosition = (node: NodeInterface, x: number, y: number) => {
|
|
248
|
+
const d3Node = this._nodeMap.get(node.getId());
|
|
249
|
+
if (!d3Node) {
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
244
252
|
d3Node.x = x;
|
|
245
253
|
d3Node.y = y;
|
|
246
254
|
this._onLayoutChange();
|
|
@@ -248,9 +256,7 @@ export class ForceMultiGraphLayout extends GraphLayout<ForceMultiGraphLayoutProp
|
|
|
248
256
|
};
|
|
249
257
|
|
|
250
258
|
protected override _updateBounds(): void {
|
|
251
|
-
const positions =
|
|
252
|
-
this._normalizePosition(node)
|
|
253
|
-
);
|
|
259
|
+
const positions = Array.from(this._nodeMap.values(), (node) => this._normalizePosition(node));
|
|
254
260
|
this._bounds = this._calculateBounds(positions);
|
|
255
261
|
}
|
|
256
262
|
}
|
|
@@ -3,52 +3,46 @@
|
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
5
|
import {GraphLayout, GraphLayoutProps} from '../../core/graph-layout';
|
|
6
|
-
import {
|
|
7
|
-
import {Graph} from '../../graph/graph';
|
|
6
|
+
import type {Graph, NodeInterface, EdgeInterface} from '../../graph/graph';
|
|
8
7
|
|
|
9
8
|
export type HivePlotLayoutProps = GraphLayoutProps & {
|
|
10
9
|
innerRadius?: number;
|
|
11
10
|
outerRadius?: number;
|
|
12
|
-
getNodeAxis?: (node:
|
|
11
|
+
getNodeAxis?: (node: NodeInterface) => any;
|
|
13
12
|
};
|
|
14
13
|
|
|
15
14
|
export class HivePlotLayout extends GraphLayout<HivePlotLayoutProps> {
|
|
16
15
|
static defaultProps = {
|
|
16
|
+
...GraphLayout.defaultProps,
|
|
17
17
|
innerRadius: 100,
|
|
18
18
|
outerRadius: 500,
|
|
19
|
-
getNodeAxis: (node:
|
|
19
|
+
getNodeAxis: (node: NodeInterface) => node.getPropertyValue('group')
|
|
20
20
|
} as const satisfies Readonly<Required<HivePlotLayoutProps>>;
|
|
21
21
|
|
|
22
22
|
_name = 'HivePlot';
|
|
23
|
-
_graph: Graph;
|
|
24
|
-
_totalAxis: number;
|
|
25
|
-
_axis: Record<string,
|
|
26
|
-
_nodeMap =
|
|
27
|
-
_nodePositionMap =
|
|
28
|
-
|
|
29
|
-
constructor(
|
|
30
|
-
super(
|
|
31
|
-
this._options = {
|
|
32
|
-
...HivePlotLayout.defaultProps,
|
|
33
|
-
...options
|
|
34
|
-
};
|
|
23
|
+
_graph: Graph | null = null;
|
|
24
|
+
_totalAxis: number = 0;
|
|
25
|
+
_axis: Record<string, NodeInterface[]> = {};
|
|
26
|
+
_nodeMap = new Map<string | number, NodeInterface>();
|
|
27
|
+
_nodePositionMap = new Map<string | number, [number, number]>();
|
|
28
|
+
|
|
29
|
+
constructor(props: HivePlotLayoutProps = {}) {
|
|
30
|
+
super(props, HivePlotLayout.defaultProps);
|
|
35
31
|
}
|
|
36
32
|
|
|
37
33
|
initializeGraph(graph: Graph) {
|
|
38
34
|
this.updateGraph(graph);
|
|
39
35
|
}
|
|
40
36
|
|
|
41
|
-
updateGraph(graph) {
|
|
42
|
-
const {getNodeAxis, innerRadius, outerRadius} = this.
|
|
37
|
+
updateGraph(graph: Graph) {
|
|
38
|
+
const {getNodeAxis, innerRadius, outerRadius} = this.props;
|
|
43
39
|
this._graph = graph;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return res;
|
|
47
|
-
}, {});
|
|
40
|
+
const nodes = Array.from(graph.getNodes());
|
|
41
|
+
this._nodeMap = new Map(nodes.map((node) => [node.getId(), node]));
|
|
48
42
|
|
|
49
43
|
// bucket nodes into few axis
|
|
50
44
|
|
|
51
|
-
this._axis =
|
|
45
|
+
this._axis = nodes.reduce((res, node) => {
|
|
52
46
|
const axis = getNodeAxis(node);
|
|
53
47
|
if (!res[axis]) {
|
|
54
48
|
res[axis] = [];
|
|
@@ -77,7 +71,8 @@ export class HivePlotLayout extends GraphLayout<HivePlotLayoutProps> {
|
|
|
77
71
|
const angleInterval = 360 / Object.keys(this._axis).length;
|
|
78
72
|
|
|
79
73
|
// calculate positions
|
|
80
|
-
this._nodePositionMap =
|
|
74
|
+
this._nodePositionMap = new Map();
|
|
75
|
+
Object.keys(this._axis).forEach((axis, axisIdx) => {
|
|
81
76
|
const axisAngle = angleInterval * axisIdx;
|
|
82
77
|
const bucketedNodes = this._axis[axis];
|
|
83
78
|
const interval = (outerRadius - innerRadius) / bucketedNodes.length;
|
|
@@ -86,13 +81,13 @@ export class HivePlotLayout extends GraphLayout<HivePlotLayoutProps> {
|
|
|
86
81
|
const radius = innerRadius + idx * interval;
|
|
87
82
|
const x = Math.cos((axisAngle / 180) * Math.PI) * radius + center[0];
|
|
88
83
|
const y = Math.sin((axisAngle / 180) * Math.PI) * radius + center[1];
|
|
89
|
-
|
|
84
|
+
this._nodePositionMap.set(node.getId(), [x, y]);
|
|
90
85
|
});
|
|
91
|
-
|
|
92
|
-
}, {});
|
|
86
|
+
});
|
|
93
87
|
}
|
|
94
88
|
|
|
95
89
|
start() {
|
|
90
|
+
this._onLayoutStart();
|
|
96
91
|
this._onLayoutChange();
|
|
97
92
|
this._onLayoutDone();
|
|
98
93
|
}
|
|
@@ -103,23 +98,27 @@ export class HivePlotLayout extends GraphLayout<HivePlotLayoutProps> {
|
|
|
103
98
|
|
|
104
99
|
resume() {}
|
|
105
100
|
|
|
106
|
-
getNodePosition = (node) => this._nodePositionMap
|
|
101
|
+
getNodePosition = (node: NodeInterface) => this._nodePositionMap.get(node.getId());
|
|
107
102
|
|
|
108
|
-
getEdgePosition = (edge) => {
|
|
109
|
-
const {getNodeAxis} = this.
|
|
103
|
+
getEdgePosition = (edge: EdgeInterface) => {
|
|
104
|
+
const {getNodeAxis} = this.props;
|
|
110
105
|
const sourceNodeId = edge.getSourceNodeId();
|
|
111
106
|
const targetNodeId = edge.getTargetNodeId();
|
|
112
107
|
|
|
113
|
-
const sourcePosition = this._nodePositionMap
|
|
114
|
-
const targetPosition = this._nodePositionMap
|
|
108
|
+
const sourcePosition = this._nodePositionMap.get(sourceNodeId);
|
|
109
|
+
const targetPosition = this._nodePositionMap.get(targetNodeId);
|
|
110
|
+
|
|
111
|
+
if (!sourcePosition || !targetPosition) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
115
114
|
|
|
116
|
-
const sourceNode = this._nodeMap
|
|
117
|
-
const targetNode = this._nodeMap
|
|
115
|
+
const sourceNode = this._nodeMap.get(sourceNodeId);
|
|
116
|
+
const targetNode = this._nodeMap.get(targetNodeId);
|
|
118
117
|
|
|
119
|
-
const sourceNodeAxis = getNodeAxis(sourceNode);
|
|
120
|
-
const targetNodeAxis = getNodeAxis(targetNode);
|
|
118
|
+
const sourceNodeAxis = sourceNode ? getNodeAxis(sourceNode) : null;
|
|
119
|
+
const targetNodeAxis = targetNode ? getNodeAxis(targetNode) : null;
|
|
121
120
|
|
|
122
|
-
if (sourceNodeAxis === targetNodeAxis) {
|
|
121
|
+
if (sourceNodeAxis !== null && sourceNodeAxis === targetNodeAxis) {
|
|
123
122
|
return {
|
|
124
123
|
type: 'line',
|
|
125
124
|
sourcePosition,
|
|
@@ -130,9 +129,9 @@ export class HivePlotLayout extends GraphLayout<HivePlotLayoutProps> {
|
|
|
130
129
|
|
|
131
130
|
const controlPoint = computeControlPoint({
|
|
132
131
|
sourcePosition,
|
|
133
|
-
sourceNodeAxis,
|
|
132
|
+
sourceNodeAxis: sourceNodeAxis ?? 0,
|
|
134
133
|
targetPosition,
|
|
135
|
-
targetNodeAxis,
|
|
134
|
+
targetNodeAxis: targetNodeAxis ?? 0,
|
|
136
135
|
totalAxis: this._totalAxis
|
|
137
136
|
});
|
|
138
137
|
|
|
@@ -144,14 +143,14 @@ export class HivePlotLayout extends GraphLayout<HivePlotLayoutProps> {
|
|
|
144
143
|
};
|
|
145
144
|
};
|
|
146
145
|
|
|
147
|
-
lockNodePosition = (node, x, y) => {
|
|
148
|
-
this._nodePositionMap
|
|
146
|
+
lockNodePosition = (node: NodeInterface, x: number, y: number) => {
|
|
147
|
+
this._nodePositionMap.set(node.getId(), [x, y]);
|
|
149
148
|
this._onLayoutChange();
|
|
150
149
|
this._onLayoutDone();
|
|
151
150
|
};
|
|
152
151
|
|
|
153
152
|
protected override _updateBounds(): void {
|
|
154
|
-
const positions =
|
|
153
|
+
const positions = Array.from(this._nodePositionMap.values(), (position) =>
|
|
155
154
|
this._normalizePosition(position)
|
|
156
155
|
);
|
|
157
156
|
this._bounds = this._calculateBounds(positions);
|
|
@@ -3,21 +3,33 @@
|
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
5
|
import {GraphLayout, GraphLayoutProps} from '../../core/graph-layout';
|
|
6
|
-
import {Graph} from '../../graph/graph';
|
|
6
|
+
import type {Graph, NodeInterface, EdgeInterface} from '../../graph/graph';
|
|
7
7
|
|
|
8
8
|
export type RadialLayoutProps = GraphLayoutProps & {
|
|
9
9
|
radius?: number;
|
|
10
10
|
tree?: any;
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
-
const
|
|
13
|
+
const getTreeNode = (nodeId: string, nodeMap: Record<string, {children?: string[]; isLeaf?: boolean}>) => {
|
|
14
14
|
const node = nodeMap[nodeId];
|
|
15
|
+
if (node) {
|
|
16
|
+
return node;
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
id: nodeId,
|
|
20
|
+
children: [],
|
|
21
|
+
isLeaf: true
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const traverseTree = (nodeId, nodeMap) => {
|
|
26
|
+
const node = getTreeNode(nodeId, nodeMap);
|
|
15
27
|
if (node.isLeaf) {
|
|
16
28
|
return node;
|
|
17
29
|
}
|
|
18
30
|
return {
|
|
19
31
|
...node,
|
|
20
|
-
children: node.children.map((nid) => traverseTree(nid, nodeMap))
|
|
32
|
+
children: (node.children ?? []).map((nid) => traverseTree(nid, nodeMap))
|
|
21
33
|
};
|
|
22
34
|
};
|
|
23
35
|
|
|
@@ -39,6 +51,9 @@ const getTreeDepth = (node, depth = 0) => {
|
|
|
39
51
|
};
|
|
40
52
|
|
|
41
53
|
const getPath = (node, targetId, path) => {
|
|
54
|
+
if (!node) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
42
57
|
if (node.id === targetId) {
|
|
43
58
|
path.push(node.id);
|
|
44
59
|
return true;
|
|
@@ -53,21 +68,19 @@ const getPath = (node, targetId, path) => {
|
|
|
53
68
|
|
|
54
69
|
export class RadialLayout extends GraphLayout<RadialLayoutProps> {
|
|
55
70
|
static defaultProps = {
|
|
56
|
-
|
|
57
|
-
|
|
71
|
+
...GraphLayout.defaultProps,
|
|
72
|
+
radius: 500,
|
|
73
|
+
tree: []
|
|
74
|
+
} as const satisfies Readonly<Required<RadialLayoutProps>>;
|
|
58
75
|
|
|
59
76
|
_name = 'RadialLayout';
|
|
60
|
-
_graph: Graph = null;
|
|
77
|
+
_graph: Graph | null = null;
|
|
61
78
|
// custom layout data structure
|
|
62
79
|
_hierarchicalPoints = {};
|
|
63
80
|
nestedTree;
|
|
64
81
|
|
|
65
|
-
constructor(
|
|
66
|
-
super(
|
|
67
|
-
this._options = {
|
|
68
|
-
...RadialLayout.defaultProps,
|
|
69
|
-
...options
|
|
70
|
-
};
|
|
82
|
+
constructor(props: RadialLayoutProps = {}) {
|
|
83
|
+
super(props, RadialLayout.defaultProps);
|
|
71
84
|
}
|
|
72
85
|
|
|
73
86
|
initializeGraph(graph: Graph): void {
|
|
@@ -79,18 +92,24 @@ export class RadialLayout extends GraphLayout<RadialLayoutProps> {
|
|
|
79
92
|
}
|
|
80
93
|
|
|
81
94
|
start(): void {
|
|
82
|
-
|
|
95
|
+
if (!this._graph) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const nodes = Array.from(this._graph.getNodes());
|
|
99
|
+
const nodeCount = nodes.length;
|
|
83
100
|
if (nodeCount === 0) {
|
|
84
101
|
return;
|
|
85
102
|
}
|
|
86
103
|
|
|
87
|
-
const {tree} = this.
|
|
104
|
+
const {tree} = this.props;
|
|
88
105
|
|
|
89
106
|
if (!tree || tree.length === 0) {
|
|
90
107
|
return;
|
|
91
108
|
}
|
|
92
109
|
|
|
93
|
-
|
|
110
|
+
this._onLayoutStart();
|
|
111
|
+
|
|
112
|
+
const {radius} = this.props;
|
|
94
113
|
const unitAngle = 360 / nodeCount;
|
|
95
114
|
|
|
96
115
|
// hierarchical positions
|
|
@@ -154,12 +173,12 @@ export class RadialLayout extends GraphLayout<RadialLayoutProps> {
|
|
|
154
173
|
|
|
155
174
|
update() {}
|
|
156
175
|
|
|
157
|
-
getNodePosition = (node) => {
|
|
158
|
-
return this._hierarchicalPoints[node.
|
|
176
|
+
getNodePosition = (node: NodeInterface) => {
|
|
177
|
+
return this._hierarchicalPoints[node.getId()];
|
|
159
178
|
};
|
|
160
179
|
|
|
161
180
|
// spline curve version
|
|
162
|
-
getEdgePosition = (edge) => {
|
|
181
|
+
getEdgePosition = (edge: EdgeInterface) => {
|
|
163
182
|
const sourceNodeId = edge.getSourceNodeId();
|
|
164
183
|
const targetNodeId = edge.getTargetNodeId();
|
|
165
184
|
const sourceNodePos = this._hierarchicalPoints[sourceNodeId];
|
|
@@ -197,8 +216,8 @@ export class RadialLayout extends GraphLayout<RadialLayoutProps> {
|
|
|
197
216
|
};
|
|
198
217
|
};
|
|
199
218
|
|
|
200
|
-
lockNodePosition = (node, x, y) => {
|
|
201
|
-
this._hierarchicalPoints[node.
|
|
219
|
+
lockNodePosition = (node: NodeInterface, x: number, y: number) => {
|
|
220
|
+
this._hierarchicalPoints[node.getId()] = [x, y];
|
|
202
221
|
this._onLayoutChange();
|
|
203
222
|
this._onLayoutDone();
|
|
204
223
|
};
|