@sigma/layer-maplibre 3.0.0 → 4.0.0-alpha.1
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 +118 -146
- package/dist/sigma-layer-maplibre.cjs.prod.js +118 -146
- package/dist/sigma-layer-maplibre.esm.js +119 -147
- package/package.json +9 -3
package/LICENSE.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Copyright (C)
|
|
1
|
+
Copyright (C) 2012-2026, 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,59 +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
|
-
// 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
78
|
/**
|
|
132
79
|
* On the graph, we store the 2D projection of the geographical lat/long.
|
|
133
80
|
*
|
|
@@ -139,40 +86,26 @@ function bindMaplibreLayer(sigma, opts) {
|
|
|
139
86
|
// Keeping data for the cleanup
|
|
140
87
|
var isKilled = false;
|
|
141
88
|
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) || {}));
|
|
89
|
+
var prevCustomBBox = sigma.getCustomBBox();
|
|
164
90
|
|
|
165
91
|
// `stagePadding: 0` is mandatory, so the bbox of the map & Sigma is the same.
|
|
166
92
|
sigma.setSetting("stagePadding", 0);
|
|
167
|
-
|
|
168
93
|
// disable camera rotation
|
|
169
94
|
sigma.setSetting("enableCameraRotation", false);
|
|
170
95
|
|
|
171
|
-
//
|
|
172
|
-
//
|
|
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
|
|
173
106
|
function updateGraphCoordinates(graph) {
|
|
174
107
|
graph.updateEachNodeAttributes(function (_node, attrs) {
|
|
175
|
-
var coords = latlngToGraph(
|
|
108
|
+
var coords = latlngToGraph(opts !== null && opts !== void 0 && opts.getNodeLatLng ? opts.getNodeLatLng(attrs) : {
|
|
176
109
|
lat: attrs.lat,
|
|
177
110
|
lng: attrs.lng
|
|
178
111
|
});
|
|
@@ -183,95 +116,134 @@ function bindMaplibreLayer(sigma, opts) {
|
|
|
183
116
|
});
|
|
184
117
|
}
|
|
185
118
|
|
|
186
|
-
//
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}
|
|
119
|
+
// Update graph coordinates and refresh sigma so normalization is ready
|
|
120
|
+
updateGraphCoordinates(sigma.getGraph());
|
|
121
|
+
sigma.refresh();
|
|
190
122
|
|
|
191
|
-
//
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
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
|
-
}
|
|
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()));
|
|
208
128
|
}
|
|
209
129
|
|
|
210
|
-
//
|
|
211
|
-
//
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
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]
|
|
136
|
+
}
|
|
137
|
+
});
|
|
217
138
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
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
|
+
}
|
|
222
168
|
|
|
223
|
-
|
|
224
|
-
|
|
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);
|
|
225
180
|
|
|
226
|
-
|
|
227
|
-
|
|
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
|
+
}));
|
|
228
191
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
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
|
|
234
212
|
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// When sigma is resized, resize the map, recompute zoom limit, and re-sync
|
|
216
|
+
function fnOnResize() {
|
|
235
217
|
map.resize();
|
|
218
|
+
updateMaxCameraRatio();
|
|
219
|
+
lx = NaN;
|
|
220
|
+
syncMapFromSigma();
|
|
236
221
|
}
|
|
237
222
|
|
|
238
223
|
// Clean up function to remove everything
|
|
239
224
|
function clean() {
|
|
240
225
|
if (!isKilled) {
|
|
241
226
|
isKilled = true;
|
|
242
|
-
map.off("moveend", fnSyncSigmaWithMap);
|
|
243
227
|
map.remove();
|
|
244
228
|
sigma.killLayer(mapLayerName);
|
|
245
|
-
sigma.off("afterRender",
|
|
229
|
+
sigma.off("afterRender", syncMapFromSigma);
|
|
246
230
|
sigma.off("resize", fnOnResize);
|
|
231
|
+
sigma.off("kill", clean);
|
|
247
232
|
|
|
248
233
|
// Reset settings
|
|
249
234
|
sigma.setSetting("stagePadding", prevSigmaSettings.stagePadding);
|
|
250
235
|
sigma.setSetting("enableCameraRotation", prevSigmaSettings.enableCameraRotation);
|
|
236
|
+
sigma.setSetting("maxCameraRatio", prevSigmaSettings.maxCameraRatio);
|
|
237
|
+
sigma.setSetting("cameraPanBoundaries", prevSigmaSettings.cameraPanBoundaries);
|
|
238
|
+
sigma.setCustomBBox(prevCustomBBox);
|
|
251
239
|
}
|
|
252
240
|
}
|
|
253
241
|
|
|
254
|
-
//
|
|
255
|
-
updateGraphCoordinates(sigma.getGraph());
|
|
256
|
-
|
|
257
|
-
// When the map is ready
|
|
242
|
+
// When the map is ready, start syncing
|
|
258
243
|
map.once("load", function () {
|
|
259
|
-
|
|
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
|
|
244
|
+
sigma.on("afterRender", syncMapFromSigma);
|
|
270
245
|
sigma.on("resize", fnOnResize);
|
|
271
|
-
// Do the cleanup
|
|
272
246
|
sigma.on("kill", clean);
|
|
273
|
-
// Keep sigma camera on the map
|
|
274
|
-
map.on("moveend", fnSyncSigmaWithMap);
|
|
275
247
|
});
|
|
276
248
|
return {
|
|
277
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,59 +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
|
-
// 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
78
|
/**
|
|
132
79
|
* On the graph, we store the 2D projection of the geographical lat/long.
|
|
133
80
|
*
|
|
@@ -139,40 +86,26 @@ function bindMaplibreLayer(sigma, opts) {
|
|
|
139
86
|
// Keeping data for the cleanup
|
|
140
87
|
var isKilled = false;
|
|
141
88
|
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) || {}));
|
|
89
|
+
var prevCustomBBox = sigma.getCustomBBox();
|
|
164
90
|
|
|
165
91
|
// `stagePadding: 0` is mandatory, so the bbox of the map & Sigma is the same.
|
|
166
92
|
sigma.setSetting("stagePadding", 0);
|
|
167
|
-
|
|
168
93
|
// disable camera rotation
|
|
169
94
|
sigma.setSetting("enableCameraRotation", false);
|
|
170
95
|
|
|
171
|
-
//
|
|
172
|
-
//
|
|
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
|
|
173
106
|
function updateGraphCoordinates(graph) {
|
|
174
107
|
graph.updateEachNodeAttributes(function (_node, attrs) {
|
|
175
|
-
var coords = latlngToGraph(
|
|
108
|
+
var coords = latlngToGraph(opts !== null && opts !== void 0 && opts.getNodeLatLng ? opts.getNodeLatLng(attrs) : {
|
|
176
109
|
lat: attrs.lat,
|
|
177
110
|
lng: attrs.lng
|
|
178
111
|
});
|
|
@@ -183,95 +116,134 @@ function bindMaplibreLayer(sigma, opts) {
|
|
|
183
116
|
});
|
|
184
117
|
}
|
|
185
118
|
|
|
186
|
-
//
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}
|
|
119
|
+
// Update graph coordinates and refresh sigma so normalization is ready
|
|
120
|
+
updateGraphCoordinates(sigma.getGraph());
|
|
121
|
+
sigma.refresh();
|
|
190
122
|
|
|
191
|
-
//
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
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
|
-
}
|
|
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()));
|
|
208
128
|
}
|
|
209
129
|
|
|
210
|
-
//
|
|
211
|
-
//
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
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]
|
|
136
|
+
}
|
|
137
|
+
});
|
|
217
138
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
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
|
+
}
|
|
222
168
|
|
|
223
|
-
|
|
224
|
-
|
|
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);
|
|
225
180
|
|
|
226
|
-
|
|
227
|
-
|
|
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
|
+
}));
|
|
228
191
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
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
|
|
234
212
|
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// When sigma is resized, resize the map, recompute zoom limit, and re-sync
|
|
216
|
+
function fnOnResize() {
|
|
235
217
|
map.resize();
|
|
218
|
+
updateMaxCameraRatio();
|
|
219
|
+
lx = NaN;
|
|
220
|
+
syncMapFromSigma();
|
|
236
221
|
}
|
|
237
222
|
|
|
238
223
|
// Clean up function to remove everything
|
|
239
224
|
function clean() {
|
|
240
225
|
if (!isKilled) {
|
|
241
226
|
isKilled = true;
|
|
242
|
-
map.off("moveend", fnSyncSigmaWithMap);
|
|
243
227
|
map.remove();
|
|
244
228
|
sigma.killLayer(mapLayerName);
|
|
245
|
-
sigma.off("afterRender",
|
|
229
|
+
sigma.off("afterRender", syncMapFromSigma);
|
|
246
230
|
sigma.off("resize", fnOnResize);
|
|
231
|
+
sigma.off("kill", clean);
|
|
247
232
|
|
|
248
233
|
// Reset settings
|
|
249
234
|
sigma.setSetting("stagePadding", prevSigmaSettings.stagePadding);
|
|
250
235
|
sigma.setSetting("enableCameraRotation", prevSigmaSettings.enableCameraRotation);
|
|
236
|
+
sigma.setSetting("maxCameraRatio", prevSigmaSettings.maxCameraRatio);
|
|
237
|
+
sigma.setSetting("cameraPanBoundaries", prevSigmaSettings.cameraPanBoundaries);
|
|
238
|
+
sigma.setCustomBBox(prevCustomBBox);
|
|
251
239
|
}
|
|
252
240
|
}
|
|
253
241
|
|
|
254
|
-
//
|
|
255
|
-
updateGraphCoordinates(sigma.getGraph());
|
|
256
|
-
|
|
257
|
-
// When the map is ready
|
|
242
|
+
// When the map is ready, start syncing
|
|
258
243
|
map.once("load", function () {
|
|
259
|
-
|
|
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
|
|
244
|
+
sigma.on("afterRender", syncMapFromSigma);
|
|
270
245
|
sigma.on("resize", fnOnResize);
|
|
271
|
-
// Do the cleanup
|
|
272
246
|
sigma.on("kill", clean);
|
|
273
|
-
// Keep sigma camera on the map
|
|
274
|
-
map.on("moveend", fnSyncSigmaWithMap);
|
|
275
247
|
});
|
|
276
248
|
return {
|
|
277
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,59 +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
|
-
// 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
74
|
/**
|
|
128
75
|
* On the graph, we store the 2D projection of the geographical lat/long.
|
|
129
76
|
*
|
|
@@ -135,40 +82,26 @@ function bindMaplibreLayer(sigma, opts) {
|
|
|
135
82
|
// Keeping data for the cleanup
|
|
136
83
|
var isKilled = false;
|
|
137
84
|
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) || {}));
|
|
85
|
+
var prevCustomBBox = sigma.getCustomBBox();
|
|
160
86
|
|
|
161
87
|
// `stagePadding: 0` is mandatory, so the bbox of the map & Sigma is the same.
|
|
162
88
|
sigma.setSetting("stagePadding", 0);
|
|
163
|
-
|
|
164
89
|
// disable camera rotation
|
|
165
90
|
sigma.setSetting("enableCameraRotation", false);
|
|
166
91
|
|
|
167
|
-
//
|
|
168
|
-
//
|
|
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
|
|
169
102
|
function updateGraphCoordinates(graph) {
|
|
170
103
|
graph.updateEachNodeAttributes(function (_node, attrs) {
|
|
171
|
-
var coords = latlngToGraph(
|
|
104
|
+
var coords = latlngToGraph(opts !== null && opts !== void 0 && opts.getNodeLatLng ? opts.getNodeLatLng(attrs) : {
|
|
172
105
|
lat: attrs.lat,
|
|
173
106
|
lng: attrs.lng
|
|
174
107
|
});
|
|
@@ -179,95 +112,134 @@ function bindMaplibreLayer(sigma, opts) {
|
|
|
179
112
|
});
|
|
180
113
|
}
|
|
181
114
|
|
|
182
|
-
//
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
115
|
+
// Update graph coordinates and refresh sigma so normalization is ready
|
|
116
|
+
updateGraphCoordinates(sigma.getGraph());
|
|
117
|
+
sigma.refresh();
|
|
186
118
|
|
|
187
|
-
//
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
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
|
-
}
|
|
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()));
|
|
204
124
|
}
|
|
205
125
|
|
|
206
|
-
//
|
|
207
|
-
//
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
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]
|
|
132
|
+
}
|
|
133
|
+
});
|
|
213
134
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
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));
|
|
163
|
+
}
|
|
218
164
|
|
|
219
|
-
|
|
220
|
-
|
|
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);
|
|
221
176
|
|
|
222
|
-
|
|
223
|
-
|
|
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
|
+
}));
|
|
224
187
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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
|
|
230
208
|
});
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// When sigma is resized, resize the map, recompute zoom limit, and re-sync
|
|
212
|
+
function fnOnResize() {
|
|
231
213
|
map.resize();
|
|
214
|
+
updateMaxCameraRatio();
|
|
215
|
+
lx = NaN;
|
|
216
|
+
syncMapFromSigma();
|
|
232
217
|
}
|
|
233
218
|
|
|
234
219
|
// Clean up function to remove everything
|
|
235
220
|
function clean() {
|
|
236
221
|
if (!isKilled) {
|
|
237
222
|
isKilled = true;
|
|
238
|
-
map.off("moveend", fnSyncSigmaWithMap);
|
|
239
223
|
map.remove();
|
|
240
224
|
sigma.killLayer(mapLayerName);
|
|
241
|
-
sigma.off("afterRender",
|
|
225
|
+
sigma.off("afterRender", syncMapFromSigma);
|
|
242
226
|
sigma.off("resize", fnOnResize);
|
|
227
|
+
sigma.off("kill", clean);
|
|
243
228
|
|
|
244
229
|
// Reset settings
|
|
245
230
|
sigma.setSetting("stagePadding", prevSigmaSettings.stagePadding);
|
|
246
231
|
sigma.setSetting("enableCameraRotation", prevSigmaSettings.enableCameraRotation);
|
|
232
|
+
sigma.setSetting("maxCameraRatio", prevSigmaSettings.maxCameraRatio);
|
|
233
|
+
sigma.setSetting("cameraPanBoundaries", prevSigmaSettings.cameraPanBoundaries);
|
|
234
|
+
sigma.setCustomBBox(prevCustomBBox);
|
|
247
235
|
}
|
|
248
236
|
}
|
|
249
237
|
|
|
250
|
-
//
|
|
251
|
-
updateGraphCoordinates(sigma.getGraph());
|
|
252
|
-
|
|
253
|
-
// When the map is ready
|
|
238
|
+
// When the map is ready, start syncing
|
|
254
239
|
map.once("load", function () {
|
|
255
|
-
|
|
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
|
|
240
|
+
sigma.on("afterRender", syncMapFromSigma);
|
|
266
241
|
sigma.on("resize", fnOnResize);
|
|
267
|
-
// Do the cleanup
|
|
268
242
|
sigma.on("kill", clean);
|
|
269
|
-
// Keep sigma camera on the map
|
|
270
|
-
map.on("moveend", fnSyncSigmaWithMap);
|
|
271
243
|
});
|
|
272
244
|
return {
|
|
273
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.1",
|
|
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.1"
|
|
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": "629d2d5400b721c001f4301a244f2f4f74565961"
|
|
49
55
|
}
|