<div id="sigma-container"></div>
<style>
#sigma-container {
width: 100%;
height: 100%;
}
</style>
<script>
import Graph from "graphology";
import clusters from "graphology-generators/random/clusters";
import forceAtlas2 from "graphology-layout-forceatlas2";
import FA2Layout from "graphology-layout-forceatlas2/worker";
import circlepack from "graphology-layout/circlepack";
import { DEFAULT_STYLES } from "sigma/types";
import seedrandom from "seedrandom";
import Sigma from "sigma";
import { registerControls } from "../_controls";
const rng = seedrandom("sigma");
let fa2Layout: FA2Layout;
const { order, size, clusterCount } = registerControls({
order: { type: "number", label: "Nodes", default: 5000, min: 100, step: 100 },
size: { type: "number", label: "Edges", default: 10000, min: 100, step: 100 },
clusterCount: { type: "number", label: "Clusters", default: 3, min: 1, step: 1 },
fa2: {
type: "toggle",
label: "Toggle ForceAtlas2",
default: false,
action: (running) => {
if (running) fa2Layout.start();
else fa2Layout.stop();
},
},
});
// Generate a clustered random graph
const graph = clusters(Graph, { order, size, clusters: clusterCount, rng });
circlepack.assign(graph, { hierarchyAttributes: ["cluster"] });
// Assign colors per cluster and sizes from degree
const colors: Record<string, string> = {};
for (let i = 0; i < clusterCount; i++) {
colors[i] = "#" + Math.floor(rng() * 16777215).toString(16);
}
let i = 0;
graph.forEachNode((node, { cluster }) => {
graph.mergeNodeAttributes(node, {
size: graph.degree(node) / 3,
label: `Node n°${++i}, cluster n°${cluster}`,
color: colors[cluster + ""],
});
});
// Render
const container = document.getElementById("sigma-container") as HTMLElement;
const renderer = new Sigma(graph, container, {
styles: {
edges: [DEFAULT_STYLES.edges, { color: "#e6e6e6" }],
},
});
// Prepare FA2 layout worker
const sensibleSettings = forceAtlas2.inferSettings(graph);
fa2Layout = new FA2Layout(graph, { settings: sensibleSettings });
// Slight camera tilt for better label readability
renderer.getCamera().setState({ angle: 0.2 });
</script>