Lattice Grid Buy a licence

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.

Building…
Loading a live grid…

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>