<div id="sigma-container"></div>
<link rel="stylesheet" href="https://unpkg.com/maplibre-gl@4.5.0/dist/maplibre-gl.css" />
import bindMaplibreLayer from "@sigma/layer-maplibre";
import Graph from "graphology";
import { nodeExtent } from "graphology-metrics/graph";
import type { Attributes, SerializedGraph } from "graphology-types";
import type { StyleSpecification } from "maplibre-gl";
import Sigma from "sigma";
import { DEFAULT_STYLES } from "sigma/types";
const mapStyle: StyleSpecification = {
url: "https://demotiles.maplibre.org/tiles/tiles.json",
glyphs: "https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf",
paint: { "background-color": "#f5f5f5" },
"source-layer": "countries",
paint: { "fill-color": "#ffffff" },
id: "countries-boundary",
"source-layer": "countries",
paint: { "line-color": "#dee2e6", "line-width": 1 },
"source-layer": "geolines",
paint: { "line-color": "#dee2e6", "line-width": 1.5 },
"source-layer": "centroids",
"text-font": ["Open Sans Semibold"],
"text-halo-color": "#ffffff",
const container = document.getElementById("sigma-container") as HTMLElement;
const res = await fetch("/data/airports.json");
const data = await res.json();
const graph = Graph.from(data as SerializedGraph);
graph.updateEachNodeAttributes((node, attributes) => ({
label: attributes.fullName,
degree: graph.degree(node),
const [minDegree, maxDegree] = nodeExtent(graph, "degree");
const renderer = new Sigma(graph, container, {
labelRenderedSizeThreshold: 20,
edges: [DEFAULT_STYLES.edges, { color: "#ffaeaf", size: 0.0001 }],
bindMaplibreLayer(renderer, {
mapOptions: { style: mapStyle },
getNodeLatLng: (attrs: Attributes) => ({ lat: attrs.latitude, lng: attrs.longitude }),