JavaScript is required

Append Graph Data in Stages

This example initializes a centered relation-graph view with one inline dataset and then grows it by appending two more `RGJsonData` fragments through gated overlay buttons. It also reuses a draggable helper window for runtime canvas settings and image export, making it a focused reference for deterministic multi-step graph reveal flows.

Append Graph Data in Stages

What This Example Builds

This example renders a centered relationship map that starts with one hub and a small set of connected nodes. A floating helper window lets the user append a second data layer and then a third layer without replacing the graph that is already on screen.

The visual result is intentionally simple: warm beige nodes, straight connectors, and a full-height canvas with very little framing. The main point is the staged reveal flow. Instead of opening branches by clicking nodes, the example uses explicit product controls to release more graph structure in a fixed order.

How the Data Is Organized

The graph data is split into three inline RGJsonData fragments in MyGraph.tsx, and all three use rootId: '2'. The first payload contains the initial seven nodes and six labeled lines. The second payload adds more entities around existing nodes such as 7, 8, 9, and 1, and the third payload adds five child nodes under node 5.

There is no preprocessing pipeline before setJsonData() or appendJsonData(). Each fragment is declared as a literal nodes and lines array and then passed directly to the graph instance. In a business application, the same structure could be filled from staged API responses, permission-based detail layers, or workflow checkpoints that expose more relationships over time.

How relation-graph Is Used

index.tsx wraps the example in RGProvider, which makes the relation-graph hooks available to both the graph component and the shared helper window. Inside MyGraph.tsx, RGHooks.useGraphInstance() drives the whole lifecycle: it loads the initial dataset with setJsonData(), centers the view with moveToCenter(), fits it with zoomToFit(), and later merges additional fragments with appendJsonData().

The RelationGraph instance is configured as a centered viewer with layoutName: 'center', straight lines, border-based junction points, and simple default node and line styling. There are no custom node, line, canvas, or viewport slots in this example. The SCSS file exists but does not materially restyle the graph, so most of the visible behavior comes from the graph options and the imported helper window component.

The helper window is also part of how relation-graph is used here. Its settings panel reads graph state through RGHooks.useGraphStore(), updates wheel and drag behavior through setOptions(), and exports the canvas by calling prepareForImageGeneration(), getOptions(), domToImageByModernScreenshot(), and restoreAfterImageGeneration().

Key Interactions

  • Load Level 2 Data appends the second RGJsonData fragment and then disables itself.
  • Load Level 3 Data stays disabled until level 2 has been appended, then appends the final fragment and disables itself.
  • The helper window can be dragged, minimized, and switched into a settings panel.
  • The settings panel changes wheel behavior, changes canvas drag behavior, and downloads an image of the current graph.
  • Node click and line click handlers are wired, but they only log the clicked objects and do not drive the staged reveal.

Key Code Fragments

This block shows that the example is deliberately configured as a centered, straight-line viewer with border-anchored edges and warm default node styling.

const graphOptions: RGOptions = {
    defaultNodeBorderWidth: 1,
    defaultNodeBorderColor: '#333333',
    defaultNodeColor: 'rgba(250, 228, 197, 1)',
    defaultLineWidth: 1,
    defaultLineShape: RGLineShape.StandardStraight,
    layout: {
        layoutName: 'center',
    },
    defaultJunctionPoint: RGJunctionPoint.border
};

This fragment proves that the graph is initialized once with a base dataset and then centered and fit before any later growth happens.

const initializeGraph = async () => {
    const myJsonData: RGJsonData = {
        rootId: '2',
        nodes: [
            { id: '1', text: 'Node-1' },
            // ... other initial nodes and lines ...
        ]
    };

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

This handler shows the core pattern of the example: build another RGJsonData fragment and merge it into the existing graph with appendJsonData().

const loadNextLevel2Data = () => {
    setLevel2DataIsloaded(true);
    const myJsonData: RGJsonData = {
        rootId: '2',
        nodes: [
            // ... level 2 nodes ...
        ],
        lines: [
            // ... level 2 lines ...
        ]
    };
    graphInstance.appendJsonData(myJsonData);
};

The staged reveal is enforced directly in the UI by disabling buttons according to the local loading flags.

<SimpleUIButton disabled={level2DataIsloaded}
    onClick={() => loadNextLevel2Data()}
>
    Load Level 2 Data
</SimpleUIButton>
<SimpleUIButton disabled={!level2DataIsloaded || level3DataIsloaded}
    onClick={() => loadNextLevel3Data()}
>
    Load Level 3 Data
</SimpleUIButton>

The helper overlay is not just decorative; it exposes runtime canvas settings through relation-graph store and instance APIs.

const { options } = RGHooks.useGraphStore();
const dragMode = options.dragEventAction;
const wheelMode = options.wheelEventAction;

<SettingRow
    label="Wheel Event:"
    options={[
        { label: 'Scroll', value: 'scroll' },
        { label: 'Zoom', value: 'zoom' },
        { label: 'None', value: 'none' },
    ]}
    value={wheelMode}
    onChange={(newValue: string) => { graphInstance.setOptions({ wheelEventAction: newValue }); }}
/>

What Makes This Example Distinct

This example stands out because it grows an already rendered graph by appending staged inline RGJsonData fragments with appendJsonData(). That is the important difference. Other nearby examples also use RGProvider, RGHooks.useGraphInstance(), setJsonData(), a centered layout, and the same floating helper window, so those parts are not what make this example unusual.

Compared with layout-center, the emphasis here is structural growth rather than visual reconfiguration of a complete graph. Compared with deep-each, the reveal flow is button-driven and deterministic rather than click-driven traversal inside static data. Compared with canvas-event, the reusable lesson is guided disclosure of new relationship layers, not canvas event instrumentation.

Within the helper-window examples, this one uses the overlay as a sequential append controller. The floating window is not only a shell for settings or export; it is also the place where the next graph layer becomes available, and the level 3 action is intentionally gated behind level 2.

Where Else This Pattern Applies

This pattern transfers well to applications that need explicit, ordered disclosure of graph detail. Examples include due-diligence tools that reveal ownership layers step by step, organization charts that unlock deeper reporting levels after a user action, and supply-chain or dependency maps that load downstream tiers only when the current stage has been reviewed.

It also fits systems where the next graph fragment comes from a backend but must still be merged into the current view instead of replacing it. The example uses hard-coded payloads, but the same append-and-gate structure works for staged search results, permission-controlled relationship layers, or wizard-style investigative workflows.