in src/helpers/edge-helpers.js [86:188]
export function calculateOffset(
nodeSize: any,
src: any,
trg: any,
nodeKey: string,
includesArrow?: boolean = true,
viewWrapperElem: React.RefObject<HTMLDivElement>
) {
let response = getDefaultIntersectResponse();
if (trg == null || trg[nodeKey] == null) {
return response;
}
// Note: document.getElementById is by far the fastest way to get a node.
// compare 2.82ms for querySelector('#node-a2 use.node') vs
// 0.31ms and 99us for document.getElementById()
// Although it doesn't allow multiple graphs.
// We can use viewWrapperElem to scope the querySelector to a smaller set of elements to improve the speed
const nodeElem = viewWrapperElem.querySelector(`[id='node-${trg[nodeKey]}']`);
if (!nodeElem) {
return response;
}
const trgNode = nodeElem.querySelector(`use.node`);
// the test for trgNode.getAttributeNS makes sure we really have a node and not some other type of object
if (!trgNode || (trgNode && !trgNode.getAttribute)) {
return response;
}
let href = trgNode.getAttribute('href');
if (!href) {
href = trgNode.getAttributeNS('http://www.w3.org/1999/xlink', 'href');
}
if (!href) {
return response;
}
const defSvgRectElement: SVGRectElement | null = viewWrapperElem.querySelector(
`defs>${href} rect:not([data-intersect-ignore=true])`
);
// Conditionally trying to select the element in other ways is faster than trying to
// do the selection.
const defSvgPathElement: SVGPathElement | null = !defSvgRectElement
? viewWrapperElem.querySelector(
`defs>${href} path:not([data-intersect-ignore=true])`
)
: null;
const defSvgCircleElement:
| SVGCircleElement
| SVGEllipseElement
| SVGPolygonElement
| null =
!defSvgPathElement && !defSvgPathElement
? viewWrapperElem.querySelector(
`defs>${href} circle:not([data-intersect-ignore=true]), defs>${href} ellipse:not([data-intersect-ignore=true]), defs>${href} polygon:not([data-intersect-ignore=true])`
)
: null;
if (defSvgRectElement) {
// it's a rectangle
response = {
...response,
...getRotatedRectIntersect(
defSvgRectElement,
src,
trg,
includesArrow,
viewWrapperElem
),
};
} else if (defSvgPathElement) {
// it's a complex path
response = {
...response,
...getPathIntersect(
defSvgPathElement,
src,
trg,
includesArrow,
viewWrapperElem
),
};
} else {
// it's a circle or some other type
response = {
...response,
...getCircleIntersect(
defSvgCircleElement,
src,
trg,
includesArrow,
viewWrapperElem
),
};
}
return response;
}