Skip to content

Sizing

Both engines are responsive by default and resize in place — when their container changes size they reconcile the rendering surface and re-render without tearing down, so the view, layers, hover, and selection all survive. Which mode you get depends on the props you pass to plot() / geoMap() (or the React <Plot> / <GeoMap>). The three demos below each sit in a drag-to-resize box so you can feel the difference — resize them and watch the map react live. See the Sizing reference for the full rundown.

Pass both width and height for a static pixel box. The map ignores its container — drag the parent below and the map stays exactly 320 × 200. This is the opt-out from responsive sizing (the pre-responsive behavior), useful when you need a guaranteed export size or a pixel-locked layout.

resizable parent (the map ignores it) — drag the bottom-right corner to resize

FixedSize.tsx
import { geoNaturalEarth1 } from "d3-geo";
import { GeoMap } from "@mapequation/d3gl/react";
import { fitProjection } from "@mapequation/d3gl/geo";
import { ResizableBox } from "../../components/ResizableBox.js";
import { addWorld } from "./world.js";
const WIDTH = 320;
const HEIGHT = 200;
/**
* Fixed mode — pass both `width` and `height`. The map is a static pixel box; it ignores
* its container, so as you drag the (larger) parent it stays put. This is the opt-out from
* responsive sizing (the pre-responsive behavior).
*/
export default function FixedSize() {
return (
<ResizableBox resize="both" initialWidth={440} initialHeight={300} label="resizable parent (the map ignores it)">
<GeoMap
width={WIDTH}
height={HEIGHT}
backend="canvas"
projection={fitProjection(geoNaturalEarth1(), { type: "Sphere" }, WIDTH, HEIGHT)}
onReady={addWorld}
/>
</ResizableBox>
);
}

Pass nothing and the map fills its parent box on both axes — the parent must supply a height (here the resizable box does). Drag the corner: the engine resizes in place and geoMap refits the projection to the new box, so the world keeps filling it whatever the shape. This is the right mode for a map that should occupy a flex/grid cell or a full-bleed panel.

resizable parent (map fills it) — drag the bottom-right corner to resize

FillParent.tsx
import { geoNaturalEarth1 } from "d3-geo";
import { GeoMap } from "@mapequation/d3gl/react";
import { fitProjection } from "@mapequation/d3gl/geo";
import { ResizableBox } from "../../components/ResizableBox.js";
import { addWorld } from "./world.js";
const W = 380;
const H = 240;
/**
* Fill-parent mode — pass no `width`/`height`/`aspectRatio`. The map fills its parent box
* on both axes (the parent must supply a height). Drag the corner: the engine resizes in
* place and refits the projection to the new box, so the world keeps filling it.
*/
export default function FillParent() {
return (
<ResizableBox resize="both" initialWidth={W} initialHeight={H} label="resizable parent (map fills it)">
<GeoMap
backend="canvas"
projection={fitProjection(geoNaturalEarth1(), { type: "Sphere" }, W, H)}
onReady={addWorld}
/>
</ResizableBox>
);
}

Pass aspectRatio (width ÷ height) and the map fills the available width while keeping that ratio — its height is derived, not set. Drag the right edge: the width changes, the height follows, and the projection rescales uniformly, preserving the framing exactly. This is the most common choice for an embedded map or chart that should stay proportional as the column it lives in grows and shrinks.

resizable width (height follows the ratio) — drag the right edge to resize

AspectRatio.tsx
import { geoNaturalEarth1 } from "d3-geo";
import { GeoMap } from "@mapequation/d3gl/react";
import { fitProjection } from "@mapequation/d3gl/geo";
import { ResizableBox } from "../../components/ResizableBox.js";
import { addWorld } from "./world.js";
const W = 380;
const RATIO = 2; // width ÷ height
/**
* Aspect-ratio mode — pass `aspectRatio`. The map fills the available width and derives its
* height from the ratio, so it stays proportional. Drag the right edge (width only): the
* height tracks automatically and the projection rescales, preserving the framing exactly.
*/
export default function AspectRatio() {
return (
<ResizableBox resize="horizontal" initialWidth={W} label="resizable width (height follows the ratio)">
<GeoMap
aspectRatio={RATIO}
backend="canvas"
projection={fitProjection(geoNaturalEarth1(), { type: "Sphere" }, W, W / RATIO)}
onReady={addWorld}
/>
</ResizableBox>
);
}