[{"data":1,"prerenderedAt":7},["ShallowReactive",2],{"example-markdown-content:en:node-resize-controls-and-styles":3},{"markdown":4,"isPaidExample":5,"isTruncated":5,"charLimit":6},"# Click-to-Resize Nodes with Switchable Resize Handle Styles\n\n## What This Example Builds\n\nThis example builds a small node-resizing workspace on top of a relation graph. The screen shows a full-height dotted canvas, a mixed sample graph with different node shapes and sizes, and a floating helper window that explains the interaction and exposes a style switcher.\n\nThe main user flow is direct size editing. Clicking a node makes it the current editing target, which causes relation-graph's built-in resize overlay to appear around that node. The user can then drag the resize handles and switch the overlay between the default appearance and two custom skins.\n\nThe most useful part of the example is its narrow scope. It does not try to become a full graph editor. Instead, it isolates the minimum setup for selected-node resizing and shows how to restyle the built-in resize controls with CSS.\n\n## How the Data Is Organized\n\nThe graph data is declared inline inside `initializeGraph()` as one `RGJsonData` object with `rootId`, a flat `nodes` array, and a `lines` array. The nodes are intentionally varied: some change border width or color, some change fill or font color, one is circular, two are rectangular, one has explicit `width` and `height`, and one uses fixed coordinates.\n\nThere is only one preprocessing step before `setJsonData()`: every line is mapped to add a generated `id` value. After that, the dataset is loaded once, centered, and zoomed to fit. The example does not do server synchronization, resize persistence, or incremental graph assembly in its own code.\n\nIn a real application, the same structure could represent dashboard cards, equipment blocks, organization units, topology devices, or workflow steps where operators need to adjust node dimensions in context without building a larger authoring tool.\n\n## How relation-graph Is Used\n\nThe entry file wraps the demo in `RGProvider`, and `MyGraph` uses `RGHooks.useGraphInstance()` to control the live graph. On mount, it loads the inline dataset with `setJsonData()`, then calls `moveToCenter()` and `zoomToFit()` so the sample graph is immediately usable.\n\nThe graph options stay minimal. The only explicit option is `dragEventAction: 'move'`, which turns canvas dragging into viewport panning. The editing flow is driven by two graph events: `onNodeClick` calls `setEditingNodes([nodeObject])`, while `onCanvasClick` calls `setEditingNodes([])`. That means the built-in editing-node state is the single source of truth for whether resize handles should be shown.\n\nThe resize UI is mounted through `RGSlotOnView`, not through custom node rendering. Inside that slot, `RGEditingNodeController` hosts `RGEditingResize`, which lets relation-graph draw and manage the resize overlay for the current editing node. The demo keeps the default node body and changes only the editing overlay.\n\nStyling is split between a wrapper class and SCSS overrides. The root `\u003Cdiv>` uses `myGraphStyle` in its class list, `SimpleUISelect` changes that value at runtime, and the SCSS file uses `.my-graph-style-01` and `.my-graph-style-02` to restyle `.rg-editing-ctrl` and `.rg-resize-ctl`. The same SCSS file also gives the canvas its scale-aware dotted background.\n\nThe floating `DraggableWindow` is shared helper infrastructure rather than the main lesson, but it still matters for runtime behavior. Its settings panel reads graph options with `RGHooks.useGraphStore()`, changes wheel and drag behavior with `graphInstance.setOptions(...)`, and exports the graph image through `prepareForImageGeneration()` and `restoreAfterImageGeneration()`.\n\n## Key Interactions\n\nClicking a node enters resize editing mode. The code puts that node into the editing-node set, and `RGEditingResize` renders handles for that selected target.\n\nDragging the built-in handles changes the current node's dimensions directly on the canvas. The example does not add custom resize math; it relies on relation-graph's built-in controller.\n\nClicking empty canvas space clears the editing-node set. That immediately removes the resize overlay and returns the canvas to its non-editing state.\n\nThe floating selector switches resize skins without changing resize behavior. It only changes the wrapper class, so the same built-in controller is shown with different handle shapes, sizes, offsets, and accent colors.\n\nThe helper window itself is interactive. It can be dragged, minimized, expanded into a settings panel, used to switch wheel and drag behavior, and used to export the current graph as an image, but those controls are secondary to the resize workflow.\n\n## Key Code Fragments\n\nThis fragment shows that the graph data is seeded inline and that line ids are generated before the dataset is loaded.\n\n```tsx\nconst myJsonData: RGJsonData = {\n    rootId: 'a',\n    nodes: [\n        { id: 'a', text: 'Border color', borderColor: '#333333' },\n        { id: 'a1-4', text: 'XXX', nodeShape: RGNodeShape.circle },\n        { id: 'd', text: 'Node Size', width: 150, height: 150, color: '#ff8c00', borderWidth: 5, borderColor: '#ffd700', fontColor: '#ffffff' },\n    ],\n    lines: [\n        { from: 'a', to: 'b' },\n        { from: 'a', to: 'a1' }\n    ].map((line, index) => ({ ...line, id: `line_${index}` }))\n};\n```\n\nThis fragment shows the mount-time graph initialization path.\n\n```tsx\nawait graphInstance.setJsonData(myJsonData);\ngraphInstance.moveToCenter();\ngraphInstance.zoomToFit();\n```\n\nThis fragment proves that the resize target is controlled entirely through relation-graph's editing-node state.\n\n```tsx\nconst onNodeClick = (nodeObject: RGNode, $event: RGUserEvent) => {\n    console.log('onNodeClick:', nodeObject);\n    graphInstance.setEditingNodes([nodeObject]);\n};\n\nconst onCanvasClick = () => {\n    graphInstance.setEditingNodes([]);\n};\n```\n\nThis fragment shows that the UI switches resize-controller skins by changing only the wrapper class.\n\n```tsx\n\u003Cdiv className={`my-graph ${myGraphStyle}`} style={{ height: '100vh' }}>\n    \u003CDraggableWindow>\n        \u003CSimpleUISelect\n            data={[\n                {value: '', text: 'Default'},\n                {value: 'my-graph-style-01', text: 'Customize Style 1'},\n                {value: 'my-graph-style-02', text: 'Customize Style 2'},\n            ]}\n            currentValue={myGraphStyle}\n            onChange={setMyGraphStyle}\n        />\n    \u003C/DraggableWindow>\n```\n\nThis fragment shows where the built-in resize overlay is mounted in the view layer.\n\n```tsx\n\u003CRelationGraph\n    options={graphOptions}\n    onCanvasClick={onCanvasClick}\n    onNodeClick={onNodeClick}\n>\n    \u003CRGSlotOnView>\n        \u003CRGEditingNodeController>\n            \u003CRGEditingResize />\n        \u003C/RGEditingNodeController>\n    \u003C/RGSlotOnView>\n\u003C/RelationGraph>\n```\n\nThis fragment shows how the second custom skin changes controller color and handle geometry through SCSS alone.\n\n```scss\n.my-graph-style-02 {\n    .relation-graph {\n        .rg-editing-ctrl {\n            --editor-main-color: #f616df;\n            box-shadow: 0 0 0 2px var(--editor-main-color);\n            --my-size-big: 20px;\n            --my-size-small: 8px;\n            .rg-resize-ctl {\n                --resize-handler-size: 12px;\n                --resize-handler-offset: -5px;\n            }\n        }\n    }\n}\n```\n\n## What Makes This Example Distinct\n\nThe comparison data shows that this example is not distinctive merely because it uses `RGEditingNodeController`, `RGEditingResize`, editing-node state, or the shared floating helper window. Nearby examples such as `batch-operations-on-nodes`, `edit-node-text`, `gee-node-alignment-guides`, and `freely-draw-lines-on-canvas` reuse parts of that editing scaffold.\n\nWhat stands out is the narrower retrieval target. This example concentrates on one selected-node workflow: click a node, expose the built-in resize overlay, and optionally swap that overlay between the default look and two custom SCSS skins. Compared with `batch-operations-on-nodes` and `gee-node-alignment-guides`, it spends its interaction budget on resize-controller theming rather than multi-select tools, snapping, or drag-time alignment aids.\n\nIt is also a more direct geometry-editing reference than `edit-node-text` or `freely-draw-lines-on-canvas`. Those examples lean on custom node slots, inline text inputs, drawing layers, or node creation flows. This one keeps the stock node rendering and demonstrates that built-in resize controls can be restyled through CSS while the resize behavior itself stays unchanged.\n\nThe prepared rarity notes also make the live skin switch and mixed node geometry sampler important. The example deliberately mixes circle and rectangle nodes with different sizes so the resize overlay can be tested against different shapes in one compact canvas.\n\n## Where Else This Pattern Applies\n\nThis pattern transfers well to tools where users need to resize existing graph items but do not need a full authoring environment. Examples include dashboard-layout editors, organization-chart maintenance tools, equipment or floor-plan annotations, topology diagram cleanup tools, and whiteboard templates with resizable cards.\n\nA production version could keep the same editing-node workflow while replacing the inline sample data with API data, persisting width and height after resize, adding permission checks, or exposing more controller skins for different editing modes. The reusable idea is to keep resize behavior inside relation-graph's built-in controller and customize its appearance with wrapper-level CSS.\n",false,500,1782615405029]