Public
Edited
Jun 15, 2023
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
const root = DOM.element("div", {
style: `width:${dimensions.mapWidth}px; height:${dimensions.mapHeight}px;`
});

yield root;

const basemapWindow = DOM.element("div", {
id: "basemap-window",
style: `position: absolute;
right: ${dimensions.right}px;
bottom: ${dimensions.bottom}px;
width: ${dimensions.width}px;
height: ${dimensions.height}px;
background: steelblue;
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
border-radius: 0.25rem;`
});

const map = new mapboxgl.Map({
container: root,
style: "mapbox://styles/mapbox/outdoors-v12",
center: [-120.56827, 37.65],
zoom: 7,
projection: {
name: "lambertConformalConic",
center: [-120, 37],
parallels: [37 + 4 / 60, 38 + 26 / 60]
}
});

// Append the basemapWindow in the lower right corner of root.
root.appendChild(basemapWindow);

invalidation.then(() => map.remove());
}
Insert cell
Insert cell
dimensions = {
return {
width: 64,
height: 64,
right: 16,
bottom: 36,
mapWidth: width,
mapHeight: width / 1.6
};
}
Insert cell
Insert cell
Insert cell
function center(basemapWindow, root, map) {
const { top: rootTop, left: rootLeft } = root.getBoundingClientRect();
const { top, left, width, height } = basemapWindow.getBoundingClientRect();

const xCenter = left - rootLeft + width / 2;
const yCenter = top - rootTop + height / 2;

return map.unproject([xCenter, yCenter]);
}
Insert cell
{
const root = DOM.element("div", {
style: `width:${dimensions.mapWidth}px; height:${dimensions.mapHeight}px`
});

yield root;

const basemapWindow = DOM.element("div", {
id: "basemap-window",
style: `position: absolute;
right: ${dimensions.right}px;
bottom: ${dimensions.bottom}px;
width: ${dimensions.width}px;
height: ${dimensions.height}px;
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
border-radius: 0.25rem;`
});

const map = new mapboxgl.Map({
container: root,
style: "mapbox://styles/mapbox/outdoors-v12",
center: [-120.56827, 37.65],
zoom: 7,
projection: {
name: "lambertConformalConic",
center: [-120, 37],
parallels: [37 + 4 / 60, 38 + 26 / 60]
}
});

root.appendChild(basemapWindow);

// Call center to get the geographic coordinates corresponding to the center of basemapWindow.
const { lng, lat } = center(basemapWindow, root, map);

const basemapWindowMap = new mapboxgl.Map({
container: basemapWindow,
style: "mapbox://styles/mapbox/satellite-streets-v12",
center: [lng, lat],
zoom: 7,
projection: {
name: "lambertConformalConic",
center: [-120, 37],
parallels: [37 + 4 / 60, 38 + 26 / 60]
}
});

invalidation.then(() => {
map.remove();
basemapWindowMap.remove();
});
}
Insert cell
Insert cell
Insert cell
function addListeners({ map, basemapWindow, basemapWindowMap, root }) {
map.on("move", () => {
const { lng, lat } = center(basemapWindow, root, map);

basemapWindowMap.setCenter([lng, lat]);
});

map.on("zoom", (event) => {
basemapWindowMap.setZoom(event.target.getZoom());
});
}
Insert cell
{
const root = DOM.element("div", {
style: `width:${dimensions.mapWidth}px; height:${dimensions.mapHeight}px;`
});

yield root;

const basemapWindow = DOM.element("div", {
id: "basemap-window",
style: `position: absolute;
right: ${dimensions.right}px;
bottom: ${dimensions.bottom}px;
width: ${dimensions.width}px;
height: ${dimensions.height}px;
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
border-radius: 0.25rem;`
});

const map = new mapboxgl.Map({
container: root,
style: "mapbox://styles/mapbox/outdoors-v12",
center: [-120.56827, 37.65],
zoom: 7,
projection: {
name: "lambertConformalConic",
center: [-120, 37],
parallels: [37 + 4 / 60, 38 + 26 / 60]
}
});

root.appendChild(basemapWindow);

const { lng, lat } = center(basemapWindow, root, map);

const basemapWindowMap = new mapboxgl.Map({
container: basemapWindow,
style: "mapbox://styles/mapbox/satellite-streets-v12",
center: [lng, lat],
zoom: 7,
projection: {
name: "lambertConformalConic",
center: [-120, 37],
parallels: [37 + 4 / 60, 38 + 26 / 60]
}
});

// Register event listeners to update basemapWindowMap's center on pan and zoom.
addListeners({ map, basemapWindow, basemapWindowMap, root });

invalidation.then(() => {
map.remove();
basemapWindowMap.remove();
});
}
Insert cell
Insert cell
Insert cell
Insert cell
{
const root = DOM.element("div", {
style: `width:${dimensions.mapWidth}px; height:${dimensions.mapHeight}px;`
});

yield root;

const basemapWindows = locs.map(({ top, right, width, height }, i) => {
return DOM.element("div", {
id: `basemap-window-${i}`,
style: `position: absolute;
top: ${top}px;
right: ${right}px;
width: ${width}px;
height: ${height}px;
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
border-radius: 0.25rem;
`
});
});

const map = new mapboxgl.Map({
container: root,
style: "mapbox://styles/mapbox/outdoors-v12",
center: [-120.56827, 37.65],
zoom: 7,
projection: {
name: "lambertConformalConic",
center: [-120, 37],
parallels: [37 + 4 / 60, 38 + 26 / 60]
}
});

const basemaps = basemapWindows.map((basemapWindow, i) => {
root.appendChild(basemapWindow);

const { lng, lat } = center(basemapWindow, root, map);

const basemap = new mapboxgl.Map({
container: basemapWindow,
style: tileStyles[i],
center: [lng, lat],
zoom: 7,
projection: {
name: "lambertConformalConic",
center: [-120, 37],
parallels: [37 + 4 / 60, 38 + 26 / 60]
}
});

return basemap;
});

map.on("move", (event) => {
d3.zip(basemapWindows, basemaps).forEach(([basemapWindow, basemap], i) => {
const { lng, lat } = center(basemapWindow, root, map);

basemap.setCenter([lng, lat]);
});
});

map.on("zoom", (event) => {
basemaps.forEach((basemap) => {
basemap.setZoom(event.target.getZoom());
});
});

invalidation.then(() => {
map.remove();
basemaps.forEach((basemap) => basemap.remove());
});
}
Insert cell
locs = new Array(9).fill().map((_, i) => {
return {
right: padding.outside,
top: padding.outside + i * windowHeight + i * padding.between,
width: windowHeight,
height: windowHeight
};
})
Insert cell
Insert cell
windowHeight = (width / 1.6 - 2 * padding.outside - 5 * padding.between) /
tileStyles.length
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more