JavaScript is required

Built-In Line Dash and Animation

This example builds a small left-to-right tree that compares relation-graph's built-in dashed and animated line presets in one static view. The line effects come directly from inline `dashType` and `animation` values, while icon-only nodes and a floating settings and export panel provide the surrounding presentation shell.

Built-In Line Dash and Animation Reference

What This Example Builds

This example renders a small left-to-right tree that works as a comparison board for relation-graph’s built-in line effects. One branch shows four dashType presets plus one normal line, and another branch shows four animation presets on the default curved line renderer. The screen also includes icon-only circular nodes, a green gradient canvas, and a floating helper window that can be dragged, minimized, switched into a settings panel, and used for image export.

How the Data Is Organized

The graph data is declared inline inside initializeGraph() as one RGJsonData object with rootId, nodes, and lines. Each node uses a simple { id, text, data: { icon } } shape, and each line uses from, to, text, plus optional dashType or animation fields. There is no preprocessing before setJsonData(): the example passes the static dataset directly into relation-graph, so the same pattern could be replaced with workflow transitions, route states, service dependencies, or other edge-status data.

How relation-graph Is Used

RGProvider wraps the demo, and RGHooks.useGraphInstance() drives all graph lifecycle work. The local graphOptions keep relation-graph on its default rendering path while tuning the presentation: a tree layout grows from the left, node spacing is widened for readability, lines use RGLineShape.StandardCurve, labels follow the path through defaultLineTextOnPath, and the built-in toolbar is positioned horizontally in the lower-right corner.

The example customizes nodes with RGSlotOnNode, not with a custom line renderer. node.data.icon is mapped to Lucide icons so the tree branches stay visually distinct while the line styles remain the real lesson. The shared DraggableWindow helper uses RGHooks.useGraphStore() and graphInstance.setOptions() to switch wheel and drag behavior at runtime, and it uses prepareForImageGeneration() plus restoreAfterImageGeneration() to export the current canvas as an image.

Styling stays local and lightweight. The SCSS file adds the green gradient background, makes the toolbar translucent, centers content inside circular nodes, and overrides the checked-node appearance by using checkedItemBackgroundColor as the icon badge background. There are no editing tools, custom line slots, or runtime line mutations in this example.

Key Interactions

  • The graph loads once on mount, then calls moveToCenter() and zoomToFit() so every built-in line variant is visible immediately.
  • Users inspect dashed, normal, and animated links side by side; those variants are predefined in the initial data rather than switched dynamically.
  • The floating helper window can be dragged, minimized, and toggled into a settings mode.
  • The settings panel changes wheel and drag behavior at runtime and can export the current graph view as an image.

Key Code Fragments

This options block shows that the demo stays on relation-graph’s default renderer and uses layout and option tuning to create a clean comparison surface.

const graphOptions: RGOptions = {
    defaultLineColor: 'rgba(255, 255, 255, 0.6)',
    defaultNodeColor: 'transparent',
    defaultNodeBorderWidth: 0,
    defaultNodeShape: RGNodeShape.circle,
    toolBarDirection: 'h',
    toolBarPositionH: 'right',
    toolBarPositionV: 'bottom',
    defaultLineShape: RGLineShape.StandardCurve,
    defaultJunctionPoint: RGJunctionPoint.lr,
    defaultLineTextOnPath: true,
    layout: {
        layoutName: 'tree',
        from: 'left',
        treeNodeGapH: 310,
        treeNodeGapV: 70
    }
};

This inline line dataset is the core proof that the visual variation comes from built-in per-line data fields instead of CSS classes or post-load line updates.

lines: [
    { id: 'line-1', from: 'a', to: 'b', text: 'dataType=1', dashType: 1 },
    { id: 'line-2', from: 'b', to: 'b1', text: 'dataType=2', dashType: 2 },
    { id: 'line-3', from: 'b', to: 'b2', text: 'dataType=3', dashType: 3 },
    { id: 'line-4', from: 'b2', to: 'b2-1', text: 'dataType=4', dashType: 4 },
    { id: 'line-5', from: 'b2', to: 'b2-2', text: 'Normal' },
    { id: 'line-6', from: 'a', to: 'c', text: 'animation=1', animation: 1 },
    { id: 'line-7', from: 'c', to: 'c1', text: 'animation=2', animation: 2 },
    { id: 'line-8', from: 'c', to: 'c2', text: 'animation=3', animation: 3 },
    { id: 'line-9', from: 'c', to: 'c3', text: 'animation=4', animation: 4 }
]

This node slot keeps the edges on the default renderer while turning each node into an icon badge chosen from node.data.icon.

<RGSlotOnNode>
    {({ node }: RGNodeSlotProps) => {
        const iconName = node.data?.icon || 'default';
        const IconComponent = IconMapper[iconName] || CircleDot;
        return (
            <div className="my-icon-node h-20 w-20 text-white rounded flex place-items-center justify-center hover:bg-white hover:bg-opacity-40">
                <IconComponent size={40} />
            </div>
        );
    }}
</RGSlotOnNode>

This shared helper panel is where runtime canvas controls and image export are connected to the graph instance.

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

The comparison data places this example closest to line-style2, custom-line-style, and custom-line-animation, but its role is narrower and simpler than those neighbors. Against line-style2, it does not rely on checked-line state or CSS wrapper classes; it shows all built-in variants at once in the initial dataset. Against custom-line-style, it avoids className, SCSS-driven line skins, and updateLine() calls. Against custom-line-animation, it stays on relation-graph’s built-in animation values instead of adding SVG filters or richer custom effects.

That makes this example a strong starting point when the requirement is, “Can the default renderer already do enough?” The verified rarity data also marks its combination of left-to-right tree layout, icon-only circular node slots, path labels, and side-by-side built-in dashType plus animation presets as an uncommon feature mix in the example set.

Where Else This Pattern Applies

  • Status-oriented dependency maps where dashed links mean delayed or indirect relationships and animated links mark active traffic.
  • Logistics or operations views where icon nodes identify entity types and edge motion highlights live routes without introducing custom SVG work.
  • Workflow, approval, or pipeline diagrams that need a compact built-in legend for edge states before investing in heavier theming.
  • Internal design-system or onboarding demos that teach teams which line semantics can be expressed through relation-graph’s native data properties alone.