JavaScript is required

Customize Toolbar Buttons

This example shows how to disable relation-graph's built-in toolbar and replace it with custom controls mounted through `RGSlotOnView`. It combines `RGToolBar`, two `RGMiniToolBar` variants, shared React state for mirrored favorite buttons, and a toggleable `RGMiniView` with light SCSS styling.

Custom Toolbar Buttons with a Toggleable Minimap

What This Example Builds

This example builds a small graph viewer that hides relation-graph’s default toolbar and replaces it with custom overlay controls. Users see a centered sample graph, a vertical mini toolbar on the top left, a standard toolbar, and a second mini toolbar on the top right that can show or hide a minimap. The key lesson is how to reuse relation-graph’s toolbar containers as shells for project-specific buttons instead of accepting the default graph chrome.

How the Data Is Organized

The graph data is declared inline inside initializeGraph as a static RGJsonData object with rootId: 'a', five nodes, and four lines. There is no fetch step and no transformation pipeline before setJsonData; the only preprocessing is the literal construction of the dataset and the per-node visual overrides such as color, nodeShape, width, and height. In a real application, the same structure could represent people and reporting lines, services and dependencies, or devices and upstream links.

How relation-graph Is Used

index.tsx wraps the example in RGProvider, which makes RGHooks.useGraphInstance() available inside MyGraph.tsx. The graph options use the center layout, disable debug output, and set showToolBar: false so the built-in toolbar does not render. After mount, the component calls setJsonData(...), moveToCenter(), and zoomToFit() on the graph instance to load and normalize the initial view.

The custom controls are mounted through RGSlotOnView. Inside that overlay layer, the example renders one RGToolBar, one top-left vertical RGMiniToolBar, one top-right horizontal RGMiniToolBar, and a conditional RGMiniView. The SCSS file then restyles .rg-miniview with a pink outline, a tinted visible-area mask, and a lower top offset. No node slots, canvas slots, editing APIs, or graph mutation flows are used here; this remains a viewer-oriented customization example.

Key Interactions

  • Clicking either star button toggles the shared favo state, so the favorite icon updates in both the mini toolbar and the standard toolbar.
  • Clicking the locate button in the top-right mini toolbar toggles showMiniView, which mounts or unmounts RGMiniView.
  • The share and help buttons call alert(...), so they act as placeholders for product actions rather than as graph operations.

Key Code Fragments

This options block proves that the built-in toolbar is intentionally disabled so the overlay slot can replace it.

const graphOptions: RGOptions = {
    debug: false,
    layout: {
        layoutName: 'center'
    },
    showToolBar: false // We render custom toolbar content in the view slot.
};

This initialization sequence shows that the custom toolbar layer still sits on a normal relation-graph startup flow.

const myJsonData: RGJsonData = {
    rootId: 'a',
    nodes: [
        { id: 'a', text: 'A', color: '#43a2f1' },
        { id: 'b', text: 'B', color: '#229502ff' },
        { id: 'c', text: 'C', nodeShape: 1, width: 120, height: 80 }
        // ...
    ]
};

await graphInstance.setJsonData(myJsonData);
graphInstance.moveToCenter();
graphInstance.zoomToFit();

This handler proves that the favorite action is only local React state and that the other buttons are placeholders.

const myToolbarBtnAction = (msg: string) => {
    if (msg === 'favo') {
        setFavo(!favo);
    } else {
        alert(msg);
    }
};

This slot composition is the core pattern: multiple toolbar surfaces and the minimap are mounted inside the graph view overlay.

<RGSlotOnView>
    <RGMiniToolBar positionV='top' positionH='left' direction='v'>
        {/* custom favorite and share buttons */}
    </RGMiniToolBar>
    <RGToolBar>
        {/* custom favorite, share, and help buttons */}
    </RGToolBar>
    <RGMiniToolBar positionV='top' positionH='right' direction='h'>
        {/* minimap toggle button */}
    </RGMiniToolBar>
    {showMiniView && <RGMiniView position='tr' />}
</RGSlotOnView>

This SCSS fragment shows that the minimap is lightly branded without changing its underlying behavior.

.rg-miniview {
    top: 50px;
    box-shadow: 0 0 0 1px #ec4899;

    .rg-mv-visible-area {
        box-shadow: 0 0 0 9999px #ec489a3f;
        border: #ec4899 solid 1px;
    }
}

What Makes This Example Distinct

According to the comparison data, this example stands out because it combines one RGToolBar, two differently positioned RGMiniToolBar instances, and a conditional RGMiniView in the same RGSlotOnView layer while the built-in toolbar is disabled. That is a more specific composition pattern than a generic toolbar styling demo.

Compared with toolbar-tooltips, the main lesson here is not tooltip plumbing or hover inspection. It is the concrete reuse of built-in toolbar containers plus shared local state that keeps the favorite button synchronized across toolbar variants. Compared with simple and gee-thumbnail-diagram, the minimap is secondary and toggleable rather than the main navigation feature. Compared with node-menu-2, the graph surface stays mostly passive and the actionable entry points live in overlay chrome instead of node-level menus.

This makes the example a strong starting point when the real requirement is “replace default graph controls with branded controls and let those controls manage built-in graph widgets.”

Where Else This Pattern Applies

This pattern can be adapted to white-label graph viewers that need branded controls, monitoring or investigation dashboards that expose a minimap only on demand, and embedded admin tools that keep the graph read-only but still require custom share, bookmark, or help actions around it. It also fits multi-surface control designs where the same React state must stay consistent across a compact toolbar, a full toolbar, and a secondary utility widget.