节点之间的并行链接

parallel links between nodes

我有一个 Webcola&D3 svg 图表,其中包含节点和节点之间的 Links。 直到今天,节点之间的 Link 可能是一种方式,如果 B 连接到 A,它只是一种方式 Link。

今天我被告知我需要支持 2 路 Links,这意味着 A 可以向 B 发送 Link,B 可以向 A 发送 link。

现在我对数学和如何完成它感到困惑,我使用了一些我发现的算法来绘制 links 直到今天我猜从中心绘制 Links节点,我需要像这样并行显示 2 种方式 links:

这是我用来计算 Link 位置的算法:

let parent = connection.parent;

        const sx = parent.source.x;
        const sy = parent.source.y;
        const tx = parent.target.x;
        const ty = parent.target.y;

        let angle = Math.atan2(ty - sy, tx - sx);
        const radiusSource = parent.source.radius;
        const radiusTarget = parent.target.radius;

        let x1 = sx + Math.cos(angle) * radiusSource;
        let x2 = tx - Math.cos(angle) * radiusTarget;
        let y1 = sy + Math.sin(angle) * radiusSource;
        let y2 = ty - Math.sin(angle) * radiusTarget;

        angle = angle * 180 / Math.PI;
        let opposite = Math.abs(angle) > 90;

        if (opposite)
            angle -= 180;

        connection.coords = [x1, y1, x2, y2, angle, opposite];
        return connection.coords;

这是函数的一部分,结果进入路径的 'd' attr,如下所示:

.attr('d', `M${x1} ${y1} L ${x2} ${y2}`)

现在 2 路 Link 的结果是它们相互覆盖,谁能帮我改进这个算法,使 2 路 Link 并行?

Update: Links的位置需要根据new radian计算offset,如:

let parent = connection.parent;

const sx = parent.source.x;
const sy = parent.source.y;
const tx = parent.target.x;
const ty = parent.target.y;
const radiusSource = parent.source.radius;
const radiusTarget = parent.target.radius;

let radian = Math.atan2(ty - sy, tx - sx);
let offset = 0.1 // Offset ratio of radian, can be adjusted
let offsetRadian;

let angle = radian * 180 / Math.PI;
let opposite = Math.abs(angle) > 90;
if (opposite) {
    angle -= 180;
    offsetRadian = radian * (1 + offset);
} else {
    offsetRadian = radian * (1 - offset);
}

let x1 = sx + Math.cos(offsetRadian) * radiusSource;
let y1 = sy + Math.sin(offsetRadian) * radiusSource;

let x2 = tx - Math.sin(offsetRadian) * radiusTarget;
let y2 = ty - Math.cos(offsetRadian) * radiusTarget;

connection.coords = [x1, y1, x2, y2, angle, opposite];
return connection.coords;