Parallel edges and self-loops
Sigma handles two special edge cases: multiple edges between the same pair of nodes (parallel edges), and edges that connect a node to itself (self-loops).
Parallel edges
When multiple edges connect the same pair of nodes, sigma can spread them apart automatically. Sigma provides built-in state flags parallelIndex and parallelCount on edges to support this.
Use the parallelPath style property to choose a curved path for parallel edges, and parallelSpread to control the spacing:
import Sigma from "sigma";import { extremityArrow, layerPlain, pathCurved, pathLine, pathLoop } from "sigma/rendering";import { DEFAULT_STYLES } from "sigma/types";
import { getSmallGraph } from "../_data/small-graph";
const container = document.getElementById("sigma-container") as HTMLElement;const graph = getSmallGraph({ multi: true, type: "mixed" });
// Add parallel edges to showcase the feature:
// Multiple directed edges, same direction (a -> b already exists)graph.addDirectedEdge("a", "b", { size: 3, color: "#F6903D", head: "arrow" });graph.addDirectedEdge("a", "b", { size: 3, color: "#FACC14", head: "arrow" });
// Directed edges in both directions (c -> e already exists, add e -> c)graph.addDirectedEdge("e", "c", { size: 3, color: "#61DDAA", head: "arrow" });
// Undirected parallel edgesgraph.addUndirectedEdge("d", "e", { size: 3, color: "#78D3F8" });graph.addUndirectedEdge("d", "e", { size: 3, color: "#247BA0" });
new Sigma(graph, container, { primitives: { edges: { paths: [pathLine(), pathCurved(), pathLoop()], extremities: [extremityArrow()], layers: [layerPlain()], }, }, styles: { nodes: { ...DEFAULT_STYLES.nodes, color: { attribute: "color" }, size: { attribute: "size" }, }, edges: { ...DEFAULT_STYLES.edges, color: { attribute: "color" }, size: { attribute: "size" }, path: "straight", selfLoopPath: "loop", parallelPath: "curved", head: { attribute: "head" }, }, }, settings: { itemSizesReference: "positions", autoRescale: true, },});Self-loops
Edges that connect a node to itself are rendered as loops. The selfLoopPath style property controls their shape:
import Sigma from "sigma";import { extremityArrow, layerDashed, layerFill, layerPlain, pathLine, pathLoop } from "sigma/rendering";import { DEFAULT_STYLES } from "sigma/types";
import { getSmallGraph } from "../_data/small-graph";
const container = document.getElementById("sigma-container") as HTMLElement;const PI = Math.PI;const graph = getSmallGraph({ multi: true });
// Add self-loops showcasing various features:graph.addEdge("a", "a", { size: 3, color: "#E8684A", head: "arrow" });graph.addEdge("d", "d", { size: 2, color: "#9270CA", head: "arrow", loopAngle: (3 * PI) / 2, dashSize: 6 });graph.addEdge("e", "e", { size: 6, color: "#5B8FF9", loopAngle: PI, loopSpread: (110 * PI) / 180 });graph.addEdge("f", "f", { size: 2, color: "#9270CA", head: "arrow", loopAngle: 0, loopSpread: (70 * PI) / 180 });
// Add parallel self-loops on a few nodes to showcase automatic angle distribution:graph.addEdge("b", "b", { size: 3, color: "#61DDAA", head: "arrow", tail: "arrow" });graph.addEdge("b", "b", { size: 2, color: "#F6903D", head: "arrow", tail: "arrow" });graph.addEdge("c", "c", { size: 3, color: "#A33DF6", head: "arrow" });graph.addEdge("c", "c", { size: 2, color: "#61ADDD", head: "arrow" });graph.addEdge("c", "c", { size: 2, color: "#9270CA", head: "arrow" });
new Sigma(graph, container, { primitives: { nodes: { layers: [layerFill()], }, edges: { paths: [pathLine(), pathLoop()], variables: { dashSize: { type: "number", default: 0 } }, extremities: [extremityArrow()], layers: [ layerPlain(), layerDashed({ dashSize: { attribute: "dashSize", default: 0, mode: "pixels" }, gapSize: { value: 6, mode: "pixels" }, gapColor: "#ffffff", }), ], }, }, styles: { nodes: { ...DEFAULT_STYLES.nodes, color: { attribute: "color" }, size: { attribute: "size" }, }, edges: { ...DEFAULT_STYLES.edges, color: { attribute: "color" }, size: { attribute: "size" }, path: "straight", selfLoopPath: "loop", head: { attribute: "head" }, tail: { attribute: "tail" }, }, }, settings: { itemSizesReference: "positions", autoRescale: true, },});