@sigma/layer-maplibre 3.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE.txt ADDED
@@ -0,0 +1,12 @@
1
+ Copyright (C) 2013-2024, Alexis Jacomy, Guillaume Plique, Benoît Simard https://www.sigmajs.org
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
4
+ to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
5
+ and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
10
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
12
+ IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,27 @@
1
+ # Sigma.js - Maplibre background layer
2
+
3
+ This package contains a maplibre background layer for [sigma.js](https://sigmajs.org).
4
+
5
+ It displays a map on the graph's background and handle the camera synchronisation.
6
+
7
+ ## How to use
8
+
9
+ First you need to install [maplibre](https://maplibre.org/) in your application.
10
+ You can check this [page](https://maplibre.org/maplibre-gl-js/docs/) to see how to do it.
11
+ Especially, don't forget to load `maplibre-gl.css` in your application.
12
+
13
+ Then, within your application that uses sigma.js, you can use [`@sigma/layer-maplibre`](https://www.npmjs.com/package/@sigma/layer-maplibre) as following:
14
+
15
+ ```typescript
16
+ import bindLeafletLayer from "@sigma/layer-maplibre";
17
+
18
+ const graph = new Graph();
19
+ graph.addNode("nantes", { x: 0, y: 0, lat: 47.2308, lng: 1.5566, size: 10, label: "Nantes" });
20
+ graph.addNode("paris", { x: 0, y: 0, lat: 48.8567, lng: 2.351, size: 10, label: "Paris" });
21
+ graph.addEdge("nantes", "paris");
22
+
23
+ const sigma = new Sigma(graph, container);
24
+ bindMaplibreLayer(sigma);
25
+ ```
26
+
27
+ Please check the related [Storybook](https://github.com/jacomyal/sigma.js/tree/main/packages/storybook/stories/layer-maplibre) for more advanced examples.
@@ -0,0 +1,24 @@
1
+ import Graph from "graphology";
2
+ import { Attributes } from "graphology-types";
3
+ import { Map, MapOptions } from "maplibre-gl";
4
+ import { Sigma } from "sigma";
5
+ import { graphToLatlng, latlngToGraph } from "./utils.js";
6
+ /**
7
+ * On the graph, we store the 2D projection of the geographical lat/long.
8
+ *
9
+ * @param sigma The sigma instance
10
+ * @param opts.mapOptions Options that will be provided to map constructor.
11
+ * @param opts.getNodeLatLng Function to retrieve lat/long values from a node's attributs (default is lat & lng)
12
+ */
13
+ export default function bindMaplibreLayer(sigma: Sigma, opts?: {
14
+ mapOptions?: Omit<MapOptions, "container" | "center" | "zoom" | "minPitch" | "maxPitch">;
15
+ getNodeLatLng?: (nodeAttributes: Attributes) => {
16
+ lat: number;
17
+ lng: number;
18
+ };
19
+ }): {
20
+ clean: () => void;
21
+ map: Map;
22
+ updateGraphCoordinates: (graph: Graph) => void;
23
+ };
24
+ export { graphToLatlng, latlngToGraph };
@@ -0,0 +1,31 @@
1
+ import { Map } from "maplibre-gl";
2
+ import { Sigma } from "sigma";
3
+ export declare const MAX_VALID_LATITUDE = 85.051129;
4
+ /**
5
+ * Given a geo point returns its graph coords.
6
+ */
7
+ export declare function latlngToGraph(map: Map, coord: {
8
+ lat: number;
9
+ lng: number;
10
+ }): {
11
+ x: number;
12
+ y: number;
13
+ };
14
+ /**
15
+ * Given a graph coords returns its lat/lng coords.
16
+ */
17
+ export declare function graphToLatlng(map: Map, coords: {
18
+ x: number;
19
+ y: number;
20
+ }): {
21
+ lat: number;
22
+ lng: number;
23
+ };
24
+ /**
25
+ * BBOX sync : map to sigma
26
+ */
27
+ export declare function syncSigmaWithMap(sigma: Sigma, map: Map): void;
28
+ /**
29
+ * BBOX sync : sigma to map
30
+ */
31
+ export declare function syncMapWithSigma(sigma: Sigma, map: Map): void;
@@ -0,0 +1,3 @@
1
+ export * from "./declarations/src/index.js";
2
+ export { _default as default } from "./sigma-layer-maplibre.cjs.default.js";
3
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbWEtbGF5ZXItbWFwbGlicmUuY2pzLmQubXRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi9kZWNsYXJhdGlvbnMvc3JjL2luZGV4LmQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEifQ==
@@ -0,0 +1,3 @@
1
+ export * from "./declarations/src/index";
2
+ export { default } from "./declarations/src/index";
3
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbWEtbGF5ZXItbWFwbGlicmUuY2pzLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuL2RlY2xhcmF0aW9ucy9zcmMvaW5kZXguZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSJ9
@@ -0,0 +1 @@
1
+ export { default as _default } from "./declarations/src/index.js"
@@ -0,0 +1 @@
1
+ exports._default = require("./sigma-layer-maplibre.cjs.js").default;
@@ -0,0 +1,258 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var maplibreGl = require('maplibre-gl');
6
+ var settings = require('sigma/settings');
7
+
8
+ function toPrimitive(t, r) {
9
+ if ("object" != typeof t || !t) return t;
10
+ var e = t[Symbol.toPrimitive];
11
+ if (void 0 !== e) {
12
+ var i = e.call(t, r || "default");
13
+ if ("object" != typeof i) return i;
14
+ throw new TypeError("@@toPrimitive must return a primitive value.");
15
+ }
16
+ return ("string" === r ? String : Number)(t);
17
+ }
18
+
19
+ function toPropertyKey(t) {
20
+ var i = toPrimitive(t, "string");
21
+ return "symbol" == typeof i ? i : String(i);
22
+ }
23
+
24
+ function _defineProperty(obj, key, value) {
25
+ key = toPropertyKey(key);
26
+ if (key in obj) {
27
+ Object.defineProperty(obj, key, {
28
+ value: value,
29
+ enumerable: true,
30
+ configurable: true,
31
+ writable: true
32
+ });
33
+ } else {
34
+ obj[key] = value;
35
+ }
36
+ return obj;
37
+ }
38
+
39
+ function ownKeys(e, r) {
40
+ var t = Object.keys(e);
41
+ if (Object.getOwnPropertySymbols) {
42
+ var o = Object.getOwnPropertySymbols(e);
43
+ r && (o = o.filter(function (r) {
44
+ return Object.getOwnPropertyDescriptor(e, r).enumerable;
45
+ })), t.push.apply(t, o);
46
+ }
47
+ return t;
48
+ }
49
+ function _objectSpread2(e) {
50
+ for (var r = 1; r < arguments.length; r++) {
51
+ var t = null != arguments[r] ? arguments[r] : {};
52
+ r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
53
+ _defineProperty(e, r, t[r]);
54
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
55
+ Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
56
+ });
57
+ }
58
+ return e;
59
+ }
60
+
61
+ /**
62
+ * Given a geo point returns its graph coords.
63
+ */
64
+ function latlngToGraph(map, coord) {
65
+ var data = maplibreGl.MercatorCoordinate.fromLngLat(coord);
66
+ return {
67
+ x: data.x,
68
+ // Y are reversed between geo / sigma
69
+ y: map.getContainer().clientHeight - data.y
70
+ };
71
+ }
72
+
73
+ /**
74
+ * Given a graph coords returns its lat/lng coords.
75
+ */
76
+ function graphToLatlng(map, coords) {
77
+ var mcoords = new maplibreGl.MercatorCoordinate(coords.x, map.getContainer().clientHeight - coords.y, 0);
78
+ var data = mcoords.toLngLat();
79
+ return {
80
+ lat: data.lat,
81
+ lng: data.lng
82
+ };
83
+ }
84
+
85
+ /**
86
+ * BBOX sync : map to sigma
87
+ */
88
+ function syncSigmaWithMap(sigma, map) {
89
+ var mapBound = map.getBounds();
90
+
91
+ // Compute sigma center
92
+ var center = sigma.viewportToFramedGraph(sigma.graphToViewport(latlngToGraph(map, mapBound.getCenter())));
93
+
94
+ // Compute sigma ratio
95
+ var northEast = sigma.graphToViewport(latlngToGraph(map, mapBound.getNorthEast()));
96
+ var southWest = sigma.graphToViewport(latlngToGraph(map, mapBound.getSouthWest()));
97
+ var viewportBoundDimension = {
98
+ width: Math.abs(northEast.x - southWest.x),
99
+ height: Math.abs(northEast.y - southWest.y)
100
+ };
101
+ var viewportDim = sigma.getDimensions();
102
+ var ratio = Math.min(viewportBoundDimension.width / viewportDim.width, viewportBoundDimension.height / viewportDim.height) * sigma.getCamera().getState().ratio;
103
+ sigma.getCamera().setState(_objectSpread2(_objectSpread2({}, center), {}, {
104
+ ratio: ratio
105
+ }));
106
+ }
107
+
108
+ /**
109
+ * BBOX sync : sigma to map
110
+ */
111
+ function syncMapWithSigma(sigma, map) {
112
+ var viewportDimensions = sigma.getDimensions();
113
+
114
+ // Graph BBox
115
+ var graphBottomLeft = sigma.viewportToGraph({
116
+ x: 0,
117
+ y: viewportDimensions.height
118
+ }, {
119
+ padding: 0
120
+ });
121
+ var graphTopRight = sigma.viewportToGraph({
122
+ x: viewportDimensions.width,
123
+ y: 0
124
+ }, {
125
+ padding: 0
126
+ });
127
+
128
+ // Geo BBox
129
+ var geoSouthWest = graphToLatlng(map, graphBottomLeft);
130
+ var geoNorthEast = graphToLatlng(map, graphTopRight);
131
+
132
+ // Set map BBox
133
+ var bounds = new maplibreGl.LngLatBounds([geoSouthWest, geoNorthEast]);
134
+ map.fitBounds(bounds, {
135
+ duration: 0
136
+ });
137
+ }
138
+
139
+ /**
140
+ * On the graph, we store the 2D projection of the geographical lat/long.
141
+ *
142
+ * @param sigma The sigma instance
143
+ * @param opts.mapOptions Options that will be provided to map constructor.
144
+ * @param opts.getNodeLatLng Function to retrieve lat/long values from a node's attributs (default is lat & lng)
145
+ */
146
+ function bindMaplibreLayer(sigma, opts) {
147
+ // Creating map container
148
+ var mapContainer = document.createElement("div");
149
+ var mapContainerId = "".concat(sigma.getContainer().id, "-map");
150
+ mapContainer.setAttribute("id", mapContainerId);
151
+ mapContainer.setAttribute("style", "position: relative; top:0; left:0; width: 100%; height:100%; z-index:-1");
152
+ sigma.getContainer().appendChild(mapContainer);
153
+
154
+ // Initialize the map
155
+ var map = new maplibreGl.Map(_objectSpread2(_objectSpread2({}, (opts === null || opts === void 0 ? void 0 : opts.mapOptions) || {}), {}, {
156
+ container: mapContainerId,
157
+ style: "https://demotiles.maplibre.org/style.json",
158
+ center: [0, 0],
159
+ zoom: 1,
160
+ minPitch: 0,
161
+ maxPitch: 0
162
+ }));
163
+
164
+ // `stagePadding: 0` is mandatory, so the bbox of the map & Sigma is the same.
165
+ sigma.setSetting("stagePadding", 0);
166
+
167
+ // disable camera rotation
168
+ sigma.setSetting("enableCameraRotation", false);
169
+
170
+ // Function that change the given graph by generating the sigma x,y coords by taking the geo coordinates
171
+ // and project them in the 2D space of the map
172
+ function updateGraphCoordinates(graph) {
173
+ graph.updateEachNodeAttributes(function (_node, attrs) {
174
+ var coords = latlngToGraph(map, opts !== null && opts !== void 0 && opts.getNodeLatLng ? opts.getNodeLatLng(attrs) : {
175
+ lat: attrs.lat,
176
+ lng: attrs.lng
177
+ });
178
+ return _objectSpread2(_objectSpread2({}, attrs), {}, {
179
+ x: coords.x,
180
+ y: coords.y
181
+ });
182
+ });
183
+ }
184
+
185
+ // Function that sync the map with sigma
186
+ function fnSyncMapWithSigma() {
187
+ syncMapWithSigma(sigma, map);
188
+ }
189
+
190
+ // Function that sync sigma with map if it's needed
191
+ function fnSyncSigmaWithMap() {
192
+ if (!sigma.getCamera().isAnimated() && !map.isMoving()) {
193
+ // Check that sigma & map are already in sync
194
+ var southWest = graphToLatlng(map, sigma.viewportToGraph({
195
+ x: 0,
196
+ y: sigma.getDimensions().height
197
+ }));
198
+ var northEast = graphToLatlng(map, sigma.viewportToGraph({
199
+ x: sigma.getDimensions().width,
200
+ y: 0
201
+ }));
202
+ var diff = Math.max(map.getBounds().getSouthWest().distanceTo(new maplibreGl.LngLat(southWest.lng, southWest.lat)), map.getBounds().getNorthEast().distanceTo(new maplibreGl.LngLat(northEast.lng, northEast.lat)));
203
+ if (diff > 1) {
204
+ syncSigmaWithMap(sigma, map);
205
+ }
206
+ }
207
+ }
208
+
209
+ // When sigma is resize, we need to update the graph coordinate (the ref has changed)
210
+ // and recompute the zoom bounds
211
+ function fnOnResize() {
212
+ updateGraphCoordinates(sigma.getGraph());
213
+ fnSyncSigmaWithMap();
214
+ }
215
+
216
+ // Clean up function to remove everything
217
+ function clean() {
218
+ map.off("moveend", fnSyncSigmaWithMap);
219
+ map.remove();
220
+ mapContainer.remove();
221
+ sigma.off("afterRender", fnSyncMapWithSigma);
222
+ sigma.off("resize", fnOnResize);
223
+ sigma.setSetting("stagePadding", settings.DEFAULT_SETTINGS.stagePadding);
224
+ sigma.setSetting("enableCameraRotation", true);
225
+ }
226
+
227
+ // Update the sigma graph for geospatial coords
228
+ updateGraphCoordinates(sigma.getGraph());
229
+
230
+ // When the map is ready
231
+ map.once("load", function () {
232
+ // Compute sigma ratio bounds
233
+ // /!\ must be done after the first map render
234
+ map.once("moveend", function () {
235
+ fnSyncSigmaWithMap();
236
+ });
237
+ // Do the first sync
238
+ fnSyncMapWithSigma();
239
+
240
+ // At each render of sigma, we do the map sync
241
+ sigma.on("afterRender", fnSyncMapWithSigma);
242
+ // Listen on resize
243
+ sigma.on("resize", fnOnResize);
244
+ // Do the cleanup
245
+ sigma.on("kill", clean);
246
+ // Keep sigma camera on the map
247
+ map.on("moveend", fnSyncSigmaWithMap);
248
+ });
249
+ return {
250
+ clean: clean,
251
+ map: map,
252
+ updateGraphCoordinates: updateGraphCoordinates
253
+ };
254
+ }
255
+
256
+ exports["default"] = bindMaplibreLayer;
257
+ exports.graphToLatlng = graphToLatlng;
258
+ exports.latlngToGraph = latlngToGraph;
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ if (process.env.NODE_ENV === "production") {
4
+ module.exports = require("./sigma-layer-maplibre.cjs.prod.js");
5
+ } else {
6
+ module.exports = require("./sigma-layer-maplibre.cjs.dev.js");
7
+ }
@@ -0,0 +1,5 @@
1
+ export {
2
+ graphToLatlng,
3
+ latlngToGraph
4
+ } from "./sigma-layer-maplibre.cjs.js";
5
+ export { _default as default } from "./sigma-layer-maplibre.cjs.default.js";
@@ -0,0 +1,258 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var maplibreGl = require('maplibre-gl');
6
+ var settings = require('sigma/settings');
7
+
8
+ function toPrimitive(t, r) {
9
+ if ("object" != typeof t || !t) return t;
10
+ var e = t[Symbol.toPrimitive];
11
+ if (void 0 !== e) {
12
+ var i = e.call(t, r || "default");
13
+ if ("object" != typeof i) return i;
14
+ throw new TypeError("@@toPrimitive must return a primitive value.");
15
+ }
16
+ return ("string" === r ? String : Number)(t);
17
+ }
18
+
19
+ function toPropertyKey(t) {
20
+ var i = toPrimitive(t, "string");
21
+ return "symbol" == typeof i ? i : String(i);
22
+ }
23
+
24
+ function _defineProperty(obj, key, value) {
25
+ key = toPropertyKey(key);
26
+ if (key in obj) {
27
+ Object.defineProperty(obj, key, {
28
+ value: value,
29
+ enumerable: true,
30
+ configurable: true,
31
+ writable: true
32
+ });
33
+ } else {
34
+ obj[key] = value;
35
+ }
36
+ return obj;
37
+ }
38
+
39
+ function ownKeys(e, r) {
40
+ var t = Object.keys(e);
41
+ if (Object.getOwnPropertySymbols) {
42
+ var o = Object.getOwnPropertySymbols(e);
43
+ r && (o = o.filter(function (r) {
44
+ return Object.getOwnPropertyDescriptor(e, r).enumerable;
45
+ })), t.push.apply(t, o);
46
+ }
47
+ return t;
48
+ }
49
+ function _objectSpread2(e) {
50
+ for (var r = 1; r < arguments.length; r++) {
51
+ var t = null != arguments[r] ? arguments[r] : {};
52
+ r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
53
+ _defineProperty(e, r, t[r]);
54
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
55
+ Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
56
+ });
57
+ }
58
+ return e;
59
+ }
60
+
61
+ /**
62
+ * Given a geo point returns its graph coords.
63
+ */
64
+ function latlngToGraph(map, coord) {
65
+ var data = maplibreGl.MercatorCoordinate.fromLngLat(coord);
66
+ return {
67
+ x: data.x,
68
+ // Y are reversed between geo / sigma
69
+ y: map.getContainer().clientHeight - data.y
70
+ };
71
+ }
72
+
73
+ /**
74
+ * Given a graph coords returns its lat/lng coords.
75
+ */
76
+ function graphToLatlng(map, coords) {
77
+ var mcoords = new maplibreGl.MercatorCoordinate(coords.x, map.getContainer().clientHeight - coords.y, 0);
78
+ var data = mcoords.toLngLat();
79
+ return {
80
+ lat: data.lat,
81
+ lng: data.lng
82
+ };
83
+ }
84
+
85
+ /**
86
+ * BBOX sync : map to sigma
87
+ */
88
+ function syncSigmaWithMap(sigma, map) {
89
+ var mapBound = map.getBounds();
90
+
91
+ // Compute sigma center
92
+ var center = sigma.viewportToFramedGraph(sigma.graphToViewport(latlngToGraph(map, mapBound.getCenter())));
93
+
94
+ // Compute sigma ratio
95
+ var northEast = sigma.graphToViewport(latlngToGraph(map, mapBound.getNorthEast()));
96
+ var southWest = sigma.graphToViewport(latlngToGraph(map, mapBound.getSouthWest()));
97
+ var viewportBoundDimension = {
98
+ width: Math.abs(northEast.x - southWest.x),
99
+ height: Math.abs(northEast.y - southWest.y)
100
+ };
101
+ var viewportDim = sigma.getDimensions();
102
+ var ratio = Math.min(viewportBoundDimension.width / viewportDim.width, viewportBoundDimension.height / viewportDim.height) * sigma.getCamera().getState().ratio;
103
+ sigma.getCamera().setState(_objectSpread2(_objectSpread2({}, center), {}, {
104
+ ratio: ratio
105
+ }));
106
+ }
107
+
108
+ /**
109
+ * BBOX sync : sigma to map
110
+ */
111
+ function syncMapWithSigma(sigma, map) {
112
+ var viewportDimensions = sigma.getDimensions();
113
+
114
+ // Graph BBox
115
+ var graphBottomLeft = sigma.viewportToGraph({
116
+ x: 0,
117
+ y: viewportDimensions.height
118
+ }, {
119
+ padding: 0
120
+ });
121
+ var graphTopRight = sigma.viewportToGraph({
122
+ x: viewportDimensions.width,
123
+ y: 0
124
+ }, {
125
+ padding: 0
126
+ });
127
+
128
+ // Geo BBox
129
+ var geoSouthWest = graphToLatlng(map, graphBottomLeft);
130
+ var geoNorthEast = graphToLatlng(map, graphTopRight);
131
+
132
+ // Set map BBox
133
+ var bounds = new maplibreGl.LngLatBounds([geoSouthWest, geoNorthEast]);
134
+ map.fitBounds(bounds, {
135
+ duration: 0
136
+ });
137
+ }
138
+
139
+ /**
140
+ * On the graph, we store the 2D projection of the geographical lat/long.
141
+ *
142
+ * @param sigma The sigma instance
143
+ * @param opts.mapOptions Options that will be provided to map constructor.
144
+ * @param opts.getNodeLatLng Function to retrieve lat/long values from a node's attributs (default is lat & lng)
145
+ */
146
+ function bindMaplibreLayer(sigma, opts) {
147
+ // Creating map container
148
+ var mapContainer = document.createElement("div");
149
+ var mapContainerId = "".concat(sigma.getContainer().id, "-map");
150
+ mapContainer.setAttribute("id", mapContainerId);
151
+ mapContainer.setAttribute("style", "position: relative; top:0; left:0; width: 100%; height:100%; z-index:-1");
152
+ sigma.getContainer().appendChild(mapContainer);
153
+
154
+ // Initialize the map
155
+ var map = new maplibreGl.Map(_objectSpread2(_objectSpread2({}, (opts === null || opts === void 0 ? void 0 : opts.mapOptions) || {}), {}, {
156
+ container: mapContainerId,
157
+ style: "https://demotiles.maplibre.org/style.json",
158
+ center: [0, 0],
159
+ zoom: 1,
160
+ minPitch: 0,
161
+ maxPitch: 0
162
+ }));
163
+
164
+ // `stagePadding: 0` is mandatory, so the bbox of the map & Sigma is the same.
165
+ sigma.setSetting("stagePadding", 0);
166
+
167
+ // disable camera rotation
168
+ sigma.setSetting("enableCameraRotation", false);
169
+
170
+ // Function that change the given graph by generating the sigma x,y coords by taking the geo coordinates
171
+ // and project them in the 2D space of the map
172
+ function updateGraphCoordinates(graph) {
173
+ graph.updateEachNodeAttributes(function (_node, attrs) {
174
+ var coords = latlngToGraph(map, opts !== null && opts !== void 0 && opts.getNodeLatLng ? opts.getNodeLatLng(attrs) : {
175
+ lat: attrs.lat,
176
+ lng: attrs.lng
177
+ });
178
+ return _objectSpread2(_objectSpread2({}, attrs), {}, {
179
+ x: coords.x,
180
+ y: coords.y
181
+ });
182
+ });
183
+ }
184
+
185
+ // Function that sync the map with sigma
186
+ function fnSyncMapWithSigma() {
187
+ syncMapWithSigma(sigma, map);
188
+ }
189
+
190
+ // Function that sync sigma with map if it's needed
191
+ function fnSyncSigmaWithMap() {
192
+ if (!sigma.getCamera().isAnimated() && !map.isMoving()) {
193
+ // Check that sigma & map are already in sync
194
+ var southWest = graphToLatlng(map, sigma.viewportToGraph({
195
+ x: 0,
196
+ y: sigma.getDimensions().height
197
+ }));
198
+ var northEast = graphToLatlng(map, sigma.viewportToGraph({
199
+ x: sigma.getDimensions().width,
200
+ y: 0
201
+ }));
202
+ var diff = Math.max(map.getBounds().getSouthWest().distanceTo(new maplibreGl.LngLat(southWest.lng, southWest.lat)), map.getBounds().getNorthEast().distanceTo(new maplibreGl.LngLat(northEast.lng, northEast.lat)));
203
+ if (diff > 1) {
204
+ syncSigmaWithMap(sigma, map);
205
+ }
206
+ }
207
+ }
208
+
209
+ // When sigma is resize, we need to update the graph coordinate (the ref has changed)
210
+ // and recompute the zoom bounds
211
+ function fnOnResize() {
212
+ updateGraphCoordinates(sigma.getGraph());
213
+ fnSyncSigmaWithMap();
214
+ }
215
+
216
+ // Clean up function to remove everything
217
+ function clean() {
218
+ map.off("moveend", fnSyncSigmaWithMap);
219
+ map.remove();
220
+ mapContainer.remove();
221
+ sigma.off("afterRender", fnSyncMapWithSigma);
222
+ sigma.off("resize", fnOnResize);
223
+ sigma.setSetting("stagePadding", settings.DEFAULT_SETTINGS.stagePadding);
224
+ sigma.setSetting("enableCameraRotation", true);
225
+ }
226
+
227
+ // Update the sigma graph for geospatial coords
228
+ updateGraphCoordinates(sigma.getGraph());
229
+
230
+ // When the map is ready
231
+ map.once("load", function () {
232
+ // Compute sigma ratio bounds
233
+ // /!\ must be done after the first map render
234
+ map.once("moveend", function () {
235
+ fnSyncSigmaWithMap();
236
+ });
237
+ // Do the first sync
238
+ fnSyncMapWithSigma();
239
+
240
+ // At each render of sigma, we do the map sync
241
+ sigma.on("afterRender", fnSyncMapWithSigma);
242
+ // Listen on resize
243
+ sigma.on("resize", fnOnResize);
244
+ // Do the cleanup
245
+ sigma.on("kill", clean);
246
+ // Keep sigma camera on the map
247
+ map.on("moveend", fnSyncSigmaWithMap);
248
+ });
249
+ return {
250
+ clean: clean,
251
+ map: map,
252
+ updateGraphCoordinates: updateGraphCoordinates
253
+ };
254
+ }
255
+
256
+ exports["default"] = bindMaplibreLayer;
257
+ exports.graphToLatlng = graphToLatlng;
258
+ exports.latlngToGraph = latlngToGraph;
@@ -0,0 +1,252 @@
1
+ import { MercatorCoordinate, LngLatBounds, Map, LngLat } from 'maplibre-gl';
2
+ import { DEFAULT_SETTINGS } from 'sigma/settings';
3
+
4
+ function toPrimitive(t, r) {
5
+ if ("object" != typeof t || !t) return t;
6
+ var e = t[Symbol.toPrimitive];
7
+ if (void 0 !== e) {
8
+ var i = e.call(t, r || "default");
9
+ if ("object" != typeof i) return i;
10
+ throw new TypeError("@@toPrimitive must return a primitive value.");
11
+ }
12
+ return ("string" === r ? String : Number)(t);
13
+ }
14
+
15
+ function toPropertyKey(t) {
16
+ var i = toPrimitive(t, "string");
17
+ return "symbol" == typeof i ? i : String(i);
18
+ }
19
+
20
+ function _defineProperty(obj, key, value) {
21
+ key = toPropertyKey(key);
22
+ if (key in obj) {
23
+ Object.defineProperty(obj, key, {
24
+ value: value,
25
+ enumerable: true,
26
+ configurable: true,
27
+ writable: true
28
+ });
29
+ } else {
30
+ obj[key] = value;
31
+ }
32
+ return obj;
33
+ }
34
+
35
+ function ownKeys(e, r) {
36
+ var t = Object.keys(e);
37
+ if (Object.getOwnPropertySymbols) {
38
+ var o = Object.getOwnPropertySymbols(e);
39
+ r && (o = o.filter(function (r) {
40
+ return Object.getOwnPropertyDescriptor(e, r).enumerable;
41
+ })), t.push.apply(t, o);
42
+ }
43
+ return t;
44
+ }
45
+ function _objectSpread2(e) {
46
+ for (var r = 1; r < arguments.length; r++) {
47
+ var t = null != arguments[r] ? arguments[r] : {};
48
+ r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
49
+ _defineProperty(e, r, t[r]);
50
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
51
+ Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
52
+ });
53
+ }
54
+ return e;
55
+ }
56
+
57
+ /**
58
+ * Given a geo point returns its graph coords.
59
+ */
60
+ function latlngToGraph(map, coord) {
61
+ var data = MercatorCoordinate.fromLngLat(coord);
62
+ return {
63
+ x: data.x,
64
+ // Y are reversed between geo / sigma
65
+ y: map.getContainer().clientHeight - data.y
66
+ };
67
+ }
68
+
69
+ /**
70
+ * Given a graph coords returns its lat/lng coords.
71
+ */
72
+ function graphToLatlng(map, coords) {
73
+ var mcoords = new MercatorCoordinate(coords.x, map.getContainer().clientHeight - coords.y, 0);
74
+ var data = mcoords.toLngLat();
75
+ return {
76
+ lat: data.lat,
77
+ lng: data.lng
78
+ };
79
+ }
80
+
81
+ /**
82
+ * BBOX sync : map to sigma
83
+ */
84
+ function syncSigmaWithMap(sigma, map) {
85
+ var mapBound = map.getBounds();
86
+
87
+ // Compute sigma center
88
+ var center = sigma.viewportToFramedGraph(sigma.graphToViewport(latlngToGraph(map, mapBound.getCenter())));
89
+
90
+ // Compute sigma ratio
91
+ var northEast = sigma.graphToViewport(latlngToGraph(map, mapBound.getNorthEast()));
92
+ var southWest = sigma.graphToViewport(latlngToGraph(map, mapBound.getSouthWest()));
93
+ var viewportBoundDimension = {
94
+ width: Math.abs(northEast.x - southWest.x),
95
+ height: Math.abs(northEast.y - southWest.y)
96
+ };
97
+ var viewportDim = sigma.getDimensions();
98
+ var ratio = Math.min(viewportBoundDimension.width / viewportDim.width, viewportBoundDimension.height / viewportDim.height) * sigma.getCamera().getState().ratio;
99
+ sigma.getCamera().setState(_objectSpread2(_objectSpread2({}, center), {}, {
100
+ ratio: ratio
101
+ }));
102
+ }
103
+
104
+ /**
105
+ * BBOX sync : sigma to map
106
+ */
107
+ function syncMapWithSigma(sigma, map) {
108
+ var viewportDimensions = sigma.getDimensions();
109
+
110
+ // Graph BBox
111
+ var graphBottomLeft = sigma.viewportToGraph({
112
+ x: 0,
113
+ y: viewportDimensions.height
114
+ }, {
115
+ padding: 0
116
+ });
117
+ var graphTopRight = sigma.viewportToGraph({
118
+ x: viewportDimensions.width,
119
+ y: 0
120
+ }, {
121
+ padding: 0
122
+ });
123
+
124
+ // Geo BBox
125
+ var geoSouthWest = graphToLatlng(map, graphBottomLeft);
126
+ var geoNorthEast = graphToLatlng(map, graphTopRight);
127
+
128
+ // Set map BBox
129
+ var bounds = new LngLatBounds([geoSouthWest, geoNorthEast]);
130
+ map.fitBounds(bounds, {
131
+ duration: 0
132
+ });
133
+ }
134
+
135
+ /**
136
+ * On the graph, we store the 2D projection of the geographical lat/long.
137
+ *
138
+ * @param sigma The sigma instance
139
+ * @param opts.mapOptions Options that will be provided to map constructor.
140
+ * @param opts.getNodeLatLng Function to retrieve lat/long values from a node's attributs (default is lat & lng)
141
+ */
142
+ function bindMaplibreLayer(sigma, opts) {
143
+ // Creating map container
144
+ var mapContainer = document.createElement("div");
145
+ var mapContainerId = "".concat(sigma.getContainer().id, "-map");
146
+ mapContainer.setAttribute("id", mapContainerId);
147
+ mapContainer.setAttribute("style", "position: relative; top:0; left:0; width: 100%; height:100%; z-index:-1");
148
+ sigma.getContainer().appendChild(mapContainer);
149
+
150
+ // Initialize the map
151
+ var map = new Map(_objectSpread2(_objectSpread2({}, (opts === null || opts === void 0 ? void 0 : opts.mapOptions) || {}), {}, {
152
+ container: mapContainerId,
153
+ style: "https://demotiles.maplibre.org/style.json",
154
+ center: [0, 0],
155
+ zoom: 1,
156
+ minPitch: 0,
157
+ maxPitch: 0
158
+ }));
159
+
160
+ // `stagePadding: 0` is mandatory, so the bbox of the map & Sigma is the same.
161
+ sigma.setSetting("stagePadding", 0);
162
+
163
+ // disable camera rotation
164
+ sigma.setSetting("enableCameraRotation", false);
165
+
166
+ // Function that change the given graph by generating the sigma x,y coords by taking the geo coordinates
167
+ // and project them in the 2D space of the map
168
+ function updateGraphCoordinates(graph) {
169
+ graph.updateEachNodeAttributes(function (_node, attrs) {
170
+ var coords = latlngToGraph(map, opts !== null && opts !== void 0 && opts.getNodeLatLng ? opts.getNodeLatLng(attrs) : {
171
+ lat: attrs.lat,
172
+ lng: attrs.lng
173
+ });
174
+ return _objectSpread2(_objectSpread2({}, attrs), {}, {
175
+ x: coords.x,
176
+ y: coords.y
177
+ });
178
+ });
179
+ }
180
+
181
+ // Function that sync the map with sigma
182
+ function fnSyncMapWithSigma() {
183
+ syncMapWithSigma(sigma, map);
184
+ }
185
+
186
+ // Function that sync sigma with map if it's needed
187
+ function fnSyncSigmaWithMap() {
188
+ if (!sigma.getCamera().isAnimated() && !map.isMoving()) {
189
+ // Check that sigma & map are already in sync
190
+ var southWest = graphToLatlng(map, sigma.viewportToGraph({
191
+ x: 0,
192
+ y: sigma.getDimensions().height
193
+ }));
194
+ var northEast = graphToLatlng(map, sigma.viewportToGraph({
195
+ x: sigma.getDimensions().width,
196
+ y: 0
197
+ }));
198
+ var diff = Math.max(map.getBounds().getSouthWest().distanceTo(new LngLat(southWest.lng, southWest.lat)), map.getBounds().getNorthEast().distanceTo(new LngLat(northEast.lng, northEast.lat)));
199
+ if (diff > 1) {
200
+ syncSigmaWithMap(sigma, map);
201
+ }
202
+ }
203
+ }
204
+
205
+ // When sigma is resize, we need to update the graph coordinate (the ref has changed)
206
+ // and recompute the zoom bounds
207
+ function fnOnResize() {
208
+ updateGraphCoordinates(sigma.getGraph());
209
+ fnSyncSigmaWithMap();
210
+ }
211
+
212
+ // Clean up function to remove everything
213
+ function clean() {
214
+ map.off("moveend", fnSyncSigmaWithMap);
215
+ map.remove();
216
+ mapContainer.remove();
217
+ sigma.off("afterRender", fnSyncMapWithSigma);
218
+ sigma.off("resize", fnOnResize);
219
+ sigma.setSetting("stagePadding", DEFAULT_SETTINGS.stagePadding);
220
+ sigma.setSetting("enableCameraRotation", true);
221
+ }
222
+
223
+ // Update the sigma graph for geospatial coords
224
+ updateGraphCoordinates(sigma.getGraph());
225
+
226
+ // When the map is ready
227
+ map.once("load", function () {
228
+ // Compute sigma ratio bounds
229
+ // /!\ must be done after the first map render
230
+ map.once("moveend", function () {
231
+ fnSyncSigmaWithMap();
232
+ });
233
+ // Do the first sync
234
+ fnSyncMapWithSigma();
235
+
236
+ // At each render of sigma, we do the map sync
237
+ sigma.on("afterRender", fnSyncMapWithSigma);
238
+ // Listen on resize
239
+ sigma.on("resize", fnOnResize);
240
+ // Do the cleanup
241
+ sigma.on("kill", clean);
242
+ // Keep sigma camera on the map
243
+ map.on("moveend", fnSyncSigmaWithMap);
244
+ });
245
+ return {
246
+ clean: clean,
247
+ map: map,
248
+ updateGraphCoordinates: updateGraphCoordinates
249
+ };
250
+ }
251
+
252
+ export { bindMaplibreLayer as default, graphToLatlng, latlngToGraph };
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@sigma/layer-maplibre",
3
+ "version": "3.0.0-beta.2",
4
+ "description": "A plugin to set a geographical map in background",
5
+ "main": "dist/sigma-layer-maplibre.cjs.js",
6
+ "module": "dist/sigma-layer-maplibre.esm.js",
7
+ "types": "dist/sigma-layer-maplibre.cjs.d.ts",
8
+ "files": [
9
+ "/dist"
10
+ ],
11
+ "sideEffects": false,
12
+ "homepage": "https://www.sigmajs.org",
13
+ "bugs": "http://github.com/jacomyal/sigma.js/issues",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "http://github.com/jacomyal/sigma.js.git"
17
+ },
18
+ "keywords": [
19
+ "graph",
20
+ "graphology",
21
+ "sigma"
22
+ ],
23
+ "contributors": [
24
+ {
25
+ "name": "Benoît Simard",
26
+ "url": "http://github.com/sim51"
27
+ }
28
+ ],
29
+ "license": "MIT",
30
+ "preconstruct": {
31
+ "entrypoints": [
32
+ "index.ts"
33
+ ]
34
+ },
35
+ "peerDependencies": {
36
+ "maplibre-gl": "^4.5.0",
37
+ "sigma": ">=3.0.0-beta.10"
38
+ },
39
+ "exports": {
40
+ ".": {
41
+ "module": "./dist/sigma-layer-maplibre.esm.js",
42
+ "import": "./dist/sigma-layer-maplibre.cjs.mjs",
43
+ "default": "./dist/sigma-layer-maplibre.cjs.js"
44
+ },
45
+ "./package.json": "./package.json"
46
+ },
47
+ "gitHead": "06cec186aa1e094808b36400805064b074988bf8"
48
+ }