[{"data":1,"prerenderedAt":7},["ShallowReactive",2],{"example-markdown-content:en:center-layout-expand-relayout-toggle":3},{"markdown":4,"isPaidExample":5,"isTruncated":5,"charLimit":6},"# Live Expand/Collapse Relayout in a Centered Hierarchy\n\n## What This Example Builds\n\nThis example builds a full-height centered hierarchy viewer for comparing what happens after a user expands or collapses branches with relation-graph's built-in expand holder. The canvas shows one root-centered subsystem-style graph with large cyan circular nodes, teal connectors, repeated `Subsystem` labels rendered on the line path, and a floating white helper window layered above the graph.\n\nUsers can expand or collapse branches directly on the graph, switch the follow-up behavior between `Re-layout` and `Do not re-layout`, drag the helper window, minimize it, and open a secondary settings overlay. That overlay comes from a shared local helper and adds wheel-mode, drag-mode, and image-download controls, but the main point of the example is the live toggle for `reLayoutWhenExpandedOrCollapsed` in a center layout rather than any custom animation-tuning logic.\n\n## How the Data Is Organized\n\nThe data is declared inline inside `initializeGraph()` as one `RGJsonData` object. It uses `rootId: '2'`, defines 39 hard-coded nodes, and connects them with 38 explicit lines. The labels mix subsystem names, manufacturing steps, and component names, but the structure itself stays simple: nodes only need `id` and `text`, while lines only need `from`, `to`, and the repeated edge label text.\n\nThere is no preprocessing step before `setJsonData(...)`. The component does not fetch data, normalize records, or derive a second layout structure. In a real application, the same pattern could represent a product architecture map, an equipment decomposition, a manufacturing capability breakdown, a technical subsystem tree, or any other root-centered hierarchy where the team needs to decide whether expansion should trigger a fresh layout pass.\n\n## How relation-graph Is Used\n\n`index.tsx` wraps the example in `RGProvider`, and `MyGraph.tsx` uses `RGHooks.useGraphInstance()` to control the graph through the instance API. The graph options configure `layoutName: 'center'` with `distanceCoefficient: 1.5`, circular nodes sized to `100x100`, cyan node fill, teal line color, bottom-positioned expand holders, and line text rendered directly on the connector path. The result is a root-centered diagram where the visual impact of post-expand relayout is easy to compare because branches can redistribute in multiple directions around the root.\n\nThe component loads its inline hierarchy with `setJsonData(...)`, then immediately calls `moveToCenter()` and `zoomToFit()` so the full graph starts framed in view. A second effect watches the React `relayout` state and pushes it into the live graph instance through `updateOptions({ reLayoutWhenExpandedOrCollapsed })`. That runtime synchronization is the main relation-graph technique in this sample: the graph behavior changes without rebuilding the dataset or remounting the component.\n\nThere are no custom node, line, canvas, or viewport slots in this example, and there are no example-specific graph event handlers. Expand and collapse behavior comes from relation-graph's built-in holder, not from custom slots or manual branch visibility code. The example also does not implement editing or authoring features.\n\nThe floating control surface comes from the shared local `DraggableWindow` helper. That helper is not unique to this example, but it matters because it makes the relayout selector movable and gives the demo a secondary settings overlay. Inside that overlay, `CanvasSettingsPanel` uses `RGHooks.useGraphStore()` to read `wheelEventAction` and `dragEventAction`, calls `graphInstance.setOptions(...)` to update those values on the live graph, and uses `prepareForImageGeneration()` plus `restoreAfterImageGeneration()` to support image export. The local SCSS file only contains empty wrapper selectors, so nearly all visible styling comes from graph options and the shared floating window instead of from custom CSS overrides.\n\n## Key Interactions\n\n- Clicking a built-in expand holder opens or closes a branch in the centered hierarchy.\n- Clicking `Re-layout` or `Do not re-layout` updates `reLayoutWhenExpandedOrCollapsed` on the mounted graph, so the next expand or collapse action either repacks the visible hierarchy or preserves the current branch placement.\n- The helper window can be dragged by its title bar, which keeps the control surface movable instead of fixed to one screen position.\n- The helper window can be minimized, which lets the example switch between a teaching mode with visible controls and a cleaner viewing mode.\n- The settings button opens a shared overlay that can change wheel behavior, change canvas drag behavior, and download the graph as an image. Those controls are secondary shared utilities rather than the example's main lesson.\n\n## Key Code Fragments\n\nThis fragment shows that the example is deliberately configured as a centered hierarchy with larger spacing, large circular nodes, and a runtime relayout option:\n\n```tsx\nconst graphOptions: RGOptions = {\n    layout: {\n        layoutName: 'center',\n        distanceCoefficient: 1.5\n    },\n    defaultNodeBorderWidth: 1,\n    defaultNodeShape: RGNodeShape.circle,\n    defaultNodeWidth: 100,\n    defaultNodeHeight: 100,\n    defaultLineColor: 'rgba(0, 186, 189, 1)',\n    defaultNodeColor: 'rgba(0, 206, 209, 1)',\n    reLayoutWhenExpandedOrCollapsed: relayout,\n    defaultExpandHolderPosition: 'bottom',\n    defaultLineTextOnPath: true\n};\n```\n\nThis fragment shows that the hierarchy is assembled inline and passed directly to relation-graph without any transformation step:\n\n```tsx\nconst myJsonData: RGJsonData = {\n    rootId: '2',\n    nodes: [\n        { id: '2', text: 'ALTXX' },\n        { id: '3', text: 'CH2 TTN' },\n        { id: '4', text: 'CH1 AlCu' },\n        // ... additional nodes omitted\n    ],\n    lines: [\n        { from: '2', to: '5', text: 'Subsystem' },\n        { from: '2', to: '6', text: 'Subsystem' },\n        // ... additional lines omitted\n    ]\n};\n```\n\nThis fragment shows the mount-time loading sequence: load the hierarchy once, then center and fit it in the viewport:\n\n```tsx\nawait graphInstance.setJsonData(myJsonData);\ngraphInstance.moveToCenter();\ngraphInstance.zoomToFit();\n```\n\nThis fragment shows the runtime option-synchronization pattern that makes the example useful:\n\n```tsx\nconst syncOptionsToGraph = () => {\n    graphInstance.updateOptions({\n        reLayoutWhenExpandedOrCollapsed: relayout\n    });\n};\n\nuseEffect(() => {\n    syncOptionsToGraph();\n}, [relayout]);\n```\n\nThis fragment shows that the user-facing control is a direct boolean selector instead of a reset, rebuild, or script-driven action:\n\n```tsx\n\u003CSimpleUISelect\n    data={[\n        { value: true, text: 'Re-layout' },\n        { value: false, text: 'Do not re-layout' }\n    ]}\n    currentValue={relayout}\n    onChange={(newValue: boolean) => {\n        setRelayout(newValue);\n    }}\n/>\n```\n\nThis fragment shows that the shared overlay can still reconfigure live canvas behavior through the graph instance:\n\n```tsx\nconst { options } = RGHooks.useGraphStore();\nconst dragMode = options.dragEventAction;\nconst wheelMode = options.wheelEventAction;\n\n\u003CSettingRow\n    label=\"Wheel Event:\"\n    value={wheelMode}\n    onChange={(newValue: string) => { graphInstance.setOptions({ wheelEventAction: newValue }); }}\n/>\n```\n\n## What Makes This Example Distinct\n\nThe comparison data shows that `expand-animation` is the closest direct neighbor because both examples use the same floating selector pattern and the same `updateOptions({ reLayoutWhenExpandedOrCollapsed })` technique. The difference is the layout context. This example uses a centered hierarchy with `distanceCoefficient: 1.5`, large cyan circular nodes, bottom expand holders, and path-labeled teal connectors, so branch redistribution happens around one root instead of along a single vertical direction.\n\nCompared with `open-all-close-all`, this sample does not script recursive whole-graph playback, timed expansion, or animation choreography. It isolates the simpler decision of whether ordinary user-driven expand or collapse actions should trigger relayout. Compared with `multiple-expand-buttons`, it relies on the built-in expand holder rather than custom node slots and manual left-or-right branch visibility logic.\n\nWhat makes it especially useful is the combination of a 39-node centered subsystem hierarchy, live synchronization of `reLayoutWhenExpandedOrCollapsed`, a floating helper window, and path-based line labels on one screen. That makes it a stronger starting point for root-centered hierarchy products than the top-down tree version when the team needs to evaluate how much spatial movement should happen after disclosure. The comparison artifacts also make one boundary clear: this is not a true animation-parameter demo, because the reviewed source does not configure custom timing, easing, or transition code.\n\n## Where Else This Pattern Applies\n\nThis pattern transfers well to subsystem maps, product structure viewers, equipment trees, capability maps, and technical knowledge hierarchies where the root sits near the middle of the canvas and users repeatedly open or close branches while trying to keep orientation. It is especially relevant when the product team needs to decide whether expansion should preserve local positions or trigger a full visual rebalance.\n\nThe same approach can also be reused in settings-heavy graph tools, QA harnesses, or admin interfaces that expose layout behavior as a runtime preference. Instead of hard-coding one disclosure policy, a product can let users compare both modes on the same dataset before committing to the default.\n",false,500,1782615434096]