@antv/layout 0.3.17-beta.0 → 0.3.17-beta.2

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.
@@ -541,6 +541,22 @@ export class DagreLayout extends Base {
541
541
  });
542
542
  const layerCoordsArr = Array.from(layerCoords).sort(layerCoordSort);
543
543
 
544
+ // pre-define the isHorizontal related functions to avoid redundant calc in interations
545
+ const isDifferentLayer = isHorizontal
546
+ ? (point1: Point, point2: Point) => point1.x !== point2.x
547
+ : (point1: Point, point2: Point) => point1.y !== point2.y;
548
+ const filterControlPointsOutOfBoundary = isHorizontal
549
+ ? (ps: Point[], point1: Point, point2: Point) => {
550
+ const max = Math.max(point1.y, point2.y);
551
+ const min = Math.min(point1.y, point2.y);
552
+ return ps.filter((point) => point.y <= max && point.y >= min);
553
+ }
554
+ : (ps: Point[], point1: Point, point2: Point) => {
555
+ const max = Math.max(point1.x, point2.x);
556
+ const min = Math.min(point1.x, point2.x);
557
+ return ps.filter((point) => point.x <= max && point.x >= min);
558
+ };
559
+
544
560
  g.edges().forEach((edge: any) => {
545
561
  const coord = g.edge(edge);
546
562
  const i = edges.findIndex((it) => {
@@ -554,52 +570,17 @@ export class DagreLayout extends Base {
554
570
  self.controlPoints &&
555
571
  edges[i].type !== "loop"
556
572
  ) {
557
- edges[i].controlPoints =
558
- coord?.points?.slice(1, coord.points.length - 1) || []; // 去掉头尾
559
-
560
573
  const sourceNode = self.nodeMap[edge.v];
561
574
  const targetNode = self.nodeMap[edge.w];
562
-
563
- // 酌情增加控制点,使折线不穿过跨层的节点
564
- if (sourceNode && targetNode) {
565
- let { x: sourceX, y: sourceY } = sourceNode;
566
- let { x: targetX, y: targetY } = targetNode;
567
- if (isHorizontal) {
568
- sourceX = sourceNode.y;
569
- sourceY = sourceNode.x;
570
- targetX = targetNode.y;
571
- targetY = targetNode.x;
572
- }
573
- // 为跨层级的边增加第一个控制点。忽略垂直的/横向的边。
574
- // 新控制点 = {
575
- // x: 终点x,
576
- // y: (起点y + 下一层y) / 2, #下一层y可能不等于终点y
577
- // }
578
- if (targetY !== sourceY && sourceX !== targetX) {
579
- const nextLayerCoord =
580
- layerCoordsArr[layerCoordsArr.indexOf(sourceY) + 1];
581
- if (nextLayerCoord) {
582
- const firstControlPoint = edges[i].controlPoints[0];
583
- const insertControlPoint = isHorizontal
584
- ? {
585
- x: (sourceY + nextLayerCoord) / 2,
586
- y: firstControlPoint?.x || targetX,
587
- }
588
- : {
589
- x: firstControlPoint?.x || targetX,
590
- y: (sourceY + nextLayerCoord) / 2,
591
- };
592
- // 当新增的控制点不存在(!=当前第一个控制点)时添加
593
- if (
594
- !firstControlPoint ||
595
- firstControlPoint.y !== insertControlPoint.y
596
- ) {
597
- edges[i].controlPoints.unshift(insertControlPoint);
598
- }
599
- }
600
- }
601
- }
602
-
575
+ edges[i].controlPoints = getControlPoints(
576
+ coord?.points,
577
+ sourceNode,
578
+ targetNode,
579
+ layerCoordsArr,
580
+ isHorizontal,
581
+ isDifferentLayer,
582
+ filterControlPointsOutOfBoundary
583
+ );
603
584
  edges[i].controlPoints.forEach((point: any) => {
604
585
  point.x += dBegin[0];
605
586
  point.y += dBegin[1];
@@ -639,3 +620,113 @@ export class DagreLayout extends Base {
639
620
  return "dagre";
640
621
  }
641
622
  }
623
+
624
+ /**
625
+ * Format controlPoints to avoid polylines crossing nodes
626
+ * @param points
627
+ * @param sourceNode
628
+ * @param targetNode
629
+ * @param layerCoordsArr
630
+ * @param isHorizontal
631
+ * @returns
632
+ */
633
+ const getControlPoints = (
634
+ points: Point[] | undefined,
635
+ sourceNode: OutNode,
636
+ targetNode: OutNode,
637
+ layerCoordsArr: number[],
638
+ isHorizontal: boolean,
639
+ isDifferentLayer: (point1: Point, point2: Point) => boolean,
640
+ filterControlPointsOutOfBoundary: (
641
+ ps: Point[],
642
+ point1: Point,
643
+ point2: Point
644
+ ) => Point[]
645
+ ) => {
646
+ let controlPoints = points?.slice(1, points.length - 1) || []; // 去掉头尾
647
+ // 酌情增加控制点,使折线不穿过跨层的节点
648
+ if (sourceNode && targetNode) {
649
+ let { x: sourceX, y: sourceY } = sourceNode;
650
+ let { x: targetX, y: targetY } = targetNode;
651
+ if (isHorizontal) {
652
+ sourceX = sourceNode.y;
653
+ sourceY = sourceNode.x;
654
+ targetX = targetNode.y;
655
+ targetY = targetNode.x;
656
+ }
657
+ // 为跨层级的边增加第一个控制点。忽略垂直的/横向的边。
658
+ // 新控制点 = {
659
+ // x: 终点x,
660
+ // y: (起点y + 下一层y) / 2, #下一层y可能不等于终点y
661
+ // }
662
+ if (targetY !== sourceY && sourceX !== targetX) {
663
+ const sourceLayer = layerCoordsArr.indexOf(sourceY);
664
+ const sourceNextLayerCoord = layerCoordsArr[sourceLayer + 1];
665
+ if (sourceNextLayerCoord) {
666
+ const firstControlPoint = controlPoints[0];
667
+ const insertStartControlPoint = isHorizontal
668
+ ? {
669
+ x: (sourceY + sourceNextLayerCoord) / 2,
670
+ y: firstControlPoint?.y || targetX,
671
+ }
672
+ : {
673
+ x: firstControlPoint?.x || targetX,
674
+ y: (sourceY + sourceNextLayerCoord) / 2,
675
+ };
676
+ // 当新增的控制点不存在(!=当前第一个控制点)时添加
677
+ if (
678
+ !firstControlPoint ||
679
+ isDifferentLayer(firstControlPoint, insertStartControlPoint)
680
+ ) {
681
+ controlPoints.unshift(insertStartControlPoint);
682
+ }
683
+ }
684
+
685
+ const targetLayer = layerCoordsArr.indexOf(targetY);
686
+ const layerDiff = Math.abs(targetLayer - sourceLayer);
687
+ if (layerDiff === 1) {
688
+ controlPoints = filterControlPointsOutOfBoundary(
689
+ controlPoints,
690
+ sourceNode,
691
+ targetNode
692
+ );
693
+ // one controlPoint at least
694
+ if (!controlPoints.length) {
695
+ controlPoints.push(
696
+ isHorizontal
697
+ ? {
698
+ x: (sourceY + targetY) / 2,
699
+ y: sourceX,
700
+ }
701
+ : {
702
+ x: sourceX,
703
+ y: (sourceY + targetY) / 2,
704
+ }
705
+ );
706
+ }
707
+ } else if (layerDiff > 1) {
708
+ const targetLastLayerCoord = layerCoordsArr[targetLayer - 1];
709
+ if (targetLastLayerCoord) {
710
+ const lastControlPoints = controlPoints[controlPoints.length - 1];
711
+ const insertEndControlPoint = isHorizontal
712
+ ? {
713
+ x: (targetY + targetLastLayerCoord) / 2,
714
+ y: lastControlPoints?.y || targetX,
715
+ }
716
+ : {
717
+ x: lastControlPoints?.x || sourceX,
718
+ y: (targetY + targetLastLayerCoord) / 2,
719
+ };
720
+ // 当新增的控制点不存在(!=当前最后一个控制点)时添加
721
+ if (
722
+ !lastControlPoints ||
723
+ isDifferentLayer(lastControlPoints, insertEndControlPoint)
724
+ ) {
725
+ controlPoints.push(insertEndControlPoint);
726
+ }
727
+ }
728
+ }
729
+ }
730
+ }
731
+ return controlPoints;
732
+ };