export function calculateOffset()

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;
}