@eccenca/gui-elements
Version:
GUI elements based on other libraries, usable in React application, written in Typescript.
202 lines (184 loc) • 6.56 kB
text/typescript
import { getEdgeCenter, Position } from "react-flow-renderer";
import { GetBezierPathParams } from "@xyflow/react";
import { EdgeDefaultProps } from "./EdgeDefault";
import { EdgeStepProps } from "./EdgeStep";
import { getSmoothStepPath } from "./getSmoothStepPath";
interface EdgePositionCorrectionProps
extends Omit<EdgeDefaultProps, "id" | "source" | "target" | "drawSvgPath" | "data"> {
correctionLength?: number;
correctionRadius?: number;
}
const posCorrectionEdge = ({
sourceX,
sourceY,
sourcePosition,
targetX,
targetY,
targetPosition,
correctionLength = 7,
correctionRadius = 7,
}: EdgePositionCorrectionProps) => {
let newSourceX = sourceX;
let newSourceY = sourceY;
let newTargetX = targetX;
let newTargetY = targetY;
let startCommandCorrection = `M ${sourceX},${sourceY} `;
let endCommandCorrection = ``;
if (sourcePosition === Position.Left && sourceX < targetX) {
newSourceX = newSourceX - 2 * correctionLength;
if (sourceY < targetY) {
newSourceY = sourceY + correctionRadius;
startCommandCorrection =
startCommandCorrection +
` L ${
newSourceX + correctionRadius
},${sourceY} A ${correctionRadius} ${correctionRadius} ${90} ${0} ${0} `;
} else {
newSourceY = sourceY - correctionRadius;
startCommandCorrection =
startCommandCorrection +
` L ${
newSourceX + correctionRadius
},${sourceY} A ${correctionRadius} ${correctionRadius} ${90} ${0} ${1} `;
}
}
if (sourcePosition === Position.Right && sourceX > targetX) {
newSourceX =
targetPosition === Position.Right
? newSourceX + correctionLength + correctionRadius
: newSourceX + correctionLength;
if (sourceY < targetY) {
newSourceY = sourceY + correctionRadius;
startCommandCorrection =
startCommandCorrection +
` L ${
newSourceX - correctionRadius
},${sourceY} A ${correctionRadius} ${correctionRadius} ${90} ${0} ${1} `;
} else {
newSourceY = sourceY - correctionRadius;
startCommandCorrection =
startCommandCorrection +
` L ${
newSourceX - correctionRadius
},${sourceY} A ${correctionRadius} ${correctionRadius} ${90} ${0} ${0} `;
}
}
if (targetPosition === Position.Left && sourceX > targetX) {
newTargetX = newTargetX - 3 * correctionLength;
if (sourceY < targetY) {
newTargetY = targetY - correctionRadius;
endCommandCorrection = ` A ${correctionRadius} ${correctionRadius} ${90} ${0} ${0} ${
newTargetX + correctionRadius
},${targetY} L ${targetX},${targetY}`;
} else {
newTargetY = targetY + correctionRadius;
endCommandCorrection = ` A ${correctionRadius} ${correctionRadius} ${90} ${0} ${1} ${
newTargetX + correctionRadius
},${targetY} L ${targetX},${targetY}`;
}
}
if (targetPosition === Position.Right && sourceX < targetX) {
newTargetX = newTargetX + 3 * correctionLength;
if (sourceY < targetY) {
newTargetY = targetY - correctionRadius;
endCommandCorrection = ` A ${correctionRadius} ${correctionRadius} ${90} ${0} ${1} ${
newTargetX - correctionRadius
},${targetY} L ${targetX},${targetY}`;
} else {
newTargetY = targetY + correctionRadius;
endCommandCorrection = ` A ${correctionRadius} ${correctionRadius} ${90} ${0} ${0} ${
newTargetX - correctionRadius
},${targetY} L ${targetX},${targetY}`;
}
}
return {
newSourceX,
newSourceY,
newTargetX,
newTargetY,
startCommandCorrection,
endCommandCorrection,
};
};
interface PathCommandCorrectionProps {
pathCommand: string;
startCorrection: string;
endCorrection: string;
}
const pathCommandCorrection = ({ pathCommand, startCorrection, endCorrection }: PathCommandCorrectionProps) => {
return startCorrection + pathCommand.substring(1) + endCorrection;
};
export const drawEdgeStraight = ({
sourceX,
sourceY,
sourcePosition,
targetX,
targetY,
targetPosition,
}: EdgeDefaultProps) => {
const corrections = posCorrectionEdge({
sourceX,
sourceY,
sourcePosition,
targetX,
targetY,
targetPosition,
correctionRadius: 0,
});
const pathCommand = `M ${corrections.newSourceX},${corrections.newSourceY}L ${corrections.newTargetX},${corrections.newTargetY}`;
return pathCommandCorrection({
pathCommand,
startCorrection: corrections.startCommandCorrection,
endCorrection: corrections.endCommandCorrection,
});
};
export const getStraightPath = (params: Omit<GetBezierPathParams, "curvature">) => {
const path = drawEdgeStraight(params as EdgeDefaultProps);
const [labelX, labelY, offsetX, offsetY] = getEdgeCenter({
sourceX: params.sourceX,
sourceY: params.sourceY,
targetX: params.targetX,
targetY: params.targetY,
});
return [path, labelX, labelY, offsetX, offsetY] as [
path: string,
labelX: number,
labelY: number,
offsetX: number,
offsetY: number
];
};
export const drawEdgeStep = ({
sourceX,
sourceY,
sourcePosition,
targetX,
targetY,
targetPosition,
data = {},
}: EdgeStepProps) => {
const corrections = posCorrectionEdge({
sourceX,
sourceY,
sourcePosition,
targetX,
targetY,
targetPosition,
correctionLength: data.stepCornerRadius || 7,
correctionRadius: data.stepCornerRadius || 7,
});
const pathCommand = getSmoothStepPath({
sourceX: corrections.newSourceX,
sourceY: corrections.newSourceY,
sourcePosition,
targetX: corrections.newTargetX,
targetY: corrections.newTargetY,
targetPosition,
borderRadius: data.stepCornerRadius || 7,
});
return pathCommandCorrection({
pathCommand,
startCorrection: corrections.startCommandCorrection,
endCorrection: corrections.endCommandCorrection,
});
};