监听图谱大小变化
这个示例展示当宿主容器尺寸变化时,如何保持 relation-graph 视图居中并自适应。选择器驱动方形包裹层尺寸变化,图通过 `onViewResize` 调用现有实例的 `moveToCenter()` 和 `zoomToFit()` 进行响应。
当容器尺寸变化时保持 Relation Graph 居中
此示例构建了什么
这个示例在一个方形宿主面板内,为固定的示例图构建了一个小型查看器。画布上方的选择器可以在 400、600、800 和 1000 像素之间切换宿主尺寸,而图会在视图尺寸变化后自动重新居中并缩放到适配状态。
从视觉上看,页面保持了极简风格:青色矩形节点、蓝绿色直线,以及一个带红色边框的视口框。重点不在示例数据本身,而在于这种对尺寸变化安全的嵌入模式:修改外层容器大小,让 RelationGraph 触发 onViewResize,然后再次规范化视口。
数据如何组织
图数据以内联方式声明为一个 RGJsonData 对象,其中包含 rootId、nodes 和 lines。节点使用扁平记录,例如 { id: 'b1-3', text: 'b1-3' },每条连线也都有显式的 id,例如 { id: 'l12', from: 'a', to: 'c' }。
在调用 setJsonData() 之前没有任何预处理步骤。组件只构造一次 JSON 对象,直接将其传给图实例,并把尺寸变化状态单独保存在 currentSize 中。在真实应用中,同样的数据结构可以表示从 API 加载的组织树、依赖图或工作流分支图。
如何使用 relation-graph
整个集成刻意保持得很小。index.tsx 用 RGProvider 包装整个演示,MyGraph.tsx 则通过 RGHooks.useGraphInstance() 获取当前激活的图实例。随后,组件使用 setJsonData() 加载数据,通过 moveToCenter() 让图居中,再调用 zoomToFit() 让视口适配内容。
这个示例没有配置自定义布局算法、编辑模式或任何渲染插槽。相反,它依赖一个紧凑的 options 对象来定义无边框矩形节点、直线连线以及边框连接点。这里的关键特性是 RelationGraph 组件还绑定了 onViewResize。当宿主面板尺寸变化时,回调会让现有图重新居中并重新适配,而不是重建数据或重新布局出一个新模型。
样式分成图选项和外层 React 包装两部分。可见的方形面板来自普通的包装标记,以及由 React 状态驱动的内联宽高样式。导入的 SCSS 文件只包含空的选择器骨架,因此这个示例实际上是在讲解行为模式,而不是自定义皮肤。
关键交互
显式的用户交互就是尺寸选择器。点击不同的值会更新 currentSize,从而同时改变方形图宿主容器的宽度和高度。
功能性的交互会在该状态变化后立刻发生。RelationGraph 会触发 onViewResize,处理函数随后调用 moveToCenter() 和 zoomToFit(),这样同一张图就能在新的视口尺寸中保持居中并完整可见。
这一视口规范化模式在启动时也会执行一次。内联 JSON 数据加载完成后,组件会让初始视图居中并适配,因此首次渲染和后续尺寸变化事件都遵循同一条规则。
关键代码片段
这个包装层让基于 provider 作用域的图实例 hook 可以在示例内部使用。
<RGProvider>
<MyGraph />
</RGProvider>
这个 options 对象说明,该演示只把 relation-graph 的默认能力用于行为层面,而视觉定制仅限于少量形状和颜色设置。
const graphOptions: RGOptions = {
debug: false,
defaultNodeBorderWidth: 0,
defaultLineColor: 'rgba(0, 186, 189, 1)',
defaultNodeColor: 'rgba(0, 206, 209, 1)',
defaultNodeShape: RGNodeShape.rect,
defaultLineShape: RGLineShape.StandardStraight,
defaultJunctionPoint: RGJunctionPoint.border
};
这段启动流程表明,图只会从内联 JSON 加载一次,并在挂载后立即完成规范化。
await graphInstance.setJsonData(myJsonData);
graphInstance.moveToCenter();
graphInstance.zoomToFit();
这个处理函数就是尺寸变化模式的核心:响应图视图的 resize 事件,让当前图重新居中并重新适配。
const onViewResize = () => {
console.log('onViewResize');
graphInstance.moveToCenter();
graphInstance.zoomToFit();
};
这个由状态驱动的包装层说明,尺寸变化来自外围 React UI,而不是图数据发生了变化。
const [currentSize, setCurrentSize] = useState(400);
<div className="border-2 border-red-600 shadow-xl"
style={{
width: currentSize + 'px',
height: currentSize + 'px',
position: 'relative'
}}
>
<RelationGraph options={graphOptions} onViewResize={onViewResize} />
</div>
这个示例的独特之处
与附近的 zoom、layout-tree、customize-fullscreen-action 和 graph-instance-api 等示例相比,这个示例聚焦的是对尺寸变化有响应能力的嵌入方式,而不是缩放预设、重新布局、全屏组合或分支控制 API。
它最突出的特征是显式绑定了 onViewResize。对比数据将这个回调、由选择器驱动的方形宿主容器,以及后续的 moveToCenter() 与 zoomToFit() 调用序列标记为该示例集合中较少见的特性。这一点很重要,因为图数据和选项在挂载之后保持不变。第二条视口管理路径存在的唯一目的,就是在容器尺寸变化时,让已经加载好的图仍然保持可用。
对于这种模式来说,这个示例也显得格外紧凑。它把基于 provider 的启动方式、内联 RGJsonData、显式连线 id、状态驱动的包装层,以及由尺寸变化触发的视口修正组合在一起,同时又没有加入插槽、编辑工具或领域特定内容。因此,当真实问题是宿主容器尺寸变化,而不是图语义本身时,它是一个更干净的起点。
这一模式还适用于哪些场景
这一模式非常适合可展开、可折叠或可拖拽到不同面板尺寸中的仪表盘卡片。相同的“事件到实例”流程可以在卡片几何尺寸变化时保持图的可读性,而不必每次都重建图数据。
它同样适用于分栏面板、可调整大小的对话框、标签页面板以及低代码编辑器,在这些场景中,图只是更大界面中的一个部分。此时最重要的思想是:让外层 UI 状态控制容器尺寸,并在周围布局发生变化后,通过 onViewResize 恢复一个合理的视口。