topo-engine 0.1.7 → 0.1.9

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/docs/API.md CHANGED
@@ -7,6 +7,7 @@
7
7
  ## 目录
8
8
 
9
9
  - [快速开始](#快速开始)
10
+ - [引用规则(id / psrId / assetNo 统一)](#引用规则id--psrid--assetno-统一)
10
11
  - [类型定义](#类型定义)
11
12
  - [一、查询 API](#一查询-api)
12
13
  - [二、视图控制](#二视图控制)
@@ -24,6 +25,42 @@
24
25
 
25
26
  ---
26
27
 
28
+ ## 引用规则(id / psrId / assetNo 统一)
29
+
30
+ > 引擎内所有「目标 / 节点 / 设备 / 用户」入参(下称 `ref`)**统一接受三种引用**,
31
+ > 方法与场景无关,传内部 id、psrId 还是资产编号由调用方自由决定:
32
+
33
+ | 引用 | 命中对象 | 典型值 |
34
+ | --- | --- | --- |
35
+ | 节点内部 `id` | 普通节点 | `'1'`、`'40'` |
36
+ | `psrId`(设备编码) | 普通节点(变压器/开关/导线点/计量箱…) | `'8ff4786d548a7073a2517297e801518ff456732f4d'` |
37
+ | `assetNo`(资产编号,兼容 `consNo`/`consId`) | 计量箱内该户 **电表户** | `'4230010007008084768'` |
38
+
39
+ **命中「箱内电表户」后的语义(按函数类型):**
40
+
41
+ - **视觉 / 定位 / 动画**(`locateNode`、`highlightNode`、`setNodeGlow`、`setNodePulse`、
42
+ `setText`、`setNodeColor`、`getNodePosition`、组件 `selectNode`…)→ **精确作用在该户表位**:
43
+ 光环/高亮环/脉动/文字/染色画在该格电表上,定位聚焦表位中心;
44
+ - **查询 / 拓扑**(`getNode`、`getNeighbors`、`getStreamNodes`、`getSubtreeNodes`、
45
+ `getPath`、`getEdge*`…)→ 该户**按所在计量箱参与拓扑**:
46
+ `getNode(assetNo)` 返回所在箱节点副本并附带 `customer / customerIndex / customerCount / targetKind:'customer'`;
47
+ - **通用节点样式**(`setNodeStyle` 等)→ 作用于其所在计量箱节点;
48
+ - **卡片**(`showCard(assetNo)`)→ 卡片定位在该户表位旁,内容缺省按客户档案自动生成。
49
+
50
+ **辅助解析(业务判断用):**
51
+
52
+ ```js
53
+ const t = topo.resolveRef('4230010007008084768');
54
+ // → { kind:'customer', boxId:'40', boxNode, index:0, customer:{…}, key:'40#cust0', assetNo, name }
55
+ const c = topo.getCustomer('4230010007008084768');
56
+ // → { node, customer, index, count, boxId } | null
57
+ ```
58
+
59
+ > 说明:`findNodes` / `getAllNodes` 等**无目标入参**的聚合查询保持原语义(返回模型节点,不含电表户,
60
+ > 电表户从箱节点的 `_customers` 中读取)。连线/拓扑线端点本就支持 id/psrId/assetNo。
61
+
62
+ ---
63
+
27
64
  ## 快速开始
28
65
 
29
66
  ```vue
@@ -205,18 +242,19 @@ interface ConnectionOptions {
205
242
 
206
243
  ## 一、查询 API
207
244
 
208
- ### `getNode(nodeId)`
245
+ ### `getNode(ref)`
209
246
 
210
- 获取单个节点完整数据。
247
+ 获取单个目标(节点 / 箱内电表户)完整数据。
211
248
 
212
249
  ```ts
213
- getNode(nodeId: string): NodeData | null
250
+ getNode(ref: string): NodeData | null
214
251
  ```
215
252
 
216
253
  **参数:**
217
- - `nodeId` — 节点 ID
254
+ - `ref` — 节点 id / psrId / 资产编号 assetNo(见[引用规则](#引用规则id--psrid--assetno-统一))
218
255
 
219
- **返回:** 节点数据对象,未找到返回 `null`
256
+ **返回:** 命中普通节点返回模型节点;命中电表户返回**其所在计量箱节点副本**,
257
+ 并附带 `customer`(客户档案)、`customerIndex`、`customerCount`、`targetKind:'customer'`;未找到返回 `null`
220
258
 
221
259
  **示例:**
222
260
  ```js
@@ -391,12 +429,12 @@ getMainEdge(): EdgeData[]
391
429
 
392
430
  ---
393
431
 
394
- ### `getNodePosition(nodeId)`
432
+ ### `getNodePosition(ref)`
395
433
 
396
- 获取节点在画布中的坐标。
434
+ 获取节点 / 户表位中心坐标(assetNo → 该户表位中心)。
397
435
 
398
436
  ```ts
399
- getNodePosition(nodeId: string): { x: number; y: number } | null
437
+ getNodePosition(ref: string): { x: number; y: number } | null
400
438
  ```
401
439
 
402
440
  ---
@@ -491,16 +529,16 @@ zoomOut(step?: number): void
491
529
 
492
530
  ---
493
531
 
494
- ### `locateNode(nodeId, zoom?)`
532
+ ### `locateNode(ref, zoom?)`
495
533
 
496
- 定位节点到视口中央,可选缩放。
534
+ 定位目标到视口中央(节点中心 / 户表位中心),可选缩放。
497
535
 
498
536
  ```ts
499
- locateNode(nodeId: string, zoom?: number): void
537
+ locateNode(ref: string, zoom?: number): void
500
538
  ```
501
539
 
502
540
  **参数:**
503
- - `nodeId` — 要定位的节点 ID
541
+ - `ref` — 节点 id / psrId / 资产编号 assetNo
504
542
  - `zoom` — 可选的目标缩放比例
505
543
 
506
544
  **示例:**
@@ -526,12 +564,12 @@ getViewport(): { zoom: number; center: { x: number; y: number } }
526
564
 
527
565
  ## 三、节点样式
528
566
 
529
- ### `setNodeStyle(nodeId, style)`
567
+ ### `setNodeStyle(ref, style)`
530
568
 
531
- 设置单个节点的视觉样式。
569
+ 设置单个目标的视觉样式(assetNo → 作用于所在计量箱节点)。
532
570
 
533
571
  ```ts
534
- setNodeStyle(nodeId: string, style: NodeStyle): void
572
+ setNodeStyle(ref: string, style: NodeStyle): void
535
573
  ```
536
574
 
537
575
  **示例:**
@@ -575,6 +613,118 @@ resetAllNodeStyles(): void
575
613
 
576
614
  ---
577
615
 
616
+ ### 节点 / 箱内电表户染色(psrId / 资产编号)
617
+
618
+ > 给图元“换颜色”。引用规则与 `addConnection` 完全一致:
619
+ > - **普通节点** —— 节点内部 id 或 **`psrId`(设备编码)**:变压器 / 开关 / 熔丝 /
620
+ > 导线连接点 / 母线 / 用户接入点 / 计量箱本体均可;
621
+ > - **箱内电表户** —— 客户档案里的 **`assetNo`(资产编号)**(兼容 `consNo`/`consId`):
622
+ > 命中计量箱内该户的**电表图标 + 户名**(单户箱即整箱那一只表;多户箱只染该格)。
623
+ >
624
+ > 渲染效果:
625
+ > - 普通节点为**整图单色换装**——主体 / 引线 / 描边全部换成指定色,
626
+ > 白字与浅色细节(开关 Kxx 标签、内高光、装饰条)保留以保证可读;
627
+ > - 箱内电表户染该户表体 / 显示窗 / 脉冲点与户名颜色;悬停(青)与选中(金)优先级更高,
628
+ > 取消悬停 / 选中后自动回到所染颜色。
629
+ >
630
+ > 染色记录保存在 API 内部,**主题切换 / 数据重渲染后自动保留并重放**(同一次会话内
631
+ > 无需重新调用;`resetNodeColor` / `resetAllNodeColors` 可清除)。
632
+
633
+ #### `setNodeColor(ref, color)`
634
+
635
+ 按 **节点 psrId / id** 或 **用户 assetNo(资产编号)** 染色。
636
+
637
+ ```ts
638
+ setNodeColor(ref: string, color: string | null): boolean
639
+ // color 传 null / '' / undefined 等价于清除该处染色(回到主题默认配色)
640
+ ```
641
+
642
+ **示例:**
643
+ ```js
644
+ // 1) 普通节点:按 psrId(设备编码)把变压器染红
645
+ topo.setNodeColor('8ff4786d548a7073a2517297e801518ff456732f4d', '#FF0000');
646
+
647
+ // 2) 电表户:按资产编号(assetNo)把某户电表染橙
648
+ topo.setNodeColor('4230010007008084768', '#FF6600');
649
+
650
+ // 3) 也支持节点内部 id
651
+ topo.setNodeColor('5', '#00FF00');
652
+
653
+ // 4) 清除染色(回到主题默认色)
654
+ topo.setNodeColor('4230010007008084768', null);
655
+ ```
656
+
657
+ ---
658
+
659
+ #### `batchSetNodeColor(entries, color?)`
660
+
661
+ 批量染色(如后端返回「psrId → 状态色」「assetNo → 状态色」列表时一次性下发)。
662
+ 三种入参形式:
663
+
664
+ ```ts
665
+ batchSetNodeColor(entries: any, color?: string): {
666
+ total: number;
667
+ ok: number;
668
+ failed: Array<{ ref: string, reason: string }>;
669
+ }
670
+ ```
671
+
672
+ **示例:**
673
+ ```js
674
+ // 形式 1:[ref, color] 数组
675
+ topo.batchSetNodeColor([
676
+ ['8ff4786d548a7073a2517297e801518ff456732f4d', '#FF0000'],
677
+ ['4230010007008084768', '#FF6600'],
678
+ ]);
679
+
680
+ // 形式 2:对象数组(color 缺省时用第 2 参)
681
+ topo.batchSetNodeColor([
682
+ { psrId: '8ff4…', color: '#FF0000' },
683
+ { assetNo: '4230…' },
684
+ ], '#FF6600');
685
+
686
+ // 形式 3:ref → color 对象
687
+ topo.batchSetNodeColor({
688
+ '8ff4786d548a7073a2517297e801518ff456732f4d': '#FF0000',
689
+ '4230010007008084768': '#FF6600',
690
+ });
691
+ ```
692
+
693
+ ---
694
+
695
+ #### `resetNodeColor(ref)`
696
+
697
+ 清除指定节点 / 电表户的染色。
698
+
699
+ ```ts
700
+ resetNodeColor(ref: string): boolean
701
+ ```
702
+
703
+ ---
704
+
705
+ #### `resetAllNodeColors()`
706
+
707
+ 清除全部染色(所有节点与电表户回到主题默认配色)。
708
+
709
+ ```ts
710
+ resetAllNodeColors(): void
711
+ ```
712
+
713
+ ---
714
+
715
+ #### `getNodeColor(ref)`
716
+
717
+ 查询某处当前生效的染色(未命中返回 `null`)。
718
+
719
+ ```ts
720
+ getNodeColor(ref: string):
721
+ | { kind: 'node', id: string, color: string | null }
722
+ | { kind: 'customer', id: string, boxId: string, index: number, color: string | null }
723
+ | null
724
+ ```
725
+
726
+ ---
727
+
578
728
  ## 四、边样式
579
729
 
580
730
  ### `setEdgeStyle(srcId, tgtId, style)`
@@ -618,12 +768,12 @@ resetEdgeStyle(srcId: string, tgtId: string): void
618
768
 
619
769
  ## 五、高亮与标注
620
770
 
621
- ### `highlightNode(nodeId, options?)`
771
+ ### `highlightNode(ref, options?)`
622
772
 
623
- 高亮节点(选中效果 + 可选文字标注)。
773
+ 高亮目标(节点 → 金框 + 可选标注;箱内电表户 → 该户表位高亮环 + 可选标注)。
624
774
 
625
775
  ```ts
626
- highlightNode(nodeId: string, options?: HighlightOptions): void
776
+ highlightNode(ref: string, options?: HighlightOptions): void
627
777
  ```
628
778
 
629
779
  **示例:**
@@ -711,12 +861,12 @@ topo.dimOthers(keep, 0.15);
711
861
 
712
862
  ## 六、动画
713
863
 
714
- ### `setNodePulse(nodeId, options?)`
864
+ ### `setNodePulse(ref, options?)`
715
865
 
716
- 节点脉动/光晕动画。
866
+ 目标脉动动画(节点 → 图元透明度呼吸;箱内电表户 → 该户电表格淡入淡出)。
717
867
 
718
868
  ```ts
719
- setNodePulse(nodeId: string, options?: PulseOptions): void
869
+ setNodePulse(ref: string, options?: { duration?: number; min?: number; max?: number }): void
720
870
  ```
721
871
 
722
872
  **示例:**
@@ -726,17 +876,60 @@ topo.setNodePulse('123', { color: '#FF0000', duration: 1500 });
726
876
 
727
877
  ---
728
878
 
729
- ### `setNodeGlow(nodeId, options?)`
879
+ ### `setNodeGlow(ref, options?)`
880
+
881
+ **节点光晕动画** —— 节点周围“扩散 + 渐隐”的发光环(两层光环、呼吸式循环),
882
+ 用于告警 / 定位 / 状态强调等场景。
883
+
884
+ ```ts
885
+ setNodeGlow(ref: string, options?: {
886
+ color?: string; // 光晕颜色,默认 '#00C8FF'(青)
887
+ spread?: number; // 光环外扩半径 (px),默认 14
888
+ radius?: number; // spread 的别名(兼容早期文档)
889
+ duration?: number; // 一个周期时长 (ms),默认 1600
890
+ opacity?: number; // 光环最大透明度 (0-1),默认 0.9
891
+ }): boolean
892
+ ```
893
+
894
+ **说明:**
895
+ - `ref` 支持 **节点内部 id / psrId(设备编码)** → 图元光环;
896
+ **客户 assetNo(资产编号,兼容 consNo/consId)→ 该户表位光环**(多户箱只亮那一格,单户箱即整箱那只表);
897
+ - 多个目标可同时发光;`removeAllAnimations()` 会一并停止光晕与脉动;
898
+ - 与「染色 / 高亮」互不冲突:光环画在图元之上、选中金框之下,随节点/表位对齐。
899
+
900
+ **示例:**
901
+ ```js
902
+ // 默认青色光晕
903
+ topo.setNodeGlow('8ff4786d548a7073a2517297e801518ff456732f4d');
904
+
905
+ // 红色告警光晕(更亮、扩散更大、周期更快)
906
+ topo.setNodeGlow('8ff4…', { color: '#FF0000', spread: 20, duration: 900, opacity: 1 });
907
+
908
+ // 停止:removeNodeGlow(ref) / 停止全部 removeAllNodeGlows()
909
+ topo.removeNodeGlow('8ff4…');
910
+ ```
911
+
912
+ ---
913
+
914
+ ### `removeNodeGlow(ref)`
730
915
 
731
- 节点发光效果。
916
+ 停止指定节点的光晕动画。
732
917
 
733
918
  ```ts
734
- setNodeGlow(nodeId: string, options?: { color?: string; radius?: number }): void
919
+ removeNodeGlow(ref: string): boolean
735
920
  ```
736
921
 
737
922
  ---
738
923
 
739
- ### `setEdgeFlow(srcId, tgtId, options?)`
924
+ ### `removeAllNodeGlows()`
925
+
926
+ 停止全部节点的光晕动画。
927
+
928
+ ```ts
929
+ removeAllNodeGlows(): void
930
+ ```
931
+
932
+ ---### `setEdgeFlow(srcId, tgtId, options?)`
740
933
 
741
934
  边流动动画(视觉流动效果)。
742
935
 
@@ -783,12 +976,12 @@ removeAllAnimations(): void
783
976
 
784
977
  ## 七、文字标注
785
978
 
786
- ### `setText(nodeId, text, options?)`
979
+ ### `setText(ref, text, options?)`
787
980
 
788
- 在节点旁设置附加文字。
981
+ 在目标旁设置附加文字(节点 → 节点旁标注;箱内电表户 → 表位上方小标注)。
789
982
 
790
983
  ```ts
791
- setText(nodeId: string, text: string, options?: {
984
+ setText(ref: string, text: string, options?: {
792
985
  fontSize?: number; // 默认 12
793
986
  color?: string; // 默认 '#FFFFFF'
794
987
  position?: 'top' | 'bottom' | 'left' | 'right'; // 默认 'top'
@@ -856,12 +1049,13 @@ changeUserName(mode: 'full' | 'short' | 'hidden'): void
856
1049
 
857
1050
  ## 八、卡片盒
858
1051
 
859
- ### `showCard(nodeId, content)`
1052
+ ### `showCard(ref, content?)`
860
1053
 
861
- 在节点旁弹出信息卡片。
1054
+ 在节点 / 箱内电表户旁弹出信息卡片(assetNo → 卡片定位在该户表位旁)。
1055
+ `content` 可省略:不传时自动按「设备信息 / 客户档案」生成 `title` 与 `fields`。
862
1056
 
863
1057
  ```ts
864
- showCard(nodeId: string, content: CardContent): void
1058
+ showCard(ref: string, content?: CardContent): void
865
1059
  ```
866
1060
 
867
1061
  **示例:**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "topo-engine",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "配电台区单线图拓扑成图引擎 (Vue3 + G6 v5 + Node/Vite)",