in src/sankeyDiagram.ts [2083:2181]
private getSvgPathForBackwardLink(link: SankeyDiagramLink) {
let pathParams: string = "";
const distanceBetweenLinks: number = 3;
const distanceFromNodeToLinks: number = 5;
let fixedLinkHeight = link.height - distanceBetweenLinks;
let linkKneeSize: number = link.height;
let x0: number,
x1: number,
xi: (t: number) => number,
x2: number,
x3: number,
y0: number,
y1: number;
if (link.destination.x < link.source.x) {
x0 = link.source.x;
x1 = link.destination.x + link.destination.width;
} else {
x0 = link.source.x + link.source.width;
x1 = link.destination.x;
}
// drawing area as combination of 4 lines in one path element of svg to fill this area with required color
// upper border of link
xi = d3.interpolateNumber(x0, x1);
x2 = xi(this.curvatureOfLinks);
x3 = xi(1 - this.curvatureOfLinks);
y0 = link.source.y - (link.height + SankeyDiagram.NodeAndBackwardLinkDistance) + link.dySource + link.height / SankeyDiagram.MiddleFactor - link.height / 2;
y1 = link.destination.y - (link.height + SankeyDiagram.NodeAndBackwardLinkDistance) + link.dyDestination + link.height / SankeyDiagram.MiddleFactor - link.height / 2;
pathParams += ` M ${x0} ${y0} C ${x2} ${y0}, ${x3} ${y1}, ${x1} ${y1}`;
pathParams += `L ${link.destination.x + link.destination.width} ${y1}`;
pathParams +=
`C ${link.destination.x + link.destination.width} ${y1}, ` +
`${link.destination.x + link.destination.width + linkKneeSize} ${y1}, ` +
`${link.destination.x + link.destination.width + linkKneeSize} ${y1 + linkKneeSize}`;
// right border of link
y0 = link.destination.y - (link.height + SankeyDiagram.NodeAndBackwardLinkDistance) + link.dyDestination + link.height / SankeyDiagram.MiddleFactor + link.height / 2;
y1 = link.destination.y - (link.height + SankeyDiagram.NodeAndBackwardLinkDistance) + link.dyDestination + link.height / SankeyDiagram.MiddleFactor - link.height / 2;
let limit = y1 + link.destination.width + (fixedLinkHeight) * 2 - link.destination.width;
if (limit > link.destination.y + fixedLinkHeight - link.destination.width) {
limit = link.destination.y + fixedLinkHeight - link.destination.width;
}
pathParams +=
`C ${link.destination.x + link.destination.width + linkKneeSize} ${link.destination.y + fixedLinkHeight - linkKneeSize},` +
` ${link.destination.x + link.destination.width + linkKneeSize} ${link.destination.y + fixedLinkHeight} ,` +
` ${link.destination.x + link.destination.width + distanceFromNodeToLinks} ${link.destination.y + fixedLinkHeight}`;
pathParams += `L ${link.destination.x + link.destination.width} ${link.destination.y + fixedLinkHeight}`;
pathParams += `L ${link.destination.x + link.destination.width} ${link.destination.y}`;
pathParams += `L ${link.destination.x + link.destination.width + distanceFromNodeToLinks} ${link.destination.y}`;
pathParams += `L ${link.destination.x + link.destination.width + distanceFromNodeToLinks} ${link.destination.y - SankeyDiagram.NodeAndBackwardLinkDistance}`;
// bottom border of link
xi = d3.interpolateNumber(x0, x1);
x2 = xi(this.curvatureOfLinks);
x3 = xi(1 - this.curvatureOfLinks);
y0 = link.source.y - (link.height + SankeyDiagram.NodeAndBackwardLinkDistance) + link.dySource + link.height / SankeyDiagram.MiddleFactor + link.height / 2;
y1 = link.destination.y - (link.height + SankeyDiagram.NodeAndBackwardLinkDistance) + link.dyDestination + link.height / SankeyDiagram.MiddleFactor + link.height / 2;
pathParams += ` L ${x1 + distanceFromNodeToLinks} ${y1} C ${x2} ${y1}, ${x3} ${y0}, ${x0 - distanceFromNodeToLinks} ${y0}`;
pathParams += `L ${link.source.x - distanceFromNodeToLinks} ${y0}`;
pathParams += `L ${link.source.x - distanceFromNodeToLinks} ${y0 + SankeyDiagram.NodeAndBackwardLinkDistance}`;
pathParams += `L ${link.source.x} ${y0 + SankeyDiagram.NodeAndBackwardLinkDistance}`;
pathParams += `L ${link.source.x} ${y0 + SankeyDiagram.NodeAndBackwardLinkDistance + fixedLinkHeight}`;
pathParams += `L ${link.source.x - distanceFromNodeToLinks} ${y0 + SankeyDiagram.NodeAndBackwardLinkDistance + fixedLinkHeight}`;
pathParams +=
`C ${link.source.x - distanceFromNodeToLinks} ${y0 + SankeyDiagram.NodeAndBackwardLinkDistance + fixedLinkHeight}, ` +
`${link.source.x - distanceFromNodeToLinks - linkKneeSize} ${y0 + SankeyDiagram.NodeAndBackwardLinkDistance + link.height}, ` +
`${link.source.x - distanceFromNodeToLinks - linkKneeSize} ${y0 + SankeyDiagram.NodeAndBackwardLinkDistance + link.height - linkKneeSize}`;
// left border of link
y1 = link.source.y - (link.height + SankeyDiagram.NodeAndBackwardLinkDistance) + link.dySource + link.height / SankeyDiagram.MiddleFactor - link.height / 2;
// tslint:disable-next-line: no-suspicious-comment
pathParams += `C ${link.source.x - distanceFromNodeToLinks - linkKneeSize} ${y1 + linkKneeSize}, ${link.source.x - distanceFromNodeToLinks - linkKneeSize} ${y1}, ${link.source.x} ${y1}`; // TODO change to C
// close path to get closed area
pathParams += ` Z`;
return pathParams;
}