<div id="sigma-container"></div>
<link rel="stylesheet" href="https://unpkg.com/maplibre-gl@4.5.0/dist/maplibre-gl.css" />
<style>
#sigma-container {
width: 100%;
height: 100%;
}
</style>
<script>
import bindMaplibreLayer, { graphToLatlng } from "@sigma/layer-maplibre";
import Graph from "graphology";
import { Marker } from "maplibre-gl";
import Sigma from "sigma";
import { DEFAULT_STYLES } from "sigma/types";
import type { FeatureCollection } from "geojson";
const container = document.getElementById("sigma-container") as HTMLElement;
const graph = new Graph();
graph.addNode("paris", { x: 0, y: 0, lat: 48.8566, lng: 2.3522, label: "Paris" });
graph.addNode("london", { x: 0, y: 0, lat: 51.5074, lng: -0.1278, label: "London" });
graph.addEdge("paris", "london");
// Approximate Channel Tunnel route as inline GeoJSON
const channelTunnelGeoJSON: FeatureCollection = {
type: "FeatureCollection",
features: [
{
type: "Feature",
geometry: {
type: "LineString",
coordinates: [
[1.8, 50.93],
[1.6, 50.95],
[1.4, 50.97],
[1.3, 50.98],
[1.2, 50.99],
[1.1, 51.0],
[1.0, 51.01],
[0.9, 51.02],
],
},
properties: { name: "Channel Tunnel (approximate)" },
},
],
};
const renderer = new Sigma(graph, container, {
settings: {
labelRenderedSizeThreshold: 0,
},
styles: {
nodes: [DEFAULT_STYLES.nodes, { color: "black", size: 0.004 }],
edges: [DEFAULT_STYLES.edges, { color: "black", size: 0.001 }],
},
});
const { map } = bindMaplibreLayer(renderer, {
getNodeLatLng: (attrs) => ({ lat: attrs.lat, lng: attrs.lng }),
});
// Add GeoJSON layer and click-to-marker after map loads
map.once("load", () => {
map.addSource("channel-tunnel", { type: "geojson", data: channelTunnelGeoJSON }).addLayer({
id: "channel-tunnel-line",
type: "line",
source: "channel-tunnel",
paint: {
"line-color": "red",
"line-width": 3,
"line-dasharray": [2, 2],
},
});
// Click on the stage to place a marker
let markerOnClick: null | Marker = null;
renderer.on("clickStage", (e) => {
const graphCoords = renderer.viewportToGraph({ x: e.event.x, y: e.event.y });
const geoCoords = graphToLatlng(graphCoords);
if (!markerOnClick) {
markerOnClick = new Marker();
markerOnClick.setLngLat(geoCoords);
markerOnClick.addTo(map);
} else {
markerOnClick.setLngLat(geoCoords);
}
});
});
</script>