demo D228
Confidence intervals, charted in React
The mean lead time of each supplier with its 95% interval as a whisker, and a tile that narrows as you filter
grid.statistics.interval(col) · chart error: true
This grid charts each supplier's mean lead time with its 95 percent interval as a whisker, and a tile that narrows as you filter. It shows not just the average but how sure of it you can be, so a difference within the noise does not read as real.
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.107.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.107.0/lattice-grid.esm.min.js';
import { createLatticeReact } from 'https://cdn.latticegrid.dev/lattice-grid@1.107.0/modules/react.esm.min.js';
import { createChart } from 'https://cdn.latticegrid.dev/lattice-grid@1.107.0/modules/charts.esm.min.js';
const { LatticeGrid, LatticeChart } = createLatticeReact({ React, createGrid, createChart });
const columns = [
{ field: 'supplier', title: 'Supplier', filter: { type: 'set' } },
{ field: 'days', title: 'Lead time', type: 'number', format: { suffix: ' d', decimals: 1 }, total: 'avg' },
];
const rows = [/* e.g. [{ id: 'O0', supplier: 'Kestrel', days: 3.1 }, ...] */];
function App() {
const [grid, setGrid] = React.useState(null);
// The stat tile has no React component of its own, so it is still built
// imperatively against the live grid, the moment the ref arrives.
React.useEffect(() => {
if (!grid) return;
const tile = document.getElementById('tiles').appendChild(document.createElement('div'));
import('https://cdn.latticegrid.dev/lattice-grid@1.107.0/lattice-grid.esm.min.js').then(({ createStat }) => {
createStat({ grid, container: tile, title: 'Mean lead time', of: 'days', fn: 'avg',
interval: (value, g) => g.statistics.interval('days'), footer: '95% confidence interval' });
});
return () => { tile.remove(); };
}, [grid]);
return (
<>
{/* error: true draws each mean's interval as a whisker, computed from the
readings behind the bar. The chart reads the same grid as the tile, so
the bars and the whiskers follow the filters. */}
{grid && (
<LatticeChart
grid={grid}
type="bar"
x="supplier"
y={{ col: 'days', fn: 'avg' }}
error
title="Mean lead time by supplier, with confidence interval"
style={{ height: '250px' }}
/>
)}
<div id="tiles" style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '12px', margin: '14px 0' }} />
<LatticeGrid
rowKey="id"
toolPanel={{ side: 'left', panels: ['filters', 'columns', 'statistics'] }}
columns={columns}
rows={rows}
onGridReady={setGrid}
style={{ height: '340px' }}
/>
</>
);
}
createRoot(document.getElementById('app')).render(<App />);
</script>