<div id="sigma-container"></div>
<style>
#sigma-container {
width: 100%;
height: 100%;
}
</style>
<script>
import Graph from "graphology";
import Sigma from "sigma";
import { extremityArrow, layerPlain, pathCurved, pathLine, pathStepCurved } from "sigma/rendering";
import { DEFAULT_STYLES } from "sigma/types";
import type { EdgeLabelFontSizeMode, EdgeLabelPosition } from "sigma/types";
import { registerControls } from "../_controls";
const container = document.getElementById("sigma-container") as HTMLElement;
// Each column demonstrates one label styling variation. The first four use
// text borders for readability; the last one uses a label background
// (ribbon) instead — both styles live side by side.
const COLS = [
{ position: "over" as EdgeLabelPosition, background: false, label: "over / border" },
{ position: "above" as EdgeLabelPosition, background: false, label: "above / border" },
{ position: "below" as EdgeLabelPosition, background: false, label: "below / border" },
{ position: "auto" as EdgeLabelPosition, background: false, label: "auto / border" },
{ position: "over" as EdgeLabelPosition, background: true, label: "over / background" },
];
const PATHS = [
{ name: "straight", label: "Straight" },
{ name: "curved", label: "Curved" },
{ name: "stepCurved", label: "Step Curved" },
] as const;
const COL_SPACING = 100;
const ROW_SPACING = 80;
const NODE_SPACING = 50;
const EDGE_SIZE = 5;
const EDGE_COLOR = "#5B8FF9";
const LABEL_BACKGROUND_COLOR = "#c3d2f1";
const { fontSizeMode, headType, tailType } = registerControls({
fontSizeMode: {
type: "select",
label: "Font size mode",
default: "fixed",
options: [
{ label: "Fixed", value: "fixed" },
{ label: "Scaled", value: "scaled" },
],
},
headType: {
type: "select",
label: "Head extremity",
default: "arrow",
options: [
{ label: "None", value: "none" },
{ label: "Arrow", value: "arrow" },
],
},
tailType: {
type: "select",
label: "Tail extremity",
default: "none",
options: [
{ label: "None", value: "none" },
{ label: "Arrow", value: "arrow" },
],
},
});
const graph = new Graph();
for (let row = 0; row < PATHS.length; row++) {
for (let col = 0; col < COLS.length; col++) {
const pathInfo = PATHS[row];
const colInfo = COLS[col];
const cellX = col * COL_SPACING;
const cellY = -row * ROW_SPACING;
const sourceId = `${pathInfo.name}-${col}-source`;
graph.addNode(sourceId, {
x: cellX - NODE_SPACING / 2,
y: cellY,
});
const targetId = `${pathInfo.name}-${col}-target`;
graph.addNode(targetId, {
x: cellX + NODE_SPACING / 2,
y: cellY + NODE_SPACING / 2,
});
graph.addEdge(sourceId, targetId, {
size: EDGE_SIZE,
color: EDGE_COLOR,
label: `${pathInfo.label} / ${colInfo.label}`,
path: pathInfo.name,
labelPosition: colInfo.position,
curvature: pathInfo.name === "curved" ? 0.3 : 0,
labelBackground: colInfo.background,
});
}
}
new Sigma(graph, container, {
primitives: {
edges: {
paths: [pathLine(), pathCurved(), pathStepCurved({ cornerRadius: 1 })],
extremities: [extremityArrow()],
layers: [layerPlain()],
defaultHead: headType === "none" ? undefined : headType,
defaultTail: tailType === "none" ? undefined : tailType,
variables: { curvature: { type: "number", default: 0 } },
label: {
fontSizeMode: fontSizeMode as EdgeLabelFontSizeMode,
color: "#041a47",
textBorder: { width: 12, color: "#ffffff" },
},
},
},
styles: {
nodes: [DEFAULT_STYLES.nodes, { size: 6, color: "darkgrey", label: "" }],
edges: [
DEFAULT_STYLES.edges,
{
path: { attribute: "path" },
labelVisibility: "visible",
labelPosition: { attribute: "labelPosition", defaultValue: "over" },
},
{
whenData: "labelBackground",
then: {
labelBackgroundColor: LABEL_BACKGROUND_COLOR,
labelBackgroundPadding: 4,
},
},
],
},
settings: {
renderEdgeLabels: true,
itemSizesReference: "positions",
autoRescale: true,
},
});
</script>