Component

PassMap

Pass map for raw passing direction and completion. Use it when the story is the path of individual passes, not an aggregated network. The hero uses a curated real-data pass sample from a WhoScored-derived fixture.

Passes30
Completion83%
Result
Complete
Incomplete
Playground

Interactive props.

Curated rich sample with mixed pass types and completion states.Style panel demonstrates the unified `lines` / `dots` API.Pitch theme comes from the floating controller.
Passes30
Completion83%
Result
Complete
Incomplete
Stories

Canonical behaviors.

Pass-Type Colours

Object-map styling makes pass type the visible story without introducing a second chart-local color mode prop.

Passes30
Completion83%
Completed Only

Recipe-driven subset view for clean article graphics when incomplete passes are context, not the story.

Attacking-Half Crop

Half crop keeps only passes ending in the attacking half. Defensive-half starts clip at the halfway line.

Passes158
Completion74%
Result
Complete
Incomplete
Recipient Styling

Same pass events, but line and dot styling now follow the recipient instead of completion.

Passes30
Completion83%
Crosses

Focused cross view without invisible hover targets or misleading completion chrome.

Shot Assists

Subset view for the decisive final pass. Useful when the page is pairing passes with a shot or xG explanation.

Horizontal Orientation

Wide left-to-right layout for charts that scan horizontally.

Passes30
Completion83%
Result
Complete
Incomplete
Dense Sample

Dense first-half sample. Start with the dense recipe, then crop or subset if the pass count is still too noisy for a truthful raw-pass read.

Static Export

PassMap is supported by the static export pipeline. Hover UI disappears, but the arrows and pitch stay deterministic.

CompleteIncomplete
Empty State

Pitch visible, honest copy, and no fake arrows when nothing is plottable.

Passes0
Completion
No pass data
Cross-cutting

Shared concerns.

Choose PassMap

Use PassMap when you care about individual pass trajectories. Use PassNetwork when the story is team structure after aggregation.

Clipping Semantics

Half crop filters on the pass destination, not the start point. That is why defensive-half starts can still appear clipped at the halfway line.

Themeability

Pitch theming comes from Stadia via the shared floating controller. Use pitchColors only when the page needs an explicit branded surface.

Export

PassMap is supported by the Phase 1 static export path. That is the right route for clean share cards and article-inline graphics.

Composition

PassMap owns the raw pass-layer semantics and tooltip. Keep provider parsing outside the component, then wrap the result in surrounding layout chrome if needed.

Subset Recipes

Use passMapRecipes for editorial subset views like completed-only, crosses, and shot assists. These recipes also remove the default chrome so the chart does not claim to summarise the full input set.

Dense Data

Once a single frame pushes past roughly 70-90 passes, start with the dense recipe before changing the layout. Then crop or subset the question. If the real story is territory or structure rather than raw trajectories, switch to PassFlow or PassNetwork instead of forcing more pass-map chrome.

Responsive

Normal, small, smallest.

Pitch-based charts scale fluidly to whatever width the parent gives them. The 'smallest' cell is sized for a 5×4 small-multiples grid (~140px wide). Vertical orientation only — horizontal pitches are too wide for small-multiples.

Passes30
Completion83%
Result
Complete
Incomplete
Normal
Passes30
Completion83%
Result
Complete
Incomplete
Small
Passes30
Completion83%
Result
Complete
Incomplete
Smallest (small multiples)
Usage

Best-practice examples.

Minimal usage

Use PassMap when the chart should show the raw pass directions rather than an aggregated team structure.

                    import { PassMap } from "@withqwerty/campos-react";
import type { PassEvent } from "@withqwerty/campos-schema";

type Props = {
  passes: PassEvent[];
};

export function TeamPassMap({ passes }: Props) {
  return <PassMap passes={passes} />;
}
                  
Analytical variant

Style callbacks and maps can change the pass reading without changing the pass payload.

                    import { PassMap } from "@withqwerty/campos-react";
import type { PassEvent } from "@withqwerty/campos-schema";

type Props = {
  passes: PassEvent[];
};

export function TeamPassMapAnalytical({ passes }: Props) {
  return (
    <PassMap
      passes={passes}
      lines={{
        stroke: {
          by: ({ pass }) => pass.passType ?? "unknown",
          values: {
            ground: "#2563eb",
            high: "#7c3aed",
            cross: "#dc2626",
          },
          fallback: "#64748b",
        },
      }}
      crop="half"
      attackingDirection="right"
    />
  );
}
                  
API

Public surface.

Prop Type Default Description
passes readonly PassEvent[] required Normalized pass data in canonical Campos coordinates.
crop "full" | "half" "full" Half crop keeps only passes with destinations in the attacking half.
attackingDirection "up" | "down" | "left" | "right" "up" Controls which direction of play the pitch projects toward on screen.
lines PassMapLineStyle Callback-first styling surface for pass arrows: show, stroke, strokeWidth, strokeLinecap, strokeDasharray, opacity. Supports constants, object maps, and callbacks.
dots PassMapDotStyle Callback-first styling surface for passes without end coordinates: show, fill, radius, opacity, stroke, strokeWidth.
pitchTheme "primary" | "secondary" "primary" Delegated Stadia surface preset.
pitchColors PitchColors Direct pitch color overrides for branded or editorial surfaces.
Use with AI
LLM Prompt
Create a React component using Campos PassMap. Import PassMap and passMapRecipes from @withqwerty/campos-react, keep data parsing outside the component, show the smallest good usage first, then show one recipe-driven subset view and one crop or direction variant.
Pitch