@antv/layout 0.3.20 → 0.3.22-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/layout.min.js +1 -1
- package/dist/layout.min.js.map +1 -1
- package/es/layout/dagre/src/order/init-order.js +2 -1
- package/es/layout/dagre/src/order/init-order.js.map +1 -1
- package/es/layout/dagre/src/position/bk.js +5 -5
- package/es/layout/dagre/src/position/bk.js.map +1 -1
- package/es/layout/force2/index.d.ts +5 -4
- package/es/layout/force2/index.js +58 -34
- package/es/layout/force2/index.js.map +1 -1
- package/lib/layout/dagre/src/order/init-order.js +2 -1
- package/lib/layout/dagre/src/order/init-order.js.map +1 -1
- package/lib/layout/dagre/src/position/bk.js +8 -8
- package/lib/layout/dagre/src/position/bk.js.map +1 -1
- package/lib/layout/force2/index.d.ts +5 -4
- package/lib/layout/force2/index.js +51 -27
- package/lib/layout/force2/index.js.map +1 -1
- package/package.json +3 -2
- package/src/layout/dagre/src/order/init-order.ts +2 -1
- package/src/layout/dagre/src/position/bk.ts +7 -7
- package/src/layout/force2/index.ts +183 -78
|
@@ -13,17 +13,25 @@ import {
|
|
|
13
13
|
GForceLayoutOptions,
|
|
14
14
|
Degree,
|
|
15
15
|
NodeMap,
|
|
16
|
-
CentripetalOptions
|
|
17
|
-
} from
|
|
18
|
-
import { Base } from
|
|
19
|
-
import {
|
|
20
|
-
|
|
16
|
+
CentripetalOptions,
|
|
17
|
+
} from '../types';
|
|
18
|
+
import { Base } from '../base';
|
|
19
|
+
import {
|
|
20
|
+
isNumber,
|
|
21
|
+
isFunction,
|
|
22
|
+
isArray,
|
|
23
|
+
getDegreeMap,
|
|
24
|
+
isObject,
|
|
25
|
+
getEdgeTerminal,
|
|
26
|
+
getAvgNodePosition,
|
|
27
|
+
getCoreNodeAndRelativeLeafNodes,
|
|
28
|
+
} from '../../util';
|
|
29
|
+
import { forceNBody } from './ForceNBody';
|
|
21
30
|
|
|
22
31
|
type INode = OutNode & {
|
|
23
32
|
size: number | PointTuple;
|
|
24
33
|
};
|
|
25
34
|
|
|
26
|
-
|
|
27
35
|
const proccessToFunc = (
|
|
28
36
|
value: number | Function | undefined,
|
|
29
37
|
defaultV?: number
|
|
@@ -60,7 +68,10 @@ export class Force2Layout extends Base {
|
|
|
60
68
|
public edgeStrength: number | ((d?: any) => number) | undefined = 200;
|
|
61
69
|
|
|
62
70
|
/** 斥力系数 */
|
|
63
|
-
public nodeStrength:
|
|
71
|
+
public nodeStrength:
|
|
72
|
+
| number
|
|
73
|
+
| ((d?: any, edges?: any[]) => number)
|
|
74
|
+
| undefined = 1000;
|
|
64
75
|
|
|
65
76
|
/** 库伦系数 */
|
|
66
77
|
public coulombDisScale: number = 0.005;
|
|
@@ -87,13 +98,19 @@ export class Force2Layout extends Base {
|
|
|
87
98
|
public getCenter: ((d?: any, degree?: number) => number[]) | undefined;
|
|
88
99
|
|
|
89
100
|
/** 计算画布上下两侧对节点吸引力大小 */
|
|
90
|
-
public defSideCoe?: (node: Node) => number;
|
|
101
|
+
public defSideCoe?: (node: Node, edges: Edge[]) => number;
|
|
91
102
|
|
|
92
103
|
/** 理想边长 */
|
|
93
|
-
public linkDistance:
|
|
104
|
+
public linkDistance:
|
|
105
|
+
| number
|
|
106
|
+
| ((edge?: any, source?: any, target?: any) => number)
|
|
107
|
+
| undefined = 200;
|
|
94
108
|
|
|
95
109
|
/** 理想边长,兼容 graphin-force */
|
|
96
|
-
public defSpringLen:
|
|
110
|
+
public defSpringLen:
|
|
111
|
+
| number
|
|
112
|
+
| ((edge?: any, source?: any, target?: any) => number)
|
|
113
|
+
| undefined;
|
|
97
114
|
|
|
98
115
|
/** 重力大小 */
|
|
99
116
|
public gravity: number = 0;
|
|
@@ -126,7 +143,7 @@ export class Force2Layout extends Base {
|
|
|
126
143
|
public distanceThresholdMode: 'mean' | 'max' | 'min' = 'mean';
|
|
127
144
|
|
|
128
145
|
/** 每次迭代结束的回调函数 */
|
|
129
|
-
public tick: (() => void) | null = () => {
|
|
146
|
+
public tick: (() => void) | null = () => {};
|
|
130
147
|
|
|
131
148
|
/** 是否允许每次迭代结束调用回调函数 */
|
|
132
149
|
public enableTick: boolean;
|
|
@@ -151,7 +168,12 @@ export class Force2Layout extends Base {
|
|
|
151
168
|
public animate: Boolean;
|
|
152
169
|
|
|
153
170
|
/** 监控信息,不配置则不计算 */
|
|
154
|
-
public monitor: (params: {
|
|
171
|
+
public monitor: (params: {
|
|
172
|
+
energy: number;
|
|
173
|
+
nodes: INode[];
|
|
174
|
+
edge: Edge[];
|
|
175
|
+
iterations: number;
|
|
176
|
+
}) => void;
|
|
155
177
|
|
|
156
178
|
/** 存储节点度数 */
|
|
157
179
|
private degreesMap: { [id: string]: Degree };
|
|
@@ -184,24 +206,38 @@ export class Force2Layout extends Base {
|
|
|
184
206
|
}
|
|
185
207
|
|
|
186
208
|
public getCentripetalOptions() {
|
|
187
|
-
const {
|
|
209
|
+
const {
|
|
210
|
+
leafCluster,
|
|
211
|
+
clustering,
|
|
212
|
+
nodeClusterBy,
|
|
213
|
+
nodes,
|
|
214
|
+
nodeMap,
|
|
215
|
+
clusterNodeStrength: propsClusterNodeStrength,
|
|
216
|
+
} = this;
|
|
188
217
|
|
|
189
218
|
const getClusterNodeStrength = (node: Node) =>
|
|
190
|
-
typeof propsClusterNodeStrength === 'function'
|
|
219
|
+
typeof propsClusterNodeStrength === 'function'
|
|
220
|
+
? propsClusterNodeStrength(node)
|
|
221
|
+
: propsClusterNodeStrength;
|
|
191
222
|
|
|
192
223
|
let centripetalOptions = {};
|
|
193
224
|
let sameTypeLeafMap: any;
|
|
194
225
|
// 如果传入了需要叶子节点聚类
|
|
195
226
|
if (leafCluster) {
|
|
196
227
|
sameTypeLeafMap = this.getSameTypeLeafMap() || {};
|
|
197
|
-
const relativeNodesType =
|
|
228
|
+
const relativeNodesType =
|
|
229
|
+
Array.from(new Set(nodes?.map((node) => node[nodeClusterBy]))) || [];
|
|
198
230
|
centripetalOptions = {
|
|
199
231
|
single: 100,
|
|
200
232
|
leaf: (node, nodes, edges) => {
|
|
201
233
|
// 找出与它关联的边的起点或终点出发的所有一度节点中同类型的叶子节点
|
|
202
|
-
const { relativeLeafNodes, sameTypeLeafNodes } =
|
|
234
|
+
const { relativeLeafNodes, sameTypeLeafNodes } =
|
|
235
|
+
sameTypeLeafMap[node.id] || {};
|
|
203
236
|
// 如果都是同一类型或者每种类型只有1个,则施加默认向心力
|
|
204
|
-
if (
|
|
237
|
+
if (
|
|
238
|
+
sameTypeLeafNodes?.length === relativeLeafNodes?.length ||
|
|
239
|
+
relativeNodesType?.length === 1
|
|
240
|
+
) {
|
|
205
241
|
return 1;
|
|
206
242
|
}
|
|
207
243
|
return getClusterNodeStrength(node);
|
|
@@ -242,14 +278,18 @@ export class Force2Layout extends Base {
|
|
|
242
278
|
// 如果传入了全局节点聚类
|
|
243
279
|
if (clustering) {
|
|
244
280
|
if (!sameTypeLeafMap) sameTypeLeafMap = this.getSameTypeLeafMap();
|
|
245
|
-
const clusters: string[] = Array.from(
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
281
|
+
const clusters: string[] = Array.from(
|
|
282
|
+
new Set(
|
|
283
|
+
nodes.map((node, i) => {
|
|
284
|
+
return node[nodeClusterBy];
|
|
285
|
+
})
|
|
286
|
+
)
|
|
287
|
+
).filter((item) => item !== undefined);
|
|
250
288
|
const centerNodeInfo: { [key: string]: { x: number; y: number } } = {};
|
|
251
289
|
clusters.forEach((cluster) => {
|
|
252
|
-
const sameTypeNodes = nodes
|
|
290
|
+
const sameTypeNodes = nodes
|
|
291
|
+
.filter((item) => item[nodeClusterBy] === cluster)
|
|
292
|
+
.map((node) => nodeMap[node.id]);
|
|
253
293
|
// 找出同类型节点平均位置节点的距离最近的节点作为中心节点
|
|
254
294
|
centerNodeInfo[cluster] = getAvgNodePosition(sameTypeNodes);
|
|
255
295
|
});
|
|
@@ -274,9 +314,12 @@ export class Force2Layout extends Base {
|
|
|
274
314
|
};
|
|
275
315
|
|
|
276
316
|
const { leaf, single, others } = this.centripetalOptions;
|
|
277
|
-
if (leaf && typeof leaf !== 'function')
|
|
278
|
-
|
|
279
|
-
if (
|
|
317
|
+
if (leaf && typeof leaf !== 'function')
|
|
318
|
+
this.centripetalOptions.leaf = () => leaf;
|
|
319
|
+
if (single && typeof single !== 'function')
|
|
320
|
+
this.centripetalOptions.single = () => single;
|
|
321
|
+
if (others && typeof others !== 'function')
|
|
322
|
+
this.centripetalOptions.others = () => others;
|
|
280
323
|
}
|
|
281
324
|
|
|
282
325
|
public updateCfg(cfg: any) {
|
|
@@ -296,6 +339,7 @@ export class Force2Layout extends Base {
|
|
|
296
339
|
* 执行布局
|
|
297
340
|
*/
|
|
298
341
|
public execute() {
|
|
342
|
+
console.log('here');
|
|
299
343
|
const self = this;
|
|
300
344
|
self.stop();
|
|
301
345
|
const { nodes, edges, defSpringLen } = self;
|
|
@@ -307,10 +351,10 @@ export class Force2Layout extends Base {
|
|
|
307
351
|
return;
|
|
308
352
|
}
|
|
309
353
|
|
|
310
|
-
if (!self.width && typeof window !==
|
|
354
|
+
if (!self.width && typeof window !== 'undefined') {
|
|
311
355
|
self.width = window.innerWidth;
|
|
312
356
|
}
|
|
313
|
-
if (!self.height && typeof window !==
|
|
357
|
+
if (!self.height && typeof window !== 'undefined') {
|
|
314
358
|
self.height = window.innerHeight;
|
|
315
359
|
}
|
|
316
360
|
if (!self.center) {
|
|
@@ -332,11 +376,10 @@ export class Force2Layout extends Base {
|
|
|
332
376
|
let massWeight = 1;
|
|
333
377
|
if (isNumber(d.mass)) massWeight = d.mass;
|
|
334
378
|
const degree = self.degreesMap[d.id].all;
|
|
335
|
-
return
|
|
379
|
+
return !degree || degree < 5 ? massWeight : degree * 5 * massWeight;
|
|
336
380
|
};
|
|
337
381
|
}
|
|
338
382
|
|
|
339
|
-
|
|
340
383
|
// node size function
|
|
341
384
|
const nodeSize = self.nodeSize;
|
|
342
385
|
let nodeSizeFunc;
|
|
@@ -355,7 +398,8 @@ export class Force2Layout extends Base {
|
|
|
355
398
|
if (d.size) {
|
|
356
399
|
if (isArray(d.size)) {
|
|
357
400
|
return Math.max(d.size[0], d.size[1]) + nodeSpacingFunc(d);
|
|
358
|
-
}
|
|
401
|
+
}
|
|
402
|
+
if (isObject(d.size)) {
|
|
359
403
|
return Math.max(d.size.width, d.size.height) + nodeSpacingFunc(d);
|
|
360
404
|
}
|
|
361
405
|
return (d.size as number) + nodeSpacingFunc(d);
|
|
@@ -395,17 +439,16 @@ export class Force2Layout extends Base {
|
|
|
395
439
|
sDegree: degree.out,
|
|
396
440
|
force: {
|
|
397
441
|
mass: self.getMass(node),
|
|
398
|
-
nodeStrength: self.nodeStrength(node)
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
}
|
|
442
|
+
nodeStrength: self.nodeStrength(node, edges),
|
|
443
|
+
},
|
|
444
|
+
},
|
|
445
|
+
},
|
|
402
446
|
};
|
|
403
447
|
nodeIdxMap[node.id] = i;
|
|
404
448
|
});
|
|
405
449
|
self.nodeMap = nodeMap;
|
|
406
450
|
self.nodeIdxMap = nodeIdxMap;
|
|
407
451
|
|
|
408
|
-
|
|
409
452
|
self.edgeInfos = [];
|
|
410
453
|
edges?.forEach((edge) => {
|
|
411
454
|
const sourceNode = nodeMap[edge.source];
|
|
@@ -415,29 +458,39 @@ export class Force2Layout extends Base {
|
|
|
415
458
|
} else {
|
|
416
459
|
self.edgeInfos.push({
|
|
417
460
|
edgeStrength: self.edgeStrength(edge),
|
|
418
|
-
linkDistance: defSpringLen
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
461
|
+
linkDistance: defSpringLen
|
|
462
|
+
? defSpringLen(
|
|
463
|
+
{
|
|
464
|
+
...edge,
|
|
465
|
+
source: sourceNode,
|
|
466
|
+
target: targetNode,
|
|
467
|
+
},
|
|
468
|
+
sourceNode,
|
|
469
|
+
targetNode
|
|
470
|
+
)
|
|
471
|
+
: self.linkDistance(edge, sourceNode, targetNode) ||
|
|
472
|
+
1 + (nodeSize(sourceNode) + nodeSize(sourceNode) || 0) / 2,
|
|
427
473
|
});
|
|
428
474
|
}
|
|
429
475
|
});
|
|
430
476
|
|
|
431
477
|
this.getCentripetalOptions();
|
|
432
478
|
|
|
433
|
-
self.onLayoutEnd = self.onLayoutEnd || (() => {
|
|
479
|
+
self.onLayoutEnd = self.onLayoutEnd || (() => {});
|
|
434
480
|
|
|
435
481
|
self.run();
|
|
436
482
|
}
|
|
437
483
|
|
|
438
484
|
public run() {
|
|
439
485
|
const self = this;
|
|
440
|
-
const {
|
|
486
|
+
const {
|
|
487
|
+
maxIteration,
|
|
488
|
+
nodes,
|
|
489
|
+
workerEnabled,
|
|
490
|
+
minMovement,
|
|
491
|
+
animate,
|
|
492
|
+
nodeMap,
|
|
493
|
+
} = self;
|
|
441
494
|
|
|
442
495
|
if (!nodes) return;
|
|
443
496
|
|
|
@@ -451,13 +504,17 @@ export class Force2Layout extends Base {
|
|
|
451
504
|
const silence = !animate;
|
|
452
505
|
if (workerEnabled || silence) {
|
|
453
506
|
let usedIter = 0;
|
|
454
|
-
for (
|
|
507
|
+
for (
|
|
508
|
+
let i = 0;
|
|
509
|
+
(self.judgingDistance > minMovement || i < 1) && i < maxIter;
|
|
510
|
+
i++
|
|
511
|
+
) {
|
|
455
512
|
usedIter = i;
|
|
456
513
|
self.runOneStep(i, velArray);
|
|
457
514
|
}
|
|
458
515
|
self.onLayoutEnd(Object.values(nodeMap));
|
|
459
516
|
} else {
|
|
460
|
-
if (typeof window ===
|
|
517
|
+
if (typeof window === 'undefined') return;
|
|
461
518
|
let iter = 0;
|
|
462
519
|
// interval for render the result after each iteration
|
|
463
520
|
this.timeInterval = window.setInterval(() => {
|
|
@@ -513,7 +570,13 @@ export class Force2Layout extends Base {
|
|
|
513
570
|
const self = this;
|
|
514
571
|
const { nodes, nodeMap, factor, coulombDisScale } = self;
|
|
515
572
|
const nodeSize = self.nodeSize as Function;
|
|
516
|
-
forceNBody(
|
|
573
|
+
forceNBody(
|
|
574
|
+
nodes,
|
|
575
|
+
nodeMap,
|
|
576
|
+
factor,
|
|
577
|
+
coulombDisScale * coulombDisScale,
|
|
578
|
+
accArray
|
|
579
|
+
);
|
|
517
580
|
}
|
|
518
581
|
|
|
519
582
|
// hooks law
|
|
@@ -559,7 +622,17 @@ export class Force2Layout extends Base {
|
|
|
559
622
|
// attract to center
|
|
560
623
|
public calGravity(accArray: number[]) {
|
|
561
624
|
const self = this;
|
|
562
|
-
const {
|
|
625
|
+
const {
|
|
626
|
+
nodes,
|
|
627
|
+
edges = [],
|
|
628
|
+
nodeMap,
|
|
629
|
+
width,
|
|
630
|
+
height,
|
|
631
|
+
center,
|
|
632
|
+
gravity: defaultGravity,
|
|
633
|
+
degreesMap,
|
|
634
|
+
centripetalOptions,
|
|
635
|
+
} = self;
|
|
563
636
|
if (!nodes) return;
|
|
564
637
|
const nodeLength = nodes.length;
|
|
565
638
|
for (let i = 0; i < nodeLength; i++) {
|
|
@@ -583,13 +656,26 @@ export class Force2Layout extends Base {
|
|
|
583
656
|
}
|
|
584
657
|
|
|
585
658
|
if (gravity) {
|
|
586
|
-
accArray[idx] -= gravity * vecX / mass;
|
|
587
|
-
accArray[idx + 1] -= gravity * vecY / mass;
|
|
659
|
+
accArray[idx] -= (gravity * vecX) / mass;
|
|
660
|
+
accArray[idx + 1] -= (gravity * vecY) / mass;
|
|
588
661
|
}
|
|
589
662
|
|
|
590
663
|
if (centripetalOptions) {
|
|
591
|
-
const {
|
|
592
|
-
|
|
664
|
+
const {
|
|
665
|
+
leaf,
|
|
666
|
+
single,
|
|
667
|
+
others,
|
|
668
|
+
center: centriCenter,
|
|
669
|
+
} = centripetalOptions;
|
|
670
|
+
const {
|
|
671
|
+
x: centriX,
|
|
672
|
+
y: centriY,
|
|
673
|
+
centerStrength,
|
|
674
|
+
} = centriCenter?.(node, nodes, edges, width, height) || {
|
|
675
|
+
x: 0,
|
|
676
|
+
y: 0,
|
|
677
|
+
centerStrength: 0,
|
|
678
|
+
};
|
|
593
679
|
if (!isNumber(centriX) || !isNumber(centriY)) continue;
|
|
594
680
|
const vx = (node.x - centriX) / mass;
|
|
595
681
|
const vy = (node.y - centriY) / mass;
|
|
@@ -626,17 +712,26 @@ export class Force2Layout extends Base {
|
|
|
626
712
|
}
|
|
627
713
|
|
|
628
714
|
// TODO: 待 graphin 修改正确
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
715
|
+
public attractToSide(accArray: number[]) {
|
|
716
|
+
const { defSideCoe, height, nodes, edges } = this;
|
|
717
|
+
if (!defSideCoe || typeof defSideCoe !== 'function' || !nodes?.length)
|
|
718
|
+
return;
|
|
719
|
+
const relatedEdges: { [nodeId: string]: Edge[] } = {};
|
|
720
|
+
edges.forEach((edge) => {
|
|
721
|
+
const { source, target } = edge;
|
|
722
|
+
relatedEdges[source.id] = relatedEdges[source.id] || [];
|
|
723
|
+
relatedEdges[source.id].push(edge);
|
|
724
|
+
relatedEdges[target.id] = relatedEdges[target.id] || [];
|
|
725
|
+
relatedEdges[target.id].push(edge);
|
|
726
|
+
});
|
|
727
|
+
nodes.forEach((node, i) => {
|
|
728
|
+
const sideCoe = defSideCoe!(node, relatedEdges[node.id] || []);
|
|
729
|
+
if (sideCoe === 0) return;
|
|
730
|
+
const targetY = sideCoe > 0 ? 0 : height;
|
|
731
|
+
const strength = Math.abs(sideCoe);
|
|
732
|
+
accArray[2 * i + 1] -= strength * (targetY - node.y);
|
|
733
|
+
});
|
|
734
|
+
}
|
|
640
735
|
|
|
641
736
|
public updateVelocity(
|
|
642
737
|
accArray: number[],
|
|
@@ -647,8 +742,11 @@ export class Force2Layout extends Base {
|
|
|
647
742
|
const { nodes, damping, maxSpeed } = self;
|
|
648
743
|
if (!nodes?.length) return;
|
|
649
744
|
nodes.forEach((_, i) => {
|
|
650
|
-
let vx =
|
|
651
|
-
|
|
745
|
+
let vx =
|
|
746
|
+
(velArray[2 * i] + accArray[2 * i] * stepInterval) * damping || 0.01;
|
|
747
|
+
let vy =
|
|
748
|
+
(velArray[2 * i + 1] + accArray[2 * i + 1] * stepInterval) * damping ||
|
|
749
|
+
0.01;
|
|
652
750
|
const vLength = Math.sqrt(vx * vx + vy * vy);
|
|
653
751
|
if (vLength > maxSpeed) {
|
|
654
752
|
const param2 = maxSpeed / vLength;
|
|
@@ -660,10 +758,7 @@ export class Force2Layout extends Base {
|
|
|
660
758
|
});
|
|
661
759
|
}
|
|
662
760
|
|
|
663
|
-
public updatePosition(
|
|
664
|
-
velArray: number[],
|
|
665
|
-
stepInterval: number,
|
|
666
|
-
) {
|
|
761
|
+
public updatePosition(velArray: number[], stepInterval: number) {
|
|
667
762
|
const self = this;
|
|
668
763
|
const { nodes, distanceThresholdMode, nodeMap } = self;
|
|
669
764
|
if (!nodes?.length) {
|
|
@@ -693,21 +788,24 @@ export class Force2Layout extends Base {
|
|
|
693
788
|
const distanceMagnitude = Math.sqrt(distX * distX + distY * distY);
|
|
694
789
|
switch (distanceThresholdMode) {
|
|
695
790
|
case 'max':
|
|
696
|
-
if (self.judgingDistance < distanceMagnitude)
|
|
791
|
+
if (self.judgingDistance < distanceMagnitude)
|
|
792
|
+
self.judgingDistance = distanceMagnitude;
|
|
697
793
|
break;
|
|
698
794
|
case 'min':
|
|
699
|
-
if (self.judgingDistance > distanceMagnitude)
|
|
795
|
+
if (self.judgingDistance > distanceMagnitude)
|
|
796
|
+
self.judgingDistance = distanceMagnitude;
|
|
700
797
|
break;
|
|
701
798
|
default:
|
|
702
799
|
sum = sum + distanceMagnitude;
|
|
703
800
|
break;
|
|
704
801
|
}
|
|
705
802
|
});
|
|
706
|
-
if (!distanceThresholdMode || distanceThresholdMode === 'mean')
|
|
803
|
+
if (!distanceThresholdMode || distanceThresholdMode === 'mean')
|
|
804
|
+
self.judgingDistance = sum / nodes.length;
|
|
707
805
|
}
|
|
708
806
|
|
|
709
807
|
public stop() {
|
|
710
|
-
if (this.timeInterval && typeof window !==
|
|
808
|
+
if (this.timeInterval && typeof window !== 'undefined') {
|
|
711
809
|
window.clearInterval(this.timeInterval);
|
|
712
810
|
}
|
|
713
811
|
}
|
|
@@ -722,7 +820,7 @@ export class Force2Layout extends Base {
|
|
|
722
820
|
}
|
|
723
821
|
|
|
724
822
|
public getType() {
|
|
725
|
-
return
|
|
823
|
+
return 'force2';
|
|
726
824
|
}
|
|
727
825
|
|
|
728
826
|
private getSameTypeLeafMap() {
|
|
@@ -733,7 +831,14 @@ export class Force2Layout extends Base {
|
|
|
733
831
|
nodes.forEach((node, i) => {
|
|
734
832
|
const degree = degreesMap[node.id].all;
|
|
735
833
|
if (degree === 1) {
|
|
736
|
-
sameTypeLeafMap[node.id] = getCoreNodeAndRelativeLeafNodes(
|
|
834
|
+
sameTypeLeafMap[node.id] = getCoreNodeAndRelativeLeafNodes(
|
|
835
|
+
'leaf',
|
|
836
|
+
node,
|
|
837
|
+
edges,
|
|
838
|
+
nodeClusterBy,
|
|
839
|
+
degreesMap,
|
|
840
|
+
nodeMap
|
|
841
|
+
);
|
|
737
842
|
}
|
|
738
843
|
});
|
|
739
844
|
return sameTypeLeafMap;
|