@antv/layout 0.3.19 → 0.3.21

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.
@@ -10,8 +10,8 @@ import {
10
10
  PointTuple,
11
11
  Point,
12
12
  Node,
13
- } from "./types";
14
- import dagre from "./dagre/index";
13
+ } from './types';
14
+ import dagre from './dagre/index';
15
15
  import {
16
16
  isArray,
17
17
  isNumber,
@@ -19,19 +19,19 @@ import {
19
19
  getEdgeTerminal,
20
20
  getFunc,
21
21
  isString,
22
- } from "../util";
23
- import { Base } from "./base";
24
- import { Graph as DagreGraph } from "./dagre/graph";
22
+ } from '../util';
23
+ import { Base } from './base';
24
+ import { Graph as DagreGraph } from './dagre/graph';
25
25
 
26
26
  /**
27
27
  * 层次布局
28
28
  */
29
29
  export class DagreLayout extends Base {
30
30
  /** layout 方向, 可选 TB, BT, LR, RL */
31
- public rankdir: "TB" | "BT" | "LR" | "RL" = "TB";
31
+ public rankdir: 'TB' | 'BT' | 'LR' | 'RL' = 'TB';
32
32
 
33
33
  /** 节点对齐方式,可选 UL, UR, DL, DR */
34
- public align: undefined | "UL" | "UR" | "DL" | "DR";
34
+ public align: undefined | 'UL' | 'UR' | 'DL' | 'DR';
35
35
 
36
36
  /** 布局的起始(左上角)位置 */
37
37
  public begin: PointTuple;
@@ -93,7 +93,7 @@ export class DagreLayout extends Base {
93
93
 
94
94
  public getDefaultCfg() {
95
95
  return {
96
- rankdir: "TB", // layout 方向, 可选 TB, BT, LR, RL
96
+ rankdir: 'TB', // layout 方向, 可选 TB, BT, LR, RL
97
97
  align: undefined, // 节点对齐方式,可选 UL, UR, DL, DR
98
98
  nodeSize: undefined, // 节点大小
99
99
  nodesepFunc: undefined, // 节点水平间距(px)
@@ -149,6 +149,20 @@ export class DagreLayout extends Base {
149
149
  nodeComboMap[node.comboId].push(node.id);
150
150
  });
151
151
 
152
+ let sortedNodes: OutNode[] = [];
153
+ const visitedMap: { [id: string]: boolean } = {};
154
+ if (self.nodeOrder?.length) {
155
+ self.nodeOrder.forEach((id) => {
156
+ visitedMap[id] = true;
157
+ sortedNodes.push(self.nodeMap[id]);
158
+ });
159
+ nodes.forEach((node) => {
160
+ if (!visitedMap[node.id]) sortedNodes.push(node);
161
+ });
162
+ } else {
163
+ sortedNodes = nodes;
164
+ }
165
+
152
166
  let nodeSizeFunc: (d?: any) => number[];
153
167
  if (!nodeSize) {
154
168
  nodeSizeFunc = (d: any) => {
@@ -173,7 +187,7 @@ export class DagreLayout extends Base {
173
187
  let horisep: Function = nodesepfunc;
174
188
  let vertisep: Function = ranksepfunc;
175
189
 
176
- if (rankdir === "LR" || rankdir === "RL") {
190
+ if (rankdir === 'LR' || rankdir === 'RL') {
177
191
  horisep = ranksepfunc;
178
192
  vertisep = nodesepfunc;
179
193
  }
@@ -202,7 +216,7 @@ export class DagreLayout extends Base {
202
216
  });
203
217
  }
204
218
 
205
- nodes
219
+ sortedNodes
206
220
  .filter((node) => node.layout !== false)
207
221
  .forEach((node) => {
208
222
  const size = nodeSizeFunc(node);
@@ -229,8 +243,8 @@ export class DagreLayout extends Base {
229
243
 
230
244
  edges.forEach((edge) => {
231
245
  // dagrejs Wiki https://github.com/dagrejs/dagre/wiki#configuring-the-layout
232
- const source = getEdgeTerminal(edge, "source");
233
- const target = getEdgeTerminal(edge, "target");
246
+ const source = getEdgeTerminal(edge, 'source');
247
+ const target = getEdgeTerminal(edge, 'target');
234
248
  if (this.layoutNode(source) && this.layoutNode(target)) {
235
249
  g.setEdge(source, target, {
236
250
  weight: edge.weight || 1,
@@ -295,23 +309,22 @@ export class DagreLayout extends Base {
295
309
  dBegin[1] = begin[1] - minY;
296
310
  }
297
311
 
298
- const isHorizontal = rankdir === "LR" || rankdir === "RL";
312
+ const isHorizontal = rankdir === 'LR' || rankdir === 'RL';
299
313
  // 变形为辐射
300
314
  if (radial) {
301
315
  const { focusNode, ranksep, getRadialPos } = this;
302
316
  const focusId = isString(focusNode) ? focusNode : focusNode?.id;
303
317
  const focusLayer = focusId ? g.node(focusId)?._rank : 0;
304
318
  const layers: any[] = [];
305
- const dim = isHorizontal ? "y" : "x";
306
- const sizeDim = isHorizontal ? "height" : "width";
319
+ const dim = isHorizontal ? 'y' : 'x';
320
+ const sizeDim = isHorizontal ? 'height' : 'width';
307
321
  // 找到整个图作为环的坐标维度(dim)的最大、最小值,考虑节点宽度
308
322
  let min = Infinity;
309
323
  let max = -Infinity;
310
324
  g.nodes().forEach((node: any) => {
311
325
  const coord = g.node(node)! as any;
312
- const i = nodes.findIndex((it) => it.id === node);
313
- if (!nodes[i]) return;
314
- const currentNodesep = nodesepfunc(nodes[i]);
326
+ if (!self.nodeMap[node]) return;
327
+ const currentNodesep = nodesepfunc(self.nodeMap[node]);
315
328
 
316
329
  if (focusLayer === 0) {
317
330
  if (!layers[coord._rank]) {
@@ -409,15 +422,14 @@ export class DagreLayout extends Base {
409
422
  arcRange
410
423
  );
411
424
  // 将新坐标写入源数据
412
- const i = nodes.findIndex((it) => it.id === node);
413
- if (!nodes[i]) return;
414
- nodes[i].x = newX + dBegin[0];
415
- nodes[i].y = newY + dBegin[1];
425
+ if (!self.nodeMap[node]) return;
426
+ self.nodeMap[node].x = newX + dBegin[0];
427
+ self.nodeMap[node].y = newY + dBegin[1];
416
428
  // @ts-ignore: pass layer order to data for increment layout use
417
- nodes[i]._order = coord._order;
429
+ self.nodeMap[node]._order = coord._order;
418
430
 
419
431
  // 找到本层最大的一个 ranksep,作为下一层与本层的间隙,叠加到下一层的半径上
420
- const currentNodeRanksep = ranksepfunc(nodes[i]);
432
+ const currentNodeRanksep = ranksepfunc(self.nodeMap[node]);
421
433
  if (maxRanksep < currentNodeRanksep) maxRanksep = currentNodeRanksep;
422
434
  });
423
435
  return maxRanksep;
@@ -436,12 +448,12 @@ export class DagreLayout extends Base {
436
448
  // 第一层只有一个节点,直接放在圆心,初始半径设定为 0
437
449
  if (isFirstLevel && layerNodes.nodes.length === 1) {
438
450
  // 将新坐标写入源数据
439
- const i = nodes.findIndex((it) => it.id === layerNodes.nodes[0]);
440
- if (i <= -1) return;
441
- nodes[i].x = dBegin[0];
442
- nodes[i].y = dBegin[1];
451
+ const nodeId = layerNodes.nodes[0];
452
+ if (!self.nodeMap[nodeId]) return;
453
+ self.nodeMap[nodeId].x = dBegin[0];
454
+ self.nodeMap[nodeId].y = dBegin[1];
443
455
  radiusMap[layerNodes.nodes[0]] = 0;
444
- radius = ranksepfunc(nodes[i]);
456
+ radius = ranksepfunc(self.nodeMap[nodeId]);
445
457
  isFirstLevel = false;
446
458
  return;
447
459
  }
@@ -477,17 +489,17 @@ export class DagreLayout extends Base {
477
489
  g.edges().forEach((edge: any) => {
478
490
  const coord = g.edge(edge);
479
491
  const i = edges.findIndex((it) => {
480
- const source = getEdgeTerminal(it, "source");
481
- const target = getEdgeTerminal(it, "target");
492
+ const source = getEdgeTerminal(it, 'source');
493
+ const target = getEdgeTerminal(it, 'target');
482
494
  return source === edge.v && target === edge.w;
483
495
  });
484
496
  if (i <= -1) return;
485
497
  if (
486
498
  self.edgeLabelSpace &&
487
499
  self.controlPoints &&
488
- edges[i].type !== "loop"
500
+ edges[i].type !== 'loop'
489
501
  ) {
490
- const otherDim = dim === "x" ? "y" : "x";
502
+ const otherDim = dim === 'x' ? 'y' : 'x';
491
503
  const controlPoints = coord?.points?.slice(
492
504
  1,
493
505
  coord.points.length - 1
@@ -521,7 +533,7 @@ export class DagreLayout extends Base {
521
533
  });
522
534
  } else {
523
535
  const layerCoords: Set<number> = new Set();
524
- const isInvert = rankdir === "BT" || rankdir === "RL";
536
+ const isInvert = rankdir === 'BT' || rankdir === 'RL';
525
537
  const layerCoordSort = isInvert
526
538
  ? (a: number, b: number) => b - a
527
539
  : (a: number, b: number) => a - b;
@@ -560,16 +572,21 @@ export class DagreLayout extends Base {
560
572
  g.edges().forEach((edge: any) => {
561
573
  const coord = g.edge(edge);
562
574
  const i = edges.findIndex((it) => {
563
- const source = getEdgeTerminal(it, "source");
564
- const target = getEdgeTerminal(it, "target");
575
+ const source = getEdgeTerminal(it, 'source');
576
+ const target = getEdgeTerminal(it, 'target');
565
577
  return source === edge.v && target === edge.w;
566
578
  });
567
579
  if (i <= -1) return;
568
580
  if (
569
581
  self.edgeLabelSpace &&
570
582
  self.controlPoints &&
571
- edges[i].type !== "loop"
583
+ edges[i].type !== 'loop'
572
584
  ) {
585
+ coord?.points?.forEach((point: any) => {
586
+ point.x += dBegin[0];
587
+ point.y += dBegin[1];
588
+ });
589
+
573
590
  const sourceNode = self.nodeMap[edge.v];
574
591
  const targetNode = self.nodeMap[edge.w];
575
592
  edges[i].controlPoints = getControlPoints(
@@ -581,10 +598,6 @@ export class DagreLayout extends Base {
581
598
  isDifferentLayer,
582
599
  filterControlPointsOutOfBoundary
583
600
  );
584
- edges[i].controlPoints.forEach((point: any) => {
585
- point.x += dBegin[0];
586
- point.y += dBegin[1];
587
- });
588
601
  }
589
602
  });
590
603
  }
@@ -617,7 +630,7 @@ export class DagreLayout extends Base {
617
630
  }
618
631
 
619
632
  public getType() {
620
- return "dagre";
633
+ return 'dagre';
621
634
  }
622
635
  }
623
636