@sigma/layer-maplibre 3.0.0-beta.10

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/3-additional-packages/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.js";
2
+ export { default } from "./declarations/src/index.js";
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,285 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var maplibreGl = require('maplibre-gl');
6
+
7
+ function _toPrimitive(t, r) {
8
+ if ("object" != typeof t || !t) return t;
9
+ var e = t[Symbol.toPrimitive];
10
+ if (void 0 !== e) {
11
+ var i = e.call(t, r || "default");
12
+ if ("object" != typeof i) return i;
13
+ throw new TypeError("@@toPrimitive must return a primitive value.");
14
+ }
15
+ return ("string" === r ? String : Number)(t);
16
+ }
17
+
18
+ function _toPropertyKey(t) {
19
+ var i = _toPrimitive(t, "string");
20
+ return "symbol" == typeof i ? i : i + "";
21
+ }
22
+
23
+ function _defineProperty(e, r, t) {
24
+ return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
25
+ value: t,
26
+ enumerable: !0,
27
+ configurable: !0,
28
+ writable: !0
29
+ }) : e[r] = t, e;
30
+ }
31
+
32
+ function ownKeys(e, r) {
33
+ var t = Object.keys(e);
34
+ if (Object.getOwnPropertySymbols) {
35
+ var o = Object.getOwnPropertySymbols(e);
36
+ r && (o = o.filter(function (r) {
37
+ return Object.getOwnPropertyDescriptor(e, r).enumerable;
38
+ })), t.push.apply(t, o);
39
+ }
40
+ return t;
41
+ }
42
+ function _objectSpread2(e) {
43
+ for (var r = 1; r < arguments.length; r++) {
44
+ var t = null != arguments[r] ? arguments[r] : {};
45
+ r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
46
+ _defineProperty(e, r, t[r]);
47
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
48
+ Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
49
+ });
50
+ }
51
+ return e;
52
+ }
53
+
54
+ /**
55
+ * Given a geo point returns its graph coords.
56
+ */
57
+ function latlngToGraph(map, coord) {
58
+ var data = maplibreGl.MercatorCoordinate.fromLngLat(coord);
59
+ return {
60
+ x: data.x,
61
+ // Y are reversed between geo / sigma
62
+ y: map.getContainer().clientHeight - data.y
63
+ };
64
+ }
65
+
66
+ /**
67
+ * Given a graph coords returns its lat/lng coords.
68
+ */
69
+ function graphToLatlng(map, coords) {
70
+ var mcoords = new maplibreGl.MercatorCoordinate(coords.x, map.getContainer().clientHeight - coords.y, 0);
71
+ var data = mcoords.toLngLat();
72
+ return {
73
+ lat: data.lat,
74
+ lng: data.lng
75
+ };
76
+ }
77
+
78
+ /**
79
+ * BBOX sync : map to sigma
80
+ */
81
+ function syncSigmaWithMap(sigma, map) {
82
+ // Compute sigma center
83
+ var center = sigma.viewportToFramedGraph(sigma.graphToViewport(latlngToGraph(map, map.getCenter())));
84
+
85
+ // Compute sigma ratio
86
+ var mapBound = map.getBounds();
87
+ var northEast = sigma.graphToViewport(latlngToGraph(map, mapBound.getNorthEast()));
88
+ var southWest = sigma.graphToViewport(latlngToGraph(map, mapBound.getSouthWest()));
89
+ var viewportBoundDimension = {
90
+ width: Math.abs(northEast.x - southWest.x),
91
+ height: Math.abs(northEast.y - southWest.y)
92
+ };
93
+ var viewportDim = sigma.getDimensions();
94
+ var ratio = Math.min(viewportBoundDimension.width / viewportDim.width, viewportBoundDimension.height / viewportDim.height) * sigma.getCamera().getState().ratio;
95
+ sigma.getCamera().setState(_objectSpread2(_objectSpread2({}, center), {}, {
96
+ ratio: ratio
97
+ }));
98
+ }
99
+
100
+ /**
101
+ * BBOX sync : sigma to map
102
+ */
103
+ function syncMapWithSigma(sigma, map) {
104
+ var viewportDimensions = sigma.getDimensions();
105
+
106
+ // Graph BBox
107
+ var graphBottomLeft = sigma.viewportToGraph({
108
+ x: 0,
109
+ y: viewportDimensions.height
110
+ }, {
111
+ padding: 0
112
+ });
113
+ var graphTopRight = sigma.viewportToGraph({
114
+ x: viewportDimensions.width,
115
+ y: 0
116
+ }, {
117
+ padding: 0
118
+ });
119
+
120
+ // Geo BBox
121
+ var geoSouthWest = graphToLatlng(map, graphBottomLeft);
122
+ var geoNorthEast = graphToLatlng(map, graphTopRight);
123
+
124
+ // Set map BBox
125
+ var bounds = new maplibreGl.LngLatBounds([geoSouthWest, geoNorthEast]);
126
+ map.fitBounds(bounds, {
127
+ duration: 0
128
+ });
129
+ }
130
+
131
+ /**
132
+ * On the graph, we store the 2D projection of the geographical lat/long.
133
+ *
134
+ * @param sigma The sigma instance
135
+ * @param opts.mapOptions Options that will be provided to map constructor.
136
+ * @param opts.getNodeLatLng Function to retrieve lat/long values from a node's attributs (default is lat & lng)
137
+ */
138
+ function bindMaplibreLayer(sigma, opts) {
139
+ // Keeping data for the cleanup
140
+ var isKilled = false;
141
+ var prevSigmaSettings = sigma.getSettings();
142
+
143
+ // Creating map container
144
+ var mapLayerName = "layer-maplibre";
145
+ var mapContainer = sigma.createLayer(mapLayerName, "div", {
146
+ style: {
147
+ position: "absolute",
148
+ inset: "0"
149
+ },
150
+ // 'edges' is the first sigma layer
151
+ beforeLayer: "edges"
152
+ });
153
+ sigma.getContainer().prepend(mapContainer);
154
+
155
+ // Initialize the map
156
+ var map = new maplibreGl.Map(_objectSpread2({
157
+ container: mapContainer,
158
+ style: "https://demotiles.maplibre.org/style.json",
159
+ center: [0, 0],
160
+ zoom: 1,
161
+ minPitch: 0,
162
+ maxPitch: 0
163
+ }, (opts === null || opts === void 0 ? void 0 : opts.mapOptions) || {}));
164
+
165
+ // `stagePadding: 0` is mandatory, so the bbox of the map & Sigma is the same.
166
+ sigma.setSetting("stagePadding", 0);
167
+
168
+ // disable camera rotation
169
+ sigma.setSetting("enableCameraRotation", false);
170
+
171
+ // Function that change the given graph by generating the sigma x,y coords by taking the geo coordinates
172
+ // and project them in the 2D space of the map
173
+ function updateGraphCoordinates(graph) {
174
+ graph.updateEachNodeAttributes(function (_node, attrs) {
175
+ var coords = latlngToGraph(map, opts !== null && opts !== void 0 && opts.getNodeLatLng ? opts.getNodeLatLng(attrs) : {
176
+ lat: attrs.lat,
177
+ lng: attrs.lng
178
+ });
179
+ return _objectSpread2(_objectSpread2({}, attrs), {}, {
180
+ x: coords.x,
181
+ y: coords.y
182
+ });
183
+ });
184
+ }
185
+
186
+ // Function that sync the map with sigma
187
+ function fnSyncMapWithSigma() {
188
+ syncMapWithSigma(sigma, map);
189
+ }
190
+
191
+ // Function that sync sigma with map if it's needed
192
+ function fnSyncSigmaWithMap() {
193
+ if (!sigma.getCamera().isAnimated() && !map.isMoving()) {
194
+ // Check that sigma & map are already in sync
195
+ var southWest = graphToLatlng(map, sigma.viewportToGraph({
196
+ x: 0,
197
+ y: sigma.getDimensions().height
198
+ }));
199
+ var northEast = graphToLatlng(map, sigma.viewportToGraph({
200
+ x: sigma.getDimensions().width,
201
+ y: 0
202
+ }));
203
+ 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)));
204
+ if (diff > 1) {
205
+ syncSigmaWithMap(sigma, map);
206
+ }
207
+ }
208
+ }
209
+
210
+ // When sigma is resize, we need to update the graph coordinate (the ref has changed)
211
+ // and recompute the zoom bounds
212
+ function fnOnResize() {
213
+ // Avoid sync map with sigma while we do the resize
214
+ // otherwise there is a sideeffect...
215
+ sigma.off("afterRender", fnSyncMapWithSigma);
216
+ var center = map.getCenter();
217
+
218
+ // Ask the map to resize
219
+ map.once("resize", function () {
220
+ // NB: resize can change the center of the map, and we want to keep it
221
+ map.setCenter(center);
222
+
223
+ // Map ref has changed, we need to update the graph coordinates
224
+ updateGraphCoordinates(sigma.getGraph());
225
+
226
+ // Do the sync
227
+ fnSyncSigmaWithMap();
228
+
229
+ // Re-enable the map sync with sigma in the next frame
230
+ setTimeout(function () {
231
+ fnSyncMapWithSigma();
232
+ sigma.on("afterRender", fnSyncMapWithSigma);
233
+ }, 0);
234
+ });
235
+ map.resize();
236
+ }
237
+
238
+ // Clean up function to remove everything
239
+ function clean() {
240
+ if (!isKilled) {
241
+ isKilled = true;
242
+ map.off("moveend", fnSyncSigmaWithMap);
243
+ map.remove();
244
+ sigma.killLayer(mapLayerName);
245
+ sigma.off("afterRender", fnSyncMapWithSigma);
246
+ sigma.off("resize", fnOnResize);
247
+
248
+ // Reset settings
249
+ sigma.setSetting("stagePadding", prevSigmaSettings.stagePadding);
250
+ sigma.setSetting("enableCameraRotation", prevSigmaSettings.enableCameraRotation);
251
+ }
252
+ }
253
+
254
+ // Update the sigma graph for geospatial coords
255
+ updateGraphCoordinates(sigma.getGraph());
256
+
257
+ // When the map is ready
258
+ map.once("load", function () {
259
+ // Compute sigma ratio bounds
260
+ // /!\ must be done after the first map render
261
+ map.once("moveend", function () {
262
+ fnSyncSigmaWithMap();
263
+ });
264
+ // Do the first sync
265
+ fnSyncMapWithSigma();
266
+
267
+ // At each render of sigma, we do the map sync
268
+ sigma.on("afterRender", fnSyncMapWithSigma);
269
+ // Listen on resize
270
+ sigma.on("resize", fnOnResize);
271
+ // Do the cleanup
272
+ sigma.on("kill", clean);
273
+ // Keep sigma camera on the map
274
+ map.on("moveend", fnSyncSigmaWithMap);
275
+ });
276
+ return {
277
+ clean: clean,
278
+ map: map,
279
+ updateGraphCoordinates: updateGraphCoordinates
280
+ };
281
+ }
282
+
283
+ exports["default"] = bindMaplibreLayer;
284
+ exports.graphToLatlng = graphToLatlng;
285
+ 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,285 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var maplibreGl = require('maplibre-gl');
6
+
7
+ function _toPrimitive(t, r) {
8
+ if ("object" != typeof t || !t) return t;
9
+ var e = t[Symbol.toPrimitive];
10
+ if (void 0 !== e) {
11
+ var i = e.call(t, r || "default");
12
+ if ("object" != typeof i) return i;
13
+ throw new TypeError("@@toPrimitive must return a primitive value.");
14
+ }
15
+ return ("string" === r ? String : Number)(t);
16
+ }
17
+
18
+ function _toPropertyKey(t) {
19
+ var i = _toPrimitive(t, "string");
20
+ return "symbol" == typeof i ? i : i + "";
21
+ }
22
+
23
+ function _defineProperty(e, r, t) {
24
+ return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
25
+ value: t,
26
+ enumerable: !0,
27
+ configurable: !0,
28
+ writable: !0
29
+ }) : e[r] = t, e;
30
+ }
31
+
32
+ function ownKeys(e, r) {
33
+ var t = Object.keys(e);
34
+ if (Object.getOwnPropertySymbols) {
35
+ var o = Object.getOwnPropertySymbols(e);
36
+ r && (o = o.filter(function (r) {
37
+ return Object.getOwnPropertyDescriptor(e, r).enumerable;
38
+ })), t.push.apply(t, o);
39
+ }
40
+ return t;
41
+ }
42
+ function _objectSpread2(e) {
43
+ for (var r = 1; r < arguments.length; r++) {
44
+ var t = null != arguments[r] ? arguments[r] : {};
45
+ r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
46
+ _defineProperty(e, r, t[r]);
47
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
48
+ Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
49
+ });
50
+ }
51
+ return e;
52
+ }
53
+
54
+ /**
55
+ * Given a geo point returns its graph coords.
56
+ */
57
+ function latlngToGraph(map, coord) {
58
+ var data = maplibreGl.MercatorCoordinate.fromLngLat(coord);
59
+ return {
60
+ x: data.x,
61
+ // Y are reversed between geo / sigma
62
+ y: map.getContainer().clientHeight - data.y
63
+ };
64
+ }
65
+
66
+ /**
67
+ * Given a graph coords returns its lat/lng coords.
68
+ */
69
+ function graphToLatlng(map, coords) {
70
+ var mcoords = new maplibreGl.MercatorCoordinate(coords.x, map.getContainer().clientHeight - coords.y, 0);
71
+ var data = mcoords.toLngLat();
72
+ return {
73
+ lat: data.lat,
74
+ lng: data.lng
75
+ };
76
+ }
77
+
78
+ /**
79
+ * BBOX sync : map to sigma
80
+ */
81
+ function syncSigmaWithMap(sigma, map) {
82
+ // Compute sigma center
83
+ var center = sigma.viewportToFramedGraph(sigma.graphToViewport(latlngToGraph(map, map.getCenter())));
84
+
85
+ // Compute sigma ratio
86
+ var mapBound = map.getBounds();
87
+ var northEast = sigma.graphToViewport(latlngToGraph(map, mapBound.getNorthEast()));
88
+ var southWest = sigma.graphToViewport(latlngToGraph(map, mapBound.getSouthWest()));
89
+ var viewportBoundDimension = {
90
+ width: Math.abs(northEast.x - southWest.x),
91
+ height: Math.abs(northEast.y - southWest.y)
92
+ };
93
+ var viewportDim = sigma.getDimensions();
94
+ var ratio = Math.min(viewportBoundDimension.width / viewportDim.width, viewportBoundDimension.height / viewportDim.height) * sigma.getCamera().getState().ratio;
95
+ sigma.getCamera().setState(_objectSpread2(_objectSpread2({}, center), {}, {
96
+ ratio: ratio
97
+ }));
98
+ }
99
+
100
+ /**
101
+ * BBOX sync : sigma to map
102
+ */
103
+ function syncMapWithSigma(sigma, map) {
104
+ var viewportDimensions = sigma.getDimensions();
105
+
106
+ // Graph BBox
107
+ var graphBottomLeft = sigma.viewportToGraph({
108
+ x: 0,
109
+ y: viewportDimensions.height
110
+ }, {
111
+ padding: 0
112
+ });
113
+ var graphTopRight = sigma.viewportToGraph({
114
+ x: viewportDimensions.width,
115
+ y: 0
116
+ }, {
117
+ padding: 0
118
+ });
119
+
120
+ // Geo BBox
121
+ var geoSouthWest = graphToLatlng(map, graphBottomLeft);
122
+ var geoNorthEast = graphToLatlng(map, graphTopRight);
123
+
124
+ // Set map BBox
125
+ var bounds = new maplibreGl.LngLatBounds([geoSouthWest, geoNorthEast]);
126
+ map.fitBounds(bounds, {
127
+ duration: 0
128
+ });
129
+ }
130
+
131
+ /**
132
+ * On the graph, we store the 2D projection of the geographical lat/long.
133
+ *
134
+ * @param sigma The sigma instance
135
+ * @param opts.mapOptions Options that will be provided to map constructor.
136
+ * @param opts.getNodeLatLng Function to retrieve lat/long values from a node's attributs (default is lat & lng)
137
+ */
138
+ function bindMaplibreLayer(sigma, opts) {
139
+ // Keeping data for the cleanup
140
+ var isKilled = false;
141
+ var prevSigmaSettings = sigma.getSettings();
142
+
143
+ // Creating map container
144
+ var mapLayerName = "layer-maplibre";
145
+ var mapContainer = sigma.createLayer(mapLayerName, "div", {
146
+ style: {
147
+ position: "absolute",
148
+ inset: "0"
149
+ },
150
+ // 'edges' is the first sigma layer
151
+ beforeLayer: "edges"
152
+ });
153
+ sigma.getContainer().prepend(mapContainer);
154
+
155
+ // Initialize the map
156
+ var map = new maplibreGl.Map(_objectSpread2({
157
+ container: mapContainer,
158
+ style: "https://demotiles.maplibre.org/style.json",
159
+ center: [0, 0],
160
+ zoom: 1,
161
+ minPitch: 0,
162
+ maxPitch: 0
163
+ }, (opts === null || opts === void 0 ? void 0 : opts.mapOptions) || {}));
164
+
165
+ // `stagePadding: 0` is mandatory, so the bbox of the map & Sigma is the same.
166
+ sigma.setSetting("stagePadding", 0);
167
+
168
+ // disable camera rotation
169
+ sigma.setSetting("enableCameraRotation", false);
170
+
171
+ // Function that change the given graph by generating the sigma x,y coords by taking the geo coordinates
172
+ // and project them in the 2D space of the map
173
+ function updateGraphCoordinates(graph) {
174
+ graph.updateEachNodeAttributes(function (_node, attrs) {
175
+ var coords = latlngToGraph(map, opts !== null && opts !== void 0 && opts.getNodeLatLng ? opts.getNodeLatLng(attrs) : {
176
+ lat: attrs.lat,
177
+ lng: attrs.lng
178
+ });
179
+ return _objectSpread2(_objectSpread2({}, attrs), {}, {
180
+ x: coords.x,
181
+ y: coords.y
182
+ });
183
+ });
184
+ }
185
+
186
+ // Function that sync the map with sigma
187
+ function fnSyncMapWithSigma() {
188
+ syncMapWithSigma(sigma, map);
189
+ }
190
+
191
+ // Function that sync sigma with map if it's needed
192
+ function fnSyncSigmaWithMap() {
193
+ if (!sigma.getCamera().isAnimated() && !map.isMoving()) {
194
+ // Check that sigma & map are already in sync
195
+ var southWest = graphToLatlng(map, sigma.viewportToGraph({
196
+ x: 0,
197
+ y: sigma.getDimensions().height
198
+ }));
199
+ var northEast = graphToLatlng(map, sigma.viewportToGraph({
200
+ x: sigma.getDimensions().width,
201
+ y: 0
202
+ }));
203
+ 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)));
204
+ if (diff > 1) {
205
+ syncSigmaWithMap(sigma, map);
206
+ }
207
+ }
208
+ }
209
+
210
+ // When sigma is resize, we need to update the graph coordinate (the ref has changed)
211
+ // and recompute the zoom bounds
212
+ function fnOnResize() {
213
+ // Avoid sync map with sigma while we do the resize
214
+ // otherwise there is a sideeffect...
215
+ sigma.off("afterRender", fnSyncMapWithSigma);
216
+ var center = map.getCenter();
217
+
218
+ // Ask the map to resize
219
+ map.once("resize", function () {
220
+ // NB: resize can change the center of the map, and we want to keep it
221
+ map.setCenter(center);
222
+
223
+ // Map ref has changed, we need to update the graph coordinates
224
+ updateGraphCoordinates(sigma.getGraph());
225
+
226
+ // Do the sync
227
+ fnSyncSigmaWithMap();
228
+
229
+ // Re-enable the map sync with sigma in the next frame
230
+ setTimeout(function () {
231
+ fnSyncMapWithSigma();
232
+ sigma.on("afterRender", fnSyncMapWithSigma);
233
+ }, 0);
234
+ });
235
+ map.resize();
236
+ }
237
+
238
+ // Clean up function to remove everything
239
+ function clean() {
240
+ if (!isKilled) {
241
+ isKilled = true;
242
+ map.off("moveend", fnSyncSigmaWithMap);
243
+ map.remove();
244
+ sigma.killLayer(mapLayerName);
245
+ sigma.off("afterRender", fnSyncMapWithSigma);
246
+ sigma.off("resize", fnOnResize);
247
+
248
+ // Reset settings
249
+ sigma.setSetting("stagePadding", prevSigmaSettings.stagePadding);
250
+ sigma.setSetting("enableCameraRotation", prevSigmaSettings.enableCameraRotation);
251
+ }
252
+ }
253
+
254
+ // Update the sigma graph for geospatial coords
255
+ updateGraphCoordinates(sigma.getGraph());
256
+
257
+ // When the map is ready
258
+ map.once("load", function () {
259
+ // Compute sigma ratio bounds
260
+ // /!\ must be done after the first map render
261
+ map.once("moveend", function () {
262
+ fnSyncSigmaWithMap();
263
+ });
264
+ // Do the first sync
265
+ fnSyncMapWithSigma();
266
+
267
+ // At each render of sigma, we do the map sync
268
+ sigma.on("afterRender", fnSyncMapWithSigma);
269
+ // Listen on resize
270
+ sigma.on("resize", fnOnResize);
271
+ // Do the cleanup
272
+ sigma.on("kill", clean);
273
+ // Keep sigma camera on the map
274
+ map.on("moveend", fnSyncSigmaWithMap);
275
+ });
276
+ return {
277
+ clean: clean,
278
+ map: map,
279
+ updateGraphCoordinates: updateGraphCoordinates
280
+ };
281
+ }
282
+
283
+ exports["default"] = bindMaplibreLayer;
284
+ exports.graphToLatlng = graphToLatlng;
285
+ exports.latlngToGraph = latlngToGraph;
@@ -0,0 +1,279 @@
1
+ import { MercatorCoordinate, LngLatBounds, Map, LngLat } from 'maplibre-gl';
2
+
3
+ function _toPrimitive(t, r) {
4
+ if ("object" != typeof t || !t) return t;
5
+ var e = t[Symbol.toPrimitive];
6
+ if (void 0 !== e) {
7
+ var i = e.call(t, r || "default");
8
+ if ("object" != typeof i) return i;
9
+ throw new TypeError("@@toPrimitive must return a primitive value.");
10
+ }
11
+ return ("string" === r ? String : Number)(t);
12
+ }
13
+
14
+ function _toPropertyKey(t) {
15
+ var i = _toPrimitive(t, "string");
16
+ return "symbol" == typeof i ? i : i + "";
17
+ }
18
+
19
+ function _defineProperty(e, r, t) {
20
+ return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
21
+ value: t,
22
+ enumerable: !0,
23
+ configurable: !0,
24
+ writable: !0
25
+ }) : e[r] = t, e;
26
+ }
27
+
28
+ function ownKeys(e, r) {
29
+ var t = Object.keys(e);
30
+ if (Object.getOwnPropertySymbols) {
31
+ var o = Object.getOwnPropertySymbols(e);
32
+ r && (o = o.filter(function (r) {
33
+ return Object.getOwnPropertyDescriptor(e, r).enumerable;
34
+ })), t.push.apply(t, o);
35
+ }
36
+ return t;
37
+ }
38
+ function _objectSpread2(e) {
39
+ for (var r = 1; r < arguments.length; r++) {
40
+ var t = null != arguments[r] ? arguments[r] : {};
41
+ r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
42
+ _defineProperty(e, r, t[r]);
43
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
44
+ Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
45
+ });
46
+ }
47
+ return e;
48
+ }
49
+
50
+ /**
51
+ * Given a geo point returns its graph coords.
52
+ */
53
+ function latlngToGraph(map, coord) {
54
+ var data = MercatorCoordinate.fromLngLat(coord);
55
+ return {
56
+ x: data.x,
57
+ // Y are reversed between geo / sigma
58
+ y: map.getContainer().clientHeight - data.y
59
+ };
60
+ }
61
+
62
+ /**
63
+ * Given a graph coords returns its lat/lng coords.
64
+ */
65
+ function graphToLatlng(map, coords) {
66
+ var mcoords = new MercatorCoordinate(coords.x, map.getContainer().clientHeight - coords.y, 0);
67
+ var data = mcoords.toLngLat();
68
+ return {
69
+ lat: data.lat,
70
+ lng: data.lng
71
+ };
72
+ }
73
+
74
+ /**
75
+ * BBOX sync : map to sigma
76
+ */
77
+ function syncSigmaWithMap(sigma, map) {
78
+ // Compute sigma center
79
+ var center = sigma.viewportToFramedGraph(sigma.graphToViewport(latlngToGraph(map, map.getCenter())));
80
+
81
+ // Compute sigma ratio
82
+ var mapBound = map.getBounds();
83
+ var northEast = sigma.graphToViewport(latlngToGraph(map, mapBound.getNorthEast()));
84
+ var southWest = sigma.graphToViewport(latlngToGraph(map, mapBound.getSouthWest()));
85
+ var viewportBoundDimension = {
86
+ width: Math.abs(northEast.x - southWest.x),
87
+ height: Math.abs(northEast.y - southWest.y)
88
+ };
89
+ var viewportDim = sigma.getDimensions();
90
+ var ratio = Math.min(viewportBoundDimension.width / viewportDim.width, viewportBoundDimension.height / viewportDim.height) * sigma.getCamera().getState().ratio;
91
+ sigma.getCamera().setState(_objectSpread2(_objectSpread2({}, center), {}, {
92
+ ratio: ratio
93
+ }));
94
+ }
95
+
96
+ /**
97
+ * BBOX sync : sigma to map
98
+ */
99
+ function syncMapWithSigma(sigma, map) {
100
+ var viewportDimensions = sigma.getDimensions();
101
+
102
+ // Graph BBox
103
+ var graphBottomLeft = sigma.viewportToGraph({
104
+ x: 0,
105
+ y: viewportDimensions.height
106
+ }, {
107
+ padding: 0
108
+ });
109
+ var graphTopRight = sigma.viewportToGraph({
110
+ x: viewportDimensions.width,
111
+ y: 0
112
+ }, {
113
+ padding: 0
114
+ });
115
+
116
+ // Geo BBox
117
+ var geoSouthWest = graphToLatlng(map, graphBottomLeft);
118
+ var geoNorthEast = graphToLatlng(map, graphTopRight);
119
+
120
+ // Set map BBox
121
+ var bounds = new LngLatBounds([geoSouthWest, geoNorthEast]);
122
+ map.fitBounds(bounds, {
123
+ duration: 0
124
+ });
125
+ }
126
+
127
+ /**
128
+ * On the graph, we store the 2D projection of the geographical lat/long.
129
+ *
130
+ * @param sigma The sigma instance
131
+ * @param opts.mapOptions Options that will be provided to map constructor.
132
+ * @param opts.getNodeLatLng Function to retrieve lat/long values from a node's attributs (default is lat & lng)
133
+ */
134
+ function bindMaplibreLayer(sigma, opts) {
135
+ // Keeping data for the cleanup
136
+ var isKilled = false;
137
+ var prevSigmaSettings = sigma.getSettings();
138
+
139
+ // Creating map container
140
+ var mapLayerName = "layer-maplibre";
141
+ var mapContainer = sigma.createLayer(mapLayerName, "div", {
142
+ style: {
143
+ position: "absolute",
144
+ inset: "0"
145
+ },
146
+ // 'edges' is the first sigma layer
147
+ beforeLayer: "edges"
148
+ });
149
+ sigma.getContainer().prepend(mapContainer);
150
+
151
+ // Initialize the map
152
+ var map = new Map(_objectSpread2({
153
+ container: mapContainer,
154
+ style: "https://demotiles.maplibre.org/style.json",
155
+ center: [0, 0],
156
+ zoom: 1,
157
+ minPitch: 0,
158
+ maxPitch: 0
159
+ }, (opts === null || opts === void 0 ? void 0 : opts.mapOptions) || {}));
160
+
161
+ // `stagePadding: 0` is mandatory, so the bbox of the map & Sigma is the same.
162
+ sigma.setSetting("stagePadding", 0);
163
+
164
+ // disable camera rotation
165
+ sigma.setSetting("enableCameraRotation", false);
166
+
167
+ // Function that change the given graph by generating the sigma x,y coords by taking the geo coordinates
168
+ // and project them in the 2D space of the map
169
+ function updateGraphCoordinates(graph) {
170
+ graph.updateEachNodeAttributes(function (_node, attrs) {
171
+ var coords = latlngToGraph(map, opts !== null && opts !== void 0 && opts.getNodeLatLng ? opts.getNodeLatLng(attrs) : {
172
+ lat: attrs.lat,
173
+ lng: attrs.lng
174
+ });
175
+ return _objectSpread2(_objectSpread2({}, attrs), {}, {
176
+ x: coords.x,
177
+ y: coords.y
178
+ });
179
+ });
180
+ }
181
+
182
+ // Function that sync the map with sigma
183
+ function fnSyncMapWithSigma() {
184
+ syncMapWithSigma(sigma, map);
185
+ }
186
+
187
+ // Function that sync sigma with map if it's needed
188
+ function fnSyncSigmaWithMap() {
189
+ if (!sigma.getCamera().isAnimated() && !map.isMoving()) {
190
+ // Check that sigma & map are already in sync
191
+ var southWest = graphToLatlng(map, sigma.viewportToGraph({
192
+ x: 0,
193
+ y: sigma.getDimensions().height
194
+ }));
195
+ var northEast = graphToLatlng(map, sigma.viewportToGraph({
196
+ x: sigma.getDimensions().width,
197
+ y: 0
198
+ }));
199
+ var diff = Math.max(map.getBounds().getSouthWest().distanceTo(new LngLat(southWest.lng, southWest.lat)), map.getBounds().getNorthEast().distanceTo(new LngLat(northEast.lng, northEast.lat)));
200
+ if (diff > 1) {
201
+ syncSigmaWithMap(sigma, map);
202
+ }
203
+ }
204
+ }
205
+
206
+ // When sigma is resize, we need to update the graph coordinate (the ref has changed)
207
+ // and recompute the zoom bounds
208
+ function fnOnResize() {
209
+ // Avoid sync map with sigma while we do the resize
210
+ // otherwise there is a sideeffect...
211
+ sigma.off("afterRender", fnSyncMapWithSigma);
212
+ var center = map.getCenter();
213
+
214
+ // Ask the map to resize
215
+ map.once("resize", function () {
216
+ // NB: resize can change the center of the map, and we want to keep it
217
+ map.setCenter(center);
218
+
219
+ // Map ref has changed, we need to update the graph coordinates
220
+ updateGraphCoordinates(sigma.getGraph());
221
+
222
+ // Do the sync
223
+ fnSyncSigmaWithMap();
224
+
225
+ // Re-enable the map sync with sigma in the next frame
226
+ setTimeout(function () {
227
+ fnSyncMapWithSigma();
228
+ sigma.on("afterRender", fnSyncMapWithSigma);
229
+ }, 0);
230
+ });
231
+ map.resize();
232
+ }
233
+
234
+ // Clean up function to remove everything
235
+ function clean() {
236
+ if (!isKilled) {
237
+ isKilled = true;
238
+ map.off("moveend", fnSyncSigmaWithMap);
239
+ map.remove();
240
+ sigma.killLayer(mapLayerName);
241
+ sigma.off("afterRender", fnSyncMapWithSigma);
242
+ sigma.off("resize", fnOnResize);
243
+
244
+ // Reset settings
245
+ sigma.setSetting("stagePadding", prevSigmaSettings.stagePadding);
246
+ sigma.setSetting("enableCameraRotation", prevSigmaSettings.enableCameraRotation);
247
+ }
248
+ }
249
+
250
+ // Update the sigma graph for geospatial coords
251
+ updateGraphCoordinates(sigma.getGraph());
252
+
253
+ // When the map is ready
254
+ map.once("load", function () {
255
+ // Compute sigma ratio bounds
256
+ // /!\ must be done after the first map render
257
+ map.once("moveend", function () {
258
+ fnSyncSigmaWithMap();
259
+ });
260
+ // Do the first sync
261
+ fnSyncMapWithSigma();
262
+
263
+ // At each render of sigma, we do the map sync
264
+ sigma.on("afterRender", fnSyncMapWithSigma);
265
+ // Listen on resize
266
+ sigma.on("resize", fnOnResize);
267
+ // Do the cleanup
268
+ sigma.on("kill", clean);
269
+ // Keep sigma camera on the map
270
+ map.on("moveend", fnSyncSigmaWithMap);
271
+ });
272
+ return {
273
+ clean: clean,
274
+ map: map,
275
+ updateGraphCoordinates: updateGraphCoordinates
276
+ };
277
+ }
278
+
279
+ export { bindMaplibreLayer as default, graphToLatlng, latlngToGraph };
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@sigma/layer-maplibre",
3
+ "version": "3.0.0-beta.10",
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
+ "directory": "packages/layer-maplibre"
18
+ },
19
+ "keywords": [
20
+ "graph",
21
+ "graphology",
22
+ "sigma"
23
+ ],
24
+ "contributors": [
25
+ {
26
+ "name": "Benoît Simard",
27
+ "url": "http://github.com/sim51"
28
+ }
29
+ ],
30
+ "license": "MIT",
31
+ "preconstruct": {
32
+ "entrypoints": [
33
+ "index.ts"
34
+ ]
35
+ },
36
+ "peerDependencies": {
37
+ "maplibre-gl": "^4.5.0",
38
+ "sigma": ">=3.0.0-beta.10"
39
+ },
40
+ "exports": {
41
+ ".": {
42
+ "module": "./dist/sigma-layer-maplibre.esm.js",
43
+ "import": "./dist/sigma-layer-maplibre.cjs.mjs",
44
+ "default": "./dist/sigma-layer-maplibre.cjs.js"
45
+ },
46
+ "./package.json": "./package.json"
47
+ },
48
+ "gitHead": "40bd5266410be119863fc2557f72d98d0bf754ee"
49
+ }