Colors and sizes
Most of the time, people want to map node colors and sizes to graph attributes. You control the mapping between attributes and visual properties through styles.
The example below shows how to map some node categorical attribute to colors, and some node number attribute to sizes:
import Sigma from "sigma";import { DEFAULT_STYLES } from "sigma/types";
import { getSmallGraph } from "../_data/small-graph";
const container = document.getElementById("sigma-container") as HTMLElement;
const graph = getSmallGraph();
const DATA: Record<string, { cluster: string; score: number }> = { a: { cluster: "1", score: 0.0003 }, b: { cluster: "1", score: 0.0008 }, c: { cluster: "2", score: 0.0005 }, d: { cluster: "2", score: 0.0002 }, e: { cluster: "3", score: 0.001 }, f: { cluster: "3", score: 0.0004 },};graph.forEachNode((node) => { graph.mergeNodeAttributes(node, DATA[node]);});
new Sigma(graph, container, { styles: { nodes: [ DEFAULT_STYLES.nodes, { color: { attribute: "cluster", dict: { "1": "#E8684A", "2": "#5B8FF9", "3": "#61DDAA" }, defaultValue: "#999", }, size: { attribute: "score", min: 10, max: 30, minValue: 0, maxValue: 0.001 }, }, ], edges: [DEFAULT_STYLES.edges], },});Setting colors and sizes
The most common approach reads color and size directly from graph attributes (when they are stored “as is” in the graphology instance):
import Graph from "graphology";import Sigma from "sigma";
const graph = new Graph();graph.addNode("a", { x: 0, y: 0, size: 15, color: "#e22653", label: "Node A" });graph.addNode("b", { x: 100, y: 100, size: 25, color: "#0055ff", label: "Node B" });
new Sigma(graph, container, { styles: { nodes: [{ color: { attribute: "color" }, size: { attribute: "size" } }], },});You can also set fixed values that apply to all nodes:
styles: { nodes: [ { color: "#e22653", size: 10 }, ],}Or mix fixed defaults with attribute overrides. Style rules are evaluated in order, and later values override earlier ones:
styles: { nodes: [ { color: "#cccccc", size: 10 }, { color: { attribute: "color" }, size: { attribute: "size" } }, ],}Conditional styles
You can change appearance based on node state. For example, grey out nodes that are not active:
styles: { nodes: [ { color: { attribute: "color" }, size: { attribute: "size" } }, { when: (attrs, state, graphState) => graphState.hasActiveSubgraph && !state.isActive, then: { color: "#f6f6f6" }, }, ],}See Hover and search highlight for a full example of conditional styling.
Opacity and alpha blending
Use the opacity style property to control node and edge transparency:
import { layerBorder } from "@sigma/node-border";import Graph from "graphology";import Sigma from "sigma";import { DEFAULT_STYLES } from "sigma/types";import { registerControls } from "../_controls";
const container = document.getElementById("sigma-container") as HTMLElement;
const { bgColor, useColorAlpha, nodeOpacity, edgeOpacity, edgeSize } = registerControls({ bgColor: { type: "select", label: "Background", default: "#ffffff", options: [ { label: "White", value: "#ffffff" }, { label: "Light gray", value: "#e0e0e0" }, { label: "Dark gray", value: "#333333" }, { label: "Black", value: "#000000" }, ], }, useColorAlpha: { type: "boolean", label: "Use color alpha (not opacity)", default: false }, nodeOpacity: { type: "number", label: "Node opacity", default: 0.8, min: 0, max: 1, step: 0.05 }, edgeOpacity: { type: "number", label: "Edge opacity", default: 0.1, min: 0, max: 1, step: 0.05 }, edgeSize: { type: "number", label: "Edge size", default: 25, min: 0, max: 100, step: 2.5 },});
container.style.backgroundColor = bgColor;const isDarkBg = bgColor === "#333333" || bgColor === "#000000";
// Load dataconst res = await fetch("/data/wikipedia.json");const data: { nodes: { key: string; label: string; cluster: string; x: number; y: number; score: number }[]; edges: [string, string][]; clusters: { key: string; color: string; clusterLabel: string }[];} = await res.json();
// Build cluster color mapconst clusterColors: Record<string, string> = {};for (const c of data.clusters) { clusterColors[c.key] = c.color;}
// Brighten a hex color by mixing it with whitefunction brighten(hex: string, amount = 0.5): string { const r = parseInt(hex.slice(1, 3), 16); const g = parseInt(hex.slice(3, 5), 16); const b = parseInt(hex.slice(5, 7), 16); const mix = (c: number) => Math.round(c + (255 - c) * amount); return `#${mix(r).toString(16).padStart(2, "0")}${mix(g).toString(16).padStart(2, "0")}${mix(b).toString(16).padStart(2, "0")}`;}
// Convert hex color to rgba with given alphafunction withAlpha(hex: string, alpha: number): string { const r = parseInt(hex.slice(1, 3), 16); const g = parseInt(hex.slice(3, 5), 16); const b = parseInt(hex.slice(5, 7), 16); return `rgba(${r}, ${g}, ${b}, ${alpha})`;}
const graph = new Graph();
// Add nodesfor (const node of data.nodes) { const color = clusterColors[node.cluster] || "#999"; const nodeColor = useColorAlpha ? withAlpha(color, nodeOpacity) : color; const fillColor = brighten(color, 0.5); graph.addNode(node.key, { x: node.x, y: node.y, score: node.score, label: node.label, color: nodeColor, fillColor: useColorAlpha ? withAlpha(fillColor, nodeOpacity) : fillColor, });}
// Add edges, colored by source nodefor (const [source, target] of data.edges) { if (graph.hasNode(source) && graph.hasNode(target)) { const sourceColor = clusterColors[data.nodes.find((n) => n.key === source)?.cluster ?? ""] || "#999"; graph.addEdge(source, target, { color: useColorAlpha ? withAlpha(sourceColor, edgeOpacity) : sourceColor, }); }}
new Sigma(graph, container, { primitives: { nodes: { variables: { fillColor: { type: "color", default: "#ccc" }, }, layers: [ layerBorder({ borders: [ { size: 0.15, color: { attribute: "color" }, mode: "relative" }, { size: 0, color: { attribute: "fillColor" }, fill: true }, ], }), ], }, }, styles: { nodes: [ DEFAULT_STYLES.nodes, { opacity: useColorAlpha ? 1 : nodeOpacity, size: { attribute: "score", min: 25, max: 100, minValue: 0, maxValue: 0.1 }, ...(isDarkBg ? { labelColor: { whenState: "isHovered", then: "#000", else: "#fff" } } : {}), }, ], edges: [DEFAULT_STYLES.edges, { opacity: useColorAlpha ? 1 : edgeOpacity, size: edgeSize }], },});