topo-engine 0.1.0 → 0.1.3
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 +395 -163
- package/dist/index.d.ts +115 -0
- package/dist/style.css +366 -248
- package/dist/topo-engine.cjs +228 -91
- package/dist/topo-engine.cjs.map +1 -1
- package/dist/topo-engine.js +228 -91
- package/dist/topo-engine.js.map +1 -1
- package/dist/topo-engine.umd.cjs +228 -91
- package/dist/topo-engine.umd.cjs.map +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -1,163 +1,395 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
# pnpm
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
import
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
1
|
+
# topo-engine
|
|
2
|
+
|
|
3
|
+
配电台区(低压配电网)**单线图拓扑成图引擎**,基于 **Vue 3 + AntV G6 v5**。
|
|
4
|
+
|
|
5
|
+
输入一份台区拓扑 JSON,自动完成「解析 → 建树找根 → **横平竖直、0 交叉** 的正交布局 → 深色 SCADA 风格渲染」,并提供开箱即用的 Vue 组件与一整套拓扑查询 / 样式 / 动画 / 标注控制 API。
|
|
6
|
+
|
|
7
|
+
## 功能特性
|
|
8
|
+
|
|
9
|
+
- 🧩 **Vue 3 组件** — `TopoGraph`(画布,含标题栏 / 统计 / 适应画布 / 导出 PNG 按钮)、`SidePanel`(设备详情与上下游)、`DistanceTop10`(父子连线距离 Top10 面板)
|
|
10
|
+
- 🎨 **深色 / 浅色双主题** — 黑底 SCADA 或白底两种画布风格,图元 / 导线 / 文字随之配套适配,可随时切换(`theme` prop 或工具栏按钮)
|
|
11
|
+
- 📐 **自研正交布局** — 主干沿最长路径横向铺开 + 分支带垂直直走,整图**横平竖直、0 交叉、0 重叠**,边缘路由为直线 / L 形折线
|
|
12
|
+
- 🔍 **拓扑查询 API** — 节点 / 边 / 邻居 / 子树 / 主干链 / 路径 / 坐标 查询
|
|
13
|
+
- 🎨 **样式控制** — 节点、边样式覆盖与批量重置
|
|
14
|
+
- ✨ **动画与高亮** — 节点脉动、边流动、路径高亮、其余变暗、异常标注
|
|
15
|
+
- 📝 **文字标注** — 附加文字、用户名 full / short / hidden 切换
|
|
16
|
+
- 🃏 **卡片盒** — 节点信息卡片(字段 + 按钮),适配"运行曲线/工单跳转"类场景
|
|
17
|
+
- 🔗 **连接线 / 拓扑线** — 任意两节点动态连接线、路径拓扑高亮线
|
|
18
|
+
- 🎧 **事件系统** — 点击 / 悬停 / 画布空白 / 视口变化事件总线
|
|
19
|
+
- 💾 **导出** — 整图 PNG 下载、DataURL、图数据 JSON
|
|
20
|
+
- 📦 **零配置渲染** — 组件自带深色主题与工具栏,`data` 或 `dataUrl` 二选一即可出图
|
|
21
|
+
|
|
22
|
+
## 安装
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install topo-engine
|
|
26
|
+
# 或 yarn add topo-engine / pnpm add topo-engine
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
- 环境要求:**Vue 3.4+**(peerDependency);`@antv/g6` v5 已作为依赖随包安装,无需手动配置。
|
|
30
|
+
- 组件深色样式不自动注入,使用时需引入样式文件:
|
|
31
|
+
|
|
32
|
+
```js
|
|
33
|
+
import 'topo-engine/style.css';
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 快速开始
|
|
37
|
+
|
|
38
|
+
### 1. 最小示例 —— 只画一张图
|
|
39
|
+
|
|
40
|
+
```vue
|
|
41
|
+
<script setup>
|
|
42
|
+
import { ref } from 'vue';
|
|
43
|
+
import { TopoGraph } from 'topo-engine';
|
|
44
|
+
import 'topo-engine/style.css';
|
|
45
|
+
|
|
46
|
+
// 两种数据来源任选其一:
|
|
47
|
+
// - dataUrl:内部用 fetch 加载(注意放 public/ 下或跨域可达)
|
|
48
|
+
// - data :直接传入解析好的 JSON 对象(优先级高于 dataUrl)
|
|
49
|
+
const dataUrl = ref('/data/topology.json');
|
|
50
|
+
|
|
51
|
+
const onLoaded = ({ title, stats }) => {
|
|
52
|
+
console.log('加载完成', title, stats); // { total, depth, leaves, byCat }
|
|
53
|
+
};
|
|
54
|
+
</script>
|
|
55
|
+
|
|
56
|
+
<template>
|
|
57
|
+
<!-- 组件撑满父容器,父容器必须有明确高度 -->
|
|
58
|
+
<div class="page">
|
|
59
|
+
<TopoGraph :data-url="dataUrl" @loaded="onLoaded" />
|
|
60
|
+
</div>
|
|
61
|
+
</template>
|
|
62
|
+
|
|
63
|
+
<style scoped>
|
|
64
|
+
.page { height: 640px; }
|
|
65
|
+
</style>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### 2. 组合示例 —— 图 + 详情面板 + Top10 距离面板
|
|
69
|
+
|
|
70
|
+
```vue
|
|
71
|
+
<script setup>
|
|
72
|
+
import { ref } from 'vue';
|
|
73
|
+
import { TopoGraph, SidePanel, DistanceTop10 } from 'topo-engine';
|
|
74
|
+
import 'topo-engine/style.css';
|
|
75
|
+
|
|
76
|
+
const topo = ref(null); // ref → 调用完整控制 API
|
|
77
|
+
const graphData = ref(null); // 直接传数据对象
|
|
78
|
+
const panelOpen = ref(false);
|
|
79
|
+
const selected = ref(null);
|
|
80
|
+
const upstream = ref([]);
|
|
81
|
+
const downstream = ref([]);
|
|
82
|
+
const stats = ref({});
|
|
83
|
+
const distances = ref([]);
|
|
84
|
+
|
|
85
|
+
function onSelect({ node, upstream: up, downstream: down }) {
|
|
86
|
+
selected.value = node;
|
|
87
|
+
upstream.value = up;
|
|
88
|
+
downstream.value = down;
|
|
89
|
+
panelOpen.value = true;
|
|
90
|
+
}
|
|
91
|
+
function onTopDistances(list) { distances.value = list; }
|
|
92
|
+
function jumpTo(id) { topo.value?.selectNode(id); }
|
|
93
|
+
</script>
|
|
94
|
+
|
|
95
|
+
<template>
|
|
96
|
+
<div class="app">
|
|
97
|
+
<div class="graph-area">
|
|
98
|
+
<TopoGraph
|
|
99
|
+
ref="topo"
|
|
100
|
+
:data="graphData"
|
|
101
|
+
@node-select="onSelect"
|
|
102
|
+
@top-distances="onTopDistances"
|
|
103
|
+
/>
|
|
104
|
+
<SidePanel
|
|
105
|
+
v-if="panelOpen"
|
|
106
|
+
:node="selected"
|
|
107
|
+
:upstream="upstream"
|
|
108
|
+
:downstream="downstream"
|
|
109
|
+
:stats="stats"
|
|
110
|
+
@close="panelOpen = false"
|
|
111
|
+
@jump="jumpTo"
|
|
112
|
+
/>
|
|
113
|
+
</div>
|
|
114
|
+
<DistanceTop10
|
|
115
|
+
v-if="distances.length"
|
|
116
|
+
:distances="distances"
|
|
117
|
+
@close="distances = []"
|
|
118
|
+
@jump="jumpTo"
|
|
119
|
+
/>
|
|
120
|
+
</div>
|
|
121
|
+
</template>
|
|
122
|
+
|
|
123
|
+
<style scoped>
|
|
124
|
+
.app { display: flex; height: 720px; }
|
|
125
|
+
.graph-area { flex: 1; display: flex; min-width: 0; position: relative; }
|
|
126
|
+
</style>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### 3. 只用布局 / 解析工具函数(不依赖组件)
|
|
130
|
+
|
|
131
|
+
```javascript
|
|
132
|
+
import { parseTopo, computeOrthogonalLayout, buildGraphData } from 'topo-engine';
|
|
133
|
+
|
|
134
|
+
const model = parseTopo(rawJson); // 原始 JSON → 图模型(含 nodes/edges/rootId/stats)
|
|
135
|
+
const layout = computeOrthogonalLayout(model); // 正交布局结果(节点坐标 + 每边折线点序列)
|
|
136
|
+
const g6Data = buildGraphData(model, layout); // → G6 可直接消费的 { nodes, edges }
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
> 说明:包内渲染使用的自定义图元节点(`svg-symbol`)与正交折线边(`orth-polyline`)目前仅在 `TopoGraph` 内部注册使用,未作为公开 API 导出。直接用 G6 手工拼图时建议以 `TopoGraph` 组件(或它的 render 流程)为基准,保证节点与边风格一致。
|
|
140
|
+
|
|
141
|
+
## 输入数据格式
|
|
142
|
+
|
|
143
|
+
顶层可以是 `{ code, msg, data: { nodes, relationships, stations } }`(常见接口包装格式),也可以是直接 `{ nodes, relationships, stations }` —— 引擎两种都接受。
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
{
|
|
147
|
+
"data": {
|
|
148
|
+
"nodes": [
|
|
149
|
+
{ "id": 1, "name": "1#台区.", "psrType": "0302", "symbolId": "1664029", "status": "0" },
|
|
150
|
+
{ "id": 2, "name": "1#台区低压熔丝.", "psrType": "3301", "symbolId": "68688", "status": "0" }
|
|
151
|
+
],
|
|
152
|
+
"relationships": [ { "from": 1, "to": 2 } ],
|
|
153
|
+
"stations": [
|
|
154
|
+
{ "id": 1, "name": "1#台区.", "contain": ["8ff4786d548a7073a2517297e801518ff456732f4d"] }
|
|
155
|
+
]
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
| 字段 | 说明 |
|
|
161
|
+
| ---- | ---- |
|
|
162
|
+
| `nodes[]` | 设备/线路节点:`id`、`name`(可带结尾 `.`,渲染时会去掉)、`psrType`(图元类型码)、`symbolId`、`psrId`、`status`(`"0"` 视为正常) |
|
|
163
|
+
| `relationships[]` | 有向边 `{ from, to }`,方向为 电源 → 负荷;自动防环(BFS),入度为 0 者作为根,优先选变压器/开关 |
|
|
164
|
+
| `stations[]` | 台区/站房:`name` 作为画布标题,`contain` 内为箱内设备的 `psrId` 列表 |
|
|
165
|
+
|
|
166
|
+
`parseTopo` 后模型节点会附带派生抽像字段:`cat`、`catLabel`、`shortName`、`isLine`、`insideStation`、`isFuse` 等(完整类型见 `dist/index.d.ts`)。
|
|
167
|
+
|
|
168
|
+
主要 `psrType` → 图元类别:
|
|
169
|
+
|
|
170
|
+
| psrType | 类别 | 渲染 |
|
|
171
|
+
| ------- | ---- | ---- |
|
|
172
|
+
| `0302` | 配电变压器 | 橙色圆 + 红圈 |
|
|
173
|
+
| `3301` | 开关 / 熔丝 | 红色矩形(开关名自动缩写为 K 编号) |
|
|
174
|
+
| `3303` | 低压母线 | 白色短粗线 |
|
|
175
|
+
| `3202` / `320300000` | 电缆终端头 / 分接点 | 三角 / 红色米字 |
|
|
176
|
+
| `310100000` | 低压导线 | 青色连接点(名称缩写为杆号区间) |
|
|
177
|
+
| `3112` | 计量箱 | 黑底白框 "JX" |
|
|
178
|
+
| `3218000` | 用户接入点 | 白圈 "J"(名称缩写为户号) |
|
|
179
|
+
| `32500000` | 低压配电箱(台区) | 站房 |
|
|
180
|
+
|
|
181
|
+
## TopoGraph 组件参考
|
|
182
|
+
|
|
183
|
+
### Props
|
|
184
|
+
|
|
185
|
+
| Prop | 类型 | 默认 | 说明 |
|
|
186
|
+
| ---- | ---- | ---- | ---- |
|
|
187
|
+
| `dataUrl` | `String` | `''` | 拓扑 JSON 的 URL(内部 `fetch` 加载)。变化后自动重新加载 |
|
|
188
|
+
| `data` | `Object` | `null` | 直接传入 JSON 对象;优先级高于 `dataUrl`;深度 watch,变化自动重绘 |
|
|
189
|
+
| `theme` | `'dark' \| 'light'` | `'dark'` | 画布主题:`dark`(黑底 SCADA,默认)/ `light`(白底,图元配套加深)。支持 `v-model:theme`,也可点内置工具栏 ☀️/🌙 按钮切换 |
|
|
190
|
+
|
|
191
|
+
### Emits
|
|
192
|
+
|
|
193
|
+
| 事件 | 载荷 | 触发时机 |
|
|
194
|
+
| ---- | ---- | ---- |
|
|
195
|
+
| `loaded` | `{ title, stats }`,`stats = { total, depth, leaves, byCat }` | 每次数据渲染完成 |
|
|
196
|
+
| `node-select` | `{ node, upstream, downstream }`(均为解析后模型节点) | 点击节点(含金框选中与详情联动) |
|
|
197
|
+
| `top-distances` | `Array<{ parent: {id,name,catLabel}, child: {id,name,catLabel}, distance }>`(≤10) | 渲染完成时,父-子连线折线长度 Top10(过滤站内边与主干鱼骨边) |
|
|
198
|
+
|
|
199
|
+
### 内置交互与 UI
|
|
200
|
+
|
|
201
|
+
- 滚轮缩放、拖拽平移、悬停高亮(上下游与连线),点击选中(金色虚框,再次点空白取消)。
|
|
202
|
+
- 左上角深色工具栏:标题 / `节点 n · 边 m · 深度 d · 叶子 l` 统计 / 「适应画布」/「导出 PNG」按钮。
|
|
203
|
+
- 加载中 / 出错(如 dataUrl 404)有内置遮罩提示。
|
|
204
|
+
- 卸载时自动 `destroy()` 图实例与事件监听,无内存泄漏。
|
|
205
|
+
|
|
206
|
+
### 通过 ref 调用的方法
|
|
207
|
+
|
|
208
|
+
`<TopoGraph ref="topo">` 后,`topo` 暴露 **`TopoApi` 的全部公开方法**(下节 API 表),外加:
|
|
209
|
+
|
|
210
|
+
| 方法 | 说明 |
|
|
211
|
+
| ---- | ---- |
|
|
212
|
+
| `loadRaw(jsonText)` | 用一段 JSON 文本(如本地文件上传内容)重新成图 |
|
|
213
|
+
| `selectNode(id)` | 选中某节点并联动 `node-select` 事件 |
|
|
214
|
+
| `resetView()` | 适应画布 |
|
|
215
|
+
| `exportPng()` | 导出整图 PNG(按画布标题命名下载) |
|
|
216
|
+
| `getLayoutData()` | 获取当前正交布局数据(坐标 / 折线 / stats) |
|
|
217
|
+
| `getTopDistances()` | 获取最近一次 Top10 距离结果 |
|
|
218
|
+
|
|
219
|
+
### 主题切换(深色 / 浅色)
|
|
220
|
+
|
|
221
|
+
引擎内置两套主题,**深色为默认**(黑底 SCADA 风格,与历史版本一致);浅色为**白底**,图元(变压器 / 开关 / 计量箱 / 用户圈…)、导线(干线深灰 / 支线浅灰)、节点文字都已配套加深,适合打印或嵌入浅色页面。
|
|
222
|
+
|
|
223
|
+
- `TopoGraph`:`:theme` 取值 `'dark'`(默认)或 `'light'`,推荐 `v-model:theme` 双向绑定;组件左上工具栏内置 ☀️ / 🌙 切换按钮(点击 emit `update:theme`)。
|
|
224
|
+
- `SidePanel` / `DistanceTop10`:同样接收 `theme` prop,与画布保持一致观感。
|
|
225
|
+
- 切换主题会**按当前数据自动重建画布**:G6 画布背景、图元、边、标注文字全部随主题更新,布局不变。
|
|
226
|
+
|
|
227
|
+
```vue
|
|
228
|
+
<script setup>
|
|
229
|
+
import { ref } from 'vue';
|
|
230
|
+
import { TopoGraph } from 'topo-engine';
|
|
231
|
+
import 'topo-engine/style.css';
|
|
232
|
+
|
|
233
|
+
const theme = ref('dark'); // 初始深色,可在运行时切换
|
|
234
|
+
const dataUrl = ref('/data/topology.json');
|
|
235
|
+
</script>
|
|
236
|
+
|
|
237
|
+
<template>
|
|
238
|
+
<div class="page">
|
|
239
|
+
<TopoGraph v-model:theme="theme" :data-url="dataUrl" />
|
|
240
|
+
</div>
|
|
241
|
+
</template>
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
> 说明:主题色板定义在包内 `theme.js`(`THEMES.dark` / `THEMES.light`,已随库打包,未作为公开导出);若需要按自有品牌定制,可在外层自行覆盖 `dist/style.css` 中各组件的 `--tp-*` / `--sp-*` / `--dt-*` CSS 变量。
|
|
245
|
+
|
|
246
|
+
## 控制 API(TopoApi 方法,经组件 ref 直接调用)
|
|
247
|
+
|
|
248
|
+
> 也可自行 `import { TopoApi }`,按 `new TopoApi(graph, model, layout, nodeByIdMap)` 构造后调用同一套方法;事件与查询见下。使用组件时无需关心内部构造。
|
|
249
|
+
|
|
250
|
+
### 查询
|
|
251
|
+
|
|
252
|
+
| 方法 | 说明 |
|
|
253
|
+
| ---- | ---- |
|
|
254
|
+
| `getNode(nodeId)` | 按 ID 取节点(解析后模型节点) |
|
|
255
|
+
| `getAllNodes()` | 全部节点 |
|
|
256
|
+
| `findNodes(filter)` | 多条件 AND 过滤,`filter` 支持 `{ cat, psrType, name, shortName, status, insideStation, … }`,值可为字符串 / 布尔 / `RegExp` |
|
|
257
|
+
| `getSelectedId()` | 当前选中节点 ID |
|
|
258
|
+
| `getNeighbors(id)` | `{ upstream: [], downstream: [] }` |
|
|
259
|
+
| `getStreamNodes(id, 'upstream'\|'downstream')` | 沿流向 BFS 取节点链 |
|
|
260
|
+
| `getTrunkNodes()` / `getSubtreeNodes(id)` | 主干链节点 / 子树节点 |
|
|
261
|
+
| `getPath(a, b)` | 两节点间路径(不可达返回 `null`) |
|
|
262
|
+
| `getEdge(src, tgt)` / `getEdges()` | 按端点取边 / 全部边 |
|
|
263
|
+
| `getStreamEdges(id, dir)` / `getMainEdge()` | 沿流边的链 / 主干边 |
|
|
264
|
+
| `getNodePosition(id)` / `getEdgePath(src, tgt)` / `getGraphBounds()` | 坐标 / 边折线点序列 / 全图包围盒 |
|
|
265
|
+
| `getStats()` | `{ total, depth, leaves, byCat }` |
|
|
266
|
+
|
|
267
|
+
### 视图
|
|
268
|
+
|
|
269
|
+
`fitView(padding?)`、`zoomTo(ratio, center?)`、`zoomIn(step?)`、`zoomOut(step?)`、`locateNode(id, zoom?)`、`getViewport()`
|
|
270
|
+
|
|
271
|
+
### 样式
|
|
272
|
+
|
|
273
|
+
`setNodeStyle(id, style)`、`batchSetNodeStyle(ids, style)`、`resetNodeStyle(id)`、`resetAllNodeStyles()`
|
|
274
|
+
`setEdgeStyle(src, tgt, style)`、`batchSetEdgeStyle([[src,tgt],…], style)`、`resetEdgeStyle(src, tgt)`
|
|
275
|
+
|
|
276
|
+
### 高亮 / 变暗
|
|
277
|
+
|
|
278
|
+
```javascript
|
|
279
|
+
topo.highlightNode('5', { color: '#FF0000', label: '异常', labelColor: '#FF0000' });
|
|
280
|
+
topo.unhighlightNode('5');
|
|
281
|
+
|
|
282
|
+
const path = topo.getPath('1', '5'); // 高亮一条供电路径
|
|
283
|
+
if (path) topo.highlightPath(path.map(n => n.id), { color: '#00FF00' });
|
|
284
|
+
|
|
285
|
+
topo.dimOthers(['1', '2'], 0.15); // 除指定节点外整体变暗
|
|
286
|
+
topo.unhighlightAll();
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### 动画
|
|
290
|
+
|
|
291
|
+
```javascript
|
|
292
|
+
topo.setNodePulse('2', { color: '#00C8FF', duration: 1500 }); // 节点脉动
|
|
293
|
+
topo.setEdgeFlow('1', '2', { color: '#00C8FF', duration: 2000 }); // 边流动
|
|
294
|
+
topo.removeAnimation('2');
|
|
295
|
+
topo.removeAllAnimations();
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### 文字标注
|
|
299
|
+
|
|
300
|
+
`setText(id, text, { color, fontSize })`、`removeText(id)`、`removeAllTexts()`、`setDeviceText(cat, fontSize)`、`changeUserName('full' | 'short' | 'hidden')`
|
|
301
|
+
|
|
302
|
+
### 卡片盒
|
|
303
|
+
|
|
304
|
+
```javascript
|
|
305
|
+
topo.showCard('5', {
|
|
306
|
+
title: '设备名称',
|
|
307
|
+
fields: [
|
|
308
|
+
{ label: '类型', value: '配电变压器' },
|
|
309
|
+
{ label: 'PSR编号', value: 'xxx' },
|
|
310
|
+
],
|
|
311
|
+
buttons: [{ text: '查看运行曲线', type: 'primary', onClick: () => console.log('click') }],
|
|
312
|
+
closable: true,
|
|
313
|
+
});
|
|
314
|
+
topo.hideCard('5');
|
|
315
|
+
topo.hideAllCards();
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### 连接线 / 拓扑线
|
|
319
|
+
|
|
320
|
+
```javascript
|
|
321
|
+
topo.addConnection('1', '8', { color: '#FF6600', width: 2, style: 'dashed' }); // 任意两节点连线
|
|
322
|
+
topo.removeAllConnections();
|
|
323
|
+
|
|
324
|
+
const lineId = topo.addTopoLine(['1', '3', '8'], { color: '#FF0000', width: 3 }); // 沿线路径画高亮线
|
|
325
|
+
topo.removeTopoLine(lineId);
|
|
326
|
+
topo.removeAllTopoLines();
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### 事件总线(`on` / `off`)
|
|
330
|
+
|
|
331
|
+
| 事件 | 载荷 | 说明 |
|
|
332
|
+
| ---- | ---- | ---- |
|
|
333
|
+
| `node:click` | `{ nodeId, node }` | 节点点击 |
|
|
334
|
+
| `node:hover` / `node:unhover` | `{ nodeId, node }` / `{ nodeId }` | 悬停进入 / 离开 |
|
|
335
|
+
| `edge:click` | `{ edgeId, source, target }` | 边点击 |
|
|
336
|
+
| `canvas:click` | `{ event }` | 画布空白处点击 |
|
|
337
|
+
| `viewport:change` | `{ zoom, center }` | 视口缩放 / 平移变化 |
|
|
338
|
+
| `card:button` | `{ nodeId, buttonIndex }` | 卡片按钮点击 |
|
|
339
|
+
|
|
340
|
+
```javascript
|
|
341
|
+
const handler = ({ nodeId }) => console.log('点击了', nodeId);
|
|
342
|
+
topo.on('node:click', handler);
|
|
343
|
+
topo.off('node:click', handler); // 不传 handler 则移除该事件全部监听
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### 导出 / 底层
|
|
347
|
+
|
|
348
|
+
`exportPng(filename?)`(整图下载)、`toDataURL(opts?)`、`getGraphData()`、`getGraphInstance()`(原始 G6 Graph)、`getModel()`、`getLayoutData()`、`getNodeByIdMap()`、`update(graph, model, layout, map)`、`destroy()`
|
|
349
|
+
|
|
350
|
+
## 布局与渲染参数
|
|
351
|
+
|
|
352
|
+
`computeOrthogonalLayout(model, options)`:
|
|
353
|
+
|
|
354
|
+
| 参数 | 默认 | 含义 |
|
|
355
|
+
| ---- | ---- | ---- |
|
|
356
|
+
| `nodeGap` | `26` | 链上相邻节点边界间距 |
|
|
357
|
+
| `band` | `50` | 侧分支根到父节点中心线的距离(分支带宽) |
|
|
358
|
+
| `packGap` | `22` | 分支带内并排子分支间距 |
|
|
359
|
+
| `sideGap` | `40` | 相邻主干节点的分支带隔离间距 |
|
|
360
|
+
| `margin` | `40` | 画布外框留白 |
|
|
361
|
+
|
|
362
|
+
`TopoGraph` 组件内部即用上述默认参数,返回布局数据含每节点坐标、`edgeCP`(每条边的完整折线点序列)与 `fishboneRibs`,可配 `assertOrthogonal(model, edgeCP)` 做 0 交叉 / 正交性校验。
|
|
363
|
+
|
|
364
|
+
## TypeScript
|
|
365
|
+
|
|
366
|
+
类型声明随包发布(`dist/index.d.ts`),支持按需导入:
|
|
367
|
+
|
|
368
|
+
```typescript
|
|
369
|
+
import { TopoApi, TopoGraph } from 'topo-engine';
|
|
370
|
+
import type { TopoApi } from 'topo-engine'; // 需要类型时
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
## 常见问题
|
|
374
|
+
|
|
375
|
+
- **图不显示 / 高度为 0**:`TopoGraph` 撑满父容器(内部 `width/height: 100%`),请给外层元素设置明确高度(如 `height: 600px`)。
|
|
376
|
+
- **样式错乱 / 没有深色背景**:确认已 `import 'topo-engine/style.css'`。
|
|
377
|
+
- **`dataUrl` 加载失败**:确认文件可被 `fetch` 访问(Vite 放 `public/`,不要用相对路径);失败会触发 `error` 态显示并 `console.error`。
|
|
378
|
+
- **切换数据源**:响应式修改 `:data` / `:data-url` 会自动重新加载;本地文件可用 `ref.loadRaw(text)`。
|
|
379
|
+
- **节点 ID 传字符串**:内部统一按字符串存储(`String(id)`),查询 API 请传字符串,如 `getNode('1')`。
|
|
380
|
+
- **和 Vue 2 / 其它 G6 版本混用**:仅支持 Vue 3.4+,图内部依赖 `@antv/g6` v5,请勿重复安装不同版本。
|
|
381
|
+
|
|
382
|
+
## 本地开发
|
|
383
|
+
|
|
384
|
+
```bash
|
|
385
|
+
npm install # 安装依赖
|
|
386
|
+
npm run dev # 开发演示(内置 API Playground,可试所有控制 API)→ http://127.0.0.1:5173/
|
|
387
|
+
npm run build # 生产构建(应用 + 库)
|
|
388
|
+
npm run build:lib # 仅构建库产物到 dist/
|
|
389
|
+
npm run preview # 预览生产构建
|
|
390
|
+
npm pack --dry-run # 查看发布包内容清单
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
## License
|
|
394
|
+
|
|
395
|
+
MIT
|