Rendering System
Purpose and Scope
The Rendering System is responsible for transforming graph data (nodes, lines, and links) into visual elements displayed on screen. This system manages both SVG-based DOM rendering and canvas-based performance rendering, coordinates multi-layer visual composition, and optimizes rendering for large graphs through viewport culling.
This page provides an architectural overview of the rendering system. For detailed information about specific subsystems, see:
- Line rendering and path generation: Line Rendering System
- Connection point calculations: Junction Points & Path Calculations
- Canvas component architecture: Canvas Rendering & RGCanvas
- Performance optimizations: Performance Mode & EasyView
For information about layout algorithms that position nodes before rendering, see Layout System. For event handling on rendered elements, see User Interaction & Events.
Rendering Architecture Overview
graph TB
subgraph "Data Layer"
GraphData["RGGraphData
(nodes, lines)"]
Options["RGOptionsFull
(rendering config)"]
ShouldRender["shouldRenderNodes
shouldRenderLines
(viewport culling)"]
end
subgraph "Core Rendering Logic"
With4Line["RelationGraphWith4Line
createLineDrawInfo()"]
PathGen["Line Path Generators
generateLineFor1/4/44/49/6/8"]
JunctionCalc["_getJunctionPoint()
RGGraphMath utilities"]
end
subgraph "Component Layer"
RGCanvas["RGCanvas
(container)"]
RGCanvasContent["RGCanvasContent
(orchestrates rendering)"]
RGNode["RGNode
(node display)"]
RGLinePath["RGLinePath
(SVG path)"]
RGLineText["RGLineText
(text labels)"]
end
subgraph "Rendering Modes"
StandardMode["Standard SVG Rendering
(zoom >= 40%)"]
EasyViewMode["EasyView Canvas
(zoom < 40%)"]
end
subgraph "Output Layers"
BehindLayer["Behind Layer
(background plugins)"]
MainLayer["Main Canvas
(nodes & lines)"]
AboveLayer["Above Layer
(overlays)"]
end
GraphData --> ShouldRender
Options --> ShouldRender
ShouldRender --> RGCanvasContent
RGCanvasContent --> With4Line
With4Line --> PathGen
With4Line --> JunctionCalc
PathGen --> RGLinePath
JunctionCalc --> RGLinePath
RGCanvasContent --> RGNode
RGCanvasContent --> RGLinePath
RGCanvasContent --> RGLineText
RGCanvas --> BehindLayer
RGCanvas --> MainLayer
RGCanvas --> AboveLayer
MainLayer --> StandardMode
MainLayer --> EasyViewMode
RGNode --> MainLayer
RGLinePath --> MainLayer
RGLineText --> MainLayerDiagram: Overall Rendering System Architecture
The rendering system follows a three-tier architecture:
- Data Layer: Graph data and configuration drive what needs to be rendered
- Core Logic: Path generation and geometric calculations produce rendering instructions
- Component Layer: Framework-specific components render visual elements
Rendering Modes
The system supports two primary rendering modes that are selected based on zoom level and performance requirements:
Standard SVG/DOM Rendering
The default rendering mode uses SVG elements for lines and DOM elements for nodes. This provides:
- Full interactivity (click, hover, drag events)
- Crisp rendering at all zoom levels
- CSS styling and animations
- Slot-based customization
When used: When options.canvasZoom >= 40 or options.performanceMode is disabled.
EasyView Canvas Mode
A performance-optimized mode that renders using HTML5 Canvas 2D context:
- Lower memory footprint for large graphs
- Faster rendering for hundreds of nodes
- Limited interactivity (clicks are detected via coordinate mapping)
- Automatic activation at low zoom levels
When used: When options.canvasZoom < 40 and options.performanceMode is enabled, or when explicitly enabled via options.showEasyView.
graph LR
ZoomCheck{"canvasZoom >= 40?"}
PerfCheck{"performanceMode enabled?"}
SVGRender["Standard SVG Rendering"]
CanvasRender["EasyView Canvas"]
ZoomCheck -->|Yes| SVGRender
ZoomCheck -->|No| PerfCheck
PerfCheck -->|Yes| CanvasRender
PerfCheck -->|No| SVGRenderDiagram: Rendering Mode Selection Logic
Component Hierarchy
The rendering system is implemented through a hierarchy of framework-specific components that share common interfaces:
graph TB
RGCanvas["RGCanvas
Main container, layers, zoom/pan transform"]
RGCanvasContent["RGCanvasContent
Iterates nodes/lines, applies viewport culling"]
RGNode["RGNode
Individual node display"]
RGLinePath["RGLinePath
SVG path for line"]
RGLineText["RGLineText
Text label via teleport"]
RGConnectTarget["RGConnectTarget
Connection points for drag"]
RGEasyView["RGEasyView
Canvas fallback renderer"]
RGCanvas --> RGCanvasContent
RGCanvas --> RGEasyView
RGCanvasContent --> RGNode
RGCanvasContent --> RGLinePath
RGCanvasContent --> RGLineText
RGNode --> RGConnectTargetDiagram: Rendering Component Hierarchy
| Component | Purpose | File Locations |
|---|---|---|
RGCanvas |
Root container, manages layers and canvas transform | vue2/RGCanvas.vue, vue3/RGCanvas.vue, react/RGCanvas.tsx, svelte/RGCanvas.svelte |
RGCanvasContent |
Renders filtered nodes and lines, orchestrates child components | vue2/RGCanvasContent.vue, vue3/RGCanvasContent.vue, etc. |
RGNode |
Displays individual nodes with optional slots | vue2/RGNode.vue, vue3/RGNode.vue, etc. |
RGLinePath |
Renders SVG <path> elements for lines |
vue2/RGLinePath.vue, vue3/RGLinePath.vue, etc. |
RGLineText |
Renders line text labels using teleport/portal | vue2/RGLineText.vue, vue3/RGLineText.vue, etc. |
RGEasyView |
Canvas-based renderer for performance mode | vue2/RGEasyView.vue, vue3/RGEasyView.vue, etc. |
Rendering Pipeline
flowchart TD
DataUpdate["Graph Data Updated
addNode(), updateLine()"]
DataProvider["RGDataProvider
commits changes"]
RequestFrame["_dataUpdated()
requestAnimationFrame"]
ViewportCulling["updateShouldRenderGraphData()
filters visible items"]
RenderCheck{"Rendering Mode?"}
SVGPath["SVG Rendering Path"]
CanvasPath["Canvas Rendering Path"]
CreateLineInfo["createLineDrawInfo()
RelationGraphWith4Line"]
GeneratePath["generateLinePath()
withLineJunctionPoints()"]
PathCalculation["createLinePathData()
generateLineFor1/4/44/49/6/8"]
ComponentRender["Component Render
RGLinePath, RGNode"]
CanvasRender["Canvas 2D Context
drawImage(), fillRect()"]
DOMUpdate["DOM Updated
Browser paints"]
DataUpdate --> DataProvider
DataProvider --> RequestFrame
RequestFrame --> ViewportCulling
ViewportCulling --> RenderCheck
RenderCheck -->|Standard| SVGPath
RenderCheck -->|EasyView| CanvasPath
SVGPath --> CreateLineInfo
CreateLineInfo --> GeneratePath
GeneratePath --> PathCalculation
PathCalculation --> ComponentRender
ComponentRender --> DOMUpdate
CanvasPath --> CanvasRender
CanvasRender --> DOMUpdateDiagram: Rendering Pipeline Flow
Key Pipeline Stages
- Data Update: Application calls methods like
addNodes(),updateNode(),addLines() - Data Provider: Changes are batched and committed to reactive state
- Frame Request:
_dataUpdated()schedules arequestAnimationFramecallback - Viewport Culling:
updateShouldRenderGraphData()filters to visible items based on canvas offset and viewport size - Mode Selection: Standard SVG or EasyView canvas based on zoom and settings
- Path Generation: For lines,
RelationGraphWith4Linegenerates SVG path data - Component Rendering: Framework components render using reactive data
- Browser Paint: Native browser rendering completes the frame
Line Rendering Overview
Lines are rendered as SVG <path> elements with support for multiple shapes:
| Line Shape | Code Value | Description | Generator Function |
|---|---|---|---|
| Straight | 1 |
Direct line from start to end | generateLineFor1() |
| Simple Orthogonal | 4 |
Basic right-angle connections | generateLineFor4() |
| Standard Orthogonal | 44 |
Smart orthogonal with multiple segments | generateLineFor44() |
| Hard Orthogonal | 49 |
User-adjustable orthogonal segments | generateLineFor49() |
| Standard Curve | 6 |
Bezier curve connections | generateLineForCurve6() |
| Curve Variations | 2, 3, 5, 7 |
Different curve styles | generateLineForCurve() |
| Special Curve | 8 |
Alternative curve algorithm | generateLineFor8() |
The line rendering process:
- Junction Point Calculation: Determine where lines connect to node boundaries
- Path Generation: Generate SVG path commands based on line shape
- Text Positioning: Calculate text label position and rotation
- Arrow Markers: Apply SVG markers for arrow heads
graph LR
Link["RGLink
(fromNode, toNode)"]
Line["RGLine
(style, shape)"]
CreateInfo["createLineDrawInfo()"]
WithJunction["withLineJunctionPoints()"]
GetJunction["_getJunctionPoint()"]
CreatePath["createLinePathData()"]
PathInfo["RGLinePathInfo
(pathData, textPosition)"]
Component["RGLinePath Component"]
Link --> CreateInfo
Line --> CreateInfo
CreateInfo --> WithJunction
WithJunction --> GetJunction
WithJunction --> CreatePath
CreatePath --> PathInfo
PathInfo --> ComponentDiagram: Line Rendering Data Flow
For detailed information about line path generation and junction point calculation, see Line Rendering System and Junction Points & Path Calculations.
Node Rendering
Nodes are rendered as DOM elements (typically <div> elements) positioned absolutely within the canvas:
Key Node Properties:
- Position:
node.x,node.y(coordinates on canvas) - Size:
node.width/node.el_W,node.height/node.el_H - Shape:
node.nodeShape(0=circle, 1=rect, default from options) - Styling:
node.color,node.fontColor,node.borderColor,node.borderWidth
Node Transform Calculation:
style.transform = `translate(${node.x}px, ${node.y}px)`
style.width = `${node.el_W}px`
style.height = `${node.el_H}px`
Nodes can be customized through:
- Slot content: Replace default node rendering
- CSS variables:
--rg-node-color,--rg-node-border-color, etc. - Node-specific styles:
node.cssVarsobject
Connection Targets: Each node can display connection points (RGConnectTarget) for interactive line creation. These are positioned at specific junction points (top, right, bottom, left, center).
Multi-Layer Rendering System
The canvas uses a three-layer architecture to support flexible z-ordering:
graph TB
Container["RGCanvas Container"]
subgraph "Layer Stack (bottom to top)"
BackgroundSlot["Background Slot
(grid, watermark)"]
BehindLayer["Behind Layer
canvas-plug-behind slot"]
MainCanvas["Main Canvas
(nodes & lines)"]
AboveLayer["Above Layer
canvas-plug-above slot"]
end
Container --> BackgroundSlot
Container --> BehindLayer
Container --> MainCanvas
Container --> AboveLayer
MainCanvas --> Nodes["Rendered Nodes"]
MainCanvas --> Lines["Rendered Lines"]Diagram: Multi-Layer Canvas Architecture
Layer Purposes
| Layer | Purpose | CSS Class | Transform Applied |
|---|---|---|---|
| Background | Static background content | .rg-map-background |
No |
| Behind | Custom content below graph | .rg-canvas-slot-behind |
Yes (zoom/pan) |
| Main | Nodes and lines | .rg-map-canvas |
Yes (zoom/pan) |
| Above | Overlays (tooltips, controls) | .rg-canvas-slot-above |
Yes (zoom/pan) |
All layers except Background share the same transform:
transform: translate(${canvasOffset.x}px, ${canvasOffset.y}px)
scale(${canvasZoom / 100}, ${canvasZoom / 100})
This ensures that zoom and pan operations affect all graph content uniformly while keeping the background static.
Viewport Culling and Performance
The rendering system implements viewport culling to avoid rendering off-screen elements:
Culling Mechanism:
updateShouldRenderGraphData()calculates visible viewport bounds- Filters nodes: only those within viewport + margin are added to
shouldRenderNodes - Filters lines: only lines connecting visible nodes are added to
shouldRenderLines - Components iterate only filtered collections
Performance Benefits:
- Reduces DOM elements for large graphs (1000+ nodes)
- Maintains 60fps during pan/zoom operations
- Automatically adjusts as viewport changes
EasyView Canvas Mode: When performance mode is enabled and zoom drops below 40%, the system:
- Disables detailed SVG rendering
- Renders simplified representations to canvas
- Maintains interactivity through coordinate mapping
For detailed performance optimization techniques, see Performance Mode & EasyView.
Framework-Specific Implementations
Each platform (Vue2, Vue3, React, Svelte) implements the same rendering architecture with framework-specific patterns:
Vue 2 & 3: Uses template-based components with slots
- Reactivity: Vue’s reactive data system with refs/reactive
- Slots:
<slot name="node">,<slot name="line"> - Teleport:
<teleport>for line text positioning
React: Uses JSX components with render props
- Reactivity:
useStateanduseGraphStorecustom hook - Children: Render prop functions or React nodes
- Portal:
createPortal()for line text positioning
Svelte: Uses Svelte components with slots
- Reactivity: Svelte stores (
writable) - Slots:
<slot name="node">,<svelte:fragment> - Portal: Custom
portalaction for line text
All implementations maintain API compatibility through shared TypeScript interfaces defined in the types package.
Summary
The Rendering System transforms graph data into visual output through:
- Dual rendering modes: Standard SVG for quality, Canvas for performance
- Component-based architecture: Framework-specific implementations sharing core logic
- Multi-layer composition: Flexible z-ordering for plugins and overlays
- Viewport culling: Performance optimization for large graphs
- Path generation: Support for multiple line shapes and junction point types
The system is designed to balance visual quality, interactivity, and performance across different scales and use cases.