50 lines
1.4 KiB
TypeScript
50 lines
1.4 KiB
TypeScript
|
|
import type { DiagramEdge as DiagramEdgeType } from '../../api/queries/diagrams';
|
||
|
|
|
||
|
|
interface DiagramEdgeProps {
|
||
|
|
edge: DiagramEdgeType;
|
||
|
|
offsetY?: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function DiagramEdge({ edge, offsetY = 0 }: DiagramEdgeProps) {
|
||
|
|
const pts = edge.points;
|
||
|
|
if (!pts || pts.length < 2) return null;
|
||
|
|
|
||
|
|
// Build SVG path: move to first point, then cubic bezier or line to rest
|
||
|
|
let d = `M ${pts[0][0]} ${pts[0][1] + offsetY}`;
|
||
|
|
|
||
|
|
if (pts.length === 2) {
|
||
|
|
d += ` L ${pts[1][0]} ${pts[1][1] + offsetY}`;
|
||
|
|
} else if (pts.length === 4) {
|
||
|
|
// 4 points: start, control1, control2, end → cubic bezier
|
||
|
|
d += ` C ${pts[1][0]} ${pts[1][1] + offsetY}, ${pts[2][0]} ${pts[2][1] + offsetY}, ${pts[3][0]} ${pts[3][1] + offsetY}`;
|
||
|
|
} else {
|
||
|
|
// Multiple points: connect with line segments through intermediate points
|
||
|
|
for (let i = 1; i < pts.length; i++) {
|
||
|
|
d += ` L ${pts[i][0]} ${pts[i][1] + offsetY}`;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return (
|
||
|
|
<g className="diagram-edge">
|
||
|
|
<path
|
||
|
|
d={d}
|
||
|
|
fill="none"
|
||
|
|
stroke="#9CA3AF"
|
||
|
|
strokeWidth={1.5}
|
||
|
|
markerEnd="url(#arrowhead)"
|
||
|
|
/>
|
||
|
|
{edge.label && pts.length >= 2 && (
|
||
|
|
<text
|
||
|
|
x={(pts[0][0] + pts[pts.length - 1][0]) / 2}
|
||
|
|
y={(pts[0][1] + pts[pts.length - 1][1]) / 2 + offsetY - 6}
|
||
|
|
fill="#9C9184"
|
||
|
|
fontSize={9}
|
||
|
|
textAnchor="middle"
|
||
|
|
>
|
||
|
|
{edge.label}
|
||
|
|
</text>
|
||
|
|
)}
|
||
|
|
</g>
|
||
|
|
);
|
||
|
|
}
|