自訂邊線

自訂節點一樣,React Flow 中自訂邊線的部分也只是 React 元件:這表示您可以在邊線上呈現任何您想要的東西!本指南將說明如何實作具有一些額外控制項的自訂邊線。

基本自訂邊線

如果邊線沒有在兩個連接的節點之間呈現路徑,則對我們來說沒有太大用處。這些路徑始終是基於 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} />
    </>
  );
}

傳遞到您的自訂邊線元件的所有屬性都可以在 API 參考的 EdgeProps 類型下找到。

這給了我們一條與預設 "straight" 邊線類型行為相同的直線邊線。為了使用它,我們還需要更新 <ReactFlow /> 元件上的 edgeTypes 屬性。

請務必在元件外部定義 edgeTypes 物件,或使用 React 的 useMemo Hook 來防止不必要的重新渲染。如果您忘記這樣做,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" 來使用我們新的自訂邊線。

export default function App() {
  const data: string = "world"

  return <h1>Hello {data}</h1>
}

唯讀

新增邊線標籤

自訂邊線的更常見用途之一是在邊線路徑上呈現一些控制項或資訊。在 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」後面)。由於邊線標籤入口,我們需要做一些額外的工作來自行定位按鈕。

A screen shot of a simple flow. The edge label renderer is highlighted in the DOM inspector and the button is rendered in the centre of the flow.

幸好,我們已經看過的路線實用程式可以幫助我們做到這一點!這些函式除了呈現 SVG 路徑外,還會傳回路徑中點的 xy 座標。然後,我們可以使用這些座標將我們的自訂邊線標籤轉換到正確的位置!

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 新增至標籤的樣式中。這將確保該標籤是可點擊的。

就像自訂節點中的互動式控制項一樣,我們需要記住將 nodragnopan 類別新增至標籤,以防止滑鼠事件控制畫布。

以下是具有我們更新的自訂邊線的互動式範例。點擊刪除按鈕會從流程中移除該邊線。建立新的邊線將使用自訂節點。

export default function App() {
  const data: string = "world"

  return <h1>Hello {data}</h1>
}

唯讀