From ca2830462cecc83c202f5de8c62964c6aecc14a8 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 3 Mar 2026 09:11:07 +0000
Subject: [PATCH 1/2] Initial plan
From ec19b156690d73fa8e52b8538989e385cc70af7f Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 3 Mar 2026 09:16:19 +0000
Subject: [PATCH 2/2] docs: add three edge rendering forms and operation points
documentation (zh/en)
Co-authored-by: CraneReturn <127602190+CraneReturn@users.noreply.github.com>
---
sites/docs/docs/tutorial/basic/edge.en.md | 159 ++++++++++++++++++++++
sites/docs/docs/tutorial/basic/edge.zh.md | 159 ++++++++++++++++++++++
2 files changed, 318 insertions(+)
diff --git a/sites/docs/docs/tutorial/basic/edge.en.md b/sites/docs/docs/tutorial/basic/edge.en.md
index 81a0adeb8..9a1d3be69 100644
--- a/sites/docs/docs/tutorial/basic/edge.en.md
+++ b/sites/docs/docs/tutorial/basic/edge.en.md
@@ -18,6 +18,165 @@ The effect is as follows:
+## Three Edge Rendering Forms
+
+### Line
+
+Line is the simplest edge type. It renders directly using an SVG `` element connecting the start point to the end point.
+
+**Rendering characteristics**:
+
+- Uses an SVG `` element where `x1/y1` is the start point and `x2/y2` is the end point.
+- Simplest path calculation: only `startPoint` and `endPoint` coordinates are needed.
+- Click area (AppendWidth): a rectangle is computed on both sides of the line so that thin lines are easier to click.
+
+```tsx | pure
+// LineEdge getEdge core rendering
+getEdge() {
+ const { model } = this.props
+ const { startPoint, endPoint } = model
+ return (
+
+ )
+}
+```
+
+### Polyline
+
+Polyline (orthogonal polyline) is a multi-segment line where every segment is either horizontal or vertical. It is rendered using an SVG `` element.
+
+**Rendering characteristics**:
+
+- Uses an SVG `` element with all waypoints passed in the `points` attribute (format: `"x1,y1 x2,y2 x3,y3 ..."`).
+- Complex path calculation: uses an A* algorithm with Manhattan distance to automatically route around nodes; results are stored in `pointsList`.
+- Click area (AppendWidth): each segment has its own rectangular hit region that are all combined together.
+
+```tsx | pure
+// PolylineEdge getEdge core rendering
+getEdge() {
+ const { model } = this.props
+ const { points } = model // "x1,y1 x2,y2 x3,y3 ..."
+ return (
+
+ )
+}
+```
+
+### Bezier
+
+The bezier edge is a cubic Bézier curve rendered using an SVG `` element with the `M...C...` command.
+
+**Rendering characteristics**:
+
+- Uses an SVG `` element. The path format is `M startX startY C sNextX sNextY, ePreX ePreY, endX endY`.
+- `pointsList` always contains exactly 4 points: **start**, **start control point (sNext)**, **end control point (ePre)**, **end**.
+- The initial positions of the two control points are calculated automatically based on the source and target node positions so the curve avoids overlapping node borders.
+- Click area (AppendWidth): a transparent curve with `strokeWidth=10` is drawn on top of the actual path to enlarge the hit area.
+
+```tsx | pure
+// BezierEdgeModel path generation
+private getPath(points: Point[]): string {
+ const [start, sNext, ePre, end] = points
+ return `M ${start.x} ${start.y}
+ C ${sNext.x} ${sNext.y},
+ ${ePre.x} ${ePre.y},
+ ${end.x} ${end.y}`
+}
+```
+
+## Operation Point Differences
+
+"Operation points" are the interactive handles shown when an edge is selected, used to adjust its shape. All three edge types support common start/end adjustment points, but each type also has its own unique handles.
+
+### Common: Start/End Adjustment Points
+
+All three edge types support start/end adjustment points. Enable them at initialization with `adjustEdgeStartAndEnd`:
+
+```tsx | pure
+const lf = new LogicFlow({
+ adjustEdgeStartAndEnd: true, // Enable start/end point adjustment
+})
+```
+
+When enabled, a circular handle appears at both the **start** and **end** of a selected edge. Drag either handle to reconnect the edge to a different anchor on another node.
+
+### Line Operation Points
+
+A line has **only** start/end adjustment points. There is no way to change the intermediate path because a straight line between two points is unique.
+
+| Operation Point | Description |
+|----------------|-------------|
+| Start adjustment (SOURCE) | Drag to reconnect to a different node anchor |
+| End adjustment (TARGET) | Drag to reconnect to a different node anchor |
+
+### Polyline Operation Points
+
+In addition to start/end adjustment points, a polyline also supports **segment dragging**. Each segment has a transparent draggable region (generated by `getAppendWidth`):
+
+- **Horizontal segments**: can only be dragged vertically (move the segment up/down); cursor becomes `ns-resize`.
+- **Vertical segments**: can only be dragged horizontally (move the segment left/right); cursor becomes `ew-resize`.
+
+Use `adjustEdgeMiddle` to restrict dragging to middle segments only, preventing the first and last segments (which connect to nodes) from being accidentally moved:
+
+```tsx | pure
+const lf = new LogicFlow({
+ adjustEdgeStartAndEnd: true,
+ adjustEdgeMiddle: true, // Only middle segments can be dragged
+})
+```
+
+| Operation Point | Description |
+|----------------|-------------|
+| Start adjustment (SOURCE) | Drag to reconnect to a different node anchor |
+| End adjustment (TARGET) | Drag to reconnect to a different node anchor |
+| Segment drag regions | Translate the segment horizontally or vertically |
+
+### Bezier Operation Points
+
+In addition to start/end adjustment points, two **Bézier control points** (`sNext` and `ePre`) and their guide lines appear when a bezier edge is selected (rendered by `BezierAdjustOverlay`):
+
+- **sNext** (start control point): connected to the start point by a guide line; drag it to change the curvature direction and magnitude near the start.
+- **ePre** (end control point): connected to the end point by a guide line; drag it to change the curvature direction and magnitude near the end.
+- The two control points are independent of each other.
+
+```tsx | pure
+// BezierAdjustOverlay control-point rendering logic
+getBezierAdjust(bezier: BezierEdgeModel, graphModel: GraphModel) {
+ const [start, sNext, ePre, end] = getBezierPoints(bezier.path)
+ return [
+ // Start side: guide line + sNext control point
+ ,
+ ,
+ // End side: guide line + ePre control point
+ ,
+ ,
+ ]
+}
+```
+
+| Operation Point | Description |
+|----------------|-------------|
+| Start adjustment (SOURCE) | Drag to reconnect to a different node anchor |
+| End adjustment (TARGET) | Drag to reconnect to a different node anchor |
+| sNext (start control point) | Drag to change curve shape near the start |
+| ePre (end control point) | Drag to change curve shape near the end |
+
+### Operation Point Comparison
+
+| Operation Point Type | Line | Polyline | Bezier |
+|---------------------|:----:|:--------:|:------:|
+| Start adjustment (SOURCE) | ✓ | ✓ | ✓ |
+| End adjustment (TARGET) | ✓ | ✓ | ✓ |
+| Segment drag (move segments individually) | ✗ | ✓ | ✗ |
+| Bézier control points (sNext / ePre) | ✗ | ✗ | ✓ |
+
## Selecting built-in edges inherited by custom edges
```tsx | pure
diff --git a/sites/docs/docs/tutorial/basic/edge.zh.md b/sites/docs/docs/tutorial/basic/edge.zh.md
index 4d128ad3d..1c1b38788 100644
--- a/sites/docs/docs/tutorial/basic/edge.zh.md
+++ b/sites/docs/docs/tutorial/basic/edge.zh.md
@@ -18,6 +18,165 @@ toc: content
+## 三种边的渲染形式
+
+### 直线(line)
+
+直线是最简单的边类型,通过 SVG 的 `` 标签直接连接起点与终点,路径唯一确定。
+
+**渲染特点**:
+
+- 底层使用 SVG `` 元素,`x1/y1` 为起点,`x2/y2` 为终点。
+- 路径计算最简:只需 `startPoint` 和 `endPoint` 两个坐标。
+- 选中区域(AppendWidth):以直线为中轴,向两侧各扩展一定宽度,形成矩形点击区,方便用户选中细线。
+
+```tsx | pure
+// LineEdge 的 getEdge 核心渲染
+getEdge() {
+ const { model } = this.props
+ const { startPoint, endPoint } = model
+ return (
+
+ )
+}
+```
+
+### 折线(polyline)
+
+折线(直角折线)是所有线段均为水平或垂直方向的多段线,通过 SVG 的 `` 标签渲染多个折点。
+
+**渲染特点**:
+
+- 底层使用 SVG `` 元素,通过 `points` 属性传入所有折点坐标(格式:`"x1,y1 x2,y2 x3,y3 ..."`)。
+- 路径计算复杂:采用 A* 算法结合曼哈顿距离,自动绕过节点计算最优正交路径,结果存储在 `pointsList` 中。
+- 选中区域(AppendWidth):将折线拆分为每段线段,对每段单独计算矩形扩展区域并叠加。
+
+```tsx | pure
+// PolylineEdge 的 getEdge 核心渲染
+getEdge() {
+ const { model } = this.props
+ const { points } = model // "x1,y1 x2,y2 x3,y3 ..."
+ return (
+
+ )
+}
+```
+
+### 贝塞尔曲线(bezier)
+
+贝塞尔曲线是三次贝塞尔曲线,通过 SVG `` 的 `M...C...` 命令绘制光滑曲线。
+
+**渲染特点**:
+
+- 底层使用 SVG `` 元素,路径格式为 `M startX startY C sNextX sNextY, ePreX ePreY, endX endY`。
+- `pointsList` 固定包含 4 个点:**起点**、**起点控制点(sNext)**、**终点控制点(ePre)**、**终点**。
+- 控制点的初始位置根据起终点所在节点的方位自动计算,使曲线尽量不与节点边框重叠。
+- 选中区域(AppendWidth):在相同路径上绘制一条宽度为 10、颜色透明的曲线,扩大点击范围。
+
+```tsx | pure
+// BezierEdgeModel 的路径生成
+private getPath(points: Point[]): string {
+ const [start, sNext, ePre, end] = points
+ return `M ${start.x} ${start.y}
+ C ${sNext.x} ${sNext.y},
+ ${ePre.x} ${ePre.y},
+ ${end.x} ${end.y}`
+}
+```
+
+## 三种边的操作点区别
+
+"操作点"是指边被选中后,用于调整边形态的交互控件。三种边均支持公共的起终点调整点,但各自还有独特的操作点。
+
+### 公共操作:起终点调整点
+
+三种边都支持起终点调整点,需在初始化时开启 `adjustEdgeStartAndEnd`:
+
+```tsx | pure
+const lf = new LogicFlow({
+ adjustEdgeStartAndEnd: true, // 开启起终点调整功能
+})
+```
+
+开启后,选中边时在**起点**和**终点**各显示一个圆形调整点,拖拽可将边重新连接到其他节点的锚点。
+
+### 直线(line)的操作点
+
+直线**仅有**起终点调整点,无法改变中间路径——因为两点之间直线唯一,没有可调整的中间段。
+
+| 操作点 | 说明 |
+|--------|------|
+| 起点调整点(SOURCE) | 拖拽重新连接到其他节点锚点 |
+| 终点调整点(TARGET) | 拖拽重新连接到其他节点锚点 |
+
+### 折线(polyline)的操作点
+
+折线除起终点调整点外,还支持**线段拖拽**。每个线段均有透明可拖拽区域(由 `getAppendWidth` 生成):
+
+- **水平线段**:只能沿垂直方向拖拽(纵向平移该段);光标变为 `ns-resize`。
+- **垂直线段**:只能沿水平方向拖拽(横向平移该段);光标变为 `ew-resize`。
+
+通过配置 `adjustEdgeMiddle` 可进一步限制只允许拖拽中间线段,防止连接节点的首尾段被意外移动:
+
+```tsx | pure
+const lf = new LogicFlow({
+ adjustEdgeStartAndEnd: true,
+ adjustEdgeMiddle: true, // 仅允许拖拽中间线段,首尾线段不可拖拽
+})
+```
+
+| 操作点 | 说明 |
+|--------|------|
+| 起点调整点(SOURCE) | 拖拽重新连接到其他节点锚点 |
+| 终点调整点(TARGET) | 拖拽重新连接到其他节点锚点 |
+| 各线段拖拽区域 | 沿水平或垂直方向平移对应线段 |
+
+### 贝塞尔曲线(bezier)的操作点
+
+贝塞尔曲线除起终点调整点外,选中时还会显示**两个贝塞尔控制点**(`sNext` 和 `ePre`)及其辅助连线(由 `BezierAdjustOverlay` 渲染):
+
+- **sNext**(起点控制点):通过辅助线与起点相连,拖拽可改变曲线起点侧的弯曲方向和幅度。
+- **ePre**(终点控制点):通过辅助线与终点相连,拖拽可改变曲线终点侧的弯曲方向和幅度。
+- 两个控制点相互独立,可以单独调节。
+
+```tsx | pure
+// BezierAdjustOverlay 中的控制点渲染逻辑
+getBezierAdjust(bezier: BezierEdgeModel, graphModel: GraphModel) {
+ const [start, sNext, ePre, end] = getBezierPoints(bezier.path)
+ return [
+ // 起点侧:辅助线 + sNext 控制点
+ ,
+ ,
+ // 终点侧:辅助线 + ePre 控制点
+ ,
+ ,
+ ]
+}
+```
+
+| 操作点 | 说明 |
+|--------|------|
+| 起点调整点(SOURCE) | 拖拽重新连接到其他节点锚点 |
+| 终点调整点(TARGET) | 拖拽重新连接到其他节点锚点 |
+| sNext(起点控制点) | 拖拽改变曲线起点侧的弯曲形态 |
+| ePre(终点控制点) | 拖拽改变曲线终点侧的弯曲形态 |
+
+### 操作点对比
+
+| 操作点类型 | 直线 | 折线 | 贝塞尔曲线 |
+|-----------|:----:|:----:|:----------:|
+| 起点调整(SOURCE) | ✓ | ✓ | ✓ |
+| 终点调整(TARGET) | ✓ | ✓ | ✓ |
+| 线段拖拽(逐段移动) | ✗ | ✓ | ✗ |
+| 贝塞尔控制点(sNext / ePre) | ✗ | ✗ | ✓ |
+
## 选择自定义边继承的内置边
```tsx | pure