[{"data":1,"prerenderedAt":7},["ShallowReactive",2],{"example-markdown-content:en:node-css-skin-and-checked-state":3},{"markdown":4,"isPaidExample":5,"isTruncated":5,"charLimit":6},"# Default Tree Nodes with CSS Skinning and Checked State\n\n## What This Example Builds\n\nThis example builds a small left-to-right tree viewer that keeps relation-graph's built-in rectangular nodes and restyles them with a minimal white presentation. The canvas fills the screen, links use restrained dark curves, node chrome is mostly removed, and the remaining visual identity comes from black single-line labels plus a custom checked-state fill.\n\nUsers mainly inspect a prepared hierarchy rather than edit it. A floating helper window can be dragged, minimized, opened into a settings panel, and used to export the current graph as an image. The main lesson is how far the default node renderer can be pushed with graph options and scoped SCSS before moving to slot-rendered node bodies.\n\n## How the Data Is Organized\n\nThe graph data is declared inline as one `RGJsonData` object with a `rootId`, a flat `nodes` array, and a flat `lines` array. The sample content uses generic ids and labels such as `a`, `b1-4`, and `c3`, which makes the structure intentionally neutral so the styling pattern is easier to isolate.\n\nThere is no preprocessing before `setJsonData(...)`. The example sends the static dataset directly into relation-graph, then centers and fits it. In a production application, the same shape could represent organization levels, approval trees, product categories, decision branches, or any other lightweight hierarchy where the default text-node renderer is still sufficient.\n\n## How relation-graph Is Used\n\n`RGProvider` wraps the page, and `RGHooks.useGraphInstance()` supplies the live graph instance. The local `graphOptions` configure a `tree` layout that grows from the left, widen node spacing for readability, switch the node shape to `RGNodeShape.rect`, keep the node fill and border transparent, route links with `RGLineShape.StandardCurve`, and place the built-in toolbar horizontally at the bottom-right edge.\n\nThe example does not define `RGSlotOnNode` or any custom node-body component. Instead, it keeps relation-graph on the default renderer and changes the result with options plus scoped SCSS. The stylesheet forces `.rg-node-text` onto one line, sets the text color to black, and overrides `.rg-node-peel.rg-node-checked` so checked nodes use a translucent gray fill instead of the default emphasis.\n\nThe shared helper window adds the rest of the runtime behavior. `CanvasSettingsPanel` reads the current graph options from `RGHooks.useGraphStore()`, calls `graphInstance.setOptions(...)` to switch wheel and drag behavior, and uses `prepareForImageGeneration()` together with `restoreAfterImageGeneration()` to capture the graph canvas as an image. Those controls are useful utilities, but the local example-specific technique is the default-node skinning approach.\n\n## Key Interactions\n\n- The graph loads once on mount, then calls `moveToCenter()` and `zoomToFit()` so the full tree is visible immediately.\n- Users inspect a fixed tree in viewer mode; the local source does not add structure editing, node-authoring tools, or custom click-driven state changes.\n- The floating helper window can be dragged around the page, minimized, and reopened into a settings overlay.\n- The settings overlay switches `wheelEventAction` between scroll, zoom, and none, and switches `dragEventAction` between selection, move, and none.\n- The helper can export the current canvas as an image through the shared screenshot pipeline.\n- The stylesheet defines a checked-node appearance, but the local example code does not add its own checked-state handler.\n\n## Key Code Fragments\n\nThis options block shows that the example stays on relation-graph's default renderer and uses option choices to create a restrained tree-viewer baseline.\n\n```tsx\nconst graphOptions: RGOptions = {\n    backgroundColor: '#ffffff',\n    defaultLineColor: '#444',\n    defaultNodeColor: 'transparent',\n    defaultNodeBorderWidth: 0,\n    defaultNodeBorderColor: 'transparent',\n    defaultNodeShape: RGNodeShape.rect,\n    defaultLineShape: RGLineShape.StandardCurve,\n    defaultJunctionPoint: RGJunctionPoint.lr,\n    toolBarDirection: 'h',\n    toolBarPositionH: 'right',\n    toolBarPositionV: 'bottom',\n    layout: {\n        layoutName: 'tree',\n        from: 'left',\n        treeNodeGapH: 310,\n        treeNodeGapV: 70,\n    }\n};\n```\n\nThis fragment shows that the dataset is a direct inline tree with no preprocessing layer before it reaches the graph.\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        { id: 'b1-1', text: 'b1-1' }\n        // ...\n    ],\n    lines: [\n        { from: 'a', to: 'b', text: '' },\n        { from: 'b', to: 'b1', text: '' },\n        { from: 'b1', to: 'b1-1', text: '' }\n        // ...\n    ]\n};\n```\n\nThis initialization code proves that the example's lifecycle is simple: load the prepared tree, center it, and fit it to the viewport.\n\n```tsx\nconst initializeGraph = async () => {\n    await graphInstance.setJsonData(myJsonData);\n    graphInstance.moveToCenter();\n    graphInstance.zoomToFit();\n};\n\nuseEffect(() => {\n    initializeGraph();\n}, []);\n```\n\nThis SCSS fragment is the core styling technique: keep the default node markup, then refine text behavior and checked-state feedback through scoped selectors.\n\n```scss\n.relation-graph {\n    --rg-checked-item-bg-color: rgba(63, 62, 62, 0.34);\n\n    .rg-node {\n        .rg-node-text {\n            white-space: nowrap;\n            color: #000000;\n        }\n    }\n\n    .rg-node-peel.rg-node-checked {\n        .rg-node {\n            box-shadow: none;\n            background-color: var(--rg-checked-item-bg-color);\n        }\n    }\n}\n```\n\nThis shared settings fragment shows how the helper window turns graph-instance APIs into runtime viewing controls.\n\n```tsx\n\u003CSettingRow\n    label=\"Wheel Event:\"\n    options={[\n        { label: 'Scroll', value: 'scroll' },\n        { label: 'Zoom', value: 'zoom' },\n        { label: 'None', value: 'none' },\n    ]}\n    value={wheelMode}\n    onChange={(newValue: string) => { graphInstance.setOptions({ wheelEventAction: newValue }); }}\n/>\n```\n\nThis image-export routine shows the shared screenshot flow that prepares the graph DOM, captures it, downloads the blob, and restores the graph afterward.\n\n```tsx\nconst downloadImage = async () => {\n    const canvasDom = await graphInstance.prepareForImageGeneration();\n    let graphBackgroundColor = graphInstance.getOptions().backgroundColor;\n    if (!graphBackgroundColor || graphBackgroundColor === 'transparent') {\n        graphBackgroundColor = '#ffffff';\n    }\n    const imageBlob = await domToImageByModernScreenshot(canvasDom, {\n        backgroundColor: graphBackgroundColor\n    });\n    if (imageBlob) {\n        downloadBlob(imageBlob, 'my-image-name');\n    }\n    await graphInstance.restoreAfterImageGeneration();\n};\n```\n\n## What Makes This Example Distinct\n\nThe comparison data makes the strongest distinction clear: this example keeps the built-in rectangular text nodes and still reaches a custom-looking result mainly through options and SCSS. Compared with `node-style4`, it does not introduce `RGSlotOnNode`, icon templates, or a stronger branded theme. Compared with `node-style3`, it stays on an ordered tree layout with ordinary text labels instead of switching to a force layout and metadata-driven icon nodes.\n\nThat narrower choice gives it a specific retrieval value. It is a better starting point when a team wants low-friction CSS skinning on relation-graph's default node renderer, especially for readable non-wrapping labels and restrained checked-state feedback. The rarity data also supports the combination of a white utility shell, wide left-to-right tree spacing, transparent node chrome, dark curved links, and a translucent checked fill as an uncommon mix in the example set.\n\nThe shared helper window, runtime interaction switches, and image export are part of the experience, but they are not the unique claim here because nearby examples reuse the same scaffolding. The more defensible distinction is the emphasis on typography and checked-state refinement without leaving the default renderer.\n\n## Where Else This Pattern Applies\n\nThis pattern transfers well to internal hierarchy viewers, approval or responsibility trees, product-category explorers, and rule or decision trees where the graph needs to look more polished than the default theme but does not justify a custom node component system.\n\nIt is also a useful starting point for teams that need selection feedback and label control without adding per-node templates. If the domain data is already close to `id`, `text`, and `from`/`to` relationships, the same approach can deliver a readable branded tree with limited implementation cost.\n",false,500,1782615371824]