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