gis-view-webgl2 0.1.7 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -8
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +232 -228
- package/dist/index.js +1 -1
- package/docs/AI/345/257/271/350/257/235/346/261/207/346/200/273.md +49 -0
- package/docs/GisView.md +1 -1
- package/docs/ai/06-/344/274/232/350/257/235/347/264/242/345/274/225/344/270/216/345/244/215/346/237/245/346/226/271/346/263/225.md +48 -0
- package/docs/demos/BasicDemo.vue +2 -2
- package/docs/demos/BatchAddDemo.vue +6 -6
- package/docs/demos/ConnectDemo.vue +164 -33
- package/docs/demos/CopyMergeDemo.vue +27 -14
- package/docs/demos/EventDemo.vue +17 -20
- package/docs/demos/LabelDemo.vue +5 -5
- package/docs/demos/api-index.js +31 -29
- package/docs/demos/gis-view-demo/GisViewDemoCardHeader.vue +1 -1
- package/docs/demos/gis-view-demo/GisViewDemoStage.vue +1 -1
- package/docs/demos/gis-view-demo/panels/DataPanels.vue +1 -1
- package/docs/demos/gis-view-demo/useGisViewDemo.js +31 -33
- package/docs/format/07-/344/272/213/344/273/266/350/275/275/350/215/267/344/270/216/347/244/272/344/276/213/346/225/260/346/215/256.md +8 -7
- package/docs/from0/05-/347/233/270/346/234/272/344/270/216/344/272/244/344/272/222.md +1 -1
- package/docs/from0/07-/351/200/232/351/201/223/345/210/206/347/273/204/344/270/216/345/244/232/345/233/236/347/272/277.md +26 -10
- package/docs/manual/02-/345/235/220/346/240/207/344/270/216/346/225/260/346/215/256.md +1 -1
- package/docs/manual/04-/344/272/213/344/273/266/344/270/216/345/233/236/350/260/203.md +21 -16
- package/docs/manual/06-/346/225/260/346/215/256/344/270/216/345/234/272/346/231/257/346/233/264/346/226/260.md +9 -10
- package/docs/manual/07-/346/214/207/351/222/210/344/270/216/350/246/201/347/264/240/347/274/226/350/276/221.md +54 -31
- package/docs/manual/08-/351/200/211/344/270/255/344/270/216/346/213/220/347/202/271.md +3 -3
- package/docs/manual/09-/351/200/232/351/201/223/344/270/216/345/244/232/345/233/236/347/272/277.md +9 -6
- package/docs/manual/10-/351/200/232/351/201/223/347/274/226/350/276/221/344/270/216/346/226/260/345/242/236.md +226 -493
- package/docs/manual/12-/346/240/207/347/255/276/344/270/216/350/243/205/351/245/260.md +2 -2
- package/docs/manual/14-/350/247/206/345/233/276/344/270/216/347/255/233/351/200/211.md +12 -13
- package/docs/manual/16-/345/256/236/344/276/213/346/226/271/346/263/225/346/200/273/350/241/250.md +23 -21
- package/docs/manual/17-/345/217/202/346/225/260/351/200/237/346/237/245.md +19 -17
- package/docs/manual/18-/351/200/220/346/226/271/346/263/225/347/244/272/344/276/213.md +125 -78
- package/docs/manual/19-/350/257/273/346/225/260/344/270/216/346/213/226/346/213/275/351/242/204/350/247/210.md +1 -1
- package/docs/manual/20-/346/200/247/350/203/275/344/270/216/345/244/247/346/225/260/346/215/256.md +2 -2
- package/docs/manual/21-/350/257/264/346/230/216/344/270/216/345/270/270/350/247/201/351/227/256/351/242/230.md +4 -4
- package/docs/steps/README.md +9 -7
- package/docs/steps/bench-scale.html +1 -1
- package/docs/steps/index.html +6 -6
- package/docs/steps/selftest-actions.html +26 -25
- package/docs/steps/selftest-data.html +1 -1
- package/docs/steps/selftest-demos.html +102 -6
- package/docs/steps/selftest-docs.html +3 -3
- package/docs/steps/selftest-features.html +283 -51
- package/docs/steps/selftest-full.html +3 -3
- package/docs/steps/selftest-labels.html +1 -1
- package/docs/steps/selftest-perf.html +31 -4
- package/docs/steps/selftest-select.html +20 -5
- package/docs/steps/step-05-pick.js +4 -8
- package/docs/steps/step-07-channels.js +3 -5
- package/docs/steps/step-08-labels.js +3 -3
- package/docs/steps/step-10-full.js +3 -3
- package/docs/steps/step-12-events.js +41 -24
- package/package.json +1 -1
|
@@ -61,7 +61,7 @@ view.updateOptions({ channelWaypointDragMode: 'vertex' })
|
|
|
61
61
|
|
|
62
62
|
```js
|
|
63
63
|
view.updateOptions({
|
|
64
|
-
onContextMenu:
|
|
64
|
+
onContextMenu: payload => {
|
|
65
65
|
const context = payload.channelContext
|
|
66
66
|
if (!context) {
|
|
67
67
|
return closeMenu() // 点空白或节点:没有 channelContext,用它把框收掉
|
|
@@ -94,287 +94,218 @@ view.getChannelContext('corridor-1', 'corridor-1::2')
|
|
|
94
94
|
|
|
95
95
|
### 新增通道
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
新增流程按语义拆成两个入口,草稿缺省关闭;写 `features: { channelDraft: true }` 或 `features: 'edit'` 才进得去。程序化 `addChannel()` / `addLine()` 不受这个开关限制。两个入口共用拾取、预览、连续新增与提交状态机,但**入口语义固定,不再通过 `kind` 切换**:
|
|
98
98
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
```
|
|
99
|
+
- `beginAddChannel(options?)`:新建通道。两个节点之间已经有通道时,可按 `existingChannel` 失败、新加一组或并进指定分组。
|
|
100
|
+
- `beginAddLine(options?)`:新建线路。缺省只新建独立线路,不碰 `channels`;显式写 `existingChannel: 'newGroup' / 'joinGroup' / 'auto'` 且两端已有通道时,才把这次新建的回线挂进已有通道。
|
|
101
|
+
- `continueAddChannel(options?)`:只续当前草稿的配置,不能切换这一段是通道还是独立线路。传入旧 `kind` 不生效;当前没有草稿时按 `beginAddChannel` 的通道语义开新一段。
|
|
102
|
+
- 旧写法 `beginAddChannel({ kind: 'line' })` 已不再切换成线路;需要线路请明确调用 `beginAddLine()`。
|
|
104
103
|
|
|
105
|
-
|
|
104
|
+
缺省点第一个节点当起点,一条草稿线跟随光标;点第二个节点进入 `ready` 并给出方案表。`options.from` 可以预指定起点(节点 id / 下标 / `{ id }` / `{ index }`),调用后直接进入 `phase: 'from'`,只需再点终点;找不到起点时草稿不开始并报 warning。草稿期间点空白处继续等待,点回起点不算数,按住拖动仍然平移画布;`Esc`、右键或 `cancelAddChannel()` 退出。
|
|
106
105
|
|
|
107
|
-
|
|
106
|
+
**草稿里的 `select` 不是“落地后选中新线”**:`beginAddChannel({ select: true })` 只让点中的节点同步进选中集(走 `onSelect` / `onSelectChange`);真正落地的新回线是否选中由 `commitAddChannel(..., { select: true })` 或程序化新增方法的 `options.select` 决定,缺省都不改选中集。
|
|
108
107
|
|
|
109
|
-
|
|
110
|
-
| --- | --- | --- | --- |
|
|
111
|
-
| `color` | `string` | 蓝色 | 预览线颜色 |
|
|
112
|
-
| `width` | `number` | `2` | 预览线宽(CSS 像素) |
|
|
113
|
-
| `dot` | `number` | `4` | 两端圆点半径(CSS 像素,`0` 不画) |
|
|
114
|
-
| `arrow` | `boolean` | `false` | 末端是否画方向箭头 |
|
|
115
|
-
| `arrowSize` | `number` | `12` | 箭头大小(CSS 像素) |
|
|
108
|
+
#### 单一通道与已有通道策略
|
|
116
109
|
|
|
117
|
-
|
|
110
|
+
| 配置 | 两端已有通道 | 两端没有通道 |
|
|
111
|
+
| --- | --- | --- |
|
|
112
|
+
| `beginAddChannel()` | 推荐新分组 / 并进可用分组 | 新建通道 |
|
|
113
|
+
| `beginAddChannel({ singleChannel: true })` | 直接阻断,`plan.blocked: true`、`preferred: null` | 仍新建通道 |
|
|
114
|
+
| `beginAddChannel({ existingChannel: 'block' })` | 直接阻断 | 新建通道 |
|
|
115
|
+
| `beginAddChannel({ existingChannel: 'newGroup' })` | 在已有通道里新加一组 | 新建通道 |
|
|
116
|
+
| `beginAddChannel({ existingChannel: 'joinGroup', groupId, groupIndex })` | 并进指定分组;都不写时取当前分组 / 第一个可用分组 | 新建通道 |
|
|
117
|
+
| `beginAddChannel({ existingChannel: 'auto' })` | 有新分组余量就新分组,否则并进可用分组 | 新建通道 |
|
|
118
|
+
| `beginAddLine()` | 独立线路 | 独立线路 |
|
|
119
|
+
| `beginAddLine({ existingChannel: 'newGroup' / 'joinGroup' / 'auto' })` | 把这次新建的回线挂进已有通道的新分组 / 指定分组 / 自动分组 | 独立线路 |
|
|
120
|
+
| `beginAddLine({ existingChannel: 'block' })` | 直接阻断 | 独立线路 |
|
|
121
|
+
|
|
122
|
+
`singleChannel: true` 只给 `beginAddChannel` 补一个缺省的 `existingChannel: 'block'`;显式写了 `existingChannel` 时以显式策略为准。`groupId` 认分组 id,`groupIndex` 从 `0` 起按声明顺序认;两者都写时以 `groupId` 为准。找不到分组、分组已满或余量不足时同样进入阻断,`plan.reason` / `payload.reason` 会写明原因。
|
|
118
123
|
|
|
119
|
-
|
|
124
|
+
阻断后草稿仍停在 `ready`(`blocked: true`、`preferred: null`),不会自动改道偷偷新建:`autoCommit: true` 或手动 `commitAddChannel()` 在缺省 `resolution` 下返回 `ok: false`,并补一条 `phase: 'blocked'`;显式传一个可用的 `resolution` 仍可改道。
|
|
120
125
|
|
|
121
126
|
```js
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
)
|
|
131
|
-
|
|
127
|
+
view.beginAddChannel({ from: 'station-a' })
|
|
128
|
+
view.beginAddChannel({ from: { id: 'station-a' }, select: true })
|
|
129
|
+
view.continueAddChannel({ from: 'station-c' })
|
|
130
|
+
|
|
131
|
+
view.beginAddChannel({ from: 'station-a', singleChannel: true })
|
|
132
|
+
view.beginAddChannel({ from: 'station-a', existingChannel: 'newGroup' })
|
|
133
|
+
view.beginAddChannel({ from: 'station-a', existingChannel: 'joinGroup', groupId: 'corridor-1::2' })
|
|
134
|
+
|
|
135
|
+
view.beginAddLine({ from: 'station-a' })
|
|
136
|
+
view.beginAddLine({ from: 'station-a', existingChannel: 'newGroup' })
|
|
132
137
|
```
|
|
133
138
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
+
> `beginAddChannel` / `beginAddLine` / `continueAddChannel` 的草稿配置只支持预指定起点 `from`,没有 `to`;如果要换终点,重新开一段或在地图上点选。
|
|
140
|
+
|
|
141
|
+
#### 草稿配置
|
|
142
|
+
|
|
143
|
+
`beginAddChannel()` / `beginAddLine()` / `continueAddChannel()` 的 `GisViewChannelDraftOptions`:
|
|
144
|
+
|
|
145
|
+
| 字段 | 类型 | 缺省 | 说明 |
|
|
146
|
+
| --- | --- | --- | --- |
|
|
147
|
+
| `from` | `GisViewPointRef` | 无 | 预指定起点,直接进入 `from` 相位 |
|
|
148
|
+
| `autoCommit` | `boolean` | `false` | 两个节点一选完就按推荐方案落地 |
|
|
149
|
+
| `continuous` | `boolean \| 'chain'` | `false` | 每段落地后自动开下一段;`'chain'` 同时打开 `chain` |
|
|
150
|
+
| `chain` | `boolean` | `false` | 连续新增时以上一段终点当下一段起点;显式 `from` 优先 |
|
|
151
|
+
| `singleChannel` | `boolean` | `false` | 只约束 `beginAddChannel`:已有通道时等价于 `existingChannel: 'block'` |
|
|
152
|
+
| `existingChannel` | `'block' \| 'newGroup' \| 'joinGroup' \| 'auto'` | 无 | 已有通道时的处理策略;`beginAddLine` 用它决定是否挂已有通道 |
|
|
153
|
+
| `groupId` | `string \| number` | 无 | `joinGroup` 的目标分组 id |
|
|
154
|
+
| `groupIndex` | `number` | 无 | `joinGroup` 的目标分组序号(从 `0` 起) |
|
|
155
|
+
| `circuits` | `number` | `1` | 这次新建几回;有效 `lineData` 的条数优先 |
|
|
156
|
+
| `name` | `string` | 按两端节点生成 | 新线路名 |
|
|
157
|
+
| `lineId` | `string \| number` | 按通道 id 生成 | 新回线 id 的旧别名;与 `id` 同时给时以 `id` 为准 |
|
|
158
|
+
| `id` | `string \| number` | 无 | 新回线 id;一次多条时作为种子 |
|
|
159
|
+
| `lineProps` | `Partial<GisViewLine>` | 无 | 所有新回线共用的业务字段 |
|
|
160
|
+
| `linePropsByMember` | `Array<Partial<GisViewLine> \| undefined>` | 无 | 按下标逐条覆盖的线路属性 |
|
|
161
|
+
| `lineData` | `GisViewChannelLineData` | 无 | 第二段线路数据;给了几条这一段就按几条对齐(`circuits` 按它算) |
|
|
162
|
+
| `routing` | `'straight' \| 'orthogonal'` | `'straight'` | 直连或自动正交折线 |
|
|
163
|
+
| `path` | `GisViewCoordinate[]` | 无 | 中间拐点;有效时优先于 `routing` 的自动拐点 |
|
|
164
|
+
| `channelDraftStyle` | `GisViewChannelDraftStyle` | 全局样式 | 本次草稿的预览样式,草稿结束即丢弃 |
|
|
165
|
+
| `handoff` | `boolean` | `false` | `ready` 发完自动收掉草稿,由使用方自己落地 |
|
|
166
|
+
| `select` | `boolean` | `false` | 只控制点中的节点是否同步选中,不控制新回线落地后的选中 |
|
|
167
|
+
| `channelProps` | `Partial<GisViewChannel>` | 无 | 新建通道透传的字段 |
|
|
168
|
+
| `originalEvent` | `Event \| null` | `null` | 原样带进回调载荷 |
|
|
169
|
+
|
|
170
|
+
旧字段 `lineItems` 已移除,不再作为草稿的第二段;请统一写 `lineData`。草稿载荷里的第二段同样叫 `lineData`。
|
|
171
|
+
|
|
172
|
+
`lineData` 与程序化接口的第二段是同一份写法:一条或一批均可,裸字符串 / 数字等价于 `{ id }`,对象里的 `id` 就是该回线 id。未写 id 时,`beginAddChannel` 按通道 id 自动编号,`beginAddLine` 按 `from-to-序号` 自动编号;与已有数据撞 id 时自动加后缀。
|
|
139
173
|
|
|
140
174
|
```js
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
175
|
+
view.beginAddChannel({
|
|
176
|
+
from: 'station-a',
|
|
177
|
+
lineData: [
|
|
178
|
+
{ id: 'line-1', color: '#dd4b2e' },
|
|
179
|
+
{ id: 'line-2', color: '#2ea36b' },
|
|
180
|
+
'line-3'
|
|
181
|
+
]
|
|
182
|
+
})
|
|
147
183
|
```
|
|
148
184
|
|
|
149
|
-
|
|
185
|
+
#### 每一次点击与收尾
|
|
186
|
+
|
|
187
|
+
`onChannelDraftClick` 在草稿里每点一次都发一条:`step === 1` 是刚拿到起点,`step === 2` 是刚拿到终点,`0` 是点在空白或点回起点(`phase: 'pick'`,草稿继续等待)。载荷与 `onChannelDraft` 一致。
|
|
150
188
|
|
|
151
189
|
```js
|
|
152
190
|
view.beginAddChannel()
|
|
153
191
|
.updateOptions({
|
|
154
192
|
onChannelDraftClick: payload => {
|
|
155
|
-
if (payload.step === 1) console.log('起点', payload.from.id
|
|
193
|
+
if (payload.step === 1) console.log('起点', payload.from.id)
|
|
156
194
|
if (payload.step === 2) {
|
|
157
|
-
console.log('终点', payload.to.id,
|
|
158
|
-
view.commitAddChannel(
|
|
195
|
+
console.log('终点', payload.to.id, payload.options)
|
|
196
|
+
view.commitAddChannel(undefined, { select: true })
|
|
159
197
|
}
|
|
160
198
|
}
|
|
161
199
|
})
|
|
162
200
|
```
|
|
163
201
|
|
|
164
|
-
|
|
202
|
+
选完两个节点后草稿只是预览,除非 `autoCommit: true`,否则数据一个字节都不动。收尾方式:
|
|
165
203
|
|
|
166
204
|
- `cancelAddChannel()`:收起草稿并补一条 `phase: 'cancel'`;`endAddChannel()` 静默收起。两者都不写数据。
|
|
167
|
-
- `commitAddChannel()
|
|
168
|
-
- `
|
|
205
|
+
- `commitAddChannel(input?, options?)`:按推荐方案或容器对象落地;草稿里的 `routing` / `path` 会一起带上。
|
|
206
|
+
- `addChannel()` / `addChannelGroupLines()` / `joinChannelGroupLines()` / `addLine()`:绕开草稿提交,自己按草稿读数落地;落地后记得 `endAddChannel()` 收起假通道。
|
|
169
207
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
const middle = draft.path ?? []
|
|
174
|
-
const fullPath = middle.length ? [draft.from.coordinate, ...middle, draft.to.coordinate] : null
|
|
175
|
-
|
|
176
|
-
// ① 独立线路:addLines 收现成数据对象,path 要完整(含两端)
|
|
177
|
-
view.addLines([{
|
|
178
|
-
id: 'visual-line-1',
|
|
179
|
-
from: draft.from.id,
|
|
180
|
-
to: draft.to.id,
|
|
181
|
-
...(fullPath ? { path: fullPath } : {}),
|
|
182
|
-
color: '#2f6fd0',
|
|
183
|
-
direction: { count: 1, size: 12 }
|
|
184
|
-
}])
|
|
185
|
-
view.endAddChannel()
|
|
186
|
-
|
|
187
|
-
// ② 通道:addChannels 的 path 只写中间拐点(与 ① 二选一)
|
|
188
|
-
// view.addChannels([{ from: draft.from.id, to: draft.to.id, kind: 'channel', circuits: 2, path: middle }])
|
|
189
|
-
// view.endAddChannel()
|
|
190
|
-
}
|
|
191
|
-
```
|
|
208
|
+
#### 连续新增
|
|
209
|
+
|
|
210
|
+
`beginAddChannel({ continuous: true })` 之后,一段落地(或提交失败)会原地重开并发送 `phase: 'restart'`;继续点下一对节点即可。`continuous: 'chain'`(或 `chain: true`)会把上一段终点作为下一段起点。
|
|
192
211
|
|
|
193
|
-
|
|
212
|
+
`autoCommit` 与连续新增正交,可以同时使用。`continueAddChannel()` 可手动开下一段;传 `lineData` 会按新条数更新这一段,传 `from` 可改起点,但不会再切换入口语义。
|
|
194
213
|
|
|
195
214
|
```js
|
|
196
|
-
view.beginAddChannel({ autoCommit: true, continuous: 'chain' })
|
|
197
|
-
view.continueAddChannel({
|
|
198
|
-
view.cancelAddChannel()
|
|
215
|
+
view.beginAddChannel({ autoCommit: true, continuous: 'chain' })
|
|
216
|
+
view.continueAddChannel({ from: 'station-c' })
|
|
217
|
+
view.cancelAddChannel()
|
|
199
218
|
```
|
|
200
219
|
|
|
201
|
-
|
|
220
|
+
#### `ready` 载荷与交接
|
|
202
221
|
|
|
203
|
-
|
|
204
|
-
- **删掉那条示例假通道**:`view.endAddChannel()`(静默收掉、不补事件)/ `view.cancelAddChannel()`(收掉并补一条 `phase: 'cancel'`)—— 提前结束不新建就是这两条;`beginAddChannel({ handoff: true })` 是「ready 发完自动收」的自动版。
|
|
205
|
-
- **让点中的节点看起来是选中的**:`beginAddChannel({ select: true })` —— 起点先选上、第二个节点之后两个都在,走的是与普通点击同一份选中状态与回调(`onSelect` / `onSelectChange` 照发,`getSelections()` 立刻能读回来);它与 `features.select` 开关无关(和 `selectFeatures()` 接口一样是显式调用)。
|
|
222
|
+
`phase: 'ready'` 时:两个节点在 `payload.from` / `payload.to`;`payload.hasChannel` / `payload.hasGroup` 表示两端是否已有通道 / 分组;`payload.groups`、`payload.group`、`payload.channel` 与 `getChannelGroups()` / `getChannelBetween()` 同一份读数;已有通道 id 在 `payload.existingChannelId`。
|
|
206
223
|
|
|
207
|
-
|
|
224
|
+
`handoff: true` 时,`ready` 发完立即收掉假通道(静默结束,不补 `cancel`),使用方在回调里自己落地:
|
|
208
225
|
|
|
209
226
|
```js
|
|
210
|
-
view.beginAddChannel({ handoff: true, select: true })
|
|
227
|
+
view.beginAddChannel({ handoff: true, select: true })
|
|
211
228
|
view.updateOptions({
|
|
212
229
|
onChannelDraft: payload => {
|
|
213
|
-
if (payload.phase !== 'ready')
|
|
214
|
-
return
|
|
215
|
-
}
|
|
216
|
-
// 两个节点之间已经有分组:并进已有通道(新加一组 / 并进某一组由界面自己选)
|
|
230
|
+
if (payload.phase !== 'ready') return
|
|
217
231
|
if (payload.hasGroup) {
|
|
218
232
|
const target = payload.group?.id ?? payload.channel?.groups?.[0]?.id
|
|
219
233
|
view.joinChannelGroupLines(payload.channel.id, target, [{ id: 'line-9' }])
|
|
220
234
|
return
|
|
221
235
|
}
|
|
222
|
-
// 假通道已经收掉了,这里走自己的真实新建(dataChange / 撤销都以这次 addChannel 为准)
|
|
223
236
|
const result = view.addChannel(
|
|
224
237
|
{ from: payload.from.id, to: payload.to.id, name: '手填通道', id: 'channel-9' },
|
|
225
238
|
[{ id: 'line-1', color: '#dd4b2e' }, { id: 'line-2', color: '#2ea36b' }],
|
|
226
|
-
{ id: 'group-1' }
|
|
239
|
+
{ id: 'group-1' },
|
|
240
|
+
{ select: true }
|
|
227
241
|
)
|
|
228
|
-
if (result.ok)
|
|
229
|
-
console.log('落地:', result.channelId, result.lineIds, result.groupId)
|
|
230
|
-
}
|
|
231
|
-
if (!result.ok) {
|
|
232
|
-
console.warn(result.reason) // 失败原因与 commitAddChannel 同一套口径
|
|
233
|
-
}
|
|
242
|
+
if (!result.ok) console.warn(result.reason)
|
|
234
243
|
}
|
|
235
244
|
})
|
|
236
245
|
```
|
|
237
246
|
|
|
238
|
-
|
|
239
|
-
- 与 `autoCommit` 同时给时 `autoCommit` 先落地(草稿已经被 `commitAddChannel` 收掉 / 重开,交接就不再触发);交接模式也不会自动开下一段,想连着加就每段各自 `beginAddChannel`。
|
|
240
|
-
- 交接模式下草稿直接结束,所以 `getAddChannelDraft()` 在事件回调之后就是 `null`;要拿两个节点请只认载荷(`payload.from` / `payload.to`)。
|
|
247
|
+
交接模式不会自动开下一段;与 `autoCommit` 同时给时先自动落地,交接不再触发。交接后 `getAddChannelDraft()` 已是 `null`,两个节点只认回调载荷。
|
|
241
248
|
|
|
242
|
-
|
|
249
|
+
#### 程序化新增
|
|
243
250
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
一次加多条时结果里用 `lines` / `lineIds`(`line` / `lineId` 是第一条):多回的名字按 `<名字> #1 / #2…` 排,id 逐条查重(撞车自动往后排),落地之后整批选中(`getSelectionData().ids` 读回)。
|
|
251
|
+
| 方法 | 入参 | 说明 |
|
|
252
|
+
| --- | --- | --- |
|
|
253
|
+
| `addChannel(spec, lineData?, group?, options?)` | `spec: GisViewChannelAddSpec`;`lineData?: GisViewChannelLineData`;`group?: GisViewChannelAddGroup \| GisViewChannelAddGroup[]`;`options?: { emit?: boolean; select?: boolean }` | **只新建一个通道**。`spec` 为 `{ from, to, name?, id?, channelProps?, path?, routing?, lineData?, group? }`;对象上的 `lineData` / `group` 是第二 / 第三段别名。两端已有通道时整条失败,`reason` 指路下面两条方法 |
|
|
254
|
+
| `addChannelGroupLines(channelId, lineData?, groupInfo?, options?)` | `groupInfo?: { id?, groupId?, path?, ... }`;`options?: { emit?: boolean; select?: boolean }` | 在已有通道里新加一组;缺省组 id 为 `${通道 id}::N`,缺省不带拐点 |
|
|
255
|
+
| `joinChannelGroupLines(channelId, groupId?, lineData?, options?)` | `groupId` 认分组 id,也认从 `0` 起的序号;`options?: { emit?: boolean; select?: boolean }` | 把新回线并进已有分组;不传时选第一个还有余量的分组 |
|
|
256
|
+
| `addChannelGroups(channelId, groups, options?)` | 每项 `{ id?, groupId?, path?, lineData? \| lines?, ... }`;`options?: { emit?: boolean; label?: string; select?: boolean }` | 一次新加多组;每项只认 `lineData` / `lines`,旧 `lineItems` 会让整批明确失败且不写数据 |
|
|
257
|
+
| `addChannels(input, options?)` | 一条或一批 `GisViewChannelAddSpec`(每项写法同 `addChannel`);`options?: { emit?: boolean; select?: boolean }` | 批量只新建通道;逐条落地、只重排一次、只记一步历史 |
|
|
258
|
+
| `addLine(spec, lineData?, options?)` | `spec: GisViewLineAddSpec` 为 `{ from, to, name?, id?, lineProps?, path?, routing?, lineData? }`;`options?: { emit?: boolean; select?: boolean }` | 独立线路,不挂任何通道;落地走追加式引擎路径,可在已有通道声明时增线 |
|
|
259
|
+
| `addPoint(item, options?)` / `addPoints(items, options?)` / `addLines(items, options?)` | `options?: { emit?: boolean; select?: boolean }` | 直接追加现成数据对象;不改通道声明 |
|
|
255
260
|
|
|
256
|
-
|
|
261
|
+
所有程序化新增方法缺省都**不选中**新要素。要选中时显式传 `options.select: true`;批量方法只触发一次选中。
|
|
257
262
|
|
|
258
263
|
```js
|
|
259
|
-
view.addChannel(
|
|
260
|
-
from: 'station-a', to: 'station-b',
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
{ id: 'third', color: '#2ea36b' } // 第 3 回:换色 + 指定 id
|
|
266
|
-
]
|
|
267
|
-
})
|
|
268
|
-
// → lines:[ { id: '…-0', name: '第一回', color: '#dd4b2e', width: 5 },
|
|
269
|
-
// { id: '…-1', name: '甲通道 #2', color: '#f4a259', width: 3 },
|
|
270
|
-
// { id: 'third', name: '甲通道 #3', color: '#2ea36b', width: 3 } ]
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
`linePropsByMember[i].id` 只是**种子**:真的撞上已有 id 时仍然由 `uniqueLineId` 往后排(不写就按通道 id 自动编号)。`from` / `to` 恒为这一次的两个节点,逐条属性改不了它们。
|
|
274
|
-
|
|
275
|
-
**连同线路一起新建(第二段 `lineItems`)**:`addChannel(input, lineItems)` / `addLine(input, lineItems)` 与 `updateChannel(id, patch, linePatches, lineIds?)` 同一个直觉 —— 第二段是一条或一批逐条属性(每项可以只写一个 id:裸字符串 / 数字按 `{ id }` 收,与新签名的线路数组同一份归一),落地时逐条对应到新建的回线上;**给了几条就建几条**(`circuits` 忽略)。它与 `linePropsByMember` 是同一份写法(两者同下标都写时第二段优先),区别只在放哪儿:`linePropsByMember` 是入参里的字段(`addChannels` 的每一项也能写),第二段是方法签名上的那一格。草稿侧对应 `beginAddChannel({ lineItems })` / `continueAddChannel({ lineItems })`(载荷里带 `lineItems`,重开后这一段仍按它的条数对齐)。
|
|
264
|
+
const channelResult = view.addChannel(
|
|
265
|
+
{ from: 'station-a', to: 'station-b', name: '甲通道', id: 'channel-9' },
|
|
266
|
+
[{ id: 'line-1' }, { id: 'line-2' }],
|
|
267
|
+
{ id: 'group-1' },
|
|
268
|
+
{ select: true }
|
|
269
|
+
)
|
|
276
270
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
view.
|
|
280
|
-
{ id: '
|
|
281
|
-
{
|
|
282
|
-
])
|
|
283
|
-
|
|
284
|
-
view.addLine({ from: 'station-a', to: 'station-b'
|
|
271
|
+
view.addChannelGroupLines('corridor-1', [{ id: 'c-7' }], { id: 'group-2' }, { select: true })
|
|
272
|
+
view.joinChannelGroupLines('corridor-1', 'corridor-1::2', [{ id: 'c-8' }])
|
|
273
|
+
view.addChannelGroups('corridor-1', [
|
|
274
|
+
{ id: 'group-3', lineData: [{ id: 'c-9' }] },
|
|
275
|
+
{ lines: ['c-10'] }
|
|
276
|
+
], { select: true })
|
|
277
|
+
|
|
278
|
+
view.addLine({ from: 'station-a', to: 'station-b', name: '三回' }, [
|
|
279
|
+
{ id: 'solo-1' },
|
|
280
|
+
{ id: 'solo-2' },
|
|
281
|
+
{ id: 'solo-3' }
|
|
282
|
+
], { select: true })
|
|
283
|
+
|
|
284
|
+
view.addPoints([{ id: 'p-new', x: 10, y: 20 }], { select: true })
|
|
285
|
+
view.addLines([{ id: 'l-new', from: 'p-new', to: 'station-b' }], { select: true })
|
|
285
286
|
```
|
|
286
287
|
|
|
287
|
-
|
|
288
|
+
**`addChannel` 只负责新建**:两个节点之间已经有通道时返回 `ok: false`,`plan` 里带 `hasChannel` / `hasGroup` / `groups` / `channel`。要新加一组用 `addChannelGroupLines`,并进已有分组用 `joinChannelGroupLines`。
|
|
288
289
|
|
|
289
|
-
`
|
|
290
|
+
**回线 id 的来历**:`addChannel` 第一段的 `id` 是**通道 id**,不是回线 id 种子;回线 id 来自第二段每项的 `id`,没写就按通道 id 自动编号。`addLine` 第一段的 `id` 是回线 id 种子;一次多条时自动展开,第二段每项自己的 `id` 优先。
|
|
290
291
|
|
|
291
|
-
|
|
292
|
-
| --- | --- | --- | --- |
|
|
293
|
-
| `from` | `GisViewPointRef` | 无 | 预指定起点(id / 下标 / `{ id }` / `{ index }`),直接进 `from` 相位;找不到时报 warning 且不开始 |
|
|
294
|
-
| `autoCommit` | `boolean` | `false` | 两个节点一选完就按推荐方案自动落地,不用再调 `commitAddChannel()` |
|
|
295
|
-
| `continuous` | `boolean \| 'chain'` | `false` | 每段落地后自动开下一段;`'chain'` 等价于同时 `chain: true` |
|
|
296
|
-
| `chain` | `boolean` | `false` | 连续新增时以上一段终点当下一段起点;显式 `from` 优先于它 |
|
|
297
|
-
| `kind` | `'channel' \| 'line'` | `'channel'` | 新建通道 / 回线,或新建不挂通道的独立线路 |
|
|
298
|
-
| `circuits` | `number` | `1` | 一次新建几回;`lineItems` 给了有效项时按它的条数对齐 |
|
|
299
|
-
| `name` | `string` | 按两端节点生成 | 新线路名 |
|
|
300
|
-
| `lineId` | `string \| number` | 按通道 id 生成 | 新回线 id 的兼容别名;与 `id` 二选一 |
|
|
301
|
-
| `id` | `string \| number` | 无 | 新回线 id;与 `lineId` 同时给时优先 |
|
|
302
|
-
| `lineProps` | `Partial<GisViewLine>` | 无 | 透传给每条新回线的业务字段(颜色、宽度、电压等级…) |
|
|
303
|
-
| `linePropsByMember` | `Array<Partial<GisViewLine> \| undefined>` | 无 | 逐回属性,第 i 项只盖在第 i 条上;与 `createChannels` 同名同义 |
|
|
304
|
-
| `lineItems` | `GisViewChannelLineItems` | 无 | 连同线路一起新建的一条 / 一批;给了几条就建几条 |
|
|
305
|
-
| `routing` | `'straight' \| 'orthogonal'` | `'straight'` | 直连,或自动补一个先横后纵的拐点 |
|
|
306
|
-
| `path` | `GisViewCoordinate[]` | 无 | 中间拐点(不含两端);有效时优先于 `routing` 的自动拐点 |
|
|
307
|
-
| `channelDraftStyle` | `GisViewChannelDraftStyle` | 全局 `channelDraftStyle` | 本次草稿的预览样式,草稿结束即丢弃;含两端示例点 `dots` 与示例线路层级 `layer`,见下文「示例点与层级」 |
|
|
308
|
-
| `handoff` | `boolean` | `false` | `ready` 发完就收掉假通道,由使用方自己落地;与 `autoCommit` 同给时先自动落地 |
|
|
309
|
-
| `select` | `boolean` | `false` | 点节点时同步进选中集(走 `onSelect` / `onSelectChange`);预指定 `from` 时起点当场选中 |
|
|
310
|
-
| `channelProps` | `Partial<GisViewChannel>` | 无 | 新通道透传字段(宽度、节点宽度、偏移方式…) |
|
|
311
|
-
| `originalEvent` | `Event \| null` | `null` | 触发这次草稿的原始事件,原样带进回调载荷 |
|
|
292
|
+
**`linePropsByMember` 与 `lineData`**:二者可以同时写,按下标合并,`lineData[i]` 优先。`linePropsByMember[i]` 与 `lineData[i]` 都只作用于第 i 条回线;单条自己的 `name`、`color`、`width`、`opacity`、`id` 与任意业务字段都会原样落地。
|
|
312
293
|
|
|
313
294
|
```js
|
|
314
|
-
view.beginAddChannel({
|
|
315
|
-
from: 'station-a', // 预指定起点:接下来只点终点;不写则点两次
|
|
316
|
-
autoCommit: false, // true:两个节点一选完就按推荐方案自动落地,不用再调 commitAddChannel
|
|
317
|
-
name: '新增通道', // 新线路名,缺省按两端节点拼
|
|
318
|
-
lineId: 'new-line-1', // 新回线 id,缺省按通道 id 生成(撞车自动加后缀)
|
|
319
|
-
lineProps: { color: '#ff7a45', width: 3 }, // 新回线透传的业务字段
|
|
320
|
-
// 逐条回线的属性:第 i 项只管第 i 回,盖在 lineProps 之上(与 createChannels 同名同义)
|
|
321
|
-
linePropsByMember: [{ name: '第一回', color: '#dd4b2e' }, { color: '#2ea36b', width: 4 }],
|
|
322
|
-
channelProps: { nodeWidth: 1 } // 新建通道时透传的通道字段
|
|
323
|
-
})
|
|
324
|
-
|
|
325
|
-
view.updateOptions({
|
|
326
|
-
// 草稿的每一步都走这支回调:start / from / ready / cancel / commit / blocked
|
|
327
|
-
onChannelDraft: payload => {
|
|
328
|
-
if (payload.phase === 'from') {
|
|
329
|
-
// 两个节点的读数:index(points 里的下标)、id、item(节点数据对象)、coordinate
|
|
330
|
-
console.log('起点', payload.from.id, payload.from.item?.name, payload.from.coordinate)
|
|
331
|
-
}
|
|
332
|
-
if (payload.phase === 'ready') {
|
|
333
|
-
// 选好两个节点:options 是全部方案、preferred 是推荐方案
|
|
334
|
-
console.log(payload.from.id, payload.to.id, payload.options, payload.preferred)
|
|
335
|
-
// blocked 为 true 时只能放弃,reason 说明原因(同一个节点 / 已有通道的每个方案都不可用)
|
|
336
|
-
// 手动提交:resolution 缺省用 preferred,也可以给 { type: 'joinGroup', groupId }
|
|
337
|
-
const chosen = payload.options.find(option => option.type === 'joinGroup' && option.enabled)
|
|
338
|
-
if (chosen) {
|
|
339
|
-
// 方案读数是 { type, enabled, count, lineIds, ... },不能整条回传;只取 resolution 认识的四个键
|
|
340
|
-
view.commitAddChannel({
|
|
341
|
-
type: chosen.type,
|
|
342
|
-
groupId: chosen.groupId,
|
|
343
|
-
groupIndex: chosen.groupIndex,
|
|
344
|
-
channelId: chosen.channelId
|
|
345
|
-
})
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
if (payload.phase === 'commit') {
|
|
349
|
-
// 落地结果:line 是写进 lines 的新回线(已自动选中)
|
|
350
|
-
console.log(payload.lineId, payload.channelId, payload.groupId, payload.lineIndex)
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
})
|
|
354
|
-
|
|
355
|
-
// 程序化新增(新签名):不用点节点,按 from / to 直接落到数据上(onChannelDraft 一样收到 phase: 'commit')
|
|
356
295
|
view.addChannel(
|
|
357
|
-
{ from: 'station-a', to: 'station-b', name: '甲通道'
|
|
358
|
-
[
|
|
359
|
-
|
|
296
|
+
{ from: 'station-a', to: 'station-b', name: '甲通道' },
|
|
297
|
+
[
|
|
298
|
+
{ id: 'line-a', name: '第一回', color: '#dd4b2e' },
|
|
299
|
+
{ id: 'line-b', color: '#2ea36b' }
|
|
300
|
+
]
|
|
360
301
|
)
|
|
361
|
-
// 并进已有通道 / 独立线路:走拆出来的专门方法(或旧写法)
|
|
362
|
-
view.addChannelGroupLines('corridor-1', [{ id: 'c-7' }]) // 新加一组
|
|
363
|
-
view.joinChannelGroupLines('corridor-1', 'corridor-1::2', [{ id: 'c-8' }]) // 并进某一组
|
|
364
|
-
view.addChannel({ from: 'station-a', to: 'station-b', circuits: 3 }) // 旧写法照旧(按方案表)
|
|
365
|
-
|
|
366
|
-
// 只想问「这两个节点能怎么加」:拿到的是与草稿里同一份方案表(节点找不到时返回 null)
|
|
367
|
-
const plan = view.getChannelAddOptions('station-a', 'station-b')
|
|
368
302
|
```
|
|
369
303
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
- 提交(`commitAddChannel`)与程序化新增(`addChannel` / `addLine`)返回同一份结果(草稿里的 `routing` / `path` 会自动带上):`{ ok, reason?, plan, resolution, kind, circuits, line, lineId, lines, lineIds, lineIndex, channelId, groupId, channelLineIds, channelIndex }`(`kind: 'line'` 时 `channelId` 为 `null`、`resolution.type` 为 `'newLine'`;`channelLineIds` 是落地后这条通道的**完整成员表** —— 并进已有通道时就是「更新过的 `lineIds` 数组」,独立线路为 `null`);落地之后草稿自动结束,`onChannelDraft` 再发一条 `phase: 'commit'`(失败时发 `blocked`,载荷里同样带 `channelLineIds`),新回线自动选中,之后用 `getData()` / `onWaypointChange` / `updateLine()` 像普通线路一样改。
|
|
376
|
-
- **移除新增**:`removeLine(lineId)` 把刚落地的这条回线从数据里摘掉,通道声明(`lineIds` 与 `groups`)一起改,通道一条回线都不剩就整条删掉;`removeChannel(channelId)` 整条通道一起删。两个方法都返回结果对象(`{ ok, line / lineIds, channelId, removedChannel, reason? }`),并且已经处理好选中下标 —— 删掉线路之后 `getSelections()` 不会指到别的线上。
|
|
377
|
-
- `getAddChannelDraft()` 读当前草稿(没有草稿时为 `null`);方案表也可以直接问:`getChannelAddOptions(from, to, count?, kind?)`,实例层按节点 id、引擎层同名方法按下标;只要「这两个点之间到底有没有通道 / 有几组」的读数(不做方案判断)用 `getChannelBetween(from, to)` —— 有通道时 `hasChannel: true`、`channel` / `groups` / `groupCount` / `currentGroupId` 与方案表同一份,没有通道时 `hasChannel: false` / `channel: null` / `groups: []`,端点认不出来返回 `null`。
|
|
304
|
+
**路径口径**:`addLine` 的 `routing: 'orthogonal'` 会补一个先横后纵的 90° 拐点;`path` 一律按中间拐点解释,独立线路落地成 `[起点, ...中间拐点, 终点]` 的完整折线。`addChannel` / `addChannelGroupLines` 的新建通道 / 新分组只把中间拐点写进通道骨架,首尾仍由两端节点坐标给出。逐条回线自己写了 `path` 时以它为准。
|
|
305
|
+
|
|
306
|
+
**删除的旧入参**:`addChannel` 不再接受 `circuits`、`count`、`resolution`、`kind`、`channelId`、`groupId`、`groupIndex`、`lineId`、`lineName`、`channelName`、`lineProps`、`linePropsByMember`、`lineItems`、`newGroup`;`addLine` 不再接受 `circuits`、`count`、`resolution`、`kind`、通道字段、`lineId`、`lineName`、`lineItems`、`linePropsByMember`。`commitAddChannel` 的旧顶层分派字段同样移除。命中这些字段时方法明确失败且不写数据;请改用第二段 `lineData`、第三段 `group` / `channelGroups`,或换用拆分后的方法。
|
|
307
|
+
|
|
308
|
+
**余量计算**:`getChannelAddOptions(from, to, count?, kind?)` 的 `count` 是本次回线数;`newGroup` 要求还能新分组且 `count <= channelGroupMaxLines`,`joinGroup` 要求目标分组余量足够。`kind: 'line'` 时方案表为空、`preferred: null`,只有两端相同才 `blocked`。
|
|
378
309
|
|
|
379
310
|
**示例点与层级(`channelDraftStyle`)**
|
|
380
311
|
|
|
@@ -382,302 +313,118 @@ const plan = view.getChannelAddOptions('station-a', 'station-b')
|
|
|
382
313
|
|
|
383
314
|
`channelDraftStyle.layer` 决定示例线路画在真实节点的哪一侧:`'above'`(默认)连同箭头 / `customDraw` 一起压在真实节点上;`'below-points'` 先画示例线、箭头与 `customDraw`,再把真实节点整层盖上去,示例线因此位于实际节点层级之下。示例点不受这个开关影响,始终在真实节点之后绘制,保证两端仍看得见。
|
|
384
315
|
|
|
385
|
-
#### `commitAddChannel
|
|
316
|
+
#### `commitAddChannel`:唯一对象契约
|
|
386
317
|
|
|
387
318
|
```ts
|
|
388
|
-
commitAddChannel(
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
| { type?: 'newChannel' | 'newGroup' | 'joinGroup' | 'newLine'; groupId?: string | number; groupIndex?: number; channelId?: string | number }
|
|
393
|
-
| GisViewLine // 直接线路对象
|
|
394
|
-
| GisViewChannel // 直接通道对象(必须有 lineIds)
|
|
395
|
-
| GisViewChannelAddCommitInput // 容器写法
|
|
396
|
-
| undefined | null
|
|
397
|
-
|
|
398
|
-
options?: {
|
|
399
|
-
auto?: boolean
|
|
400
|
-
continuous?: boolean
|
|
401
|
-
originalEvent?: Event | null
|
|
402
|
-
}
|
|
319
|
+
commitAddChannel(
|
|
320
|
+
input?: GisViewChannelAddCommitInput,
|
|
321
|
+
options?: { auto?: boolean; continuous?: boolean; originalEvent?: Event | null; select?: boolean }
|
|
322
|
+
): GisViewChannelAddResult
|
|
403
323
|
```
|
|
404
324
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
1. `beginAddChannel(options?)` 进入草稿,或由 `continueAddChannel(options?)` 开出下一段。
|
|
408
|
-
2. 通过点击选好起点 / 终点;写了 `options.from` 时起点已预选,只需再点终点。草稿配置只支持 `from`,没有 `to`;写 `{ from, to }` 时 `to` 会被忽略。
|
|
409
|
-
3. `getAddChannelDraft()` 返回 `phase: 'ready'`,且 `plan`、`from`、`to` 都有值;`onChannelDraft` 也会收到同一次 `ready`。
|
|
410
|
-
4. 调 `commitAddChannel(...)`。成功后草稿结束、新回线自动选中;连续模式则在原地重开下一段。
|
|
411
|
-
|
|
412
|
-
以下两条任一不满足时不会写数据:
|
|
413
|
-
|
|
414
|
-
| 情况 | 返回 | 草稿 |
|
|
415
|
-
| --- | --- | --- |
|
|
416
|
-
| 功能开关 `channelDraft` 关着 | `{ ok: false, reason: '新增通道已被功能开关关闭' }` | 保留 |
|
|
417
|
-
| 没有草稿、仍在 `start` / `from` / `pick`,或没有可选方案 | `{ ok: false, reason: '还没有选好两个节点' }` | 保留 |
|
|
418
|
-
|
|
419
|
-
**五种写法一览**。识别顺序是:先认无参 / 旧 resolution;其余对象先看有没有容器键,有就按容器处理;没有容器键再按 `lineIds` 或线路形状识别直接对象;实在认不出的对象最后仍交回 `resolution`。所以只要写成下列任一形状,就不需要先调 `addLine` / `addChannel`:
|
|
420
|
-
|
|
421
|
-
| 写法 | 识别条件 | 缺省落地方式 | 典型用途 |
|
|
422
|
-
| --- | --- | --- | --- |
|
|
423
|
-
| 无参 | `input` 为 `undefined` / `null` | 用草稿的 `preferred` 方案 | 接受界面推荐的「新通道 / 新分组 / 并入某组」 |
|
|
424
|
-
| 旧 resolution | 字符串;或只含非 `undefined` 的 `type` / `groupId` / `groupIndex` / `channelId` 的对象 | 按方案表挑一条;`'auto'` 的优先级是 `newChannel → newGroup → joinGroup` | 让用户明确选「新通道 / 新分组 / 并入哪组」 |
|
|
425
|
-
| 直接线路对象 | 普通对象、没有 `lineIds` 数组,且至少有一个:`kind: 'line'`、`path` 数组、`from`、`to`、`start`、`end` | 按独立线路落地,不走通道方案表 | 最后一步直接把业务线路对象交给组件 |
|
|
426
|
-
| 直接通道对象 | 普通对象且 `Array.isArray(lineIds)`;同时不能再出现容器键 `channel` / `line` / `lines` / `lineData` / `lineItems` / `channelGroups` / `group` / `channelProps` / `resolution` | 缺省 `resolution: 'newChannel'`;`lineIds` 是回线 id 种子,`groups` 是分组声明 | 一次写入一条新通道及其全部成员 |
|
|
427
|
-
| 容器对象 | 出现任一容器键:`channel` / `line` / `lines` / `lineData` / `lineItems` / `channelGroups` / `group` / `channelProps` / `resolution`;只写 `lineProps` 也会按容器处理 | 各段分别覆盖草稿;`resolution` 不写时沿用草稿推荐方案 | 需要逐条回线字段、显式覆盖 `routing`,或把通道提交到已有分组 |
|
|
428
|
-
|
|
429
|
-
> 空对象 `{}` 不是「新建通道」,会按旧 resolution 交给方案表(通常得到「指定的通道 / 分组没有可用方案」)。想接受推荐方案请直接不传参。直接线路对象里的 `start` / `end` 只参与形状识别,**不会**替代 `from` / `to`;要让落地点与草稿不同,请写 `from` / `to`。
|
|
430
|
-
|
|
431
|
-
**旧 resolution 的字符串与对象**
|
|
325
|
+
调用前草稿必须已经 `ready`。第一个参数只接受**一个对象**(`undefined` / `null` 表示全部沿用草稿);字符串、数组或旧版直接线路 / 直接通道对象都会明确失败,不写数据。通道与线路对象分别放在 `channel` / `line` / `lines` / `lineData` 里。
|
|
432
326
|
|
|
433
|
-
|
|
|
327
|
+
| 字段 | 含义 |
|
|
434
328
|
| --- | --- |
|
|
435
|
-
|
|
|
436
|
-
| `
|
|
437
|
-
| `
|
|
438
|
-
| `
|
|
439
|
-
| `
|
|
440
|
-
| `
|
|
441
|
-
| `
|
|
442
|
-
| `
|
|
443
|
-
| `
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
})
|
|
470
|
-
```
|
|
471
|
-
|
|
472
|
-
> `ready` 里的 `option` 是**方案读数**,不是可直接回传的 `resolution`。建议固定只取四个定位字段;整条传进来时,带 `lineIds` 的方案可能被识别成直接通道对象,其余带容器键的对象也可能走成容器,而不是按方案表选组。
|
|
473
|
-
|
|
474
|
-
#### 直接线路对象:字段怎么分、`path` 怎么算
|
|
475
|
-
|
|
476
|
-
直接线路对象面向「最后一步已经有一份线路业务数据」的场景。它不要求先建独立线路草稿;只要当前草稿已经 `ready`,传入对象就会按 `kind: 'line'` 落地一条不挂通道的线路。
|
|
477
|
-
|
|
478
|
-
| 对象字段 | 去向 | 说明 |
|
|
479
|
-
| --- | --- | --- |
|
|
480
|
-
| `from` / `to` | 新线路两端 | 覆盖草稿两端;必须是数据里真实存在的节点 id。两端相同会按方案表给出 `blocked` 原因 |
|
|
481
|
-
| `id` | 新回线 id 种子 | 与 `options.lineId` 同义;与已有线路撞车时自动改成 `-1` / `-2` |
|
|
482
|
-
| `name` | 新线路名 | 不写时沿用草稿名(草稿缺省按两端节点生成) |
|
|
483
|
-
| `path` | **中间拐点** | 和草稿的 `path` 同一口径:首尾仍由 `from` / `to` 覆盖;要整条现成折线请用容器里的 `lines: [{ id, path: [首, …, 尾] }]` |
|
|
484
|
-
| `lineProps` | 额外线路字段 | 最后合并,优先级高于对象上的普通业务字段 |
|
|
485
|
-
| 其余字段(`color` / `width` / `lineType` / `voltageLevel`…) | `lineProps` | 原样透传到每一条新回线,可参与热力图、提示、筛选 |
|
|
486
|
-
| `kind` | 只用于识别 | 写 `'line'` 可让一个没有 `from` / `to` / `path` 的对象也按独立线路解释 |
|
|
487
|
-
|
|
488
|
-
```js
|
|
489
|
-
// 直接把业务对象交给草稿提交:虚线、颜色、线宽和自定义字段都会写进新线路
|
|
490
|
-
const result = view.commitAddChannel({
|
|
491
|
-
id: 'drop-line-1',
|
|
492
|
-
name: '备用联络线',
|
|
493
|
-
from: 'station-a',
|
|
494
|
-
to: 'station-b',
|
|
495
|
-
color: '#ff7a45',
|
|
496
|
-
width: 3,
|
|
497
|
-
lineType: 'dashed',
|
|
498
|
-
voltageLevel: '10kV',
|
|
499
|
-
// 中间拐点,不含首尾;首尾仍是 station-a / station-b 的坐标
|
|
500
|
-
path: [[116.72, 39.91], [116.86, 39.95]]
|
|
501
|
-
})
|
|
502
|
-
|
|
503
|
-
console.log(result.ok) // true
|
|
504
|
-
console.log(result.kind) // 'line'
|
|
505
|
-
console.log(result.lineIds) // ['drop-line-1']
|
|
506
|
-
console.log(result.channelId) // null
|
|
507
|
-
```
|
|
508
|
-
|
|
509
|
-
#### 直接通道对象:`lineIds`、`groups` 与样式怎么写
|
|
510
|
-
|
|
511
|
-
直接通道对象适合「一次给全通道 + 成员」。识别它的硬条件是 `lineIds` 必须是数组;没有 `lineIds` 的对象即使写了 `groups`,也只会被当成旧 resolution 或无法识别的对象。
|
|
512
|
-
|
|
513
|
-
| 对象字段 | 去向 | 说明 |
|
|
514
|
-
| --- | --- | --- |
|
|
515
|
-
| `lineIds` | 新回线 id 种子 | 每个 id 生成一条新回线;`lineIds` 为空数组时回线数量回落到草稿的 `circuits` / `lineItems`,不会清空草稿 |
|
|
516
|
-
| `groups` | 分组声明 | 等价于容器的 `channelGroups`;组的 `lineIds` 应使用这次生成的成员 id。第一组不写成员时拿本次全部回线,其余空组会被丢掉 |
|
|
517
|
-
| `id` | 新通道 id | 只决定新通道的身份;回线 id 一律来自 `lineIds`,这个 `id` 不参与逐条回线的 id 或前缀 |
|
|
518
|
-
| `name` | 通道名与新线路名 | 新线路没有逐条 `name` 时一起使用 |
|
|
519
|
-
| `from` / `to` | 新通道两端 | 覆盖草稿;实际回线端点也按它落 |
|
|
520
|
-
| `path` | 通道骨架的中间拐点 | 不含两端;分组各自写了 `path` 时以分组那一份为准 |
|
|
521
|
-
| `lineProps` | 全部新回线的公共字段 | 直接通道对象自己的 `lineProps` 会生效,优先级低于每一条逐条字段;容器写法里的 `channel.lineProps` **不合并**,见下文容器优先级 |
|
|
522
|
-
| 其余字段(`width` / `nodeWidth` / `inset` / `tooltip` / `customCode`…) | `channelProps` | 原样写到新通道上 |
|
|
523
|
-
|
|
524
|
-
```js
|
|
525
|
-
// 通道对象:两个 lineIds 各生成一条回线;groups 把它们分成两组
|
|
526
|
-
view.commitAddChannel({
|
|
527
|
-
id: 'object-channel-1',
|
|
528
|
-
name: '东侧双回',
|
|
529
|
-
from: 'station-a',
|
|
530
|
-
to: 'station-b',
|
|
531
|
-
lineIds: ['object-line-1', 'object-line-2'],
|
|
532
|
-
groups: [
|
|
533
|
-
{ id: 'object-channel-1::1', lineIds: ['object-line-1'], path: [[116.75, 39.86]] },
|
|
534
|
-
{ id: 'object-channel-1::2', lineIds: ['object-line-2'], path: [[116.75, 39.98]] }
|
|
535
|
-
],
|
|
536
|
-
width: 28,
|
|
537
|
-
nodeWidth: 1,
|
|
538
|
-
offsetMode: 'tangent',
|
|
539
|
-
lineProps: { color: '#2f6fd0', width: 2.4, lineType: 'dashed' },
|
|
540
|
-
owner: '运维一班'
|
|
541
|
-
})
|
|
542
|
-
```
|
|
543
|
-
|
|
544
|
-
> 直接通道对象的回数只由 `lineIds` 决定;`lineIds: []` 时回落到草稿的 `lineItems` / `circuits`。直接通道对象上另外写的 `circuits` 不会改回数,它会作为普通通道字段收进 `channelProps`;要覆盖本次回数,请用容器顶层 `circuits`,或在 `beginAddChannel` 时配置。
|
|
545
|
-
>
|
|
546
|
-
> `groups[].lineIds` 应写本次 `lineIds` / `lines` 真正生成的回线 id。写了不存在的 id 不会让整次提交失败:组件会报 warning,并在声明落地前按本次成员表调和(剔掉不属于本次的回线、把没落组的成员补进第一组)。
|
|
547
|
-
|
|
548
|
-
> **直接通道对象缺省按新通道提交**。要在提交对象的同时并进已有分组,必须换成容器写法并写 `resolution`,例如 `{ resolution: { type: 'joinGroup', groupId: 'corridor-1::2' }, lines: [...] }`。直接把 `resolution` 塞进「带 `lineIds` 的通道对象」会把它识别成容器,顶层 `lineIds` 不再作为通道成员使用。
|
|
549
|
-
|
|
550
|
-
#### 容器对象:逐段覆盖与精确优先级
|
|
329
|
+
| `from` / `to` | 覆盖草稿两端;必须是数据里真实存在的节点 id |
|
|
330
|
+
| `name` | 通道名 / 新线路名的统一覆盖值 |
|
|
331
|
+
| `id` | 新回线 id 种子;一次多条时自动展开。通道 id 写 `channel.id` |
|
|
332
|
+
| `resolution` | 落点:新建通道 / 新分组 / 并进分组 / 独立线路,见下文 |
|
|
333
|
+
| `channel` | 本次新建的通道对象:`{ id?, name?, from?, to?, path?, lineIds?, groups?, ...通道字段 }` |
|
|
334
|
+
| `line` | 本次新建的**独立线路**对象;对象上的普通业务字段进 `lineProps` |
|
|
335
|
+
| `lines` / `lineData` | 本次新建的回线数据,二者同义且 `lines` 优先;一条或一批,裸 id 等价于 `{ id }` |
|
|
336
|
+
| `channelGroups` / `group` | 新通道的分组声明,二者同义且 `channelGroups` 优先 |
|
|
337
|
+
| `lineProps` | 所有新回线共用的业务字段 |
|
|
338
|
+
| `linePropsByMember` | 按下标覆盖的逐条线路字段 |
|
|
339
|
+
| `channelProps` | 新通道的其余字段 |
|
|
340
|
+
| `path` / `routing` | 中间拐点与走线方式;`path` 不含两端 |
|
|
341
|
+
|
|
342
|
+
`channel.lineIds` 只在没有 `line` / `lines` / `lineData` 时当回线 id 种子;每个 id 建一条回线。`channel.groups` 与 `channelGroups` 同一份写法。传给 `channel` 的 `id` / `name` / `lineIds` / `groups` / `from` / `to` / `path` 以外的字段都进 `channelProps`。
|
|
343
|
+
|
|
344
|
+
`line` 决定这次是**独立线路**;`lines` / `lineData` 才是本次新建的成员回线表。两者不要混用来表达同一批线路。`lines: []` / `lineData: []` 不会清空草稿,而是沿用草稿的 `lineData`;想放弃草稿里的线路,重开一段不要带 `lineData` 的草稿。
|
|
345
|
+
|
|
346
|
+
#### 字段优先级
|
|
347
|
+
|
|
348
|
+
| 字段 | 优先级(左高右低) |
|
|
349
|
+
| --- | --- |
|
|
350
|
+
| `from` / `to` | 顶层 → `channel` → `line` → `lines` / `lineData` 里第一个对象项 → 草稿 |
|
|
351
|
+
| 成员回线 | `lines` → `lineData` → `line` → `channel.lineIds.map(id => ({ id }))` → 草稿 `lineData` |
|
|
352
|
+
| 分组声明 | `channelGroups` → `group` → `channel.groups` → 草稿 |
|
|
353
|
+
| 名称 | 顶层 `name` → `channel.name` → `line.name` → 草稿 |
|
|
354
|
+
| 回线 id 种子 | `line.id` → 顶层 `id` |
|
|
355
|
+
| `path` | 顶层 → `line.path` → `channel.path` → 草稿 |
|
|
356
|
+
| `routing` | 顶层 → 草稿 |
|
|
357
|
+
| `lineProps` | 草稿 → `line` 上除保留键外的业务字段 → 顶层 `lineProps` → `line.lineProps` |
|
|
358
|
+
| 逐条字段 | 同下标的 `lines` / `lineData` 项覆盖公共 `lineProps`;`linePropsByMember` 也按下标合并 |
|
|
359
|
+
| `channelProps` | 草稿 → `channel` 上除保留键外的业务字段 → 顶层 `channelProps` |
|
|
551
360
|
|
|
552
|
-
|
|
361
|
+
`lineIds`、`channelId`、`groupId`、`groupIndex`、`lineId`、`kind`、`circuits`、`count`、`lineItems`、`newGroup`、`start`、`end` 都不是合法的顶层字段;命中时整个调用失败且不写数据。并组用 `resolution: { type: 'joinGroup', groupId }`,成员用 `lines` / `lineData`,通道 id 用 `channel.id`。
|
|
553
362
|
|
|
554
|
-
|
|
555
|
-
| --- | --- | --- |
|
|
556
|
-
| `channel` | `GisViewChannel` | 新通道声明:`id` / `name` / `from` / `to` / `path` / `lineIds` / `groups` 与业务字段 |
|
|
557
|
-
| `line` | `GisViewLine` | 一条独立线路;缺省把本次 `kind` 定成 `'line'`,不是「只含一条的 `lines`」。只有同时显式写 `kind: 'channel'` 时,它才作为一条成员回线挂进通道 |
|
|
558
|
-
| `lines` | 一条或一批线路数据 | 逐条回线字段,支持对象、裸字符串 / 数字 id;**给了几条就建几条** |
|
|
559
|
-
| `lineData` / `lineItems` | 同上 | `lines` 的兼容别名;三者同时写时的优先级是 `lines > lineData > lineItems` |
|
|
560
|
-
| `channelGroups` / `group` | 一组或整份分组声明 | `channelGroups` 优先于 `group`;都写时以 `channelGroups` 为准 |
|
|
561
|
-
| `channelProps` | `Partial<GisViewChannel>` | 最后覆盖新通道字段,优先级高于 `channel` 上的普通字段 |
|
|
562
|
-
| `lineProps` | `Partial<GisViewLine>` | 公共回线字段;合并顺序是草稿 `lineProps` → 容器顶层 `lineProps` → `line.lineProps`,最后被逐条 `lines[i]` 覆盖。`channel.lineProps` 在容器里不参与合并 |
|
|
563
|
-
| `resolution` | 旧 resolution 的字符串 / 对象 | 不写时:有 `channel` 按 `newChannel`,否则沿用草稿推荐方案 |
|
|
564
|
-
| `kind` | `'channel' \| 'line'` | 显式改这一条是通道还是独立线路 |
|
|
565
|
-
| `from` / `to` / `path` / `routing` | 同草稿 | 顶层端点、中间拐点与走线方式;`routing` 只认容器这一层 |
|
|
566
|
-
| `circuits` | `number` | 没有有效 `lines` 时一次建几回;有 `lines` 时按条数(`circuits` 被忽略) |
|
|
567
|
-
| `id` / `lineId` | 线路 id 种子 | `lineId` 优先;通道 id 请写在 `channel.id` 或 `channelId` |
|
|
568
|
-
| `channelId` / `channelName` | 通道 id / 名称 | `channelId` 在无已有通道时是新通道 id;已有通道时是并组筛选条件 |
|
|
569
|
-
|
|
570
|
-
> 容器顶层只有 `channelGroups` / `group` 是分组键;裸写 `groups` 不会被读取。分组直接写在 `channel.groups`,或用 `channelGroups` / `group`。
|
|
571
|
-
|
|
572
|
-
**逐字段优先级(从高到低)**:
|
|
573
|
-
|
|
574
|
-
| 目标字段 | 优先级 |
|
|
575
|
-
| --- | --- |
|
|
576
|
-
| `from` / `to` | 容器顶层 → `channel` → `line` → `lineItems` 里第一个对象项 → 草稿。前面的裸字符串 / 数字 id 跳过,不贡献端点 |
|
|
577
|
-
| `path`(中间拐点) | 容器顶层 → `line` → `channel` → 草稿 |
|
|
578
|
-
| `routing` | 容器顶层 → 草稿(直接线路 / 直接通道对象没有这一层) |
|
|
579
|
-
| 分组 | `channelGroups` → `group` → `channel.groups` → 不声明(新通道只建一组,组 id 用通道 id) |
|
|
580
|
-
| 逐条回线 | `lines` → `lineData` → `lineItems` → `line` → `channel.lineIds.map(id => ({ id }))` → 草稿 |
|
|
581
|
-
| 线路公共字段(直接线路对象) | 对象上的普通业务字段 → 对象自己的 `lineProps` |
|
|
582
|
-
| 线路公共字段(容器) | 草稿 `lineProps` → 容器顶层 `lineProps` → `line.lineProps` → 逐条 `lines[i]`;**不读 `channel.lineProps`** |
|
|
583
|
-
| 通道字段 | 草稿 `channelProps` → `channel` 上的业务字段 → 容器 `channelProps` |
|
|
584
|
-
| 名称 | 容器 `name` → `channelName` / `channel.name` → `line.name` → 草稿名称 |
|
|
585
|
-
| `resolution` | 容器 `resolution` → 直接通道对象固定 `newChannel` → 草稿 `preferred` |
|
|
586
|
-
|
|
587
|
-
**空数组的规则**:`lines: []`、`lineData: []`、`lineItems: []` **不会清空**草稿里已有的逐条回线,而是沿用草稿。想放弃草稿里的线路,重新 `beginAddChannel()`(不要传 `lineItems`)或改用 `addLine` / `addChannel` 自行落地。
|
|
363
|
+
样例:
|
|
588
364
|
|
|
589
365
|
```js
|
|
590
|
-
// 容器写法:通道声明、两条回线、分组、样式、走线方式一次给全
|
|
591
366
|
view.commitAddChannel({
|
|
592
|
-
resolution: 'newChannel',
|
|
593
|
-
from: 'station-a',
|
|
594
|
-
to: 'station-b',
|
|
595
367
|
channel: {
|
|
596
368
|
id: 'container-channel-1',
|
|
597
369
|
name: '容器通道',
|
|
598
370
|
nodeWidth: 1,
|
|
599
|
-
width: 32
|
|
600
|
-
customCode: 'CH-001' // 不在通道保留键里的字段会进 channelProps
|
|
371
|
+
width: 32
|
|
601
372
|
},
|
|
602
373
|
lines: [
|
|
603
|
-
{ id: '
|
|
604
|
-
{ id: '
|
|
374
|
+
{ id: 'line-1', color: '#dd4b2e', width: 2.2 },
|
|
375
|
+
{ id: 'line-2', color: '#2ea36b', width: 2.2 }
|
|
605
376
|
],
|
|
606
377
|
channelGroups: [
|
|
607
|
-
{ id: 'container-channel-1::1', lineIds: ['
|
|
608
|
-
{ id: 'container-channel-1::2', lineIds: ['
|
|
378
|
+
{ id: 'container-channel-1::1', lineIds: ['line-1'], path: [[116.78, 39.88]] },
|
|
379
|
+
{ id: 'container-channel-1::2', lineIds: ['line-2'], path: [[116.78, 39.96]] }
|
|
609
380
|
],
|
|
610
|
-
routing: 'straight',
|
|
611
381
|
lineProps: { opacity: 0.9 },
|
|
612
382
|
channelProps: { tooltip: false }
|
|
613
|
-
})
|
|
383
|
+
}, { select: true })
|
|
614
384
|
```
|
|
615
385
|
|
|
616
|
-
**只给种子、逐条字段另写**:`channel.lineIds` 不会被 `lines` 覆盖成通道成员表 —— 容器里的 `lines` 才是本次新建的回线;`channel.lineIds` 只在没有 `lines` 时提供 id 种子。下面的结果是两条回线、一条新通道:
|
|
617
|
-
|
|
618
386
|
```js
|
|
619
387
|
view.commitAddChannel({
|
|
620
|
-
|
|
621
|
-
id: '
|
|
388
|
+
line: {
|
|
389
|
+
id: 'solo-line-1',
|
|
622
390
|
from: 'station-a',
|
|
623
391
|
to: 'station-b',
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
392
|
+
color: '#ff7a45',
|
|
393
|
+
width: 3,
|
|
394
|
+
lineType: 'dashed',
|
|
395
|
+
path: [[116.72, 39.91]]
|
|
396
|
+
}
|
|
627
397
|
})
|
|
628
398
|
```
|
|
629
399
|
|
|
630
|
-
|
|
400
|
+
`line.path` 与顶层 `path` 都按中间拐点解释,首尾仍取 `from` / `to` 节点坐标;要整条折线也通过节点坐标与中间拐点一起表达。
|
|
631
401
|
|
|
632
|
-
|
|
633
|
-
view.commitAddChannel({
|
|
634
|
-
channel: { id: 'mixed-channel', from: 'station-a', to: 'station-b' },
|
|
635
|
-
lines: [
|
|
636
|
-
{ id: 'mixed-1', color: '#dd4b2e', width: 2 },
|
|
637
|
-
'mixed-2',
|
|
638
|
-
{ id: 'mixed-3', lineType: 'dotted', label: '三回' }
|
|
639
|
-
],
|
|
640
|
-
group: { id: 'mixed-group', path: [[116.8, 39.9]] }
|
|
641
|
-
})
|
|
642
|
-
```
|
|
402
|
+
#### resolution 与落点
|
|
643
403
|
|
|
644
|
-
|
|
404
|
+
| `resolution` | 行为 |
|
|
405
|
+
| --- | --- |
|
|
406
|
+
| 不写 / `null` / `'auto'` | 有 `line` 时按 `newLine`,有 `channel` 时按 `newChannel`,否则用草稿的推荐方案 |
|
|
407
|
+
| `'newChannel'` | 新建通道;两端已有通道时失败 |
|
|
408
|
+
| `'newGroup'` | 在已有通道里新加一组;没有通道或余量不足时失败 |
|
|
409
|
+
| `'joinGroup'` | 并进已有分组;不带 `groupId` 时沿用方案表挑中的分组 |
|
|
410
|
+
| `'newLine'` | 新建独立线路;普通通道草稿也可显式用它改道 |
|
|
411
|
+
| `{ type, groupId?, groupIndex?, channelId? }` | 按字段收窄方案;只写 `groupId` / `groupIndex` 时自动视为 `joinGroup`,只写 `channelId` 时在该通道里按「新分组 → 可并分组」挑 |
|
|
412
|
+
| `payload.options.find(option => option.enabled)` | 不能整条回传;只取 `{ type, groupId, groupIndex, channelId }` 子集 |
|
|
645
413
|
|
|
646
|
-
|
|
414
|
+
草稿被 `singleChannel` / `existingChannel: 'block'` 阻断时,缺省提交(不传 `resolution` 或写 `'auto'`)直接失败并发 `phase: 'blocked'`;要改道必须显式传一个可用方案。方案表里的 `enabled: false` 条目不能用;`reason` 会说明余量或分组上限问题。
|
|
647
415
|
|
|
648
416
|
```js
|
|
649
|
-
//
|
|
650
|
-
view.commitAddChannel({
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
lineId: 'rerouted-line',
|
|
655
|
-
lines: [{ id: 'rerouted-line', color: '#7c4dff' }],
|
|
656
|
-
routing: 'orthogonal'
|
|
657
|
-
})
|
|
658
|
-
|
|
659
|
-
// 只改公共线路字段,其余(含推荐方案、circuits、端点、名称)全部沿用草稿
|
|
660
|
-
view.commitAddChannel({ lineProps: { width: 3.5, opacity: 0.8 } })
|
|
661
|
-
|
|
662
|
-
// 只改通道字段:通道对象的 lineIds 仍按当前草稿回线数生成
|
|
663
|
-
view.commitAddChannel({
|
|
664
|
-
channel: { id: 'styled-channel', from: 'station-a', to: 'station-b', nodeWidth: 0.8 },
|
|
665
|
-
channelProps: { width: 40, offsetMode: 'inset', inset: 0.2 }
|
|
666
|
-
})
|
|
417
|
+
view.commitAddChannel() // 接受当前推荐方案
|
|
418
|
+
view.commitAddChannel({ resolution: 'newChannel' })
|
|
419
|
+
view.commitAddChannel({ resolution: { type: 'joinGroup', groupId: 'corridor-1::2' } })
|
|
420
|
+
view.commitAddChannel({ channel: { id: 'new-channel' } }) // 新建通道
|
|
421
|
+
view.commitAddChannel({ line: { from: 'a', to: 'b' } }) // 新建独立线路
|
|
667
422
|
```
|
|
668
423
|
|
|
669
|
-
|
|
670
|
-
- 顶层 `path` 会盖过 `line.path` / `channel.path`;没有顶层 `path` 时才依次看线路、通道和草稿。
|
|
671
|
-
- `lineId` 只是 id 种子:一次多条时自动展开成 `lineId-1` / `lineId-2`;每条自己的 `lines[i].id` 优先级更高。
|
|
672
|
-
- `from` / `to` 可以覆盖草稿端点,但必须能在当前数据里找到;找不到时返回 `{ ok: false, reason: '找不到这两个节点' }`,草稿保留。
|
|
673
|
-
|
|
674
|
-
#### 提交已有通道 / 已有分组:必须显式写 `resolution`
|
|
675
|
-
|
|
676
|
-
直接通道对象默认新建通道。要可预期地并进已有通道 / 指定分组,换成容器写法并在顶层显式写 `resolution`;容器不写时只是沿用草稿推荐方案,不能保证一定是并组。并组时成员由 `lines` 给出,`channel` 段不再负责新建:
|
|
424
|
+
并进已有通道 / 分组时,使用方要在容器里写 `lines` / `lineData` 并显式给 `resolution`(或依赖 `'auto'` 的推荐方案):
|
|
677
425
|
|
|
678
426
|
```js
|
|
679
|
-
|
|
680
|
-
const joined = view.commitAddChannel({
|
|
427
|
+
view.commitAddChannel({
|
|
681
428
|
resolution: { type: 'joinGroup', groupId: 'corridor-1::2' },
|
|
682
429
|
lines: [
|
|
683
430
|
{ id: 'join-line-1', color: '#dd4b2e' },
|
|
@@ -685,25 +432,9 @@ const joined = view.commitAddChannel({
|
|
|
685
432
|
],
|
|
686
433
|
lineProps: { width: 2.4 }
|
|
687
434
|
})
|
|
688
|
-
|
|
689
|
-
console.log(joined.ok) // true
|
|
690
|
-
console.log(joined.channelId) // 'corridor-1'
|
|
691
|
-
console.log(joined.groupId) // 'corridor-1::2'
|
|
692
|
-
console.log(joined.channelLineIds) // 并完之后这条通道的完整成员表
|
|
693
435
|
```
|
|
694
436
|
|
|
695
|
-
|
|
696
|
-
- 只写 `channelId` / `groupId` / `groupIndex` 也能作为旧简写,但它们只有在两个节点之间已经有通道时才按并组解释。
|
|
697
|
-
- `channelProps` 只在新建通道时写进新通道;并进已有分组时不会改已有通道的字段,需要改通道请另调 `updateChannel`。
|
|
698
|
-
|
|
699
|
-
```js
|
|
700
|
-
// 旧简写:两个对象字段等价
|
|
701
|
-
view.commitAddChannel({ type: 'joinGroup', groupId: 'corridor-1::2' })
|
|
702
|
-
view.commitAddChannel({ groupId: 'corridor-1::2' })
|
|
703
|
-
|
|
704
|
-
// 只指定通道,让组件按「新分组 → 能并的分组」挑
|
|
705
|
-
view.commitAddChannel({ channelId: 'corridor-1' })
|
|
706
|
-
```
|
|
437
|
+
`channelProps` 只作用于新建通道;并进已有通道时不会修改原通道字段,需要改名 / 改样式请另调 `updateChannel`。
|
|
707
438
|
|
|
708
439
|
#### 连续新增、自动提交与事件
|
|
709
440
|
|
|
@@ -711,13 +442,14 @@ view.commitAddChannel({ channelId: 'corridor-1' })
|
|
|
711
442
|
|
|
712
443
|
| 字段 | 类型 | 缺省 | 说明 |
|
|
713
444
|
| --- | --- | --- | --- |
|
|
714
|
-
| `auto` | `boolean` | `false` | 只标记本次事件是自动提交;不等于 `beginAddChannel({ autoCommit: true })`。`autoCommit` 由组件内部用 `commitAddChannel(
|
|
445
|
+
| `auto` | `boolean` | `false` | 只标记本次事件是自动提交;不等于 `beginAddChannel({ autoCommit: true })`。`autoCommit` 由组件内部用 `commitAddChannel(undefined, { auto: true })` 提交 |
|
|
715
446
|
| `continuous` | `boolean` | 跟草稿的 `continuous` | 显式 `false` 强制本次落地后结束草稿;`true` 只在草稿本来就是连续模式时有效 |
|
|
716
447
|
| `originalEvent` | `Event \| null` | `null` | 连续模式重开草稿时带回去,供下一次草稿回调使用 |
|
|
448
|
+
| `select` | `boolean` | `false` | 落地后选中这次新建的全部回线;缺省不动选中集 |
|
|
717
449
|
|
|
718
450
|
```js
|
|
719
451
|
// 连续新增:本次落地后直接开下一段,并以上一段终点为下一段起点
|
|
720
|
-
view.beginAddChannel({ continuous: true, chain: true
|
|
452
|
+
view.beginAddChannel({ continuous: true, chain: true })
|
|
721
453
|
|
|
722
454
|
view.updateOptions({
|
|
723
455
|
onChannelDraft: payload => {
|
|
@@ -770,7 +502,7 @@ view.commitAddChannel(undefined, { continuous: false })
|
|
|
770
502
|
| `channelIndex` | 新通道或并进通道的下标;独立线路为 `-1` | 通常不返回;事件载荷失败时按 `-1` 兜底 |
|
|
771
503
|
|
|
772
504
|
```js
|
|
773
|
-
const result = view.commitAddChannel({ groupId: 'not-exist' })
|
|
505
|
+
const result = view.commitAddChannel({ resolution: { type: 'joinGroup', groupId: 'not-exist' } })
|
|
774
506
|
if (!result.ok) {
|
|
775
507
|
console.warn(result.reason) // 例如:找不到通道 / 指定分组没有可用方案
|
|
776
508
|
console.table(result.plan?.options ?? []) // 每条方案为什么不可用
|
|
@@ -784,19 +516,20 @@ if (!result.ok) {
|
|
|
784
516
|
- **功能关闭**:`features: { channelDraft: false }` 时提交直接拒绝。
|
|
785
517
|
- **节点找不到 / 端点相同**:`from` / `to` 覆盖成不存在的 id,或两端指到同一个节点。
|
|
786
518
|
- **方案不可用**:已有通道组数已满、目标分组余量不足,或者 `resolution` 指向不存在的通道 / 分组。
|
|
519
|
+
- **策略阻断**:`beginAddChannel({ singleChannel: true })` 或 `existingChannel: 'block'` 遇到已有通道时,`ready` 载荷已经带 `blocked: true` / `reason`;`commitAddChannel()` 无参(或 `resolution: 'auto'`)返回失败并发 `phase: 'blocked'`,不会改走新分组。要让用户改道,显式传 `resolution: 'newGroup'` 或 `resolution: { type: 'joinGroup', groupId }` 等可用方案。
|
|
787
520
|
|
|
788
521
|
**给已有通道加线路 / 删除线路**
|
|
789
522
|
|
|
790
523
|
| 想做什么 | 方法 | 要点 |
|
|
791
524
|
| --- | --- | --- |
|
|
792
|
-
| 往某条通道**新建**回线(可选分组) | `addChannelGroupLines(channelId, lineData, groupInfo?)` | 第二段 line_data 一条 / 一批:每项就是「线路的属性对象」(裸字符串 / 数字按 `{ id }` 收、不写 id 自动编号),**传几条建几条**;`groupInfo`(`{ id?, path? }`)给新分组的 id 与骨架,缺省 `${通道 id}::N
|
|
793
|
-
| 把新回线并进**指定分组** | `joinChannelGroupLines(channelId, groupId, lineData)` | `groupId` 认分组 id 也认序号(从 0
|
|
525
|
+
| 往某条通道**新建**回线(可选分组) | `addChannelGroupLines(channelId, lineData, groupInfo?, options?)` | 第二段 line_data 一条 / 一批:每项就是「线路的属性对象」(裸字符串 / 数字按 `{ id }` 收、不写 id 自动编号),**传几条建几条**;`groupInfo`(`{ id?, path? }`)给新分组的 id 与骨架,缺省 `${通道 id}::N`、不带拐点;`options.select: true` 选中新回线 |
|
|
526
|
+
| 把新回线并进**指定分组** | `joinChannelGroupLines(channelId, groupId, lineData, options?)` | `groupId` 认分组 id 也认序号(从 0 起、按声明顺序),不传挑第一个还有余量的分组;第二段同上;`options.select: true` 选中新回线 |
|
|
794
527
|
| 把**已经在数据里**的线路挂进通道 | `addChannelLines(channelId, lineIds, options?)` | 只改成员表与分组声明(回线本身早就在数据里);`options.groupId` 指定进哪一组(缺省第一组),认不出 / 已在别的通道的进 `skipped` |
|
|
795
528
|
| 从通道里摘回线 | `removeChannelLines(channelId, lineIds)` | 回线留在数据里(回到自己的 `path` / `from` / `to`);摘完一条不剩时 `ok: false`(要连通道一起删用 `removeChannel`) |
|
|
796
529
|
| 删除线路 | `removeLine(lineId)` / `removeLines(lineIds)` | 把线路从数据里删掉:挂着通道的会一起从通道声明里摘(空掉的组整组去掉),这条通道一条回线都不剩时整条通道一起删。`removeLine` 返回 `{ ok, reason?, line, lineId, index, channelId, removedChannel }`(`removedChannel` 是布尔:这条通道跟着整条走了);`removeLines` 返回 `{ ok, reason?, entries, lines, lineIds, indexes, removedChannels }`(`removedChannels` 是跟着走掉的通道数组) |
|
|
797
530
|
| 删除整条通道 | `removeChannel(channelId)` | 通道声明与它的成员回线一起删 |
|
|
798
531
|
|
|
799
|
-
三个新增入口(`addChannelGroupLines` / `joinChannelGroupLines` / `addChannelLines`)与 `addChannel` 返回同一份结果,`channelLineIds` 都是**更新后这条通道的完整成员表**;`addChannelLines` 的 `skipped`
|
|
532
|
+
三个新增入口(`addChannelGroupLines` / `joinChannelGroupLines` / `addChannelLines`)与 `addChannel` 返回同一份结果,`channelLineIds` 都是**更新后这条通道的完整成员表**;`addChannelLines` 的 `skipped` 逐条写清哪一条为什么没进。`addChannelGroupLines` / `joinChannelGroupLines` 缺省同样不选中新回线,需要时传 `options.select: true`。
|
|
800
533
|
|
|
801
534
|
### 通道改名 / 通道下增减回线 / 删除分组
|
|
802
535
|
|