demo D226
Joining a second grid in React
Orders carry a customer id but no tier; a join brings it across from a customers grid, then groups revenue by tier
join: { with, on, select }
Here orders carry a customer id but no tier, and a join brings the tier across from a separate customers grid, then groups revenue by it. It lets you enrich one dataset from another and report on the combined result, without flattening the two together beforehand.
This is the React version. The grid mounts through the createLatticeGrid adapter, which takes its configuration as ordinary props and hands back the live grid through a ref. The grid below is the same one every other tab runs.
The configuration
<link rel="stylesheet" href="https://cdn.latticegrid.dev/lattice-grid@1.108.0/lattice-grid.min.css">
<div id="app"></div>
<script type="module">
import React from 'https://esm.sh/react@18';
import { createRoot } from 'https://esm.sh/react-dom@18/client';
import { createGrid } from 'https://cdn.latticegrid.dev/lattice-grid@1.108.0/lattice-grid.esm.min.js';
import createLatticeGrid from 'https://cdn.latticegrid.dev/lattice-grid@1.108.0/modules/react.esm.min.js';
const LatticeGrid = createLatticeGrid({ React, createGrid });
const USD = { style: 'currency', currency: 'USD', decimals: 0 };
// The two sides: orders carry a customerId, and the tier lives on the customer.
const customerColumns = [
{ field: 'id', title: 'ID' },
{ field: 'name', title: 'Customer' },
{ field: 'tier', title: 'Tier' },
];
const orderColumns = [
{ field: 'customerId', title: 'Customer' },
{ field: 'region', title: 'Region', filter: { type: 'set' } },
{ field: 'amount', title: 'Value', type: 'number', format: USD, total: 'sum' },
];
const byTierColumns = [
{ field: 'tier', title: 'Tier' },
{ field: 'revenue', title: 'Revenue', type: 'number', format: USD },
{ field: 'orders', title: 'Orders', type: 'number' },
];
const customerRows = [/* [{ id: 'C0', name: 'Acme', tier: 'Enterprise' }, ...] */];
const orderRows = [/* [{ id: 'O0', customerId: 'C0', region: 'EMEA', amount: 1240 }, ...] */];
function App() {
const ordersRef = React.useRef(null);
const customersRef = React.useRef(null);
const [derived, setDerived] = React.useState(null);
// The join brings tier across from the customers grid onto each order,
// matching customerId to id, then the group runs on that brought-across
// field. Both sides are live instances, reached through their refs, so the
// roll-up follows the filters on the orders grid.
React.useEffect(() => {
const orders = ordersRef.current && ordersRef.current.grid;
const customers = customersRef.current && customersRef.current.grid;
if (orders && customers) {
setDerived({
mode: 'derived', from: orders, follow: 'filtered', refresh: 'live',
join: { with: customers, on: { left: 'customerId', right: 'id' }, select: ['tier'] },
groupBy: 'tier',
select: { revenue: { of: 'amount', fn: 'sum' }, orders: { fn: 'count' } },
sort: [{ col: 'revenue', dir: 'desc' }],
});
}
}, []);
return (
<>
<div style={{ display: 'flex', gap: '16px' }}>
<LatticeGrid
ref={ordersRef}
rowKey="id"
toolPanel={{ side: 'left', panels: ['filters', 'columns'] }}
columns={orderColumns}
rows={orderRows}
style={{ flex: 2, height: '300px' }}
/>
<LatticeGrid
ref={customersRef}
rowKey="id"
columns={customerColumns}
rows={customerRows}
style={{ flex: 1, height: '300px' }}
/>
</div>
{derived && (
<LatticeGrid
autoHeight
source={derived}
columns={byTierColumns}
style={{ marginTop: '16px' }}
/>
)}
</>
);
}
createRoot(document.getElementById('app')).render(<App />);
</script>