JavaScript is required

Slot System Overview

relation-graph slots replace or extend the internal visual layers of the graph. They are not simple “HTML mount points”; they are mounted on different layers: node layer, line layer, canvas coordinate layer, fixed viewport layer, and background layer. Different slots live in different layers, so their coordinate systems, zoom behavior, and event handling are different.

If you only need to adjust colors, line width, border radius, or fonts, prefer RGOptions, node/line data fields, or CSS variables. Use slots when you need custom DOM/SVG structures, business buttons inside nodes, multiple labels on lines, group boxes on the canvas, or fixed toolbars on the viewport.

1. Slot Overview

Slot Vue 3 / Vue 2 React Svelte Layer Follows canvas zoom/pan Main use
Node content #node <RGSlotOnNode> or nodeSlot slot="node" Inside node shell .rg-node Yes Card nodes, avatar nodes, status badges, business buttons
Node expand button #node-expand-button nodeExpandButtonSlot slot="node-expand-button" Inside node shell, at the default expand button position Yes Replace the expand/collapse button
Line content #line <RGSlotOnLine> or lineSlot slot="line" SVG line layer Yes Custom paths, arrows, line labels, line states
Lower canvas #canvas or default slot <RGSlotOnCanvas> or normal children slot="canvas" or default slot Below nodes/lines Yes Group boxes, lanes, coordinate guides, lower graph business markers
Canvas foreground #canvas-above <RGSlotOnCanvasAbove> slot="canvas-above" Above nodes/lines Yes Selection hints, floating anchors, canvas-coordinate overlays
View layer #view <RGSlotOnView> slot="view" Top fixed graph viewport layer No Fixed toolbars, context menus, floating panels, minimaps
Background layer #background <RGBackground> slot="background" .rg-map-background No Background images, watermarks, themed textures

Notes:

  • Vue3 public package names are written as @relation-graph/vue in this site documentation; Vue2 uses @relation-graph/vue2.
  • React can use slot components such as <RGSlotOnNode> / <RGSlotOnLine>, or render-function props such as nodeSlot / lineSlot / nodeExpandButtonSlot. Do not use both forms for the same slot, or the source will throw an error.
  • Default child content in Vue3/React/Svelte is placed on the lower canvas layer, equivalent to the canvas layer. It is suitable for helper content that should move with the graph.

2. Render Layers

The main internal graph layers can be understood as:

Bottom to top Internal container Public slot/content Behavior
1 .rg-map-background background Fixed to the viewport, does not follow canvas zoom; usually non-interactive
2 .rg-map-canvas.rg-canvas-behind canvas / default child content Uses canvas coordinates, follows canvasOffset and canvasZoom
3 EasyView / minimap helper layer Internal use Used by performance mode or simplified view
4 .rg-map-canvas Nodes, lines, node/line slots Main graph layer where nodes and lines are rendered
5 .rg-map-canvas.rg-canvas-above canvas-above Uses canvas coordinates and appears above nodes/lines
6 .rg-graph-plugs .rg-view-slot view Fixed to the viewport, does not follow canvas zoom

The .rg-map-canvas that contains canvas, canvas-above, nodes, and lines applies a transform like:

transform: translate(canvasOffset.x, canvasOffset.y) scale(canvasZoom / 100);
transform-origin: 0 0;

Therefore, left/top/x/y values in these layers should use canvas coordinates. view and background do not apply this transform, so their left/top values are coordinates relative to the RelationGraph component viewport.

3. Coordinate Systems

The three coordinate systems you most often use in relation-graph are:

Coordinate system Example Description
Client coordinates MouseEvent.clientX/clientY Browser window coordinates, usually from mouse or touch events.
View coordinates graphInstance.getViewXyByEvent(e) Coordinates relative to the top-left corner of the RelationGraph component. Suitable for view layer menus.
Canvas coordinates graphInstance.getCanvasXyByViewXy(viewPoint) Internal graph coordinates. Node x/y, canvas slot positioning, and line endpoints use this system.

Common conversion APIs:

API Input Return Use
getViewXyByEvent(e) Mouse/touch event { x, y } view coordinates Show a viewport-layer menu at the event position.
getViewXyByClientXy({ x, y }) Browser client coordinates { x, y } view coordinates Convert an external event position into component-local coordinates.
getCanvasXyByClientXy({ x, y }) Browser client coordinates { x, y } canvas coordinates Create a node at the mouse position.
getCanvasXyByViewXy({ x, y }) View coordinates { x, y } canvas coordinates Map fixed-layer operations back to the canvas.
getViewXyByCanvasXy({ x, y }) Canvas coordinates { x, y } view coordinates Map nodes/business points to fixed floating layers.

Example: when adding a node at the mouse position, use canvas coordinates:

const canvasPoint = graphInstance.getCanvasXyByClientXy({
  x: event.clientX,
  y: event.clientY
});

graphInstance.addNodes([
  {
    id: 'new-node',
    text: 'New Node',
    x: canvasPoint.x,
    y: canvasPoint.y
  }
]);

4. Slot Prop Types

Node, line, and expand button slots receive structured props.

Node Slot #node

export type RGNodeSlotProps = {
  node: RGNode;
  defaultExpandHolderPosition?: string;
  dragging?: boolean;
  checked?: boolean;
};
Field Type Description
node RGNode Current rendered runtime node object. It contains id, text, type, data, position, style, state, and other fields.
defaultExpandHolderPosition string | undefined Global default expand button position from options.defaultExpandHolderPosition.
dragging boolean | undefined Whether the current node is being dragged.
checked boolean | undefined Whether the current node is the internal “checked” node, used by editing/controller state.

Node Expand Button Slot #node-expand-button

export type RGNodeExpandHolderProps = {
  node: RGNode;
  expandOrCollapseNode: (e: MouseEvent | TouchEvent) => void;
  expandHolderPosition?: string;
};
Field Type Description
node RGNode Current node.
expandOrCollapseNode (e) => void Built-in expand/collapse logic. Usually called from your custom button click handler.
expandHolderPosition string | undefined Actual expand button position. Common values are left, right, top, bottom, and hide.

Line Slot #line

export type RGLineSlotProps = {
  lineConfig: RGGenerateLineConfig;
  checked?: boolean;
  defaultLineTextOnPath?: boolean;
  graphInstanceId?: string;
};
Field Type Description
lineConfig RGGenerateLineConfig Line render configuration calculated by the instance from RGLine or RGFakeLine.
checked boolean | undefined Whether the current line is the internal “checked” line.
defaultLineTextOnPath boolean | undefined Global default that controls whether line text follows the path.
graphInstanceId string | undefined Current graph instance ID. It is often used to generate unique SVG path ids.

Core fields of RGGenerateLineConfig:

Field Type Description
line RGLine | RGFakeLine Current line to render. Normal lines come from the data model; fake lines come from drag/editing state.
from RGLineTarget | undefined Start target information. It may be a node, node point, canvas point, and so on.
to RGLineTarget | undefined End target information.
totalLinesBetweenNodes number | undefined Total number of lines between the two nodes, used for multi-line offsets.
currentLineIndex number | undefined Index of the current line in a multi-line group.
defaultOptions any Snapshot of default options needed for current rendering.

5. Event Handling Principles

Many outer elements inside the graph use pointer-events: none by default to keep dragging, selection, and line click behavior stable. This means interactive elements placed in canvas, canvas-above, or view slots need to explicitly enable pointer events if they should be clickable.

Recommended:

<button class="rg-events-all">Action</button>

Or:

<button style="pointer-events: auto;">Action</button>

Notes:

  • The node slot is inside .rg-node, whose shell already handles drag-start events. If a button inside a node should not trigger node dragging, call stopPropagation on the button event.
  • The line slot is in the SVG layer. Default lines use .rg-line-bg to receive clicks, while the visible path often stays thin. Custom lines should also keep a thicker transparent click path.
  • The view layer wrapper .rg-graph-plugs uses pointer-events: none by default. Fixed toolbars, menus, and panels must enable pointer-events themselves.

6. Responsibility Boundaries of Data, CSS, and Slots

Recommended division of responsibilities:

Layer Responsible for Examples
Data fields Semantic appearance, state, business data node.color, line.color, line.lineShape, node.data.status
RGOptions Global defaults and interaction rules defaultNodeColor, defaultLineWidth, defaultLineShape, disableDragNode
CSS / CSS variables Theme, state styles, local overrides .rg-node-selected, .rg-line-checked, --rg-node-color
Slots DOM/SVG structure, complex content, business controls Card nodes, multi-label lines, group boxes, toolbars
Instance APIs Data changes, layout, viewport, event coordination addNodes, updateLine, getCanvasXyByClientXy

Do not put everything into slots. For example, line color affects consistency across the main graph, minimap, and export, so it should be placed in line.color or defaultLineColor first. Business information such as node type, status, and labels should go into node.data; slots should only render that information.

7. Platform Syntax Quick Reference

Vue 3

<RelationGraph :options="graphOptions" :initial-data="graphData">
  <template #node="{ node, checked, dragging }">
    <div class="my-node">{{ node.text }}</div>
  </template>

  <template #line="{ lineConfig, checked, graphInstanceId }">
    <MyLine :line-config="lineConfig" :checked="checked" :graph-instance-id="graphInstanceId" />
  </template>

  <template #canvas>
    <div class="group-box" style="position:absolute;left:0;top:0;">Group</div>
  </template>

  <template #view>
    <div class="toolbar rg-events-all">Toolbar</div>
  </template>
</RelationGraph>

React

import {
  RelationGraph,
  RGSlotOnNode,
  RGSlotOnLine,
  RGSlotOnCanvas,
  RGSlotOnView
} from '@relation-graph/react';

<RelationGraph options={graphOptions} initialData={graphData}>
  <RGSlotOnNode>
    {({ node, checked, dragging }) => (
      <div className="my-node">{node.text}</div>
    )}
  </RGSlotOnNode>

  <RGSlotOnLine>
    {({ lineConfig, checked, graphInstanceId }) => (
      <MyLine lineConfig={lineConfig} checked={checked} graphInstanceId={graphInstanceId} />
    )}
  </RGSlotOnLine>

  <RGSlotOnCanvas>
    <div className="group-box">Group</div>
  </RGSlotOnCanvas>

  <RGSlotOnView>
    <div className="toolbar rg-events-all">Toolbar</div>
  </RGSlotOnView>
</RelationGraph>

Svelte

<RelationGraph {options} initialData={graphData}>
  <div slot="node" let:node let:checked let:dragging class="my-node">
    {node.text}
  </div>

  <div slot="canvas" class="group-box">
    Group
  </div>

  <div slot="view" class="toolbar rg-events-all">
    Toolbar
  </div>
</RelationGraph>

8. Common Scenario Selection

Requirement Recommended slot/method Reason
Show avatars, tags, or buttons inside nodes node The node shell still handles positioning, dragging, and state.
Replace tree node expand button node-expand-button You can reuse expandOrCollapseNode without maintaining tree state yourself.
Draw different shapes for different line types line You can dispatch templates by lineConfig.line.type.
Add multiple labels to a line line + RGLineText or custom HTML/SVG The default text renderer only renders one label.
Draw lanes, group boxes, or grids canvas It moves and scales in canvas coordinates.
Draw selection hints or drag helper anchors canvas-above It follows canvas coordinates and appears above graph elements.
Fixed toolbar, context menu, property panel view It is not affected by canvas zoom.
Watermark, background image, pure decorative texture background It does not affect node and line layering.

9. Next Reading