developer guide
Leaflet as a Viewer of a JavaScript Data Grid
Your grid's rows, drawn by your own Leaflet layers, over your own map. The grid never imports Leaflet and Leaflet never imports the grid; bindLeaflet is the one connection between them, the same contract bindDeck already keeps with deck.gl.
bindLeaflet: one function, two-way
Import the Leaflet module and hand bindLeaflet a live grid and the L.Map 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 { bindLeaflet } from '@toclocoinc/lattice-grid/modules/leaflet';
const binding = bindLeaflet(grid, {
map, // your own L.Map
position: { lon: 'lon', lat: 'lat' }, // or geometry: '<col>'
viewportFilter: true,
layers: (rows, ctx) => [
L.geoJSON(ctx.features), // exactly the rows the grid currently shows
],
});
// layers is your own function, written against your own Leaflet classes; the
// module never imports Leaflet itself. It runs whenever the rows or the
// selection change, and its result replaces the previous layers on the map.
The map's own pan and zoom, as a filter
With viewportFilter on, every moveend/zoomend, including your own
setView, fitBounds or flyTo, writes one withinBbox
condition back onto the grid, replacing only its own previous one; a box set from elsewhere moves the map
to match it in turn.
Rows inside the view, from a paged source
Bound to a paged pushdown source, bindLeaflet asks the engine for the rows inside the map'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 the map's current view
// from the engine, not only the loaded page:
bindLeaflet(grid, { map, 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, id set to the row key.
Selection, both ways
A click on a feature drawn from ctx.features selects its row on the grid. For a layer of your
own that carries no feature, binding.select(key) does the same from code; ctx.selected
lets your layers function mark whichever row the grid has selected.
// A click on a feature of L.geoJSON(ctx.features) selects its row on its
// own. For a layer that carries no feature of its own:
binding.select(rowKey); // null clears the selection
// The grid needs selection: 'single' or 'multiple'.
binding.destroy(); // removes the layers, the viewport condition, and the map and grid listeners
See it running in the Leaflet demo repository. The deck.gl guide covers the same binding contract over deck.gl, and the geospatial guide covers the geometry column type that feeds both.