JavaScript is required

多个独立子系统关系网

这个示例将一份包含多个不连通簇和两个孤立节点的内联 `RGJsonData` 加载到同一 relation-graph 画布。它使用 `RGHooks.useGraphInstance()` 在挂载时调用 `setJsonData(...)`,并执行居中与视口适配,同时应用树布局、灰色曲线连线和路径贴合标签以提升碎片化数据可读性。

在一个树形视图中渲染多个彼此断开的子系统网络

这个示例构建了什么

这个示例构建了一个全高度的 relation-graph 查看器,在同一张画布上展示多个彼此断开的节点分组,以及两个完全孤立的节点。最终的视觉效果是一个采用树形走线的图,带有黑色节点描边、灰色曲线连接线,以及直接绘制在线路路径上的线标签。它的核心要点在于:单个 RelationGraph 实例可以呈现碎片化数据,而不需要为了让布局生效去额外添加人为构造的连线。

用户不需要通过按钮或自定义控件触发加载。图会在挂载时自行初始化、将视口重新居中、适配整个画布,随后页面保持为只读查看模式,并在右下角显示内置工具栏。

数据是如何组织的

数据在 MyGraph.tsx 中以一个模块级的 RGJsonData 字面量形式编写。它包含 rootId: '2'、一个 nodes 数组和一个 lines 数组。重要的结构特征是,这份数据载荷并不是一棵连续的树:一个分支从节点 2 开始,另一个从节点 6 开始,另一个从节点 10 开始,而 single-1single-2 则完全没有任何边连接。

在调用 setJsonData(...) 之前没有任何预处理步骤。这个示例不会推导辅助根节点、插入不可见边,也不会在布局前重建数据集。在真实项目中,相同的数据形态可以表示同屏展示的多个子系统清单、部分互联的设备关系图、从不同来源汇总的流程分组,或任何仍然存在孤立记录的图数据。

relation-graph 是如何使用的

index.tsx 使用 RGProvider 包裹这个演示,而 MyGraph.tsx 通过 RGHooks.useGraphInstance() 读取当前的图实例。图的配置完全通过 RelationGraph 上的 options 属性完成:节点边框被设置为 1 像素的黑色描边,工具栏以横向方式放置在右下角,线文本渲染在线路路径上,线的几何形态使用 RGJunctionPoint.lrRGLineShape.StandardCurve,并配合灰色描边颜色。

布局使用的是 relation-graph 内置的 tree 布局,并设置了 treeNodeGapH = 100。这很关键,因为源数据是碎片化的,而不是纯粹的层级结构,但该示例依然使用树形走线来保持各个分支的可读性。初始化采用命令式方式:setJsonData(...) 载入预先准备好的数据载荷,然后通过 moveToCenter()zoomToFit() 调整视口。

在审查过的源码中,没有节点、连线、画布或视口插槽,也不存在编辑工作流。本地 SCSS 文件只对 .rg-toolbar.rg-node.rg-line-text 这类选择器做了作用域限定,没有添加可见样式声明,因此大部分表现都来自 relation-graph 的默认样式,以及 graphOptions 中显式设置的选项值。

关键交互

  • 图会在组件挂载时自动加载。
  • 加载完成后,视口会居中并缩放到能够完整容纳整个碎片化数据集。
  • 用户通过内置工具栏和标准画布导航来查看结果,而不是通过自定义按钮或事件处理器。
  • 审查过的源码中没有自定义点击事件、编辑操作、展开/收起逻辑,也没有运行时模式切换。

关键代码片段

这段代码说明,数据集是直接内联编写的,并且在图加载之前就已经包含了两个孤立节点:

const myJsonData: RGJsonData = {
      rootId: '2',
      nodes: [
        { id: '2', text: 'ALTXX' },
        { id: '3', text: 'CH2 TTN' },
        { id: 'single-1', text: 'Single 1' },
        { id: 'single-2', text: 'Single 2' },

这段代码展示了,同一份数据载荷中包含多个彼此独立的连线分组,而不是一条连续的分支:

lines: [
    { from: '2', to: '5', text: '子系统' },
    { from: '2', to: '3', text: '子系统' },
    { from: '2', to: '4', text: '子系统' },
    // ... another disconnected cluster ...
    { from: '6', to: '13', text: '子系统' },
    { from: '6', to: '12', text: '子系统' },
    { from: '10', to: '33', text: '子系统' },
]

这段代码展示了这组选项如何让该示例呈现为一个采用树形走线的子系统风格查看器,而不是一个通用的默认画布:

const graphOptions: RGOptions = {
    defaultNodeBorderWidth: 1,
    defaultNodeBorderColor: '#000000',
    toolBarDirection: 'h',
    toolBarPositionH: 'right',
    toolBarPositionV: 'bottom',
    defaultLineTextOnPath: true,
    defaultJunctionPoint: RGJunctionPoint.lr,
    defaultLineShape: RGLineShape.StandardCurve,
    defaultLineColor: '#888888',
    layout: { layoutName: 'tree', treeNodeGapH: 100 }
};

这段代码证明,图实例会在挂载后以命令式方式被调用,用于加载数据并将整体结果纳入视图:

const initializeGraph = async () => {
    await graphInstance.setJsonData(myJsonData);
    graphInstance.moveToCenter();
    graphInstance.zoomToFit();
};

useEffect(() => {
    initializeGraph();
}, []);

这段代码表明,该示例被呈现为一个专用的全高度图工作区:

<div
    className={`my-graph`}
    style={{ height: '100vh' }}
>
    <RelationGraph options={graphOptions}>
    </RelationGraph>
</div>

这个示例的独特之处

根据对比数据,这个示例与 multi-groupmulti-group-3show-single-nodesshow-single-nodes2 最接近,但它解决的是不同的问题。与 multi-group 相比,它接收同样类型的碎片化数据载荷,却将其转换为一个采用树形走线的视图,并使用灰色曲线标注线标签,因此结果看起来更像一个结构化的子系统关系图,而不是一个通用的断网基线示例。

multi-group-3 相比,它从首次渲染开始就保持在同一种确定性的布局中。这里没有延迟执行的 updateOptions(...) 调用,也没有后续的 force-layout 过程。与 show-single-nodesshow-single-nodes2 相比,它更适合作为真正断开数据的参考,因为这些孤立节点在源数据载荷中就是完全无边的,而不是通过隐藏辅助线连接上去。

这种少见的组合在准备好的对比记录中表现得很明确:多个彼此断开的簇,加上两个孤立节点,使用内置树布局、路径上线标签的曲线连线、右下角工具栏导航,以及仅在挂载时执行的 load-center-fit 流程,没有编辑 UI,也没有预处理补丁方案。

这种模式还适用于哪些场景

这种模式适用于需要将多个相关分组放在一起展示的页面,即使底层数据并不完整,或者只存在部分连接。典型的迁移目标包括子系统清单、制造阶段关系图、设备与流程总览、并购阶段实体关系图,以及需要保留孤立记录可见性的主数据质量看板。

当团队想要在投入自定义渲染之前先验证碎片化图数据时,这种模式同样适用。项目可以先从这种直接加载 RGJsonData 的方式开始,确认彼此断开的分组和孤立节点能够在同一画布中稳定共存,然后再逐步增加领域特定的样式或交互。