JavaScript is required

Infrastructure Topology Dashboard

This example presents a small infrastructure topology as a monitoring-style relation-graph viewer with typed server, database, and service nodes. It combines mount-time graph initialization, a left-to-right tree layout, custom node-slot rendering, and a canvas-level VPC backdrop in one compact read-only scene.

Building an Infrastructure Topology Viewer with Typed Node Cards

What This Example Builds

This example builds a compact infrastructure topology viewer with one web server at the root and linked database, cache, and service nodes around it. The visible result is a dark, monitoring-style scene where the main server appears as a detailed status card, database nodes appear as appliance tiles, and service nodes appear as smaller utility blocks.

Users mainly inspect the prepared topology through normal graph navigation. The most notable part is the scene composition: relation-graph still renders ordinary nodes and lines, but a canvas-level VPC annotation and custom node bodies make the graph read like an operations board instead of a generic tree.

How the Data Is Organized

The data is an inline JSON topology object created inside initializeGraph(). It defines rootId, a nodes array, and a lines array, then loads that structure directly with setJsonData(...). There is no separate doLayout preprocessing stage.

The important preprocessing choice is in the node metadata. Each node stores a data.type, and some nodes carry additional fields such as server status, IP, port, CPU, memory, disk, or database engine. The renderer then branches on node.data.type to choose which node body to display. In a real system, the same shape can represent application servers, cache layers, database instances, internal APIs, or other infrastructure assets loaded from an inventory service.

How relation-graph Is Used

The example uses RGProvider in index.tsx so RGHooks.useGraphInstance() can control the graph from MyGraph.tsx. The graph options configure a left-to-right tree with fixed node gaps, rectangular node geometry, standard curved links, and left-right junction handling. Built-in node fill and border are turned off so the visible appearance comes from the custom slot content, while the default link styling stays cyan and slightly emphasized.

RelationGraph is used as a normal node-link graph rather than as a pure connector layer. RGSlotOnNode renders three different node bodies from one dataset: a large monitoring card for the server, a compact database tile, and a simple service tile. RGSlotOnCanvas adds a labeled Internal Isolation Zone (VPC-1) rectangle behind the graph scene, and that overlay is explicitly non-interactive because it uses pointer-events-none.

The instance API handles startup. On mount, the component builds the inline dataset, schedules the loading state to clear, calls setJsonData(...), then runs moveToCenter() and zoomToFit(). The SCSS file finishes the scene by forcing a dark map background and keeping the built-in node shell transparent with rounded corners.

Key Interactions

  • A loading overlay appears while g_loading is true, dimming the graph and showing a spinner.
  • After mount, the graph loads the prepared topology and automatically recenters and fits it into view.
  • The VPC backdrop does not block graph interaction because the overlay is marked with pointer-events-none.
  • Server cards raise their shadow on hover, which gives the most information-dense node a small emphasis cue.

Key Code Fragments

This options block shows that the scene is still a regular tree graph, but the built-in node chrome is stripped back so custom node markup can define the visible UI.

const userGraphOptions: RGOptions = {
    debug: false,
    layout: {
        layoutName: 'tree',
        from: 'left',
        treeNodeGapH: 150,
        treeNodeGapV: 20
    },
    defaultNodeShape: RGNodeShape.rect,
    defaultLineShape: RGLineShape.StandardCurve,

This fragment shows that the topology is loaded from inline JSON and that node metadata is prepared to drive different renderers.

const myJsonData = {
    rootId: 'server-1',
    nodes: [
        { id: 'server-1', text: 'Web Server', data: { type: 'server', ip: '192.168.1.10', port: '80', status: 'Running', cpu: '45%', mem: '6.2GB', disk: '128GB/512GB' } },
        { id: 'db-1', text: 'User DB', data: { type: 'database', dbType: 'PostgreSQL' } },
        { id: 'db-2', text: 'Cache', data: { type: 'database', dbType: 'Redis' } },
        { id: 'svc-1', text: 'Auth Service', data: { type: 'service' } },
        { id: 'svc-2', text: 'Payment API', data: { type: 'service' } },
    ],

This startup sequence is the core runtime pattern: load the inline dataset, then center and fit the viewport.

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

This slot fragment shows that one node slot branches by data.type so the same graph can render different infrastructure roles with different HTML bodies.

const NodeSlot = ({ node }: RGNodeSlotProps) => {
    const data = node.data;

    if (data.type === 'server') {
        return (
            <div className="w-[300px] border border-gray-300 rounded-lg shadow-md bg-white overflow-hidden transition-all hover:shadow-lg">

This canvas slot fragment proves that the VPC zone is an annotation layer, not the source of the actual graph nodes and lines.

<RGSlotOnCanvas>
    <div className="absolute left-[-50px] top-[-80px] w-[400px] h-[400px] bg-[rgba(116,255,5,0.1)] border border-dashed border-green-300 pointer-events-none">
        <div className="w-fit px-5 h-10 leading-10 -mt-0 bg-[rgba(116,255,5,0.2)] text-gray-700 rounded-tr-lg flex items-center justify-center gap-1.5 font-medium">
            <Layout className="w-4 h-4" />
            Internal Isolation Zone (VPC-1)
        </div>
    </div>
</RGSlotOnCanvas>

What Makes This Example Distinct

The comparison records make the main distinction clear: this example keeps the topology in ordinary graph nodes and standard loaded lines, but uses typed node slots and a canvas-only backdrop to make the result look like an infrastructure dashboard. That is a different pattern from scene-network-use-canvas-slot, where most of the visible board is built directly in RGSlotOnCanvas and relation-graph acts more like a connector layer for DOM endpoints.

Compared with scene-network, this example is smaller and more tree-structured. It does not build a full fixed dashboard shell with legend overlays, toolbar framing, or manually staged status columns. Instead, it focuses on one left-to-right infrastructure branch with a VPC label and mixed node types.

The rare combination is also important: a left-to-right tree layout, mount-time setJsonData() plus center-plus-fit initialization, node-data-driven renderer branching, cyan curved links, a dark graph canvas, and a non-interactive VPC zone annotation all appear together in one compact viewer. That makes it a strong starting point when a team wants scene-specific infrastructure presentation without moving away from standard relation-graph nodes and lines.

Where Else This Pattern Applies

  • Infrastructure inventory viewers that need one dataset to render servers, databases, caches, and services with different card bodies.
  • Operations dashboards that need a labeled environment zone or security boundary behind a normal node-link topology.
  • Internal platform maps that should open already centered and fitted instead of asking users to arrange the first view manually.
  • Technical dependency boards where scene styling matters, but the implementation should still rely on standard nodes and lines rather than absolute-positioned HTML panels.