Pool Window Viz

A single-window pooling visualisation: render one k×k patch of values, an arrow labelled with the chosen operator (max, avg, min), and the reduced result. In max / min mode the contributing cell glows so the link between input and output is explicit.

This is the focused counterpart to Pooling Explorer: use PoolWindowViz when you need to show what pooling does to one patch; use PoolingExplorer when you need to show how the window slides over an entire feature map.

Pool window: 3×3 input, Max pool.Max pool of a 3×3 window = 8.
Window (3×3)
1
3
2
0
8
4
2
1
5
max
Result
8
Customize
Pooling
max
Layout
40

Installation

npx shadcn@latest add https://craftbits.dev/r/pool-window-viz.json

Usage

import { PoolWindowViz } from "@craft-bits/core";
 
const window = [
  [1, 3, 2],
  [0, 8, 4],
  [2, 1, 5],
];
 
<PoolWindowViz windowValues={window} defaultPool="max" />;

Drive the pool op from outside the component:

const [pool, setPool] = useState<"max" | "avg" | "min">("max");
 
<PoolWindowViz
  windowValues={window}
  pool={pool}
  onPoolChange={setPool}
/>;

Render just the window grid (no arrow, no result cell):

<PoolWindowViz windowValues={window} showOperation={false} />;

Understanding the component

  1. One window, one result. Unlike PoolingExplorer, this primitive does not slide. It renders one k×k patch and one reduced value — a single zoomed-in pooling step rather than a full sweep.
  2. Three reductions. max returns the largest value in the window; min the smallest; avg the arithmetic mean (rounded to two decimals). For max and min, the cell(s) matching the extreme value glow as "contributing" — avg treats every cell equally so no single cell wins.
  3. Translucent magnitude tint. Each window cell is tinted via oklch(from var(--cb-accent) l c h / α) where α scales with |value| — high-magnitude cells stand out before any operator is applied.
  4. Contributing-cell highlight. For max / min, the winning cell gets an inset 2px --cb-accent ring and a scale(1.04) springs up via SPRINGS.smooth. The output result cell sits to the right, framed in the same accent.
  5. Optional operation. showOperation defaults to true and renders the arrow + operator + result column. Set to false if you want just the window grid in another layout.
  6. Reduced motion. With prefers-reduced-motion: reduce, the contributing-cell highlight snaps with no spring; the rest of the figure is static anyway.

Props

PropTypeDefaultDescription
windowValuesreadonly (readonly number[])[]required2D window of values (e.g. a 3×3 patch).
pool"max" | "avg" | "min"Controlled pooling op.
defaultPool"max" | "avg" | "min""max"Uncontrolled initial pooling op.
onPoolChange(pool) => voidFires when the pooling op changes.
showOperationbooleantrueRender the arrow with the operator label and the result cell.
cellSizenumber40Pixel size of a window cell.
transitionTransitionSPRINGS.smoothSpring for the contributing-cell highlight.
classNamestringMerged onto the root <div> via cn().

Accessibility

  • The figure is role="figure" with a visually hidden caption announcing the window dimensions and the pooling op.
  • An aria-live="polite" summary announces the reduced value whenever the pool op changes.
  • Color is never the only signal — every window cell renders its numeric value, the contributing cell gets a 2px inset accent ring, and the result cell is framed by a solid --cb-accent border with its numeric value inside.
  • prefers-reduced-motion: reduce snaps the contributing-cell highlight with no spring.

Credits

  • Extracted from: craftingattention (app/src/lessons/primitives/nn/PoolWindowViz.tsx). Stripped the lesson-specific 4×4 sliding-window scaffolding (POSITIONS array, visited/modesSeen tracking, phase narration, auto-scan timer chain, ChallengeBtn toolbar) and the hardcoded INPUT_GRID. Generalised to a pure single-window primitive: arbitrary windowValues, controlled + uncontrolled pool, and an optional showOperation arrow + result column. Aligns with PoolingExplorer's PoolingOp family by adding min for symmetry.