Skip to content

Commit

Permalink
[layer-leaflet/maplibre] when resizing keep the same center
Browse files Browse the repository at this point in the history
  • Loading branch information
sim51 committed Nov 20, 2024
1 parent fc828dc commit 7d85b82
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 7 deletions.
12 changes: 10 additions & 2 deletions packages/layer-leaflet/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,18 @@ export default function bindLeafletLayer(
// When sigma is resize, we need to update the graph coordinate (the ref has changed)
// and recompute the zoom bounds
function fnOnResize() {
map.invalidateSize();
// Ask the map to resize
// NB: resize can change the center of the map, and we want to keep it
const center = map.getCenter();
map.invalidateSize({ pan: false, animate: false, duration: 0 });
map.setView(center);

// Map ref has changed, we need to update the graph coordinates & bounds
updateGraphCoordinates(sigma.getGraph());
fnSyncSigmaWithMap();
setSigmaRatioBounds(sigma, map);

// Do the sync
fnSyncSigmaWithMap();
}

// Clean up function to remove everything
Expand Down
25 changes: 23 additions & 2 deletions packages/layer-maplibre/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,29 @@ export default function bindMaplibreLayer(
// When sigma is resize, we need to update the graph coordinate (the ref has changed)
// and recompute the zoom bounds
function fnOnResize() {
updateGraphCoordinates(sigma.getGraph());
fnSyncSigmaWithMap();
// Avoid sync map with sigma while we do the resize
// otherwise there is a sideeffect...
sigma.off("afterRender", fnSyncMapWithSigma);
const center = map.getCenter();

// Ask the map to resize
map.once("resize", () => {
// NB: resize can change the center of the map, and we want to keep it
map.setCenter(center);

// Map ref has changed, we need to update the graph coordinates
updateGraphCoordinates(sigma.getGraph());

// Do the sync
fnSyncSigmaWithMap();

// Re-enable the map sync with sigma in the next frame
setTimeout(() => {
fnSyncMapWithSigma();
sigma.on("afterRender", fnSyncMapWithSigma);
}, 0);
});
map.resize();
}

// Clean up function to remove everything
Expand Down
6 changes: 3 additions & 3 deletions packages/layer-maplibre/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,11 @@ export function graphToLatlng(map: Map, coords: { x: number; y: number }): { lat
* BBOX sync : map to sigma
*/
export function syncSigmaWithMap(sigma: Sigma, map: Map): void {
const mapBound = map.getBounds();

// Compute sigma center
const center = sigma.viewportToFramedGraph(sigma.graphToViewport(latlngToGraph(map, mapBound.getCenter())));
const center = sigma.viewportToFramedGraph(sigma.graphToViewport(latlngToGraph(map, map.getCenter())));

// Compute sigma ratio
const mapBound = map.getBounds();
const northEast = sigma.graphToViewport(latlngToGraph(map, mapBound.getNorthEast()));
const southWest = sigma.graphToViewport(latlngToGraph(map, mapBound.getSouthWest()));
const viewportBoundDimension = {
Expand All @@ -45,6 +44,7 @@ export function syncSigmaWithMap(sigma: Sigma, map: Map): void {
const ratio =
Math.min(viewportBoundDimension.width / viewportDim.width, viewportBoundDimension.height / viewportDim.height) *
sigma.getCamera().getState().ratio;

sigma.getCamera().setState({ ...center, ratio: ratio });
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* This is a minimal example of sigma. You can use it as a base to write new
* examples, or reproducible test cases for new issues, for instance.
*/
import bindLeafletLayer from "@sigma/layer-leaflet";
import Graph from "graphology";
import { Attributes, SerializedGraph } from "graphology-types";
import Sigma from "sigma";

import data from "./data/airports.json";

export default () => {
const container = document.getElementById("sigma-container") as HTMLElement;
const graph = Graph.from(data as SerializedGraph);
graph.updateEachNodeAttributes((_node, attributes) => ({
...attributes,
label: attributes.fullName,
x: 0,
y: 0,
}));

// initiate sigma
const renderer = new Sigma(graph, container, {
labelRenderedSizeThreshold: 20,
defaultNodeColor: "#e22352",
defaultEdgeColor: "#ffaeaf",
minEdgeThickness: 1,
nodeReducer: (node, attrs) => {
return {
...attrs,
size: Math.sqrt(graph.degree(node)) / 2,
};
},
});

bindLeafletLayer(renderer, {
getNodeLatLng: (attrs: Attributes) => ({ lat: attrs.latitude, lng: attrs.longitude }),
});

let isSmall = false;
const toggleButton = document.createElement("button");
toggleButton.innerText = "Toggle fullscreen";
toggleButton.style.position = "absolute";
toggleButton.style.zIndex = "1";
toggleButton.onclick = () => {
container.style.width = isSmall ? "100%" : "50%";
container.style.height = isSmall ? "100%" : "50%";
renderer.refresh({ schedule: false });
isSmall = !isSmall;
};
container.appendChild(toggleButton);

return () => {
renderer.kill();
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import basicSource from "./basic?raw";
import geojsonPlay from "./geojson";
import geojsonSource from "./geojson?raw";
import template from "./index.html?raw";
import resizePlay from "./resize";
import resizeSource from "./resize?raw";
import tilelayerPlay from "./tilelayer";
import tilelayerSource from "./tilelayer?raw";

Expand Down Expand Up @@ -49,3 +51,14 @@ export const withAGeoJson: Story = {
},
},
};

export const resize: Story = {
name: "Change dimensions",
render: () => template,
play: wrapStory(resizePlay),
parameters: {
storySource: {
source: resizeSource,
},
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* This is a minimal example of sigma. You can use it as a base to write new
* examples, or reproducible test cases for new issues, for instance.
*/
import bindMapLayer from "@sigma/layer-maplibre";
import Graph from "graphology";
import { Attributes, SerializedGraph } from "graphology-types";
import Sigma from "sigma";

import data from "./data/airports.json";

export default () => {
const container = document.getElementById("sigma-container") as HTMLElement;
const graph = Graph.from(data as SerializedGraph);
graph.updateEachNodeAttributes((_node, attributes) => ({
...attributes,
label: attributes.fullName,
x: 0,
y: 0,
}));

// initiate sigma
const renderer = new Sigma(graph, container, {
labelRenderedSizeThreshold: 20,
defaultNodeColor: "#e22352",
defaultEdgeColor: "#ffaeaf",
minEdgeThickness: 1,
nodeReducer: (node, attrs) => {
return {
...attrs,
size: Math.sqrt(graph.degree(node)) / 2,
};
},
});

bindMapLayer(renderer, {
getNodeLatLng: (attrs: Attributes) => ({ lat: attrs.latitude, lng: attrs.longitude }),
});

let isSmall = false;
const toggleButton = document.createElement("button");
toggleButton.innerText = "Toggle fullscreen";
toggleButton.style.position = "absolute";
toggleButton.style.zIndex = "1";
toggleButton.onclick = () => {
container.style.width = isSmall ? "100%" : "50%";
container.style.height = isSmall ? "100%" : "50%";
renderer.refresh({ schedule: false });
isSmall = !isSmall;
};
container.appendChild(toggleButton);

return () => {
renderer.kill();
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import basicSource from "./basic?raw";
import geojsonPlay from "./geojson";
import geojsonSource from "./geojson?raw";
import template from "./index.html?raw";
import resizePlay from "./resize";
import resizeSource from "./resize?raw";

const meta: Meta = {
id: "@sigma/layer-maplibre",
Expand Down Expand Up @@ -36,3 +38,14 @@ export const withAGeoJson: Story = {
},
},
};

export const resize: Story = {
name: "Change dimensions",
render: () => template,
play: wrapStory(resizePlay),
parameters: {
storySource: {
source: resizeSource,
},
},
};

0 comments on commit 7d85b82

Please sign in to comment.