カスタムエッジ
カスタムノードと同様に、React Flowのカスタムエッジの一部は単なるReactコンポーネントです。つまり、エッジに沿って何でもレンダリングできます!このガイドでは、いくつかの追加コントロールを使用してカスタムエッジを実装する方法を示します。
基本的なカスタムエッジ
エッジが接続された2つのノード間のパスをレンダリングしない場合、それはあまり役に立ちません。これらのパスは常にSVGベースであり、通常は<BaseEdge />
コンポーネントを使用してレンダリングされます。実際にレンダリングするSVGパスを計算するために、React Flowには便利なユーティリティ関数がいくつか用意されています。
カスタムエッジの開始として、ソースとターゲット間の直線パスをレンダリングします。
import { BaseEdge, getStraightPath } from '@xyflow/react';
export default function CustomEdge({ id, sourceX, sourceY, targetX, targetY }) {
const [edgePath] = getStraightPath({
sourceX,
sourceY,
targetX,
targetY,
});
return (
<>
<BaseEdge id={id} path={edgePath} />
</>
);
}
カスタムエッジコンポーネントに渡されるすべてのプロップは、EdgeProps
型の下のAPIリファレンスにあります。
これにより、デフォルトの"straight"
エッジタイプと同じ動作をする直線エッジが得られます。それを使用するには、<ReactFlow />
コンポーネントのedgeTypes
プロップも更新する必要があります。
edgeTypes
オブジェクトは、コンポーネントの外側で定義するか、ReactのuseMemo
フックを使用して、不要な再レンダリングを防ぐことが重要です。これを行うのを忘れると、React Flowはコンソールに警告を表示します。
import ReactFlow from '@xyflow/react'
import CustomEdge from './CustomEdge'
const edgeTypes = {
'custom-edge': CustomEdge
}
export function Flow() {
return <ReactFlow edgeTypes={edgeTypes} ... />
}
edgeTypes
オブジェクトを定義した後、エッジのtype
フィールドを"custom-edge"
に設定することで、新しいカスタムエッジを使用できます。
エッジラベルの追加
カスタムエッジのより一般的な用途の1つは、エッジのパスに沿っていくつかのコントロールまたは情報をレンダリングすることです。React Flowでは、それをエッジラベルと呼びますが、エッジパスとは異なり、エッジラベルは任意のReactコンポーネントにすることができます!
カスタムエッジラベルをレンダリングするには、<EdgeLabelRenderer />
コンポーネントでラップする必要があります。これはパフォーマンス上の理由から必要です。エッジラベルレンダラーは、すべてのエッジラベルがレンダリングされる単一コンテナへのポータルです。
接続されているエッジを削除するために使用できるボタンをカスタムエッジに追加してみましょう。
import {
BaseEdge,
EdgeLabelRenderer,
getStraightPath,
useReactFlow,
} from '@xyflow/react';
export default function CustomEdge({ id, sourceX, sourceY, targetX, targetY }) {
const { setEdges } = useReactFlow();
const [edgePath] = getStraightPath({
sourceX,
sourceY,
targetX,
targetY,
});
return (
<>
<BaseEdge id={id} path={edgePath} />
<EdgeLabelRenderer>
<button
onClick={() => setEdges((edges) => edges.filter((e) => e.id !== id))}
>
delete
</button>
</EdgeLabelRenderer>
</>
);
}
ここでこのエッジを使用しようとすると、ボタンがフローの中央にレンダリングされていることがわかります(「ノードA」の後ろに隠れている可能性があります)。エッジラベルポータルのため、ボタンを自分で配置するために追加の作業を行う必要があります。

幸いなことに、既に見たパスユーティリティがこれの助けになります!レンダリングするSVGパスとともに、これらの関数はパスの中点のx
座標とy
座標も返します。次に、これらの座標を使用して、カスタムエッジラベルを正しい位置に移動できます!
export default function CustomEdge({ id, sourceX, sourceY, targetX, targetY }) {
const { setEdges } = useReactFlow();
const [edgePath, labelX, labelY] = getStraightPath({ ... });
return (
...
<button
style={{
position: 'absolute',
transform: `translate(-50%, -50%) translate(${labelX}px, ${labelY}px)`,
pointerEvents: 'all',
}}
className="nodrag nopan"
onClick={() => {
setEdges((es) => es.filter((e) => e.id !== id));
}}
>
...
);
}
エッジラベルがインタラクティブであり、プレゼンテーションのためだけではないことを確認するために、ラベルのスタイルにpointer-events: all
を追加することが重要です。これにより、ラベルをクリック可能になります。
カスタムノードのインタラクティブなコントロールと同様に、マウスイベントがキャンバスを制御するのを防ぐために、ラベルにnodrag
クラスとnopan
クラスを追加することを忘れないでください。
更新されたカスタムエッジを使用したインタラクティブな例を次に示します。削除ボタンをクリックすると、そのエッジがフローから削除されます。新しいエッジを作成すると、カスタムノードが使用されます。