#Bidirectional Straight line

1 messages · Page 1 of 1 (latest)

snow siren
#

I am trying to change the bezier bidirectional edge example into an straight bidirectional edge but struggle with properly offsetting the connection. Is there already a working example for this case that I missed or does someone have a proper approach?

This is my current result, but the second point isnt properly calculated.

smoky summit
#

please provide a code example

snow siren
#
import React, {memo, useCallback} from 'react';
import {BaseEdge, EdgeProps, getStraightPath, Position, ReactFlowState, useStore} from 'reactflow';
import {getEdgeParams} from "../../../utils/mathUtils";

export type GetSpecialPathParams = {
    sourceX: number;
    sourceY: number;
    targetX: number;
    targetY: number;
};

const FloatingEdge = memo(({ id, source, target, markerEnd, style } : EdgeProps) => {
    const sourceNode = useStore(useCallback((store) => store.nodeInternals.get(source), [source]));
    const targetNode = useStore(useCallback((store) => store.nodeInternals.get(target), [target]));

    if (!sourceNode || !targetNode) {
        return null;
    }

    const isBiDirectionEdge = useStore((s: ReactFlowState) => {
        const edgeExists = s.edges.some(
            (e) =>
                (e.source === target && e.target === source) || (e.target === source && e.source === target)
        );

        return edgeExists;
    });

    const getSpecialPath = ({ sourceX, sourceY, targetX, targetY }: GetSpecialPathParams, offset: number) => {
        return `M ${sourceX} ${sourceY + offset} L ${targetX} ${targetY + offset}`;
    };


    const { sx, sy, tx, ty, sourcePos, targetPos } = getEdgeParams(sourceNode, targetNode);

    let path = "";
    if (isBiDirectionEdge) {
        path = getSpecialPath({
                    sourceX: sx,
                    sourceY: sy,
                    targetX: tx,
                    targetY: ty,
                }, sourcePos == Position.Left ? 20 : 0
            );
    } else {
        [path] = getStraightPath({
            sourceX: sx,
            sourceY: sy,
            targetX: tx,
            targetY: ty,
        });
    }

    return (
        <BaseEdge
            id={id}
            path={path}
            markerEnd={markerEnd}
            style={style}
        />
    );
})

export default FloatingEdge;
#

It basically just applies an offset based on the handle position, which isnt going to work, but I couldnt think of a better way of realising this.

smoky summit
#

it looks good to me

#

you are using the floating edge

#

and then you are applying a 20px offset

#

are you sure you want to draw a floating edge?

snow siren
#

Yes, it should be floating edges

#

But as seen in the screenshot this doesnt properly calculate the second intersection point, its just offset.

#

Which creates gaps in the lines.

smoky summit
#

but that is what your code does

#

sourceY + offset

#

targetY + offset

#

I think you want to adjust the getEdgeParams function

#

and add an offset there if it's a bidirectional edge

snow siren
#

Okay so I managed to make it work. I basically rewrote the math utils, but it seems to work now.