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.
Interactive props.
Canonical behaviors.
Object-map styling makes pass type the visible story without introducing a second chart-local color mode prop.
Recipe-driven subset view for clean article graphics when incomplete passes are context, not the story.
Half crop keeps only passes ending in the attacking half. Defensive-half starts clip at the halfway line.
Same pass events, but line and dot styling now follow the recipient instead of completion.
Focused cross view without invisible hover targets or misleading completion chrome.
Subset view for the decisive final pass. Useful when the page is pairing passes with a shot or xG explanation.
Wide left-to-right layout for charts that scan horizontally.
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.
PassMap is supported by the static export pipeline. Hover UI disappears, but the arrows and pitch stay deterministic.
Pitch visible, honest copy, and no fake arrows when nothing is plottable.
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.
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.
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"
/>
);
}
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. |
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.