NGX Graph linkTemplate - 链接中间指针对齐问题

NGX Graph linkTemplate - Links Middle Pointer alignment issue

我正在使用 NGX 图形 'linkTemplate' 在 link(边缘)的中间添加圆圈,但缺少对齐。我正在使用变换 属性 来对齐 link 中间的圆圈。 如何计算将圆圈(带图标)放在 link 中间的精确坐标?

这是我上图的代码

<ngx-graph
    class="chart-container"
    [view]="[990, 800]"
    [curve]="curve"
    [draggingEnabled]="false"
    [autoCenter]="true"
    [links]="links"
    [nodes]="nodes">

    <ng-template #defsTemplate>
      <svg:marker id="arrow-yellow" fill="#f49600" viewBox="0 -5 10 10" refX="8" refY="0" markerWidth="6" markerHeight="6" orient="auto">
        <svg:path d="M0,-5L10,0L0,5" class="arrow-head"/>
      </svg:marker>
      <svg:marker id="arrow" fill="#262626" viewBox="0 -5 10 10" refX="8" refY="0" markerWidth="6" markerHeight="6" orient="auto">
        <svg:path d="M0,-5L10,0L0,5" class="arrow-head"/>
      </svg:marker>
    </ng-template>

    <ng-template #nodeTemplate let-node>
      <svg:g class="node">
        <svg:rect
          [attr.width]="node.dimension.width + 5"
          [attr.height]="node.dimension.height - 1"
          [attr.fill]="node.isSelected ? '#FFB716' : '#f6f6f6'"
          [attr.stroke-width]="1"
          [attr.stroke]="node.isSelected ? '#f49600' : '#262626'"/>
        <svg:text alignment-baseline="central" [attr.x]="10" [attr.y]="node.dimension.height / 2" [attr.letter-spacing]="0.5">
          {{node.label}}
        </svg:text>
      </svg:g>
      <svg:g class="assignNode" [attr.transform]="'translate(' + (node.dimension.width - 1) + ',' + 0 + ')'">
        <circle cx="5" cy="5" r="9" [attr.stroke]="node.isSelected ? '#f49600' : '#262626'" stroke-width="1" fill="white" />
        <path id="assign" viewBox="0 0 5 5" d="M9.88.15a.53.53,0,0,0-.67,0h0L8.05,1.32a4,4,0,0,0-5.27.33l-.5.44,0,.06V2.2a.06.06,0,0,0-.06.06l-.5.44A4,4,0,0,0,1.34,8L.17,9.13l-.05.06a.45.45,0,0,0,.05.66.46.46,0,0,0,.67,0L2,8.63A4,4,0,0,0,7.27,8.3l.5-.5.05,0a.06.06,0,0,0,.06-.06l.5-.5a4,4,0,0,0,.33-5.26L9.88.76A.45.45,0,0,0,9.88.15ZM6.6,7.69a2.94,2.94,0,0,1-4.26,0,3.06,3.06,0,0,1-.06-4.32l.17-.17L6.72,7.47ZM7.71,6.58l-.16.17L3.22,2.43l.17-.17a3,3,0,0,1,4.27,0A3.05,3.05,0,0,1,7.71,6.58Z" />
      </svg:g>
    </ng-template>

    <ng-template #linkTemplate let-link>
      <svg:g [attr.class]="link.isLinkActive ? 'active edge': 'notActive edge'">
        <svg:path class="line" *ngIf="!link.isLinkActive" stroke-width="1" marker-end="url(#arrow)"></svg:path>
        <svg:path class="line" *ngIf="link.isLinkActive" stroke-width="1" marker-end="url(#arrow-yellow)"></svg:path>
      </svg:g>
      <svg:g class="deAssignEdge" (click)="onDeAssingEvent(link)" *ngIf="link.midPoint" [attr.transform]="'translate(' + (link.midPoint.x) + ',' + (link.midPoint.y) + ')'">
        <circle cx="5" cy="5" r="9" [attr.stroke]="link.isLinkActive ? '#f49600': '#262626'" stroke-width="1" fill="white" />
        <path d="M6.26,6.89l-.6-.6-2-2-.55-.6-.6-.55a.45.45,0,0,0-.61,0l-.38.44a3.51,3.51,0,0,0-.27,4.61l-1,1h0a.43.43,0,0,0,0,.6.43.43,0,0,0,.61,0l1-1a3.45,3.45,0,0,0,4.61-.27l.43-.44a.42.42,0,0,0,0-.6Zm-.44,1A2.64,2.64,0,0,1,2.09,4.15L2.26,4,6,7.71Z" />
        <path d="M9.83.15a.43.43,0,0,0-.61,0h0l-1,1a3.45,3.45,0,0,0-4.61.27l-.38.44h0a.5.5,0,0,0,0,.55L4.51,3.77l-.39.33.44.43.33-.33L5.71,5l-.27.38.44.44.33-.33L7.47,6.78a.42.42,0,0,0,.6,0l.44-.44a3.44,3.44,0,0,0,.27-4.6l1.05-1A.36.36,0,0,0,9.83.15ZM8,5.8,7.8,6,4.07,2.18,4.23,2A2.62,2.62,0,0,1,8,2,2.69,2.69,0,0,1,8,5.8Z" />
      </svg:g>
    </ng-template>

  </ngx-graph>

public links = [
    {
      id: 'a',
      source: 'first',
      target: 'second',
      label: 'is parent of',
      isLinkActive:  false,
      sourceIndex:1
    },
    {
      id: 'b',
      source: 'first',
      target: 'third',
      label: 'custom label',
      isLinkActive:  false,
      sourceIndex:2
    },
    {
      id: 'c',
      source: 'second',
      target: 'Four',
      label: 'custom label',
      isLinkActive:true,
      sourceIndex:1
    },
    {
      id: 'd',
      source: 'second',
      target: 'Five',
      label: 'custom label',
      isLinkActive:true,
      sourceIndex:2
    },
    {
      id: 'e',
      source: 'second',
      target: 'Six',
      label: 'custom label',
      isLinkActive:true,
      sourceIndex:3
    },
    {
      id: 'f',
      source: 'second',
      target: 'Seven',
      label: 'custom label',
      isLinkActive:true,
      sourceIndex:4
    },
    {
      id: 'g',
      source: 'third',
      target: 'Eight',
      label: 'custom label',
      isLinkActive:  false,
      sourceIndex:1
    },
    {
      id: 'h',
      source: 'third',
      target: 'Nine',
      label: 'custom label',
      isLinkActive:  false,
      sourceIndex:2
    },
    {
      id: 'i',
      source: 'third',
      target: 'Ten',
      label: 'custom label',
      isLinkActive:  false,
      sourceIndex:3
    },
    {
      id: 'j',
      source: 'Four',
      target: 'Ele',
      label: 'custom label',
      isLinkActive:  false,
      sourceIndex:1
    },
    {
      id: '1',
      source: 'Ele',
      target: 'Four',
      label: 'custom label',
      isLinkActive:  false,
      sourceIndex:1
    }
  ];

  public nodes = [
    {
      id: 'first',
      label: 'AAAAAAA',
      isSelected:false,
    },
    {
      id: 'second',
      label: 'BBBBB',
      isSelected:true,
    },
    {
      id: 'third',
      label: 'CCCC',
      isSelected:false
    },
    {
      id: 'Four',
      label: 'DDDD',
      isSelected:false
    },
    {
      id: 'Five',
      label: 'EEEEE',
      isSelected:false
    },
    {
      id: 'Six',
      label: 'FFFF',
      isSelected:false
    },
    {
      id: 'Seven',
      label: 'GGGG',
      isSelected:false
    },
    {
      id: 'Eight',
      label: 'HHH',
      isSelected:false
    },
    {
      id: 'Nine',
      label: 'III',
      isSelected:false
    },
    {
      id: 'Ten',
      label: 'JJJ',
      isSelected:false
    },
    {
      id: 'Ele',
      label: 'KKKKKKK',
      isSelected:false
    }
  ]

Stackblitz link: https://stackblitz.com/edit/ngx-graph-demo-quawhu

基于此 您可以通过创建一个与 link( link.line) 并像这样获得路径的中间:

  getXYForCenteredLinkCircle(link: Edge): [number, number] {
    var myPath = document.createElementNS("http://www.w3.org/2000/svg", "path");
    myPath.setAttributeNS(null, "d", link.line);
    var length = myPath.getTotalLength();
    let p = myPath.getPointAtLength(length / 2);
    return [p.x - 5, p.y - 5]; // Consider the center coordinates of the circle 
  }

并且在模板中:

<svg:g [attr.transform]="'translate(' + getXYForCenteredLinkCircle(link)[0] + ',' + getXYForCenteredLinkCircle(link)[1] + ')'">

它看起来像这样: