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] + ')'">
它看起来像这样:
我正在使用 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.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] + ')'">
它看起来像这样: