developer guide
deck.gl as a Viewer of a JavaScript Data Grid
Your grid's rows, drawn by your own deck.gl layers, over your own map. The grid never imports deck.gl and deck.gl never imports the grid; bindDeck is the one connection between them.
bindDeck: one function, two-way
Import the deck.gl module and hand bindDeck a live grid and the deck.gl Deck
instance a page has already built. Your own layers function is called with the rows the grid
currently shows, so a filter, a sort or a live update reaches the map the same frame it reaches the table.
import { bindDeck } from '@toclocoinc/lattice-grid/modules/deckgl';
const binding = bindDeck(grid, {
deck, // your own deck.gl Deck (or a React DeckGL's .deck)
position: { lon: 'lon', lat: 'lat' }, // or geometry: '<col>'
viewportFilter: true,
layers: (rows, ctx) => [
new ScatterplotLayer({
id: 'rows',
data: rows, // exactly the rows the grid currently shows
getPosition: (r) => [r.lon, r.lat],
getRadius: 4000,
}),
],
});
// layers is your own function, written against your own deck.gl classes; the
// module never imports deck.gl itself. It is called with the rows the grid
// shows and its result goes straight to deck.setProps({ layers }).
The map's own pan and zoom, as a filter
With viewportFilter on, every pan and zoom writes one withinBbox condition back
onto the grid, the same condition the built-in maps write, replacing only its own previous one; a box set
from elsewhere pans the map to match it in turn.
Rows inside the view, from a paged source
Bound to a paged pushdown source, bindDeck asks the engine for the rows inside deck's current
view rather than only the loaded page, and falls back to density cells past a row cap.
// A paged pushdown grid hands over the rows inside deck's current view from
// the engine, the same question the built-in maps ask, not only the loaded
// page:
bindDeck(grid, { deck, position: { lon: 'lon', lat: 'lat' }, viewportCap: 20000, layers });
// Past viewportCap, ctx.binned is true and the engine hands over density
// cells instead of individual rows. ctx.features carries the rows as GeoJSON
// features and ctx.provenance says what was handed over.
binding.destroy(); // removes the viewport-filter binding and stops updating layers
See it running: a deck.gl scatterplot over a MapLibre basemap, drawing straight from the grid. The geospatial guide covers the built-in maps and the geometry column type that also feeds this binding.