[{"data":1,"prerenderedAt":7},["ShallowReactive",2],{"example-markdown-content:en:initialize-graph-on-tab-reveal":3},{"markdown":4,"isPaidExample":5,"isTruncated":5,"charLimit":6},"# Initialize a Graph on First Tab Reveal\n\n## What This Example Builds\n\nThis example builds a full-height page with three mutually exclusive panels: `Basic Info`, `Graph`, and `Warning Info`. The user does not see a graph on first load. Instead, the page opens on a green placeholder panel, then switches to a left-to-right tree graph only when the `Graph` tab is selected.\n\nThe main point is lifecycle control rather than graph styling. The example shows how to keep `RelationGraph` out of the DOM until its panel becomes visible, then initialize the data once and immediately center and fit the viewport for the first visible render.\n\n## How the Data Is Organized\n\nThe graph data is declared inline inside `initializeGraph()` as one `RGJsonData` object with `rootId: 'a'`, 13 flat `nodes`, and 12 flat `lines`. The tree structure is expressed through `from` and `to` pairs, not through nested `children`.\n\nThere is only one preprocessing step before loading: the code iterates over every line and assigns an `id` when one is missing. After that, the dataset is passed directly to `setJsonData()`. In a real application, the same structure could represent record dependencies, troubleshooting branches, approval chains, or any detail page where a graph is one secondary tab inside a broader information screen.\n\n## How relation-graph Is Used\n\n`index.tsx` wraps the example in `RGProvider`, and `MyGraph.tsx` gets the active instance through `RGHooks.useGraphInstance()`. The visible graph is configured as a left-to-right tree with `treeNodeGapH: 120`, `treeNodeGapV: 20`, rectangular nodes, `defaultNodeWidth: 100`, `RGLineShape.StandardCurve`, `RGJunctionPoint.lr`, and right-side expand holders.\n\nNo custom node, line, canvas, or viewport slots are used here. The important pattern is deferred instance-driven loading: `setJsonData()` injects the data only after the graph tab becomes active, then `moveToCenter()` and `zoomToFit()` normalize the first visible frame. The SCSS file is present as an override scaffold, but it does not materially restyle the graph in this example.\n\nThe graph is conditionally embedded rather than permanently mounted. A local `SimpleUISelect` component controls `activeTabName`, `RelationGraph` is rendered only when `activeTabName === 'graph'`, and a `useEffect()` guarded by `graphInitedRef` ensures the initialization routine runs only on the first graph-tab activation. The reviewed source intentionally does not establish whether graph state persists after leaving and re-entering the tab.\n\n## Key Interactions\n\n- Clicking the selector switches between `Basic Info`, `Graph`, and `Warning Info`.\n- The first switch to `Graph` mounts `RelationGraph`, builds the inline dataset, loads it through `setJsonData()`, and then centers and fits the viewport.\n- Switching to `Basic Info` or `Warning Info` replaces the graph panel with placeholder content instead of merely hiding the graph with CSS.\n- The selector itself is a reusable local component whose active-state styling is driven by `currentValue`.\n\n## Key Code Fragments\n\nThis wrapper shows that the page and the graph component share the same relation-graph provider context.\n\n```tsx\nconst Demo = () => {\n    return (\n        \u003CRGProvider>\n            \u003CMyGraph />\n        \u003C/RGProvider>\n    );\n};\n```\n\nThis block shows that the visible graph is a left-to-right tree with rectangular nodes and curved links.\n\n```tsx\nconst graphOptions: RGOptions = {\n    layout: {\n        layoutName: 'tree',\n        from: 'left',\n        treeNodeGapH: 120,\n        treeNodeGapV: 20\n    },\n    defaultExpandHolderPosition: 'right',\n    defaultNodeShape: RGNodeShape.rect,\n    defaultNodeWidth: 100,\n    defaultLineShape: RGLineShape.StandardCurve,\n    defaultJunctionPoint: RGJunctionPoint.lr\n};\n```\n\nThis fragment proves that the graph payload is a flat inline `nodes` and `lines` structure rather than nested `children`.\n\n```tsx\nconst myJsonData: RGJsonData = {\n    rootId: 'a',\n    nodes: [\n        { id: 'a', text: 'a' },\n        { id: 'b', text: 'b' },\n        { id: 'b1', text: 'b1' },\n        // ... more nodes ...\n    ],\n    lines: [\n        { from: 'a', to: 'b', text: 'line1' },\n        // ... more lines ...\n    ]\n};\n```\n\nThis fragment shows the only preprocessing step and the immediate viewport normalization after the first load.\n\n```tsx\nmyJsonData.lines.forEach((line, index) => {\n    if (!line.id) {\n        line.id = `line-${index}`;\n    }\n});\nawait graphInstance.setJsonData(myJsonData);\ngraphInstance.moveToCenter();\ngraphInstance.zoomToFit();\n```\n\nThis effect is the core lifecycle pattern: do nothing until the graph tab is active, then initialize only once.\n\n```tsx\nuseEffect(() => {\n    if (activeTabName === 'graph') {\n        if (!graphInitedRef.current) {\n            graphInitedRef.current = true;\n            initializeGraph();\n        }\n    }\n}, [activeTabName]);\n```\n\nThis render branch makes the graph one panel inside a three-state workspace instead of the page's permanent surface.\n\n```tsx\n{activeTabName === 'graph' && (\n    \u003Cdiv className=\"h-full\">\n        \u003CRelationGraph options={graphOptions} />\n    \u003C/div>\n)}\n{activeTabName === 'warning' && (\n    \u003Cdiv className=\"h-full bg-yellow-100 flex justify-center place-items-center text-4xl\">\n        Warning Information\n    \u003C/div>\n)}\n```\n\n## What Makes This Example Distinct\n\nThe comparison data places this example near `customize-fullscreen-action`, `tree-data`, and `graph-instance-api`, which all share provider-scoped instance access, tree rendering, and post-load centering. What distinguishes `adv-hide-2-show` is the first-visibility lifecycle pattern: `RelationGraph` is absent until the user selects the `Graph` tab, then the example loads a flat inline dataset, generates missing line ids, and normalizes the viewport immediately after that first reveal.\n\nCompared with `customize-fullscreen-action`, this example is not about wrapper composition or fullscreen targeting. It swaps among three full-height content panels and focuses on hidden-container timing. Compared with `tree-data`, it emphasizes deferred reveal and flat `nodes` plus `lines` data instead of immediate mount with nested `children`. Compared with `graph-instance-api`, it uses the same hook and instance APIs only for initial reveal and viewport setup, not for ongoing programmatic expand or collapse controls.\n\nWithin the simpler placeholder-panel examples, the distinctive combination is tab-driven lazy reveal plus a one-time initialization guard. That makes it a better starting point for screens where the graph is an optional inspection mode rather than the default page surface.\n\n## Where Else This Pattern Applies\n\nThis pattern transfers directly to tabs, drawers, accordions, steppers, and modal detail views where a graph should not be initialized while its container is hidden. It is also useful for mixed-content record pages where users first review summary or warning information, then open a graph as a secondary analysis panel.\n\nThe same structure also fits API-driven loading. Instead of hard-coded data, an application could fetch relationships only when the graph tab becomes active, assign missing edge ids before loading, and then call center-and-fit so the first visible frame is ready for use immediately.\n",false,500,1782615433408]