phaseMapSnapshot(s)()
returns PhaseMapSnapshot[] Reusable output/cost quadrant-map packets.
Visual packets notes: Quadrant-map packet only; output/cost scoring stays outside Campos.
The Visual adapter packages analysis-ready shapes that are not raw provider feeds: phase maps and player surfaces. It is the seam for dashboard packets that should be reusable across apps while leaving scoring, calibration, and interpretation in the product using Campos.
fromVisual.phaseMapSnapshot(snapshot, ctx) PhaseMapSnapshot <ShotMap />, your own React view, a server-side
report, or an analysis script.
This seam is for app-owned analysis that still needs reusable Campos packets. The data is already interpreted upstream; Campos preserves the visual contract, evidence, caveats, and source metadata.
import { fromVisual } from "@withqwerty/campos-adapters";
const phaseMap = fromVisual.phaseMapSnapshot(snapshot, { matchId });
const playerSurface = fromVisual.playerSurfaceSnapshot(surface, { matchId }); phaseMapSnapshot(s)()
returns PhaseMapSnapshot[] Reusable output/cost quadrant-map packets.
Visual packets notes: Quadrant-map packet only; output/cost scoring stays outside Campos.
playerSurfaceSnapshot(s)()
returns PlayerSurfaceSnapshot[] Lineups, average positions, networks, and role tags.
Visual packets notes: Lineups, average positions, passing networks, and role tags as visual data.
Supported cards plot from this adapter with no extra work. Partial cards plot, but read the scope note. Dimmed cards need a surface this provider doesn't ship.
Plot events, shots, passes, and formations directly on the pitch.
Time-series and xG-driven views from shots().
These charts are adapter-independent — they take pre-aggregated inputs.
phaseMapSnapshot() carries score-space points, team centroids, axis labels,
calibration status, evidence, caveats, and source metadata. The adapter clamps values
and preserves provenance; it does not decide how output or cost should be scored.
const phaseMap = fromVisual.phaseMapSnapshot(
{
id: "match-1:phase-map",
points,
centroids,
calibration: { status: "insufficient-rich-sample" },
caveat: "Within-match diagnostic only.",
},
{ matchId: "match-1" },
); playerSurfaceSnapshot() packages the visual material a player-level analysis
page usually needs: home and away team sheets, average-position points, passing-network
edges, and role-tag candidates. Role scoring, tactical responsibility, and authored conclusions
remain consumer-owned.
const surface = fromVisual.playerSurfaceSnapshot(
{
id: "match-1:players",
home,
away,
averagePositions,
passingNetwork,
roleTags,
},
{ matchId: "match-1" },
); IDs, clamped score-space or pitch-space co-ordinates, nullable fields, inferred-edge flags, evidence, caveats, and source metadata.
Output scoring, cost scoring, role assignment, pass-network aggregation thresholds, calibration, and final football interpretation stay in the app.
Use these packets when multiple apps should draw the same analytical object but should not share one hard-coded tactical model.
Concrete credits for the projects that did the underlying research or laid the reference tables we read from.
SPADL canonical action taxonomy as a reference when we decided which Wyscout tag combinations collapse into which canonical event.