Skip to main content

Overview

The CanvasEdgeData interface represents a connection (edge) between two nodes in an Obsidian canvas. Edges define relationships and visual connections, including which sides of nodes they connect to, their appearance, and optional labels.

Interface

export interface CanvasEdgeData {
    id: string;
    fromNode: string;
    fromSide?: NodeSide;
    fromEnd?: EdgeEnd;
    toNode: string;
    toSide?: NodeSide;
    toEnd?: EdgeEnd;
    color?: CanvasColor;
    label?: string;
    [key: string]: any;
}

Properties

id
string
required
The unique identifier for this edge. Must be unique within the canvas.
fromNode
string
required
The ID of the node where this edge starts. Must match the id of an existing node in the canvas.
fromSide
NodeSide
The side of the source node where this edge connects. Determines the visual attachment point.Possible values:
  • "top" - Connect to the top side
  • "right" - Connect to the right side
  • "bottom" - Connect to the bottom side
  • "left" - Connect to the left side
If not specified, Obsidian will automatically determine the optimal side.
fromEnd
EdgeEnd
What to display at the starting end of the edge. Defaults to "none".Possible values:
  • "none" - No decoration at the start
  • "arrow" - Display an arrow at the start
toNode
string
required
The ID of the node where this edge ends. Must match the id of an existing node in the canvas.
toSide
NodeSide
The side of the destination node where this edge connects. Determines the visual attachment point.Possible values:
  • "top" - Connect to the top side
  • "right" - Connect to the right side
  • "bottom" - Connect to the bottom side
  • "left" - Connect to the left side
If not specified, Obsidian will automatically determine the optimal side.
toEnd
EdgeEnd
What to display at the ending end of the edge. Defaults to "arrow".Possible values:
  • "none" - No decoration at the end
  • "arrow" - Display an arrow at the end
color
CanvasColor
The color of this edge. Can be a number (like "1") representing one of the currently 6 supported colors, or a custom color using the hex format "#FFFFFF".
label
string
An optional text label to display on the edge. Useful for describing the relationship between connected nodes.
[key: string]
any
Supports arbitrary additional keys for forward compatibility. This allows edges to contain custom properties that may be used by future versions or plugins.

NodeSide

Defines which side of a node an edge connects to:
export type NodeSide = 'top' | 'right' | 'bottom' | 'left';

EdgeEnd

Defines what decoration appears at the end of an edge:
export type EdgeEnd = 'none' | 'arrow';

CanvasColor

A string representing a color, either as a number or hex code:
export type CanvasColor = string;

Examples

Basic Edge

A simple edge connecting two nodes with default settings:
{
  "id": "edge-1",
  "fromNode": "node-a",
  "toNode": "node-b"
}
This creates an edge from node-a to node-b with:
  • Automatically determined connection sides
  • No decoration at the start (fromEnd defaults to "none")
  • An arrow at the end (toEnd defaults to "arrow")

Bidirectional Edge

An edge with arrows on both ends:
{
  "id": "edge-2",
  "fromNode": "node-a",
  "fromEnd": "arrow",
  "toNode": "node-b",
  "toEnd": "arrow"
}

Labeled Edge

An edge with a descriptive label:
{
  "id": "edge-3",
  "fromNode": "concept-1",
  "toNode": "concept-2",
  "label": "depends on",
  "color": "2"
}

Precise Connection Points

An edge with explicitly defined connection sides:
{
  "id": "edge-4",
  "fromNode": "node-a",
  "fromSide": "right",
  "toNode": "node-b",
  "toSide": "left",
  "color": "#4CAF50",
  "label": "flows to"
}

Line Without Arrows

A simple connecting line with no arrows:
{
  "id": "edge-5",
  "fromNode": "node-a",
  "fromEnd": "none",
  "toNode": "node-b",
  "toEnd": "none",
  "color": "1"
}

Usage Example

// Creating edges programmatically
function createEdge(
    fromNodeId: string,
    toNodeId: string,
    options?: {
        label?: string;
        color?: string;
        bidirectional?: boolean;
    }
): CanvasEdgeData {
    return {
        id: `edge-${Date.now()}`,
        fromNode: fromNodeId,
        toNode: toNodeId,
        fromEnd: options?.bidirectional ? 'arrow' : 'none',
        toEnd: 'arrow',
        label: options?.label,
        color: options?.color
    };
}

// Usage
const edge = createEdge('node-1', 'node-2', {
    label: 'references',
    color: '3',
    bidirectional: false
});

Working with Edges

Finding Edges for a Node

function getNodeEdges(
    canvasData: CanvasData,
    nodeId: string
): { incoming: CanvasEdgeData[]; outgoing: CanvasEdgeData[] } {
    return {
        incoming: canvasData.edges.filter(edge => edge.toNode === nodeId),
        outgoing: canvasData.edges.filter(edge => edge.fromNode === nodeId)
    };
}

Validating Edge Connections

function validateEdge(edge: CanvasEdgeData, canvasData: CanvasData): boolean {
    const fromNodeExists = canvasData.nodes.some(node => node.id === edge.fromNode);
    const toNodeExists = canvasData.nodes.some(node => node.id === edge.toNode);
    return fromNodeExists && toNodeExists;
}

Finding Connected Nodes

function getConnectedNodes(
    nodeId: string,
    canvasData: CanvasData
): AllCanvasNodeData[] {
    const connectedNodeIds = new Set<string>();
    
    // Find all edges involving this node
    canvasData.edges.forEach(edge => {
        if (edge.fromNode === nodeId) {
            connectedNodeIds.add(edge.toNode);
        }
        if (edge.toNode === nodeId) {
            connectedNodeIds.add(edge.fromNode);
        }
    });
    
    // Return the actual node objects
    return canvasData.nodes.filter(node => 
        connectedNodeIds.has(node.id)
    );
}

Best Practices

  1. Unique IDs: Always ensure edge IDs are unique within the canvas
  2. Valid References: Verify that fromNode and toNode reference existing nodes
  3. Meaningful Labels: Use labels to clarify relationships when the connection isn’t obvious
  4. Color Consistency: Use consistent colors to represent similar types of relationships
  5. Avoid Cycles: Be mindful of creating circular dependencies that might confuse users
  • CanvasData - The top-level canvas file structure
  • CanvasNodeData - Interfaces for canvas nodes
  • NodeSide - Type for node connection sides
  • EdgeEnd - Type for edge end decorations
  • CanvasColor - Type for color encoding

Build docs developers (and LLMs) love