@next-bricks/diagram 0.68.8 → 0.68.10

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.
Files changed (85) hide show
  1. package/dist/bricks.json +3 -3
  2. package/dist/chunks/1265.bf280e6d.js +3 -0
  3. package/dist/chunks/1265.bf280e6d.js.map +1 -0
  4. package/dist/chunks/1889.fa8b5dbe.js +2 -0
  5. package/dist/chunks/1889.fa8b5dbe.js.map +1 -0
  6. package/dist/chunks/3171.8057c0f4.js +2 -0
  7. package/dist/chunks/3171.8057c0f4.js.map +1 -0
  8. package/dist/chunks/{3654.59bd8992.js → 3654.6a028b09.js} +3 -3
  9. package/dist/chunks/{3654.59bd8992.js.map → 3654.6a028b09.js.map} +1 -1
  10. package/dist/chunks/{3746.591c50d8.js → 3746.7fad241d.js} +2 -2
  11. package/dist/chunks/{3746.591c50d8.js.map → 3746.7fad241d.js.map} +1 -1
  12. package/dist/chunks/515.23d8419d.js +2 -0
  13. package/dist/chunks/515.23d8419d.js.map +1 -0
  14. package/dist/chunks/5399.d786845a.js +2 -0
  15. package/dist/chunks/5399.d786845a.js.map +1 -0
  16. package/dist/chunks/5552.7718c4ca.js +2 -0
  17. package/dist/chunks/5552.7718c4ca.js.map +1 -0
  18. package/dist/chunks/577.c9c65352.js.map +1 -1
  19. package/dist/chunks/6376.a8716290.js +2 -0
  20. package/dist/chunks/6376.a8716290.js.map +1 -0
  21. package/dist/chunks/7920.367555e2.js +3 -0
  22. package/dist/chunks/7920.367555e2.js.map +1 -0
  23. package/dist/chunks/9118.8a9d6592.js +3 -0
  24. package/dist/chunks/9118.8a9d6592.js.LICENSE.txt +11 -0
  25. package/dist/chunks/9118.8a9d6592.js.map +1 -0
  26. package/dist/chunks/948.e308c274.js +3 -0
  27. package/dist/chunks/948.e308c274.js.map +1 -0
  28. package/dist/chunks/editable-label.667b04d5.js.map +1 -1
  29. package/dist/chunks/eo-diagram.78450578.js.map +1 -1
  30. package/dist/chunks/eo-display-canvas.2a43ce91.js.map +1 -1
  31. package/dist/chunks/eo-draw-canvas.e01342d6.js.map +1 -1
  32. package/dist/chunks/experimental-node.2f4d802a.js.map +1 -1
  33. package/dist/chunks/main.91a8e473.js +2 -0
  34. package/dist/chunks/main.91a8e473.js.map +1 -0
  35. package/dist/examples.json +10 -7
  36. package/dist/index.f358949f.js +2 -0
  37. package/dist/index.f358949f.js.map +1 -0
  38. package/dist/manifest.json +359 -220
  39. package/dist/types.json +5163 -5163
  40. package/dist-types/diagram/index.d.ts +48 -1
  41. package/dist-types/diagram/interfaces.d.ts +3 -3
  42. package/dist-types/display-canvas/index.d.ts +37 -3
  43. package/dist-types/draw-canvas/index.d.ts +75 -7
  44. package/dist-types/draw-canvas/interfaces.d.ts +3 -3
  45. package/dist-types/editable-label/index.d.ts +14 -1
  46. package/dist-types/experimental-node/index.d.ts +11 -1
  47. package/docs/editable-label.md +71 -1
  48. package/docs/editable-label.react.md +100 -0
  49. package/docs/eo-diagram.md +54 -87
  50. package/docs/eo-diagram.react.md +399 -0
  51. package/docs/eo-display-canvas.md +60 -21
  52. package/docs/eo-display-canvas.react.md +376 -0
  53. package/docs/eo-draw-canvas.md +95 -40
  54. package/docs/eo-draw-canvas.react.md +989 -0
  55. package/docs/experimental-node.md +156 -0
  56. package/docs/experimental-node.react.md +157 -0
  57. package/package.json +2 -2
  58. package/dist/chunks/1265.55a02b5a.js +0 -3
  59. package/dist/chunks/1265.55a02b5a.js.map +0 -1
  60. package/dist/chunks/1889.9e9ad16a.js +0 -2
  61. package/dist/chunks/1889.9e9ad16a.js.map +0 -1
  62. package/dist/chunks/3171.3bd2c8f0.js +0 -2
  63. package/dist/chunks/3171.3bd2c8f0.js.map +0 -1
  64. package/dist/chunks/4667.53203ccd.js +0 -2
  65. package/dist/chunks/4667.53203ccd.js.map +0 -1
  66. package/dist/chunks/4837.32dece7c.js +0 -2
  67. package/dist/chunks/4837.32dece7c.js.map +0 -1
  68. package/dist/chunks/5399.b1b4981d.js +0 -2
  69. package/dist/chunks/5399.b1b4981d.js.map +0 -1
  70. package/dist/chunks/5552.e3e728b7.js +0 -2
  71. package/dist/chunks/5552.e3e728b7.js.map +0 -1
  72. package/dist/chunks/7218.e0bf22af.js +0 -2
  73. package/dist/chunks/7218.e0bf22af.js.map +0 -1
  74. package/dist/chunks/7920.df65d810.js +0 -3
  75. package/dist/chunks/7920.df65d810.js.map +0 -1
  76. package/dist/chunks/948.83e23068.js +0 -3
  77. package/dist/chunks/948.83e23068.js.map +0 -1
  78. package/dist/chunks/main.4630d30e.js +0 -2
  79. package/dist/chunks/main.4630d30e.js.map +0 -1
  80. package/dist/index.c366c6da.js +0 -2
  81. package/dist/index.c366c6da.js.map +0 -1
  82. /package/dist/chunks/{1265.55a02b5a.js.LICENSE.txt → 1265.bf280e6d.js.LICENSE.txt} +0 -0
  83. /package/dist/chunks/{3654.59bd8992.js.LICENSE.txt → 3654.6a028b09.js.LICENSE.txt} +0 -0
  84. /package/dist/chunks/{7920.df65d810.js.LICENSE.txt → 7920.367555e2.js.LICENSE.txt} +0 -0
  85. /package/dist/chunks/{948.83e23068.js.LICENSE.txt → 948.e308c274.js.LICENSE.txt} +0 -0
@@ -1,9 +1,57 @@
1
- 构件 `eo-diagram`
1
+ ---
2
+ tagName: eo-diagram
3
+ displayName: WrappedEoDiagram
4
+ description: 图表构件,支持 dagre(有向无环图)和 force(力导向图)两种布局,可渲染节点和连线,支持缩放、平移、拖拽节点、连线交互等功能。
5
+ category: diagram
6
+ source: "@next-bricks/diagram"
7
+ ---
8
+
9
+ # eo-diagram
10
+
11
+ > 图表构件,支持 dagre(有向无环图)和 force(力导向图)两种布局,可渲染节点和连线,支持缩放、平移、拖拽节点、连线交互等功能。
12
+
13
+ ## Props
14
+
15
+ | 属性 | 类型 | 必填 | 默认值 | 说明 |
16
+ | --------------------- | ----------------------------------- | ---- | ------ | ---------------------------------------------------------------------------------------------------------------- |
17
+ | layout | `"dagre" \| "force" \| undefined` | - | - | 图表布局类型,支持 `dagre`(层次有向图)和 `force`(力导向图)。 |
18
+ | nodes | `DiagramNode[] \| undefined` | - | - | 节点数据列表,每个节点需包含唯一 `id` 字段。 |
19
+ | edges | `DiagramEdge[] \| undefined` | - | - | 边(连线)数据列表,每条边需包含 `source` 和 `target` 字段,指向节点 id。 |
20
+ | nodeBricks | `NodeBrickConf[] \| undefined` | - | - | 节点砖块配置,指定渲染节点使用的自定义构件,可按节点类型匹配不同配置。 |
21
+ | lines | `LineConf[] \| undefined` | - | - | 连线样式配置,支持箭头、颜色、标签、交互等多种选项。 |
22
+ | layoutOptions | `LayoutOptions \| undefined` | - | - | 布局算法选项,dagre 布局支持 rankdir、ranksep、nodesep 等,force 布局支持 dummyNodesOnEdges、collide 等。 |
23
+ | activeTarget | `ActiveTarget \| null \| undefined` | - | - | 当前激活目标,可以是节点(`{ type: "node", nodeId }`) 或边(`{ type: "edge", edge }`),为 null 表示无激活目标。 |
24
+ | disableKeyboardAction | `boolean \| undefined` | - | - | 是否禁用键盘操作(删除节点/边、切换激活节点),当有标签正在编辑时可临时禁用以避免冲突。 |
25
+ | connectNodes | `ConnectNodesOptions \| undefined` | - | - | 连线交互配置,启用后支持从节点拖拽出新的连线,可配置连线样式和源节点过滤条件。 |
26
+ | dragNodes | `DragNodesOptions \| undefined` | - | - | 拖拽节点配置,启用后支持手动拖拽节点调整位置,可配置是否保存用户视图。 |
27
+ | zoomable | `boolean \| undefined` | - | `true` | 是否允许通过鼠标滚轮或触控板捏合手势缩放图表,默认为 true。 |
28
+ | scrollable | `boolean \| undefined` | - | `true` | 是否允许通过滚轮平移图表(非捏合手势),默认为 true。 |
29
+ | pannable | `boolean \| undefined` | - | `true` | 是否允许通过鼠标拖拽平移图表,默认为 true。 |
30
+ | scaleRange | `RangeTuple \| undefined` | - | - | 缩放比例范围,格式为 `[min, max]`,默认范围由内部常量决定。 |
31
+
32
+ ## Events
33
+
34
+ | 事件 | detail | 说明 |
35
+ | ------------------- | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
36
+ | activeTarget.change | `ActiveTarget \| null` — 当前激活目标,`{ type: "node", nodeId }` 或 `{ type: "edge", edge }` 或 null | 激活目标变化时触发,当用户点击节点或边使其激活,或点击空白处取消激活时触发。 |
37
+ | node.delete | `DiagramNode` — 被删除的节点对象,包含节点 id 及其他自定义字段 | 用户按 Delete/Backspace 键且当前激活目标为节点时触发,需外部处理实际删除逻辑。 |
38
+ | edge.delete | `DiagramEdge` — 被删除的边对象,包含 source、target 及其他自定义字段 | 用户按 Delete/Backspace 键且当前激活目标为边时触发,需外部处理实际删除逻辑。 |
39
+ | line.click | `LineTarget` — 被点击的连线信息,包含 `{ id: 连线唯一标识, edge: 对应的边数据 }` | 用户点击可交互连线时触发。 |
40
+ | line.dblclick | `LineTarget` — 被双击的连线信息,包含 `{ id: 连线唯一标识, edge: 对应的边数据 }` | 用户双击可交互连线时触发,常用于触发连线标签编辑。 |
41
+ | nodes.connect | `ConnectLineDetail` — 连线详情,包含 `{ source: 起始节点, target: 目标节点 }` | 用户从一个节点拖拽连线到另一个节点并释放时触发,需外部处理实际建立连接的逻辑。 |
42
+
43
+ ## Methods
44
+
45
+ | 方法 | 参数 | 返回值 | 说明 |
46
+ | --------------- | ------------------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------- |
47
+ | callOnLineLabel | `(id: string, method: string, args: unknown[]) => void` | `void` | 调用指定 id 的连线标签构件上的方法,常用于触发标签编辑(如 `callOnLineLabel(id, "enableEditing")`)。 |
2
48
 
3
49
  ## Examples
4
50
 
5
51
  ### Basic
6
52
 
53
+ 展示基本的 dagre 布局图表,包含节点和带箭头的连线,并支持动态添加/删除节点。
54
+
7
55
  ```yaml preview minHeight="600px"
8
56
  brick: div
9
57
  properties:
@@ -105,7 +153,6 @@ children:
105
153
  activeTarget: <%= CTX.activeTarget %>
106
154
  nodeBricks:
107
155
  - useBrick:
108
- # if: <% DATA.node.id !== "kbacon" %>
109
156
  brick: div
110
157
  properties:
111
158
  style: |
@@ -142,6 +189,8 @@ children:
142
189
 
143
190
  ### Page Architecture
144
191
 
192
+ 展示 dagre 布局图表用于页面架构可视化,包含节点标签编辑、连线标签、连线创建和节点删除交互。
193
+
145
194
  ```yaml preview minHeight="600px"
146
195
  brick: div
147
196
  properties:
@@ -349,7 +398,6 @@ children:
349
398
  : node
350
399
  ))
351
400
  %>
352
- # Take reaction only if the label has been changed
353
401
  - if: <% CTX.nodes.find(({id}) => id === DATA.node.id)?.name !== EVENT.detail %>
354
402
  action: context.replace
355
403
  args:
@@ -473,6 +521,8 @@ children:
473
521
 
474
522
  ### Force
475
523
 
524
+ 展示 force 布局的力导向图,支持拖拽节点、连线标签显示,适合展示关系网络。
525
+
476
526
  ```yaml preview minHeight="600px"
477
527
  brick: div
478
528
  properties:
@@ -500,127 +550,48 @@ context:
500
550
  - id: 工作流
501
551
  - id: 测试用例
502
552
  - id: 功能点
503
- # - id: 其他
504
553
  - name: edges
505
554
  value:
506
555
  - source: 产品
507
556
  target: 产品评价
508
557
  sourceName: 评价列表
509
558
  targetName: 所属产品
510
- sourceConstraints:
511
- required: true
512
- targetConstraints:
513
- multiple: true
514
559
  - source: 产品
515
560
  target: 产品线
516
561
  sourceName: 所属产品线
517
562
  targetName: 产品列表
518
- sourceConstraints:
519
- multiple: true
520
- targetConstraints:
521
- required: true
522
563
  - source: 产品
523
564
  target: 用户角色
524
565
  sourceName: 负责人
525
566
  targetName: 负责的产品
526
- sourceConstraints:
527
- multiple: true
528
- targetConstraints:
529
- multiple: true
530
567
  - source: 产品
531
568
  target: 模型视图
532
569
  sourceName: 模型视图列表
533
570
  targetName: 所属产品
534
- sourceConstraints:
535
- required: true
536
- targetConstraints:
537
- multiple: true
538
571
  - source: 产品
539
572
  target: 业务场景
540
573
  sourceName: 业务场景列表
541
574
  targetName: 所属产品
542
- sourceConstraints:
543
- required: true
544
- targetConstraints:
545
- multiple: true
546
- - source: 业务场景
547
- target: 业务场景
548
575
  - source: 业务场景
549
576
  target: 业务规则
550
577
  sourceName: 业务规则列表
551
578
  targetName: 所属业务场景
552
- sourceConstraints:
553
- required: true
554
- targetConstraints:
555
- multiple: true
556
- - source: 业务场景
557
- target: 用户角色
558
- sourceName: 负责人
559
- targetName: 负责的业务场景
560
- sourceConstraints:
561
- multiple: true
562
- targetConstraints:
563
- multiple: true
564
579
  - source: 产品
565
580
  target: 模型
566
581
  sourceName: 模型列表
567
582
  targetName: 关联的产品
568
- sourceConstraints:
569
- required: true
570
- targetConstraints:
571
- multiple: true
572
583
  - source: 产品
573
584
  target: 产品模块
574
585
  sourceName: 模块列表
575
586
  targetName: 所属产品
576
- sourceConstraints:
577
- required: true
578
- targetConstraints:
579
- multiple: true
580
- - source: 产品
581
- target: 产品价值点
582
- sourceName: 价值点列表
583
- targetName: 所属产品
584
- sourceConstraints:
585
- required: true
586
- targetConstraints:
587
- multiple: true
588
- - source: 业务场景
589
- target: 产品价值点
590
- sourceName: 价值点列表
591
- targetName: 关联的业务场景
592
- - source: 业务场景
593
- target: 工作流
594
- - source: 业务规则
595
- target: 工作流
596
- - source: 产品模块
597
- target: 产品模块
598
587
  - source: 产品模块
599
588
  target: 测试用例
600
589
  sourceName: 测试用例列表
601
590
  targetName: 所属产品模块
602
- sourceConstraints:
603
- multiple: true
604
- targetConstraints:
605
- multiple: true
606
591
  - source: 产品模块
607
592
  target: 功能点
608
593
  sourceName: 功能点列表
609
594
  targetName: 所属产品模块
610
- sourceConstraints:
611
- required: true
612
- targetConstraints:
613
- multiple: true
614
- - source: 测试用例
615
- target: 功能点
616
- sourceName: 关联的功能点
617
- targetName: 关联的测试用例
618
- sourceConstraints:
619
- multiple: true
620
- targetConstraints:
621
- multiple: true
622
- # - source: 产品线
623
- # target: 模型视图
624
595
  children:
625
596
  - brick: eo-diagram
626
597
  properties:
@@ -630,14 +601,11 @@ children:
630
601
  edges: <%= CTX.edges %>
631
602
  activeTarget: <%= CTX.activeTarget %>
632
603
  layoutOptions:
633
- # nodePadding: 5
634
604
  dummyNodesOnEdges: 1
635
605
  collide:
636
606
  dummyRadius: 10
637
607
  radiusDiff: 40
638
- # rankdir: LR
639
- # acyclicer: greedy
640
- # align: DL
608
+ scaleRange: [0.5, 2]
641
609
  lines:
642
610
  - label:
643
611
  - useBrick:
@@ -653,7 +621,6 @@ children:
653
621
  strokeColor: var(--palette-blue-4)
654
622
  nodeBricks:
655
623
  - useBrick:
656
- # if: <% DATA.node.id !== "kbacon" %>
657
624
  brick: div
658
625
  properties:
659
626
  style: |
@@ -0,0 +1,399 @@
1
+ ---
2
+ tagName: eo-diagram
3
+ displayName: WrappedEoDiagram
4
+ description: 图表构件,支持 dagre(有向无环图)和 force(力导向图)两种布局,可渲染节点和连线,支持缩放、平移、拖拽节点、连线交互等功能。
5
+ category: diagram
6
+ source: "@next-bricks/diagram"
7
+ ---
8
+
9
+ # WrappedEoDiagram
10
+
11
+ > 图表构件,支持 dagre(有向无环图)和 force(力导向图)两种布局,可渲染节点和连线,支持缩放、平移、拖拽节点、连线交互等功能。
12
+
13
+ ## 导入
14
+
15
+ ```tsx
16
+ import { WrappedEoDiagram } from "@easyops/wrapped-components";
17
+ ```
18
+
19
+ ## Props
20
+
21
+ | 属性 | 类型 | 必填 | 默认值 | 说明 |
22
+ | --------------------- | ------------------------------------------------ | ---- | ------ | ---------------------------------------------------------------------------------------------------------------- |
23
+ | layout | `"dagre" \| "force" \| undefined` | - | - | 图表布局类型,支持 `dagre`(层次有向图)和 `force`(力导向图)。 |
24
+ | nodes | `DiagramNode[] \| undefined` | - | - | 节点数据列表,每个节点需包含唯一 `id` 字段。 |
25
+ | edges | `DiagramEdge[] \| undefined` | - | - | 边(连线)数据列表,每条边需包含 `source` 和 `target` 字段,指向节点 id。 |
26
+ | nodeBricks | `NodeBrickConf[] \| undefined` | - | - | 节点砖块配置,指定渲染节点使用的自定义构件,可按节点类型匹配不同配置。 |
27
+ | lines | `LineConf[] \| undefined` | - | - | 连线样式配置,支持箭头、颜色、标签、交互等多种选项。 |
28
+ | layoutOptions | `LayoutOptions \| undefined` | - | - | 布局算法选项,dagre 布局支持 rankdir、ranksep、nodesep 等,force 布局支持 dummyNodesOnEdges、collide 等。 |
29
+ | activeTarget | `ActiveTarget \| null \| undefined` | - | - | 当前激活目标,可以是节点(`{ type: "node", nodeId }`) 或边(`{ type: "edge", edge }`),为 null 表示无激活目标。 |
30
+ | disableKeyboardAction | `boolean \| undefined` | - | - | 是否禁用键盘操作(删除节点/边、切换激活节点),当有标签正在编辑时可临时禁用以避免冲突。 |
31
+ | connectNodes | `ConnectNodesOptions \| undefined` | - | - | 连线交互配置,启用后支持从节点拖拽出新的连线,可配置连线样式和源节点过滤条件。 |
32
+ | dragNodes | `DragNodesOptions \| undefined` | - | - | 拖拽节点配置,启用后支持手动拖拽节点调整位置,可配置是否保存用户视图。 |
33
+ | zoomable | `boolean \| undefined` | - | `true` | 是否允许通过鼠标滚轮或触控板捏合手势缩放图表,默认为 true。 |
34
+ | scrollable | `boolean \| undefined` | - | `true` | 是否允许通过滚轮平移图表(非捏合手势),默认为 true。 |
35
+ | pannable | `boolean \| undefined` | - | `true` | 是否允许通过鼠标拖拽平移图表,默认为 true。 |
36
+ | scaleRange | `RangeTuple \| undefined` | - | - | 缩放比例范围,格式为 `[min, max]`,默认范围由内部常量决定。 |
37
+ | onActiveTargetChange | `(e: CustomEvent<ActiveTarget \| null>) => void` | - | - | 激活目标变化时触发。 |
38
+ | onNodeDelete | `(e: CustomEvent<DiagramNode>) => void` | - | - | 用户按 Delete/Backspace 键且当前激活目标为节点时触发。 |
39
+ | onEdgeDelete | `(e: CustomEvent<DiagramEdge>) => void` | - | - | 用户按 Delete/Backspace 键且当前激活目标为边时触发。 |
40
+ | onLineClick | `(e: CustomEvent<LineTarget>) => void` | - | - | 用户点击可交互连线时触发。 |
41
+ | onLineDblclick | `(e: CustomEvent<LineTarget>) => void` | - | - | 用户双击可交互连线时触发。 |
42
+ | onNodesConnect | `(e: CustomEvent<ConnectLineDetail>) => void` | - | - | 用户从一个节点拖拽连线到另一个节点并释放时触发。 |
43
+
44
+ ## Events
45
+
46
+ | 事件 | detail | 说明 |
47
+ | -------------------- | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
48
+ | onActiveTargetChange | `ActiveTarget \| null` — 当前激活目标,`{ type: "node", nodeId }` 或 `{ type: "edge", edge }` 或 null | 激活目标变化时触发,当用户点击节点或边使其激活,或点击空白处取消激活时触发。 |
49
+ | onNodeDelete | `DiagramNode` — 被删除的节点对象,包含节点 id 及其他自定义字段 | 用户按 Delete/Backspace 键且当前激活目标为节点时触发,需外部处理实际删除逻辑。 |
50
+ | onEdgeDelete | `DiagramEdge` — 被删除的边对象,包含 source、target 及其他自定义字段 | 用户按 Delete/Backspace 键且当前激活目标为边时触发,需外部处理实际删除逻辑。 |
51
+ | onLineClick | `LineTarget` — 被点击的连线信息,包含 `{ id: 连线唯一标识, edge: 对应的边数据 }` | 用户点击可交互连线时触发。 |
52
+ | onLineDblclick | `LineTarget` — 被双击的连线信息,包含 `{ id: 连线唯一标识, edge: 对应的边数据 }` | 用户双击可交互连线时触发,常用于触发连线标签编辑。 |
53
+ | onNodesConnect | `ConnectLineDetail` — 连线详情,包含 `{ source: 起始节点, target: 目标节点 }` | 用户从一个节点拖拽连线到另一个节点并释放时触发,需外部处理实际建立连接的逻辑。 |
54
+
55
+ ## Methods
56
+
57
+ | 方法 | 参数 | 返回值 | 说明 |
58
+ | --------------- | ------------------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------- |
59
+ | callOnLineLabel | `(id: string, method: string, args: unknown[]) => void` | `void` | 调用指定 id 的连线标签构件上的方法,常用于触发标签编辑(如 `callOnLineLabel(id, "enableEditing")`)。 |
60
+
61
+ ## Examples
62
+
63
+ ### Basic
64
+
65
+ 展示基本的 dagre 布局图表,包含节点和带箭头的连线,并支持动态添加/删除节点。
66
+
67
+ ```tsx
68
+ import { useState } from "react";
69
+ import { WrappedEoDiagram } from "@easyops/wrapped-components";
70
+
71
+ function BasicDiagram() {
72
+ const [activeTarget, setActiveTarget] = useState(null);
73
+ const [nodes, setNodes] = useState([
74
+ { id: "kspacey", label: "Kevin Spacey" },
75
+ { id: "swilliams", label: "Saul Williams" },
76
+ { id: "bpitt", label: "Brad Pitt" },
77
+ { id: "lwilson", label: "Luke Wilson" },
78
+ { id: "kbacon", label: "Kevin Bacon" },
79
+ ]);
80
+ const [edges, setEdges] = useState([
81
+ { source: "kspacey", target: "swilliams" },
82
+ { source: "swilliams", target: "kbacon" },
83
+ { source: "bpitt", target: "kbacon" },
84
+ { source: "lwilson", target: "kbacon" },
85
+ ]);
86
+
87
+ return (
88
+ <div
89
+ style={{
90
+ position: "fixed",
91
+ height: "100vh",
92
+ width: "100vw",
93
+ top: 0,
94
+ left: 0,
95
+ }}
96
+ >
97
+ <WrappedEoDiagram
98
+ layout="dagre"
99
+ nodes={nodes}
100
+ edges={edges}
101
+ lines={[{ arrow: true }]}
102
+ activeTarget={activeTarget}
103
+ nodeBricks={[
104
+ {
105
+ useBrick: {
106
+ brick: "div",
107
+ properties: {
108
+ style: {
109
+ width: "180px",
110
+ height: "100px",
111
+ border: "2px solid green",
112
+ display: "flex",
113
+ alignItems: "center",
114
+ justifyContent: "center",
115
+ },
116
+ },
117
+ },
118
+ },
119
+ ]}
120
+ onActiveTargetChange={(e) => setActiveTarget(e.detail)}
121
+ />
122
+ </div>
123
+ );
124
+ }
125
+ ```
126
+
127
+ ### Page Architecture
128
+
129
+ 展示 dagre 布局图表用于页面架构可视化,包含节点标签编辑、连线标签、连线创建和节点删除交互。
130
+
131
+ ```tsx
132
+ import { useState, useRef } from "react";
133
+ import { WrappedEoDiagram } from "@easyops/wrapped-components";
134
+
135
+ function PageArchDiagram() {
136
+ const diagramRef = useRef(null);
137
+ const [activeTarget, setActiveTarget] = useState(null);
138
+ const [editingLabelEdges, setEditingLabelEdges] = useState([]);
139
+ const [nodes, setNodes] = useState([
140
+ { type: "board", id: "60bf6078b095f", name: "Visual Builder", depth: 0 },
141
+ {
142
+ type: "page",
143
+ id: "60bf60848d6d2",
144
+ name: "项目列表",
145
+ depth: 1,
146
+ parentId: "60bf6078b095f",
147
+ },
148
+ {
149
+ type: "link",
150
+ id: "60bf6091a1089",
151
+ name: "新建项目",
152
+ depth: -1,
153
+ description: "新建页213",
154
+ },
155
+ ]);
156
+ const [edges, setEdges] = useState([
157
+ { type: "menu", source: "60bf6078b095f", target: "60bf60848d6d2" },
158
+ {
159
+ type: "link",
160
+ source: "60bf60848d6d2",
161
+ target: "60bf6091a1089",
162
+ description: "无项目",
163
+ },
164
+ ]);
165
+
166
+ return (
167
+ <div
168
+ style={{
169
+ position: "fixed",
170
+ height: "100vh",
171
+ width: "100vw",
172
+ top: 0,
173
+ left: 0,
174
+ }}
175
+ >
176
+ <WrappedEoDiagram
177
+ ref={diagramRef}
178
+ layout="dagre"
179
+ nodes={nodes}
180
+ edges={edges}
181
+ activeTarget={activeTarget}
182
+ disableKeyboardAction={editingLabelEdges.length > 0}
183
+ layoutOptions={{ nodePadding: [4, 10, 10] }}
184
+ connectNodes={{ arrow: true, strokeColor: "var(--theme-blue-color)" }}
185
+ lines={[
186
+ {
187
+ edgeType: "link",
188
+ strokeColor: "var(--theme-blue-color)",
189
+ arrow: true,
190
+ interactable: true,
191
+ },
192
+ {
193
+ edgeType: "menu",
194
+ strokeColor: "var(--palette-gray-5)",
195
+ arrow: true,
196
+ interactable: true,
197
+ },
198
+ ]}
199
+ nodeBricks={[
200
+ {
201
+ useBrick: {
202
+ brick: "div",
203
+ properties: {
204
+ style: {
205
+ padding: "8px 16px",
206
+ border: "1px solid var(--palette-gray-4)",
207
+ borderRadius: "4px",
208
+ background: "white",
209
+ },
210
+ },
211
+ },
212
+ },
213
+ ]}
214
+ onActiveTargetChange={(e) => setActiveTarget(e.detail)}
215
+ onNodeDelete={(e) => {
216
+ const node = e.detail;
217
+ setNodes((prev) => prev.filter(({ id }) => id !== node.id));
218
+ setEdges((prev) =>
219
+ prev.filter(
220
+ ({ source, target }) => source !== node.id && target !== node.id
221
+ )
222
+ );
223
+ }}
224
+ onEdgeDelete={(e) => {
225
+ const edge = e.detail;
226
+ setEdges((prev) =>
227
+ prev.filter(
228
+ ({ source, target }) =>
229
+ source !== edge.source || target !== edge.target
230
+ )
231
+ );
232
+ }}
233
+ onLineClick={(e) =>
234
+ setActiveTarget({ type: "edge", edge: e.detail.edge })
235
+ }
236
+ onLineDblclick={(e) => {
237
+ diagramRef.current?.callOnLineLabel(
238
+ `${e.detail.id}-center`,
239
+ "enableEditing"
240
+ );
241
+ }}
242
+ onNodesConnect={(e) => {
243
+ const { source, target } = e.detail;
244
+ if (
245
+ !edges.some(
246
+ (edge) => edge.source === source.id && edge.target === target.id
247
+ )
248
+ ) {
249
+ setEdges((prev) =>
250
+ prev.concat({
251
+ source: source.id,
252
+ target: target.id,
253
+ type: source.type === "board" ? "menu" : "link",
254
+ })
255
+ );
256
+ }
257
+ }}
258
+ />
259
+ </div>
260
+ );
261
+ }
262
+ ```
263
+
264
+ ### Force
265
+
266
+ 展示 force 布局的力导向图,支持拖拽节点、连线标签显示,适合展示关系网络。
267
+
268
+ ```tsx
269
+ import { useState } from "react";
270
+ import { WrappedEoDiagram } from "@easyops/wrapped-components";
271
+
272
+ function ForceDiagram() {
273
+ const [activeTarget, setActiveTarget] = useState(null);
274
+ const nodes = [
275
+ { id: "产品" },
276
+ { id: "产品评价" },
277
+ { id: "产品线" },
278
+ { id: "用户角色" },
279
+ { id: "模型视图" },
280
+ { id: "业务场景" },
281
+ { id: "业务规则" },
282
+ { id: "模型" },
283
+ { id: "产品模块" },
284
+ { id: "产品价值点" },
285
+ { id: "工作流" },
286
+ { id: "测试用例" },
287
+ { id: "功能点" },
288
+ ];
289
+ const edges = [
290
+ {
291
+ source: "产品",
292
+ target: "产品评价",
293
+ sourceName: "评价列表",
294
+ targetName: "所属产品",
295
+ },
296
+ {
297
+ source: "产品",
298
+ target: "产品线",
299
+ sourceName: "所属产品线",
300
+ targetName: "产品列表",
301
+ },
302
+ {
303
+ source: "产品",
304
+ target: "用户角色",
305
+ sourceName: "负责人",
306
+ targetName: "负责的产品",
307
+ },
308
+ {
309
+ source: "产品",
310
+ target: "业务场景",
311
+ sourceName: "业务场景列表",
312
+ targetName: "所属产品",
313
+ },
314
+ {
315
+ source: "业务场景",
316
+ target: "业务规则",
317
+ sourceName: "业务规则列表",
318
+ targetName: "所属业务场景",
319
+ },
320
+ {
321
+ source: "产品",
322
+ target: "模型",
323
+ sourceName: "模型列表",
324
+ targetName: "关联的产品",
325
+ },
326
+ {
327
+ source: "产品",
328
+ target: "产品模块",
329
+ sourceName: "模块列表",
330
+ targetName: "所属产品",
331
+ },
332
+ {
333
+ source: "产品模块",
334
+ target: "测试用例",
335
+ sourceName: "测试用例列表",
336
+ targetName: "所属产品模块",
337
+ },
338
+ {
339
+ source: "产品模块",
340
+ target: "功能点",
341
+ sourceName: "功能点列表",
342
+ targetName: "所属产品模块",
343
+ },
344
+ ];
345
+
346
+ return (
347
+ <div
348
+ style={{
349
+ position: "fixed",
350
+ height: "100vh",
351
+ width: "100vw",
352
+ top: 0,
353
+ left: 0,
354
+ }}
355
+ >
356
+ <WrappedEoDiagram
357
+ layout="force"
358
+ nodes={nodes}
359
+ edges={edges}
360
+ activeTarget={activeTarget}
361
+ dragNodes={{}}
362
+ scaleRange={[0.5, 2]}
363
+ layoutOptions={{
364
+ dummyNodesOnEdges: 1,
365
+ collide: { dummyRadius: 10, radiusDiff: 40 },
366
+ }}
367
+ lines={[
368
+ {
369
+ overrides: {
370
+ activeRelated: { strokeColor: "var(--palette-blue-4)" },
371
+ },
372
+ },
373
+ ]}
374
+ nodeBricks={[
375
+ {
376
+ useBrick: {
377
+ brick: "div",
378
+ properties: {
379
+ style: {
380
+ width: "160px",
381
+ height: "50px",
382
+ background: "var(--palette-green-1)",
383
+ border: "1px solid var(--palette-gray-4)",
384
+ borderRadius: "8px",
385
+ display: "flex",
386
+ alignItems: "center",
387
+ justifyContent: "center",
388
+ cursor: "pointer",
389
+ },
390
+ },
391
+ },
392
+ },
393
+ ]}
394
+ onActiveTargetChange={(e) => setActiveTarget(e.detail)}
395
+ />
396
+ </div>
397
+ );
398
+ }
399
+ ```