PitchKit
Guides

Layers

The mental model — a pitch container, overlay children, and typed accessors.

Five things to hold in your head — that's the whole model:

  1. <Pitch> owns the coordinate system. Declare the provider via type; every child reads the resulting transform from context.
  2. Children are layers, stacked in render order. Later siblings paint on top of earlier ones, exactly like the DOM.
  3. Accessors map your data to visuals. Every visual prop takes a static value or a typed per-datum function (d, i) => value.
  4. Colours are CSS variables — see Theming.
  5. Responsive is the default — see Responsive.
<Pitch type="statsbomb">
  <Heatmap data={pressures} x={(p) => p.x} y={(p) => p.y} binsX={12} binsY={8} />
  <Arrows data={passes} x={(p) => p.x} y={(p) => p.y} x2={(p) => p.x2} y2={(p) => p.y2} />
  <Scatter data={shots} x={(s) => s.x} y={(s) => s.y} r={(s) => 3 + s.xg * 9} />
</Pitch>

The overlay set

OverlayDrawsGood for
<Scatter>One circle per datumShots, touches, positions
<Arrows>Directional line + head per datumPass maps
<Comet>Tapered, optionally fading trailCarries, runs
<Annotate>Text label per datumPlayer names, callouts
<Heatmap>Binned grid on canvasDensity, xG surfaces
<Flow>One aggregate arrow per zonePass direction by zone
<Polygon>Arbitrary closed shapeZone highlights
<ConvexHull>Hull of a point setTeam/player shape
<Voronoi>Nearest-player tessellationSpace control
<GoalAngle>Wedge to both postsShot quality context

The accessor pattern is what keeps PitchKit shape-agnostic: there's no required data schema — x={(shot) => shot.location[0]} adapts any provider's records without a pre-processing step.

SVG vs canvas

Marks are SVG (crisp, inspectable, hoverable — most take a tooltip accessor). <Heatmap> is the exception: dense raster grids paint to a <canvas>, where a handful of fillRect calls beat thousands of DOM nodes. The split is per-layer and automatic — you compose both kinds freely in one pitch.

Escape hatch

For custom marks the built-ins don't cover, call usePitch() from any child of <Pitch> to get the pitch dimensions, viewport, and pixel transform, then emit your own SVG. The landing page's interactive hero uses it to turn clicks back into provider coordinates.

On this page