@sigma/layer-maplibre 3.0.0-beta.9 → 4.0.0-alpha.0
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 +1 -1
- package/README.md +1 -1
- package/dist/declarations/src/index.d.ts +1 -1
- package/dist/declarations/src/utils.d.ts +3 -14
- package/dist/sigma-layer-maplibre.cjs.dev.js +121 -129
- package/dist/sigma-layer-maplibre.cjs.prod.js +121 -129
- package/dist/sigma-layer-maplibre.esm.js +122 -130
- package/package.json +9 -3
package/LICENSE.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Copyright (C) 2013-
|
|
1
|
+
Copyright (C) 2013-2025, Alexis Jacomy, Guillaume Plique, Benoît Simard https://www.sigmajs.org
|
|
2
2
|
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
|
4
4
|
to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
package/README.md
CHANGED
|
@@ -24,4 +24,4 @@ const sigma = new Sigma(graph, container);
|
|
|
24
24
|
bindMaplibreLayer(sigma);
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
Please check the
|
|
27
|
+
Please check the [website examples](https://www.sigmajs.org/examples/) for more advanced examples.
|
|
@@ -11,7 +11,7 @@ import { graphToLatlng, latlngToGraph } from "./utils.js";
|
|
|
11
11
|
* @param opts.getNodeLatLng Function to retrieve lat/long values from a node's attributs (default is lat & lng)
|
|
12
12
|
*/
|
|
13
13
|
export default function bindMaplibreLayer(sigma: Sigma, opts?: {
|
|
14
|
-
mapOptions?: Omit<MapOptions, "container" | "center" | "zoom" | "minPitch" | "maxPitch">;
|
|
14
|
+
mapOptions?: Omit<MapOptions, "container" | "center" | "zoom" | "bounds" | "minPitch" | "maxPitch" | "interactive">;
|
|
15
15
|
getNodeLatLng?: (nodeAttributes: Attributes) => {
|
|
16
16
|
lat: number;
|
|
17
17
|
lng: number;
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import { Map } from "maplibre-gl";
|
|
2
|
-
import { Sigma } from "sigma";
|
|
3
|
-
export declare const MAX_VALID_LATITUDE = 85.051129;
|
|
4
1
|
/**
|
|
5
2
|
* Given a geo point returns its graph coords.
|
|
6
3
|
*/
|
|
7
|
-
export declare function latlngToGraph(
|
|
4
|
+
export declare function latlngToGraph(coord: {
|
|
8
5
|
lat: number;
|
|
9
6
|
lng: number;
|
|
10
7
|
}): {
|
|
@@ -12,20 +9,12 @@ export declare function latlngToGraph(map: Map, coord: {
|
|
|
12
9
|
y: number;
|
|
13
10
|
};
|
|
14
11
|
/**
|
|
15
|
-
* Given
|
|
12
|
+
* Given graph coords returns its lat/lng coords.
|
|
16
13
|
*/
|
|
17
|
-
export declare function graphToLatlng(
|
|
14
|
+
export declare function graphToLatlng(coords: {
|
|
18
15
|
x: number;
|
|
19
16
|
y: number;
|
|
20
17
|
}): {
|
|
21
18
|
lat: number;
|
|
22
19
|
lng: number;
|
|
23
20
|
};
|
|
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;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
+
var utils = require('@sigma/utils');
|
|
5
6
|
var maplibreGl = require('maplibre-gl');
|
|
6
7
|
|
|
7
8
|
function _toPrimitive(t, r) {
|
|
@@ -54,20 +55,19 @@ function _objectSpread2(e) {
|
|
|
54
55
|
/**
|
|
55
56
|
* Given a geo point returns its graph coords.
|
|
56
57
|
*/
|
|
57
|
-
function latlngToGraph(
|
|
58
|
+
function latlngToGraph(coord) {
|
|
58
59
|
var data = maplibreGl.MercatorCoordinate.fromLngLat(coord);
|
|
59
60
|
return {
|
|
60
61
|
x: data.x,
|
|
61
|
-
|
|
62
|
-
y: map.getContainer().clientHeight - data.y
|
|
62
|
+
y: 1 - data.y
|
|
63
63
|
};
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
/**
|
|
67
|
-
* Given
|
|
67
|
+
* Given graph coords returns its lat/lng coords.
|
|
68
68
|
*/
|
|
69
|
-
function graphToLatlng(
|
|
70
|
-
var mcoords = new maplibreGl.MercatorCoordinate(coords.x,
|
|
69
|
+
function graphToLatlng(coords) {
|
|
70
|
+
var mcoords = new maplibreGl.MercatorCoordinate(coords.x, 1 - coords.y, 0);
|
|
71
71
|
var data = mcoords.toLngLat();
|
|
72
72
|
return {
|
|
73
73
|
lat: data.lat,
|
|
@@ -75,60 +75,6 @@ function graphToLatlng(map, coords) {
|
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
/**
|
|
79
|
-
* BBOX sync : map to sigma
|
|
80
|
-
*/
|
|
81
|
-
function syncSigmaWithMap(sigma, map) {
|
|
82
|
-
var mapBound = map.getBounds();
|
|
83
|
-
|
|
84
|
-
// Compute sigma center
|
|
85
|
-
var center = sigma.viewportToFramedGraph(sigma.graphToViewport(latlngToGraph(map, mapBound.getCenter())));
|
|
86
|
-
|
|
87
|
-
// Compute sigma ratio
|
|
88
|
-
var northEast = sigma.graphToViewport(latlngToGraph(map, mapBound.getNorthEast()));
|
|
89
|
-
var southWest = sigma.graphToViewport(latlngToGraph(map, mapBound.getSouthWest()));
|
|
90
|
-
var viewportBoundDimension = {
|
|
91
|
-
width: Math.abs(northEast.x - southWest.x),
|
|
92
|
-
height: Math.abs(northEast.y - southWest.y)
|
|
93
|
-
};
|
|
94
|
-
var viewportDim = sigma.getDimensions();
|
|
95
|
-
var ratio = Math.min(viewportBoundDimension.width / viewportDim.width, viewportBoundDimension.height / viewportDim.height) * sigma.getCamera().getState().ratio;
|
|
96
|
-
sigma.getCamera().setState(_objectSpread2(_objectSpread2({}, center), {}, {
|
|
97
|
-
ratio: ratio
|
|
98
|
-
}));
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* BBOX sync : sigma to map
|
|
103
|
-
*/
|
|
104
|
-
function syncMapWithSigma(sigma, map) {
|
|
105
|
-
var viewportDimensions = sigma.getDimensions();
|
|
106
|
-
|
|
107
|
-
// Graph BBox
|
|
108
|
-
var graphBottomLeft = sigma.viewportToGraph({
|
|
109
|
-
x: 0,
|
|
110
|
-
y: viewportDimensions.height
|
|
111
|
-
}, {
|
|
112
|
-
padding: 0
|
|
113
|
-
});
|
|
114
|
-
var graphTopRight = sigma.viewportToGraph({
|
|
115
|
-
x: viewportDimensions.width,
|
|
116
|
-
y: 0
|
|
117
|
-
}, {
|
|
118
|
-
padding: 0
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
// Geo BBox
|
|
122
|
-
var geoSouthWest = graphToLatlng(map, graphBottomLeft);
|
|
123
|
-
var geoNorthEast = graphToLatlng(map, graphTopRight);
|
|
124
|
-
|
|
125
|
-
// Set map BBox
|
|
126
|
-
var bounds = new maplibreGl.LngLatBounds([geoSouthWest, geoNorthEast]);
|
|
127
|
-
map.fitBounds(bounds, {
|
|
128
|
-
duration: 0
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
|
|
132
78
|
/**
|
|
133
79
|
* On the graph, we store the 2D projection of the geographical lat/long.
|
|
134
80
|
*
|
|
@@ -140,40 +86,26 @@ function bindMaplibreLayer(sigma, opts) {
|
|
|
140
86
|
// Keeping data for the cleanup
|
|
141
87
|
var isKilled = false;
|
|
142
88
|
var prevSigmaSettings = sigma.getSettings();
|
|
143
|
-
|
|
144
|
-
// Creating map container
|
|
145
|
-
var mapLayerName = "layer-maplibre";
|
|
146
|
-
var mapContainer = sigma.createLayer(mapLayerName, "div", {
|
|
147
|
-
style: {
|
|
148
|
-
position: "absolute",
|
|
149
|
-
inset: "0"
|
|
150
|
-
},
|
|
151
|
-
// 'edges' is the first sigma layer
|
|
152
|
-
beforeLayer: "edges"
|
|
153
|
-
});
|
|
154
|
-
sigma.getContainer().prepend(mapContainer);
|
|
155
|
-
|
|
156
|
-
// Initialize the map
|
|
157
|
-
var map = new maplibreGl.Map(_objectSpread2({
|
|
158
|
-
container: mapContainer,
|
|
159
|
-
style: "https://demotiles.maplibre.org/style.json",
|
|
160
|
-
center: [0, 0],
|
|
161
|
-
zoom: 1,
|
|
162
|
-
minPitch: 0,
|
|
163
|
-
maxPitch: 0
|
|
164
|
-
}, (opts === null || opts === void 0 ? void 0 : opts.mapOptions) || {}));
|
|
89
|
+
var prevCustomBBox = sigma.getCustomBBox();
|
|
165
90
|
|
|
166
91
|
// `stagePadding: 0` is mandatory, so the bbox of the map & Sigma is the same.
|
|
167
92
|
sigma.setSetting("stagePadding", 0);
|
|
168
|
-
|
|
169
93
|
// disable camera rotation
|
|
170
94
|
sigma.setSetting("enableCameraRotation", false);
|
|
171
95
|
|
|
172
|
-
//
|
|
173
|
-
//
|
|
96
|
+
// Mercator graph coordinates are in [0,1]. Set customBBox to make
|
|
97
|
+
// normalization identity, and force a synchronous refresh so the
|
|
98
|
+
// normalization function is updated before camera constraints are applied.
|
|
99
|
+
sigma.setCustomBBox({
|
|
100
|
+
x: [0, 1],
|
|
101
|
+
y: [0, 1]
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// Function that updates graph node positions from geo coordinates to
|
|
105
|
+
// Mercator [0,1] space
|
|
174
106
|
function updateGraphCoordinates(graph) {
|
|
175
107
|
graph.updateEachNodeAttributes(function (_node, attrs) {
|
|
176
|
-
var coords = latlngToGraph(
|
|
108
|
+
var coords = latlngToGraph(opts !== null && opts !== void 0 && opts.getNodeLatLng ? opts.getNodeLatLng(attrs) : {
|
|
177
109
|
lat: attrs.lat,
|
|
178
110
|
lng: attrs.lng
|
|
179
111
|
});
|
|
@@ -184,74 +116,134 @@ function bindMaplibreLayer(sigma, opts) {
|
|
|
184
116
|
});
|
|
185
117
|
}
|
|
186
118
|
|
|
187
|
-
//
|
|
188
|
-
|
|
189
|
-
|
|
119
|
+
// Update graph coordinates and refresh sigma so normalization is ready
|
|
120
|
+
updateGraphCoordinates(sigma.getGraph());
|
|
121
|
+
sigma.refresh();
|
|
122
|
+
|
|
123
|
+
// Now that normalization is correct, fit the camera to the graph's
|
|
124
|
+
// Mercator extent so the initial view frames the nodes.
|
|
125
|
+
var graph = sigma.getGraph();
|
|
126
|
+
if (graph.order) {
|
|
127
|
+
sigma.getCamera().setState(utils.getCameraStateToFitViewportToNodes(sigma, graph.nodes()));
|
|
190
128
|
}
|
|
191
129
|
|
|
192
|
-
//
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
y: sigma.getDimensions().height
|
|
199
|
-
}));
|
|
200
|
-
var northEast = graphToLatlng(map, sigma.viewportToGraph({
|
|
201
|
-
x: sigma.getDimensions().width,
|
|
202
|
-
y: 0
|
|
203
|
-
}));
|
|
204
|
-
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)));
|
|
205
|
-
if (diff > 1) {
|
|
206
|
-
syncSigmaWithMap(sigma, map);
|
|
207
|
-
}
|
|
130
|
+
// Apply camera constraints. cameraPanBoundaries triggers cleanCameraState
|
|
131
|
+
// which uses graphToViewport — it needs the correct normalization.
|
|
132
|
+
sigma.setSetting("cameraPanBoundaries", {
|
|
133
|
+
boundaries: {
|
|
134
|
+
x: [-1, 2],
|
|
135
|
+
y: [0, 1]
|
|
208
136
|
}
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// Prevent zooming out beyond the world. The max ratio depends on the
|
|
140
|
+
// viewport aspect ratio: for a square graph, the Y range [0,1] fills the
|
|
141
|
+
// viewport height when ratio = min(width, height) / height.
|
|
142
|
+
function updateMaxCameraRatio() {
|
|
143
|
+
var _sigma$getDimensions = sigma.getDimensions(),
|
|
144
|
+
width = _sigma$getDimensions.width,
|
|
145
|
+
height = _sigma$getDimensions.height;
|
|
146
|
+
sigma.setSetting("maxCameraRatio", Math.min(width, height) / height);
|
|
147
|
+
}
|
|
148
|
+
updateMaxCameraRatio();
|
|
149
|
+
|
|
150
|
+
// Compute initial map bounds from sigma's current viewport, so the map's
|
|
151
|
+
// first render is already at the correct position
|
|
152
|
+
function getSigmaViewportBounds() {
|
|
153
|
+
var dims = sigma.getDimensions();
|
|
154
|
+
var graphBottomLeft = sigma.viewportToGraph({
|
|
155
|
+
x: 0,
|
|
156
|
+
y: dims.height
|
|
157
|
+
}, {
|
|
158
|
+
padding: 0
|
|
159
|
+
});
|
|
160
|
+
var graphTopRight = sigma.viewportToGraph({
|
|
161
|
+
x: dims.width,
|
|
162
|
+
y: 0
|
|
163
|
+
}, {
|
|
164
|
+
padding: 0
|
|
165
|
+
});
|
|
166
|
+
return new maplibreGl.LngLatBounds(graphToLatlng(graphBottomLeft), graphToLatlng(graphTopRight));
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Creating map container
|
|
170
|
+
var mapLayerName = "layer-maplibre";
|
|
171
|
+
var mapContainer = sigma.createLayer(mapLayerName, "div", {
|
|
172
|
+
style: {
|
|
173
|
+
position: "absolute",
|
|
174
|
+
inset: "0"
|
|
175
|
+
},
|
|
176
|
+
// 'stage' is the first sigma layer
|
|
177
|
+
beforeLayer: "stage"
|
|
178
|
+
});
|
|
179
|
+
sigma.getContainer().prepend(mapContainer);
|
|
180
|
+
|
|
181
|
+
// Initialize the map (non-interactive: sigma controls all interaction)
|
|
182
|
+
var map = new maplibreGl.Map(_objectSpread2(_objectSpread2({
|
|
183
|
+
container: mapContainer,
|
|
184
|
+
style: "https://demotiles.maplibre.org/style.json",
|
|
185
|
+
minPitch: 0,
|
|
186
|
+
maxPitch: 0
|
|
187
|
+
}, opts === null || opts === void 0 ? void 0 : opts.mapOptions), {}, {
|
|
188
|
+
interactive: false,
|
|
189
|
+
bounds: getSigmaViewportBounds()
|
|
190
|
+
}));
|
|
191
|
+
|
|
192
|
+
// Camera state memoization to skip redundant fitBounds calls
|
|
193
|
+
var lx = NaN,
|
|
194
|
+
ly = NaN,
|
|
195
|
+
lr = NaN,
|
|
196
|
+
la = NaN;
|
|
197
|
+
|
|
198
|
+
// Sync map bounds to match sigma's viewport
|
|
199
|
+
function syncMapFromSigma() {
|
|
200
|
+
var _sigma$getCamera$getS = sigma.getCamera().getState(),
|
|
201
|
+
x = _sigma$getCamera$getS.x,
|
|
202
|
+
y = _sigma$getCamera$getS.y,
|
|
203
|
+
ratio = _sigma$getCamera$getS.ratio,
|
|
204
|
+
angle = _sigma$getCamera$getS.angle;
|
|
205
|
+
if (x === lx && y === ly && ratio === lr && angle === la) return;
|
|
206
|
+
lx = x;
|
|
207
|
+
ly = y;
|
|
208
|
+
lr = ratio;
|
|
209
|
+
la = angle;
|
|
210
|
+
map.fitBounds(getSigmaViewportBounds(), {
|
|
211
|
+
duration: 0
|
|
212
|
+
});
|
|
209
213
|
}
|
|
210
214
|
|
|
211
|
-
// When sigma is
|
|
212
|
-
// and recompute the zoom bounds
|
|
215
|
+
// When sigma is resized, resize the map, recompute zoom limit, and re-sync
|
|
213
216
|
function fnOnResize() {
|
|
214
|
-
|
|
215
|
-
|
|
217
|
+
map.resize();
|
|
218
|
+
updateMaxCameraRatio();
|
|
219
|
+
lx = NaN;
|
|
220
|
+
syncMapFromSigma();
|
|
216
221
|
}
|
|
217
222
|
|
|
218
223
|
// Clean up function to remove everything
|
|
219
224
|
function clean() {
|
|
220
225
|
if (!isKilled) {
|
|
221
226
|
isKilled = true;
|
|
222
|
-
map.off("moveend", fnSyncSigmaWithMap);
|
|
223
227
|
map.remove();
|
|
224
228
|
sigma.killLayer(mapLayerName);
|
|
225
|
-
sigma.off("afterRender",
|
|
229
|
+
sigma.off("afterRender", syncMapFromSigma);
|
|
226
230
|
sigma.off("resize", fnOnResize);
|
|
231
|
+
sigma.off("kill", clean);
|
|
227
232
|
|
|
228
233
|
// Reset settings
|
|
229
234
|
sigma.setSetting("stagePadding", prevSigmaSettings.stagePadding);
|
|
230
235
|
sigma.setSetting("enableCameraRotation", prevSigmaSettings.enableCameraRotation);
|
|
236
|
+
sigma.setSetting("maxCameraRatio", prevSigmaSettings.maxCameraRatio);
|
|
237
|
+
sigma.setSetting("cameraPanBoundaries", prevSigmaSettings.cameraPanBoundaries);
|
|
238
|
+
sigma.setCustomBBox(prevCustomBBox);
|
|
231
239
|
}
|
|
232
240
|
}
|
|
233
241
|
|
|
234
|
-
//
|
|
235
|
-
updateGraphCoordinates(sigma.getGraph());
|
|
236
|
-
|
|
237
|
-
// When the map is ready
|
|
242
|
+
// When the map is ready, start syncing
|
|
238
243
|
map.once("load", function () {
|
|
239
|
-
|
|
240
|
-
// /!\ must be done after the first map render
|
|
241
|
-
map.once("moveend", function () {
|
|
242
|
-
fnSyncSigmaWithMap();
|
|
243
|
-
});
|
|
244
|
-
// Do the first sync
|
|
245
|
-
fnSyncMapWithSigma();
|
|
246
|
-
|
|
247
|
-
// At each render of sigma, we do the map sync
|
|
248
|
-
sigma.on("afterRender", fnSyncMapWithSigma);
|
|
249
|
-
// Listen on resize
|
|
244
|
+
sigma.on("afterRender", syncMapFromSigma);
|
|
250
245
|
sigma.on("resize", fnOnResize);
|
|
251
|
-
// Do the cleanup
|
|
252
246
|
sigma.on("kill", clean);
|
|
253
|
-
// Keep sigma camera on the map
|
|
254
|
-
map.on("moveend", fnSyncSigmaWithMap);
|
|
255
247
|
});
|
|
256
248
|
return {
|
|
257
249
|
clean: clean,
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
+
var utils = require('@sigma/utils');
|
|
5
6
|
var maplibreGl = require('maplibre-gl');
|
|
6
7
|
|
|
7
8
|
function _toPrimitive(t, r) {
|
|
@@ -54,20 +55,19 @@ function _objectSpread2(e) {
|
|
|
54
55
|
/**
|
|
55
56
|
* Given a geo point returns its graph coords.
|
|
56
57
|
*/
|
|
57
|
-
function latlngToGraph(
|
|
58
|
+
function latlngToGraph(coord) {
|
|
58
59
|
var data = maplibreGl.MercatorCoordinate.fromLngLat(coord);
|
|
59
60
|
return {
|
|
60
61
|
x: data.x,
|
|
61
|
-
|
|
62
|
-
y: map.getContainer().clientHeight - data.y
|
|
62
|
+
y: 1 - data.y
|
|
63
63
|
};
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
/**
|
|
67
|
-
* Given
|
|
67
|
+
* Given graph coords returns its lat/lng coords.
|
|
68
68
|
*/
|
|
69
|
-
function graphToLatlng(
|
|
70
|
-
var mcoords = new maplibreGl.MercatorCoordinate(coords.x,
|
|
69
|
+
function graphToLatlng(coords) {
|
|
70
|
+
var mcoords = new maplibreGl.MercatorCoordinate(coords.x, 1 - coords.y, 0);
|
|
71
71
|
var data = mcoords.toLngLat();
|
|
72
72
|
return {
|
|
73
73
|
lat: data.lat,
|
|
@@ -75,60 +75,6 @@ function graphToLatlng(map, coords) {
|
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
/**
|
|
79
|
-
* BBOX sync : map to sigma
|
|
80
|
-
*/
|
|
81
|
-
function syncSigmaWithMap(sigma, map) {
|
|
82
|
-
var mapBound = map.getBounds();
|
|
83
|
-
|
|
84
|
-
// Compute sigma center
|
|
85
|
-
var center = sigma.viewportToFramedGraph(sigma.graphToViewport(latlngToGraph(map, mapBound.getCenter())));
|
|
86
|
-
|
|
87
|
-
// Compute sigma ratio
|
|
88
|
-
var northEast = sigma.graphToViewport(latlngToGraph(map, mapBound.getNorthEast()));
|
|
89
|
-
var southWest = sigma.graphToViewport(latlngToGraph(map, mapBound.getSouthWest()));
|
|
90
|
-
var viewportBoundDimension = {
|
|
91
|
-
width: Math.abs(northEast.x - southWest.x),
|
|
92
|
-
height: Math.abs(northEast.y - southWest.y)
|
|
93
|
-
};
|
|
94
|
-
var viewportDim = sigma.getDimensions();
|
|
95
|
-
var ratio = Math.min(viewportBoundDimension.width / viewportDim.width, viewportBoundDimension.height / viewportDim.height) * sigma.getCamera().getState().ratio;
|
|
96
|
-
sigma.getCamera().setState(_objectSpread2(_objectSpread2({}, center), {}, {
|
|
97
|
-
ratio: ratio
|
|
98
|
-
}));
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* BBOX sync : sigma to map
|
|
103
|
-
*/
|
|
104
|
-
function syncMapWithSigma(sigma, map) {
|
|
105
|
-
var viewportDimensions = sigma.getDimensions();
|
|
106
|
-
|
|
107
|
-
// Graph BBox
|
|
108
|
-
var graphBottomLeft = sigma.viewportToGraph({
|
|
109
|
-
x: 0,
|
|
110
|
-
y: viewportDimensions.height
|
|
111
|
-
}, {
|
|
112
|
-
padding: 0
|
|
113
|
-
});
|
|
114
|
-
var graphTopRight = sigma.viewportToGraph({
|
|
115
|
-
x: viewportDimensions.width,
|
|
116
|
-
y: 0
|
|
117
|
-
}, {
|
|
118
|
-
padding: 0
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
// Geo BBox
|
|
122
|
-
var geoSouthWest = graphToLatlng(map, graphBottomLeft);
|
|
123
|
-
var geoNorthEast = graphToLatlng(map, graphTopRight);
|
|
124
|
-
|
|
125
|
-
// Set map BBox
|
|
126
|
-
var bounds = new maplibreGl.LngLatBounds([geoSouthWest, geoNorthEast]);
|
|
127
|
-
map.fitBounds(bounds, {
|
|
128
|
-
duration: 0
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
|
|
132
78
|
/**
|
|
133
79
|
* On the graph, we store the 2D projection of the geographical lat/long.
|
|
134
80
|
*
|
|
@@ -140,40 +86,26 @@ function bindMaplibreLayer(sigma, opts) {
|
|
|
140
86
|
// Keeping data for the cleanup
|
|
141
87
|
var isKilled = false;
|
|
142
88
|
var prevSigmaSettings = sigma.getSettings();
|
|
143
|
-
|
|
144
|
-
// Creating map container
|
|
145
|
-
var mapLayerName = "layer-maplibre";
|
|
146
|
-
var mapContainer = sigma.createLayer(mapLayerName, "div", {
|
|
147
|
-
style: {
|
|
148
|
-
position: "absolute",
|
|
149
|
-
inset: "0"
|
|
150
|
-
},
|
|
151
|
-
// 'edges' is the first sigma layer
|
|
152
|
-
beforeLayer: "edges"
|
|
153
|
-
});
|
|
154
|
-
sigma.getContainer().prepend(mapContainer);
|
|
155
|
-
|
|
156
|
-
// Initialize the map
|
|
157
|
-
var map = new maplibreGl.Map(_objectSpread2({
|
|
158
|
-
container: mapContainer,
|
|
159
|
-
style: "https://demotiles.maplibre.org/style.json",
|
|
160
|
-
center: [0, 0],
|
|
161
|
-
zoom: 1,
|
|
162
|
-
minPitch: 0,
|
|
163
|
-
maxPitch: 0
|
|
164
|
-
}, (opts === null || opts === void 0 ? void 0 : opts.mapOptions) || {}));
|
|
89
|
+
var prevCustomBBox = sigma.getCustomBBox();
|
|
165
90
|
|
|
166
91
|
// `stagePadding: 0` is mandatory, so the bbox of the map & Sigma is the same.
|
|
167
92
|
sigma.setSetting("stagePadding", 0);
|
|
168
|
-
|
|
169
93
|
// disable camera rotation
|
|
170
94
|
sigma.setSetting("enableCameraRotation", false);
|
|
171
95
|
|
|
172
|
-
//
|
|
173
|
-
//
|
|
96
|
+
// Mercator graph coordinates are in [0,1]. Set customBBox to make
|
|
97
|
+
// normalization identity, and force a synchronous refresh so the
|
|
98
|
+
// normalization function is updated before camera constraints are applied.
|
|
99
|
+
sigma.setCustomBBox({
|
|
100
|
+
x: [0, 1],
|
|
101
|
+
y: [0, 1]
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// Function that updates graph node positions from geo coordinates to
|
|
105
|
+
// Mercator [0,1] space
|
|
174
106
|
function updateGraphCoordinates(graph) {
|
|
175
107
|
graph.updateEachNodeAttributes(function (_node, attrs) {
|
|
176
|
-
var coords = latlngToGraph(
|
|
108
|
+
var coords = latlngToGraph(opts !== null && opts !== void 0 && opts.getNodeLatLng ? opts.getNodeLatLng(attrs) : {
|
|
177
109
|
lat: attrs.lat,
|
|
178
110
|
lng: attrs.lng
|
|
179
111
|
});
|
|
@@ -184,74 +116,134 @@ function bindMaplibreLayer(sigma, opts) {
|
|
|
184
116
|
});
|
|
185
117
|
}
|
|
186
118
|
|
|
187
|
-
//
|
|
188
|
-
|
|
189
|
-
|
|
119
|
+
// Update graph coordinates and refresh sigma so normalization is ready
|
|
120
|
+
updateGraphCoordinates(sigma.getGraph());
|
|
121
|
+
sigma.refresh();
|
|
122
|
+
|
|
123
|
+
// Now that normalization is correct, fit the camera to the graph's
|
|
124
|
+
// Mercator extent so the initial view frames the nodes.
|
|
125
|
+
var graph = sigma.getGraph();
|
|
126
|
+
if (graph.order) {
|
|
127
|
+
sigma.getCamera().setState(utils.getCameraStateToFitViewportToNodes(sigma, graph.nodes()));
|
|
190
128
|
}
|
|
191
129
|
|
|
192
|
-
//
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
y: sigma.getDimensions().height
|
|
199
|
-
}));
|
|
200
|
-
var northEast = graphToLatlng(map, sigma.viewportToGraph({
|
|
201
|
-
x: sigma.getDimensions().width,
|
|
202
|
-
y: 0
|
|
203
|
-
}));
|
|
204
|
-
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)));
|
|
205
|
-
if (diff > 1) {
|
|
206
|
-
syncSigmaWithMap(sigma, map);
|
|
207
|
-
}
|
|
130
|
+
// Apply camera constraints. cameraPanBoundaries triggers cleanCameraState
|
|
131
|
+
// which uses graphToViewport — it needs the correct normalization.
|
|
132
|
+
sigma.setSetting("cameraPanBoundaries", {
|
|
133
|
+
boundaries: {
|
|
134
|
+
x: [-1, 2],
|
|
135
|
+
y: [0, 1]
|
|
208
136
|
}
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// Prevent zooming out beyond the world. The max ratio depends on the
|
|
140
|
+
// viewport aspect ratio: for a square graph, the Y range [0,1] fills the
|
|
141
|
+
// viewport height when ratio = min(width, height) / height.
|
|
142
|
+
function updateMaxCameraRatio() {
|
|
143
|
+
var _sigma$getDimensions = sigma.getDimensions(),
|
|
144
|
+
width = _sigma$getDimensions.width,
|
|
145
|
+
height = _sigma$getDimensions.height;
|
|
146
|
+
sigma.setSetting("maxCameraRatio", Math.min(width, height) / height);
|
|
147
|
+
}
|
|
148
|
+
updateMaxCameraRatio();
|
|
149
|
+
|
|
150
|
+
// Compute initial map bounds from sigma's current viewport, so the map's
|
|
151
|
+
// first render is already at the correct position
|
|
152
|
+
function getSigmaViewportBounds() {
|
|
153
|
+
var dims = sigma.getDimensions();
|
|
154
|
+
var graphBottomLeft = sigma.viewportToGraph({
|
|
155
|
+
x: 0,
|
|
156
|
+
y: dims.height
|
|
157
|
+
}, {
|
|
158
|
+
padding: 0
|
|
159
|
+
});
|
|
160
|
+
var graphTopRight = sigma.viewportToGraph({
|
|
161
|
+
x: dims.width,
|
|
162
|
+
y: 0
|
|
163
|
+
}, {
|
|
164
|
+
padding: 0
|
|
165
|
+
});
|
|
166
|
+
return new maplibreGl.LngLatBounds(graphToLatlng(graphBottomLeft), graphToLatlng(graphTopRight));
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Creating map container
|
|
170
|
+
var mapLayerName = "layer-maplibre";
|
|
171
|
+
var mapContainer = sigma.createLayer(mapLayerName, "div", {
|
|
172
|
+
style: {
|
|
173
|
+
position: "absolute",
|
|
174
|
+
inset: "0"
|
|
175
|
+
},
|
|
176
|
+
// 'stage' is the first sigma layer
|
|
177
|
+
beforeLayer: "stage"
|
|
178
|
+
});
|
|
179
|
+
sigma.getContainer().prepend(mapContainer);
|
|
180
|
+
|
|
181
|
+
// Initialize the map (non-interactive: sigma controls all interaction)
|
|
182
|
+
var map = new maplibreGl.Map(_objectSpread2(_objectSpread2({
|
|
183
|
+
container: mapContainer,
|
|
184
|
+
style: "https://demotiles.maplibre.org/style.json",
|
|
185
|
+
minPitch: 0,
|
|
186
|
+
maxPitch: 0
|
|
187
|
+
}, opts === null || opts === void 0 ? void 0 : opts.mapOptions), {}, {
|
|
188
|
+
interactive: false,
|
|
189
|
+
bounds: getSigmaViewportBounds()
|
|
190
|
+
}));
|
|
191
|
+
|
|
192
|
+
// Camera state memoization to skip redundant fitBounds calls
|
|
193
|
+
var lx = NaN,
|
|
194
|
+
ly = NaN,
|
|
195
|
+
lr = NaN,
|
|
196
|
+
la = NaN;
|
|
197
|
+
|
|
198
|
+
// Sync map bounds to match sigma's viewport
|
|
199
|
+
function syncMapFromSigma() {
|
|
200
|
+
var _sigma$getCamera$getS = sigma.getCamera().getState(),
|
|
201
|
+
x = _sigma$getCamera$getS.x,
|
|
202
|
+
y = _sigma$getCamera$getS.y,
|
|
203
|
+
ratio = _sigma$getCamera$getS.ratio,
|
|
204
|
+
angle = _sigma$getCamera$getS.angle;
|
|
205
|
+
if (x === lx && y === ly && ratio === lr && angle === la) return;
|
|
206
|
+
lx = x;
|
|
207
|
+
ly = y;
|
|
208
|
+
lr = ratio;
|
|
209
|
+
la = angle;
|
|
210
|
+
map.fitBounds(getSigmaViewportBounds(), {
|
|
211
|
+
duration: 0
|
|
212
|
+
});
|
|
209
213
|
}
|
|
210
214
|
|
|
211
|
-
// When sigma is
|
|
212
|
-
// and recompute the zoom bounds
|
|
215
|
+
// When sigma is resized, resize the map, recompute zoom limit, and re-sync
|
|
213
216
|
function fnOnResize() {
|
|
214
|
-
|
|
215
|
-
|
|
217
|
+
map.resize();
|
|
218
|
+
updateMaxCameraRatio();
|
|
219
|
+
lx = NaN;
|
|
220
|
+
syncMapFromSigma();
|
|
216
221
|
}
|
|
217
222
|
|
|
218
223
|
// Clean up function to remove everything
|
|
219
224
|
function clean() {
|
|
220
225
|
if (!isKilled) {
|
|
221
226
|
isKilled = true;
|
|
222
|
-
map.off("moveend", fnSyncSigmaWithMap);
|
|
223
227
|
map.remove();
|
|
224
228
|
sigma.killLayer(mapLayerName);
|
|
225
|
-
sigma.off("afterRender",
|
|
229
|
+
sigma.off("afterRender", syncMapFromSigma);
|
|
226
230
|
sigma.off("resize", fnOnResize);
|
|
231
|
+
sigma.off("kill", clean);
|
|
227
232
|
|
|
228
233
|
// Reset settings
|
|
229
234
|
sigma.setSetting("stagePadding", prevSigmaSettings.stagePadding);
|
|
230
235
|
sigma.setSetting("enableCameraRotation", prevSigmaSettings.enableCameraRotation);
|
|
236
|
+
sigma.setSetting("maxCameraRatio", prevSigmaSettings.maxCameraRatio);
|
|
237
|
+
sigma.setSetting("cameraPanBoundaries", prevSigmaSettings.cameraPanBoundaries);
|
|
238
|
+
sigma.setCustomBBox(prevCustomBBox);
|
|
231
239
|
}
|
|
232
240
|
}
|
|
233
241
|
|
|
234
|
-
//
|
|
235
|
-
updateGraphCoordinates(sigma.getGraph());
|
|
236
|
-
|
|
237
|
-
// When the map is ready
|
|
242
|
+
// When the map is ready, start syncing
|
|
238
243
|
map.once("load", function () {
|
|
239
|
-
|
|
240
|
-
// /!\ must be done after the first map render
|
|
241
|
-
map.once("moveend", function () {
|
|
242
|
-
fnSyncSigmaWithMap();
|
|
243
|
-
});
|
|
244
|
-
// Do the first sync
|
|
245
|
-
fnSyncMapWithSigma();
|
|
246
|
-
|
|
247
|
-
// At each render of sigma, we do the map sync
|
|
248
|
-
sigma.on("afterRender", fnSyncMapWithSigma);
|
|
249
|
-
// Listen on resize
|
|
244
|
+
sigma.on("afterRender", syncMapFromSigma);
|
|
250
245
|
sigma.on("resize", fnOnResize);
|
|
251
|
-
// Do the cleanup
|
|
252
246
|
sigma.on("kill", clean);
|
|
253
|
-
// Keep sigma camera on the map
|
|
254
|
-
map.on("moveend", fnSyncSigmaWithMap);
|
|
255
247
|
});
|
|
256
248
|
return {
|
|
257
249
|
clean: clean,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getCameraStateToFitViewportToNodes } from '@sigma/utils';
|
|
2
|
+
import { MercatorCoordinate, Map, LngLatBounds } from 'maplibre-gl';
|
|
2
3
|
|
|
3
4
|
function _toPrimitive(t, r) {
|
|
4
5
|
if ("object" != typeof t || !t) return t;
|
|
@@ -50,20 +51,19 @@ function _objectSpread2(e) {
|
|
|
50
51
|
/**
|
|
51
52
|
* Given a geo point returns its graph coords.
|
|
52
53
|
*/
|
|
53
|
-
function latlngToGraph(
|
|
54
|
+
function latlngToGraph(coord) {
|
|
54
55
|
var data = MercatorCoordinate.fromLngLat(coord);
|
|
55
56
|
return {
|
|
56
57
|
x: data.x,
|
|
57
|
-
|
|
58
|
-
y: map.getContainer().clientHeight - data.y
|
|
58
|
+
y: 1 - data.y
|
|
59
59
|
};
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
/**
|
|
63
|
-
* Given
|
|
63
|
+
* Given graph coords returns its lat/lng coords.
|
|
64
64
|
*/
|
|
65
|
-
function graphToLatlng(
|
|
66
|
-
var mcoords = new MercatorCoordinate(coords.x,
|
|
65
|
+
function graphToLatlng(coords) {
|
|
66
|
+
var mcoords = new MercatorCoordinate(coords.x, 1 - coords.y, 0);
|
|
67
67
|
var data = mcoords.toLngLat();
|
|
68
68
|
return {
|
|
69
69
|
lat: data.lat,
|
|
@@ -71,60 +71,6 @@ function graphToLatlng(map, coords) {
|
|
|
71
71
|
};
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
/**
|
|
75
|
-
* BBOX sync : map to sigma
|
|
76
|
-
*/
|
|
77
|
-
function syncSigmaWithMap(sigma, map) {
|
|
78
|
-
var mapBound = map.getBounds();
|
|
79
|
-
|
|
80
|
-
// Compute sigma center
|
|
81
|
-
var center = sigma.viewportToFramedGraph(sigma.graphToViewport(latlngToGraph(map, mapBound.getCenter())));
|
|
82
|
-
|
|
83
|
-
// Compute sigma ratio
|
|
84
|
-
var northEast = sigma.graphToViewport(latlngToGraph(map, mapBound.getNorthEast()));
|
|
85
|
-
var southWest = sigma.graphToViewport(latlngToGraph(map, mapBound.getSouthWest()));
|
|
86
|
-
var viewportBoundDimension = {
|
|
87
|
-
width: Math.abs(northEast.x - southWest.x),
|
|
88
|
-
height: Math.abs(northEast.y - southWest.y)
|
|
89
|
-
};
|
|
90
|
-
var viewportDim = sigma.getDimensions();
|
|
91
|
-
var ratio = Math.min(viewportBoundDimension.width / viewportDim.width, viewportBoundDimension.height / viewportDim.height) * sigma.getCamera().getState().ratio;
|
|
92
|
-
sigma.getCamera().setState(_objectSpread2(_objectSpread2({}, center), {}, {
|
|
93
|
-
ratio: ratio
|
|
94
|
-
}));
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* BBOX sync : sigma to map
|
|
99
|
-
*/
|
|
100
|
-
function syncMapWithSigma(sigma, map) {
|
|
101
|
-
var viewportDimensions = sigma.getDimensions();
|
|
102
|
-
|
|
103
|
-
// Graph BBox
|
|
104
|
-
var graphBottomLeft = sigma.viewportToGraph({
|
|
105
|
-
x: 0,
|
|
106
|
-
y: viewportDimensions.height
|
|
107
|
-
}, {
|
|
108
|
-
padding: 0
|
|
109
|
-
});
|
|
110
|
-
var graphTopRight = sigma.viewportToGraph({
|
|
111
|
-
x: viewportDimensions.width,
|
|
112
|
-
y: 0
|
|
113
|
-
}, {
|
|
114
|
-
padding: 0
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
// Geo BBox
|
|
118
|
-
var geoSouthWest = graphToLatlng(map, graphBottomLeft);
|
|
119
|
-
var geoNorthEast = graphToLatlng(map, graphTopRight);
|
|
120
|
-
|
|
121
|
-
// Set map BBox
|
|
122
|
-
var bounds = new LngLatBounds([geoSouthWest, geoNorthEast]);
|
|
123
|
-
map.fitBounds(bounds, {
|
|
124
|
-
duration: 0
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
|
|
128
74
|
/**
|
|
129
75
|
* On the graph, we store the 2D projection of the geographical lat/long.
|
|
130
76
|
*
|
|
@@ -136,40 +82,26 @@ function bindMaplibreLayer(sigma, opts) {
|
|
|
136
82
|
// Keeping data for the cleanup
|
|
137
83
|
var isKilled = false;
|
|
138
84
|
var prevSigmaSettings = sigma.getSettings();
|
|
139
|
-
|
|
140
|
-
// Creating map container
|
|
141
|
-
var mapLayerName = "layer-maplibre";
|
|
142
|
-
var mapContainer = sigma.createLayer(mapLayerName, "div", {
|
|
143
|
-
style: {
|
|
144
|
-
position: "absolute",
|
|
145
|
-
inset: "0"
|
|
146
|
-
},
|
|
147
|
-
// 'edges' is the first sigma layer
|
|
148
|
-
beforeLayer: "edges"
|
|
149
|
-
});
|
|
150
|
-
sigma.getContainer().prepend(mapContainer);
|
|
151
|
-
|
|
152
|
-
// Initialize the map
|
|
153
|
-
var map = new Map(_objectSpread2({
|
|
154
|
-
container: mapContainer,
|
|
155
|
-
style: "https://demotiles.maplibre.org/style.json",
|
|
156
|
-
center: [0, 0],
|
|
157
|
-
zoom: 1,
|
|
158
|
-
minPitch: 0,
|
|
159
|
-
maxPitch: 0
|
|
160
|
-
}, (opts === null || opts === void 0 ? void 0 : opts.mapOptions) || {}));
|
|
85
|
+
var prevCustomBBox = sigma.getCustomBBox();
|
|
161
86
|
|
|
162
87
|
// `stagePadding: 0` is mandatory, so the bbox of the map & Sigma is the same.
|
|
163
88
|
sigma.setSetting("stagePadding", 0);
|
|
164
|
-
|
|
165
89
|
// disable camera rotation
|
|
166
90
|
sigma.setSetting("enableCameraRotation", false);
|
|
167
91
|
|
|
168
|
-
//
|
|
169
|
-
//
|
|
92
|
+
// Mercator graph coordinates are in [0,1]. Set customBBox to make
|
|
93
|
+
// normalization identity, and force a synchronous refresh so the
|
|
94
|
+
// normalization function is updated before camera constraints are applied.
|
|
95
|
+
sigma.setCustomBBox({
|
|
96
|
+
x: [0, 1],
|
|
97
|
+
y: [0, 1]
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// Function that updates graph node positions from geo coordinates to
|
|
101
|
+
// Mercator [0,1] space
|
|
170
102
|
function updateGraphCoordinates(graph) {
|
|
171
103
|
graph.updateEachNodeAttributes(function (_node, attrs) {
|
|
172
|
-
var coords = latlngToGraph(
|
|
104
|
+
var coords = latlngToGraph(opts !== null && opts !== void 0 && opts.getNodeLatLng ? opts.getNodeLatLng(attrs) : {
|
|
173
105
|
lat: attrs.lat,
|
|
174
106
|
lng: attrs.lng
|
|
175
107
|
});
|
|
@@ -180,74 +112,134 @@ function bindMaplibreLayer(sigma, opts) {
|
|
|
180
112
|
});
|
|
181
113
|
}
|
|
182
114
|
|
|
183
|
-
//
|
|
184
|
-
|
|
185
|
-
|
|
115
|
+
// Update graph coordinates and refresh sigma so normalization is ready
|
|
116
|
+
updateGraphCoordinates(sigma.getGraph());
|
|
117
|
+
sigma.refresh();
|
|
118
|
+
|
|
119
|
+
// Now that normalization is correct, fit the camera to the graph's
|
|
120
|
+
// Mercator extent so the initial view frames the nodes.
|
|
121
|
+
var graph = sigma.getGraph();
|
|
122
|
+
if (graph.order) {
|
|
123
|
+
sigma.getCamera().setState(getCameraStateToFitViewportToNodes(sigma, graph.nodes()));
|
|
186
124
|
}
|
|
187
125
|
|
|
188
|
-
//
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
y: sigma.getDimensions().height
|
|
195
|
-
}));
|
|
196
|
-
var northEast = graphToLatlng(map, sigma.viewportToGraph({
|
|
197
|
-
x: sigma.getDimensions().width,
|
|
198
|
-
y: 0
|
|
199
|
-
}));
|
|
200
|
-
var diff = Math.max(map.getBounds().getSouthWest().distanceTo(new LngLat(southWest.lng, southWest.lat)), map.getBounds().getNorthEast().distanceTo(new LngLat(northEast.lng, northEast.lat)));
|
|
201
|
-
if (diff > 1) {
|
|
202
|
-
syncSigmaWithMap(sigma, map);
|
|
203
|
-
}
|
|
126
|
+
// Apply camera constraints. cameraPanBoundaries triggers cleanCameraState
|
|
127
|
+
// which uses graphToViewport — it needs the correct normalization.
|
|
128
|
+
sigma.setSetting("cameraPanBoundaries", {
|
|
129
|
+
boundaries: {
|
|
130
|
+
x: [-1, 2],
|
|
131
|
+
y: [0, 1]
|
|
204
132
|
}
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// Prevent zooming out beyond the world. The max ratio depends on the
|
|
136
|
+
// viewport aspect ratio: for a square graph, the Y range [0,1] fills the
|
|
137
|
+
// viewport height when ratio = min(width, height) / height.
|
|
138
|
+
function updateMaxCameraRatio() {
|
|
139
|
+
var _sigma$getDimensions = sigma.getDimensions(),
|
|
140
|
+
width = _sigma$getDimensions.width,
|
|
141
|
+
height = _sigma$getDimensions.height;
|
|
142
|
+
sigma.setSetting("maxCameraRatio", Math.min(width, height) / height);
|
|
143
|
+
}
|
|
144
|
+
updateMaxCameraRatio();
|
|
145
|
+
|
|
146
|
+
// Compute initial map bounds from sigma's current viewport, so the map's
|
|
147
|
+
// first render is already at the correct position
|
|
148
|
+
function getSigmaViewportBounds() {
|
|
149
|
+
var dims = sigma.getDimensions();
|
|
150
|
+
var graphBottomLeft = sigma.viewportToGraph({
|
|
151
|
+
x: 0,
|
|
152
|
+
y: dims.height
|
|
153
|
+
}, {
|
|
154
|
+
padding: 0
|
|
155
|
+
});
|
|
156
|
+
var graphTopRight = sigma.viewportToGraph({
|
|
157
|
+
x: dims.width,
|
|
158
|
+
y: 0
|
|
159
|
+
}, {
|
|
160
|
+
padding: 0
|
|
161
|
+
});
|
|
162
|
+
return new LngLatBounds(graphToLatlng(graphBottomLeft), graphToLatlng(graphTopRight));
|
|
205
163
|
}
|
|
206
164
|
|
|
207
|
-
//
|
|
208
|
-
|
|
165
|
+
// Creating map container
|
|
166
|
+
var mapLayerName = "layer-maplibre";
|
|
167
|
+
var mapContainer = sigma.createLayer(mapLayerName, "div", {
|
|
168
|
+
style: {
|
|
169
|
+
position: "absolute",
|
|
170
|
+
inset: "0"
|
|
171
|
+
},
|
|
172
|
+
// 'stage' is the first sigma layer
|
|
173
|
+
beforeLayer: "stage"
|
|
174
|
+
});
|
|
175
|
+
sigma.getContainer().prepend(mapContainer);
|
|
176
|
+
|
|
177
|
+
// Initialize the map (non-interactive: sigma controls all interaction)
|
|
178
|
+
var map = new Map(_objectSpread2(_objectSpread2({
|
|
179
|
+
container: mapContainer,
|
|
180
|
+
style: "https://demotiles.maplibre.org/style.json",
|
|
181
|
+
minPitch: 0,
|
|
182
|
+
maxPitch: 0
|
|
183
|
+
}, opts === null || opts === void 0 ? void 0 : opts.mapOptions), {}, {
|
|
184
|
+
interactive: false,
|
|
185
|
+
bounds: getSigmaViewportBounds()
|
|
186
|
+
}));
|
|
187
|
+
|
|
188
|
+
// Camera state memoization to skip redundant fitBounds calls
|
|
189
|
+
var lx = NaN,
|
|
190
|
+
ly = NaN,
|
|
191
|
+
lr = NaN,
|
|
192
|
+
la = NaN;
|
|
193
|
+
|
|
194
|
+
// Sync map bounds to match sigma's viewport
|
|
195
|
+
function syncMapFromSigma() {
|
|
196
|
+
var _sigma$getCamera$getS = sigma.getCamera().getState(),
|
|
197
|
+
x = _sigma$getCamera$getS.x,
|
|
198
|
+
y = _sigma$getCamera$getS.y,
|
|
199
|
+
ratio = _sigma$getCamera$getS.ratio,
|
|
200
|
+
angle = _sigma$getCamera$getS.angle;
|
|
201
|
+
if (x === lx && y === ly && ratio === lr && angle === la) return;
|
|
202
|
+
lx = x;
|
|
203
|
+
ly = y;
|
|
204
|
+
lr = ratio;
|
|
205
|
+
la = angle;
|
|
206
|
+
map.fitBounds(getSigmaViewportBounds(), {
|
|
207
|
+
duration: 0
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// When sigma is resized, resize the map, recompute zoom limit, and re-sync
|
|
209
212
|
function fnOnResize() {
|
|
210
|
-
|
|
211
|
-
|
|
213
|
+
map.resize();
|
|
214
|
+
updateMaxCameraRatio();
|
|
215
|
+
lx = NaN;
|
|
216
|
+
syncMapFromSigma();
|
|
212
217
|
}
|
|
213
218
|
|
|
214
219
|
// Clean up function to remove everything
|
|
215
220
|
function clean() {
|
|
216
221
|
if (!isKilled) {
|
|
217
222
|
isKilled = true;
|
|
218
|
-
map.off("moveend", fnSyncSigmaWithMap);
|
|
219
223
|
map.remove();
|
|
220
224
|
sigma.killLayer(mapLayerName);
|
|
221
|
-
sigma.off("afterRender",
|
|
225
|
+
sigma.off("afterRender", syncMapFromSigma);
|
|
222
226
|
sigma.off("resize", fnOnResize);
|
|
227
|
+
sigma.off("kill", clean);
|
|
223
228
|
|
|
224
229
|
// Reset settings
|
|
225
230
|
sigma.setSetting("stagePadding", prevSigmaSettings.stagePadding);
|
|
226
231
|
sigma.setSetting("enableCameraRotation", prevSigmaSettings.enableCameraRotation);
|
|
232
|
+
sigma.setSetting("maxCameraRatio", prevSigmaSettings.maxCameraRatio);
|
|
233
|
+
sigma.setSetting("cameraPanBoundaries", prevSigmaSettings.cameraPanBoundaries);
|
|
234
|
+
sigma.setCustomBBox(prevCustomBBox);
|
|
227
235
|
}
|
|
228
236
|
}
|
|
229
237
|
|
|
230
|
-
//
|
|
231
|
-
updateGraphCoordinates(sigma.getGraph());
|
|
232
|
-
|
|
233
|
-
// When the map is ready
|
|
238
|
+
// When the map is ready, start syncing
|
|
234
239
|
map.once("load", function () {
|
|
235
|
-
|
|
236
|
-
// /!\ must be done after the first map render
|
|
237
|
-
map.once("moveend", function () {
|
|
238
|
-
fnSyncSigmaWithMap();
|
|
239
|
-
});
|
|
240
|
-
// Do the first sync
|
|
241
|
-
fnSyncMapWithSigma();
|
|
242
|
-
|
|
243
|
-
// At each render of sigma, we do the map sync
|
|
244
|
-
sigma.on("afterRender", fnSyncMapWithSigma);
|
|
245
|
-
// Listen on resize
|
|
240
|
+
sigma.on("afterRender", syncMapFromSigma);
|
|
246
241
|
sigma.on("resize", fnOnResize);
|
|
247
|
-
// Do the cleanup
|
|
248
242
|
sigma.on("kill", clean);
|
|
249
|
-
// Keep sigma camera on the map
|
|
250
|
-
map.on("moveend", fnSyncSigmaWithMap);
|
|
251
243
|
});
|
|
252
244
|
return {
|
|
253
245
|
clean: clean,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sigma/layer-maplibre",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0-alpha.0",
|
|
4
4
|
"description": "A plugin to set a geographical map in background",
|
|
5
5
|
"main": "dist/sigma-layer-maplibre.cjs.js",
|
|
6
6
|
"module": "dist/sigma-layer-maplibre.esm.js",
|
|
@@ -28,14 +28,20 @@
|
|
|
28
28
|
}
|
|
29
29
|
],
|
|
30
30
|
"license": "MIT",
|
|
31
|
+
"scripts": {
|
|
32
|
+
"test": "vitest run"
|
|
33
|
+
},
|
|
31
34
|
"preconstruct": {
|
|
32
35
|
"entrypoints": [
|
|
33
36
|
"index.ts"
|
|
34
37
|
]
|
|
35
38
|
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@sigma/utils": "^4.0.0-alpha.0"
|
|
41
|
+
},
|
|
36
42
|
"peerDependencies": {
|
|
37
43
|
"maplibre-gl": "^4.5.0",
|
|
38
|
-
"sigma": ">=
|
|
44
|
+
"sigma": ">=4.0.0-alpha.0"
|
|
39
45
|
},
|
|
40
46
|
"exports": {
|
|
41
47
|
".": {
|
|
@@ -45,5 +51,5 @@
|
|
|
45
51
|
},
|
|
46
52
|
"./package.json": "./package.json"
|
|
47
53
|
},
|
|
48
|
-
"gitHead": "
|
|
54
|
+
"gitHead": "b5c8ef7ea133f5d16282db7ad99ba7c396e7b37c"
|
|
49
55
|
}
|