Pan the map and the grid follows, 1.112
A map beside a grid looks like one screen and behaves like two. Pan to the city you care about and the grid still lists every place in the country. The count above it shows the whole country. The chart does too. Someone has to type a city into a filter, by hand, to make the numbers match what is on the map, and then do it again when they pan somewhere else.
The example above is 300 places around three cities, in a grid with a map, a count and a chart bound to it. It opens on London, so the count is about a third of the total. Zoom out and it climbs as Manchester and Edinburgh come into view. Drag north to Edinburgh and it drops again, and the bars by category recount. Click a row and the map flies to it. This is 1.112: the map is no longer a picture of the grid’s rows, it is one of the things that filters them.
The map writes the filter
Set viewportFilter: true on createMapView and every move of the map writes its visible bounds onto the grid as one bounding-box filter. It is debounced, so a long drag writes once it settles, not on every frame. It is the grid’s ordinary filter, which is why everything else follows without any wiring from you.
const map = createMapView(grid, {
container: mapEl,
libs: { deck, maplibregl },
geometry: { lat: 'lat', lng: 'lng' },
viewportFilter: true,
});
It is one bounding-box condition, not a growing pile of them: each move replaces the last.
Everything bound to the grid follows
Nothing in the example copies a number from the map to the tile. The row count is a createStat over the grid, the chart is a createChart over the grid, and both read the rows the grid is showing. When the map narrows them, they recount, the same way they would if you had typed a filter into a column.
createStat({ grid, container: tileEl, title: 'Places in view', fn: 'count' });
createChart({ grid, container: chartEl, type: 'bar', x: 'category', y: { col: 'name', fn: 'count' } });
Add a second chart, a KPI strip or a list view later and they follow the map too, because they were never listening to the map in the first place.
And the other way round
A filter set from code moves the map to it. Apply a bounding box from a saved view, a link someone pasted or a sibling panel, and the map pans to meet it, instead of the two fighting over the view. Selecting a row flies the map to the row, as it always has, so a list of places and the map they sit on stay a single thing.
Both map bindings now share it
The Leaflet binding has had this option for a while. Now the deck.gl and MapLibre binding, the one that draws extruded columns, polygons and routes, takes the same viewportFilter: true. If you pick the 3D map view for its looks, you no longer give up the filter. Nothing changes for a map that does not set the option.
Over a Parquet lake
This is what lets a data grid sit over a Parquet lake. When the rows live in files rather than in the browser, you cannot hand them all to the map and the grid. The map has to say which part of the world is on screen, and the source has to answer with only that. The public data lake demo now does exactly that: it re-queries 81 million places by byte range, with DuckDB in the browser, for the window you see.
Open the example, drag from London to Manchester, and watch the count. The map view page has the options, and the changelog has the rest of 1.112.