[{"data":1,"prerenderedAt":7},["ShallowReactive",2],{"example-markdown-content:en:industry-chain-hierarchy-map":3},{"markdown":4,"isPaidExample":5,"isTruncated":5,"charLimit":6},"# Industry Chain Hierarchy Viewer with Preset Depth Control\n\n## What This Example Builds\n\nThis example builds a read-only industry-chain viewer for a semiconductor taxonomy. The canvas opens as a top-down tree whose root is `Semiconductor`, then branches into areas such as raw materials, design, manufacturing, testing, packaging, and equipment.\n\nUsers can reveal different hierarchy depths from a floating control window, toggle a minimap overlay, open shared canvas settings, and export the graph as an image. The most important visual idea is that the graph does not just expand by depth: it also recolors and restyles each node card according to the computed level from the finished layout.\n\n## How the Data Is Organized\n\nThe data is a single inline `RGJsonData` object declared inside `initializeGraph()`. It uses a classic tree structure: one `rootId`, a flat `nodes` array, and a flat `lines` array that connects each parent to its child.\n\nThere is almost no preprocessing before `setJsonData()`. The only transformation is a `map()` over `lines` that assigns a generated `id` when a line does not already have one. The important structural processing happens after the graph has been laid out: the example reads `node.lot.level` and then updates each node's `expanded`, `color`, and `className` fields in place.\n\nIn a real application, the same shape could represent a supply chain, a product taxonomy, a manufacturing capability map, a policy breakdown, or any other multilevel business hierarchy where the source data is parent-child rather than free-form network data.\n\n## How relation-graph Is Used\n\nThe page is wrapped in `RGProvider` in `index.tsx`, and the actual graph logic pulls the shared instance through `RGHooks.useGraphInstance()`. That hook is reused in the floating utility components too, so the example keeps one graph context for loading data, changing options, and exporting the current canvas.\n\nThe graph itself is configured as a top-down tree. `graphOptions` sets `layout.layoutName = 'tree'`, `from = 'top'`, a vertical gap of `120`, centered alignment, rectangular nodes, bottom expand holders, and curved top-bottom connectors through `RGLineShape.Curve2` with `RGJunctionPoint.tb`. `reLayoutWhenExpandedOrCollapsed` is enabled, which matches the preset-depth behavior.\n\nThe example uses several graph instance APIs in sequence. On mount it calls `loading()`, `setJsonData()`, `openByLevel(1)`, `moveToCenter()`, `zoomToFit()`, and `clearLoading()`. After that, depth changes rely on `getNodes()`, `updateNode()`, and `doLayout()` so the visible hierarchy and styling stay synchronized.\n\nTwo slots define the presentation layer. `RGSlotOnNode` replaces the default node body with a custom card, and `RGSlotOnView` conditionally mounts `RGMiniView` when the minimap toggle is enabled. The node slot uses `node.lot.level` again to choose header labels such as `Industry Chain Name`, `Industry Link`, and `Subsection Link`.\n\nStyling is split between runtime node updates and SCSS overrides. Runtime code writes a per-node `color` and `className`, while `my-relation-graph.scss` reads `var(--rg-node-color)` to paint the card border, header, body text, and expand button. Level-specific classes then adjust width and typography for different tiers.\n\nThe floating panel comes from the shared `DraggableWindow` component. That helper adds dragging, minimizing, a settings overlay, wheel and drag mode switches through `setOptions()`, and image export by calling `prepareForImageGeneration()` and `restoreAfterImageGeneration()` around a DOM screenshot step.\n\n## Key Interactions\n\n- The graph auto-loads on mount and initially opens to one computed depth level before centering and fitting the view.\n- The preset selector exposes three depth commands labeled `2`, `3`, and `4`. In code those buttons pass `1`, `2`, and `3` into `openByDeep()`, so the labels are presentation text rather than raw internal level numbers.\n- Each depth change reuses the same post-layout metadata to expand or collapse nodes, assign a level color, assign a level class, rerun layout, and refit the viewport.\n- The minimap checkbox toggles an `RGMiniView` overlay on the same canvas instead of opening a separate navigator.\n- The floating helper window can be dragged, minimized, switched into a canvas-settings overlay, and used to download the current graph as an image.\n\n## Key Code Fragments\n\nThis fragment shows that the example uses one inline hierarchy dataset and fills in missing line IDs before loading it.\n\n```tsx\nconst myJsonData: RGJsonData = {\n    rootId: '0',\n    nodes: [\n        { id: '0', text: 'Semiconductor' },\n        { id: '1', text: 'Final Test' },\n        // ... many semiconductor categories omitted ...\n    ],\n    lines: [\n        { text: '', from: '0', to: '1' },\n        { text: '', from: '1', to: '2' },\n        // ... hierarchy links omitted ...\n    ].map((line, index) => ({ ...line, id: line.id || `line-${index}` }))\n};\n```\n\nThis fragment shows the load sequence: data is mounted first, then level-based expansion runs, and only after that does the viewport recenter and fit.\n\n```tsx\ngraphInstance.loading();\nawait graphInstance.setJsonData(myJsonData);\nawait openByLevel(1);\ngraphInstance.moveToCenter();\ngraphInstance.zoomToFit();\ngraphInstance.clearLoading();\n```\n\nThis fragment shows the core technique of the example: computed layout depth becomes the source of truth for expansion, color, and CSS class.\n\n```tsx\nconst nodes = graphInstance.getNodes();\nconst levelColors = ['#5b05f1', '#FD8B37', '#9b9903', '#247c02'];\nnodes.forEach(node => {\n    const nodeLevel = Math.abs(node.lot.level || 0);\n    graphInstance.updateNode(node, {\n        color: levelColors[nodeLevel] || '#247c02',\n        expanded: nodeLevel \u003C level,\n        className: 'my-industy-node-level-' + nodeLevel\n    });\n});\nawait graphInstance.doLayout();\n```\n\nThis fragment shows how the custom node slot turns the same graph data into a tier-labeled business card instead of a default text node.\n\n```tsx\n\u003CRGSlotOnNode>\n    {({ node }: RGNodeSlotProps) => {\n        const level = node.lot?.level || 0;\n        let headerText = \"Product Type\";\n        if (level === 0) headerText = \"Industry Chain Name\";\n        else if (level === 1) headerText = \"Industry Link\";\n        else if (level === 2) headerText = \"Subsection Link\";\n\n        return (\n            \u003Cdiv className={`my-industy-node my-industy-node-level-${level}`}>\n```\n\nThis fragment shows how the minimap is treated as a view-level overlay that can be mounted only when the control panel enables it.\n\n```tsx\n\u003CSimpleUIBoolean\n    currentValue={showMiniView}\n    onChange={setShowMiniView}\n    label=\"Show graph minimap\"\n/>\n// ...\n\u003CRGSlotOnView>\n    {showMiniView && \u003CRGMiniView />}\n\u003C/RGSlotOnView>\n```\n\nThis fragment shows how SCSS consumes the runtime color and class metadata to style the cards.\n\n```scss\n.my-industy-node {\n    width: 160px;\n    border-radius: 5px;\n    background-color: #ffffff;\n    border: var(--rg-node-color) solid 1px;\n    .my-card-header {\n        background-color: var(--rg-node-color);\n        color: #fff;\n    }\n    .my-card-body {\n        color: var(--rg-node-color);\n    }\n}\n```\n\n## What Makes This Example Distinct\n\nCompared with nearby examples such as `open-by-level`, `investment`, `layout-tree`, and `layout-folder2`, this example is unusually focused on one business-reading surface rather than on layout experimentation or incremental data growth. The graph stays in one top-down tree configuration and uses that stable layout to present a large inline taxonomy clearly.\n\nIts main distinction is the combination of three behaviors that are treated as one pattern. First, depth changes are preset commands instead of manual branch-by-branch navigation. Second, the same computed `node.lot.level` drives disclosure state, color, and CSS class together. Third, the viewer can optionally add `RGMiniView` without changing the core hierarchy model.\n\nThat makes it different from `open-by-level`, which shares the level-based disclosure pattern but does not turn level metadata into a custom semantic card design. It also differs from `investment`, where the main lesson is lazy-loaded ownership expansion, and from `layout-tree` or `layout-folder2`, where the emphasis is layout tuning rather than a fixed industry-taxonomy presentation.\n\n## Where Else This Pattern Applies\n\nThis pattern transfers well to other read-only hierarchy viewers where the user needs fast jumps between overview depth and detail depth without editing the dataset.\n\nPossible migration targets include supplier-tier maps, capability breakdowns for manufacturing lines, multilevel product catalogs, regulatory or standards taxonomies, and organization knowledge maps. In each case, the key reusable idea is to let relation-graph compute the tree level once, then use that derived level to coordinate disclosure rules, semantic labeling, and visual emphasis.\n",false,500,1782615395150]