ScatterPlot
General-purpose Cartesian scatter chart for football analysis. Use it when the story is the relationship between two metrics in one snapshot, with optional annotation layers and selective emphasis. Hero fixture: current-season team shot-for versus shot-against aggregates derived from local league datasets.
Canonical behaviors.
Dark-theme finishing scatter with a y=x reference line.
Same chart surface, different scouting question: carries vs passes into the final third.
Size, labels, and outlier selection can all change while the base scatter stays the same.
Ghosting keeps full-population context without giving every point equal visual weight.
No plottable points. No fake axis story.
Stress case for mixed-script labels and connector placement near dense points.
Static mode keeps guides, regions, and visible labels meaningful without hover.
Composition patterns.
Use the shared note seam for sample and eligibility context instead of duplicating prose around the card.
Shared concerns.
Choose ScatterPlot
Use ScatterPlot for one-timepoint metric relationships. If time movement is the story, move to CometChart instead.
Annotation Budget
Labels, guides, regions, ghosts, and reference lines all compete. Pick the smallest set that answers the question.
Encoding Ownership
Marker styling belongs inside the component. Upstream code should provide clean fields and labels; keyed maps and callbacks handle the visual logic.
Export / Static
ScatterPlot is part of the stable export union, but only through the bounded export prop surface. `staticMode` is the live-component path when the chart must remain meaningful without hover.
Responsive Behavior
ScatterPlot should preserve point positioning and readable axis labels first. On smaller widths, annotation density should yield before the metric relationship does.
Composition
ScatterPlot is a standalone analytical chart, but shared methodology notes can live inside the chart frame rather than being rebuilt in page chrome.
Width pressure.
At smaller widths the analytical relationship should survive before dense annotation does.
Wide layouts preserve more label separation, region copy, and guide clarity.
Best-practice examples.
Minimal usage
ScatterPlot needs x/y keys first. Everything else is optional marker styling or annotation.
import { ScatterPlot } from "@withqwerty/campos-react";
export function TeamScatter({ points }) {
return (
<ScatterPlot
points={points}
idKey="team"
xKey="shotsForPerMatch"
yKey="shotsAgainstPerMatch"
xLabel="Shots taken per match"
yLabel="Shots faced per match"
/>
);
}
Recipe-driven finishing view
Use named scatter recipes for the benchmark idioms users already recognize, then layer custom marker encoding on top.
import { ScatterPlot, scatterPlotRecipes } from "@withqwerty/campos-react";
export function FinishingScatter({ points }) {
return (
<ScatterPlot
points={points}
idKey="playerId"
xKey="xg"
yKey="goals"
xLabel="Expected goals"
yLabel="Goals"
labelKey="name"
{...scatterPlotRecipes.finishing.props}
/>
);
}
Public surface.
| Prop | Type | Default | Description |
|---|---|---|---|
points | readonly T[] | required | Array of data objects with numeric fields. |
xKey | keyof T & string | required | Field to plot on the x-axis. |
yKey | keyof T & string | required | Field to plot on the y-axis. |
xLabel | string | xKey | X-axis label. |
yLabel | string | yKey | Y-axis label. |
markers | ScatterPlotMarkersStyle<T> | — | First-class marker style surface. Accepts constants, keyed map shorthands, or callbacks for fill, radius, stroke, opacity, and shape. |
regionStyle | ScatterPlotRegionsStyle | — | First-class styling surface for region fills, region visibility, and region-label colour. |
guideStyle | ScatterPlotGuidesStyle | — | First-class styling surface for rendered guide lines and guide labels. |
labelStyle | ScatterPlotLabelsStyle | — | First-class styling surface for visible point labels and their connector strokes. |
labelKey | keyof T & string | — | Field used for point labels and tooltip identity. |
labelStrategy | "manual" | "extremes" | "outliers" | "manual" | How visible labels are chosen. |
autoLabelCount | number | 6 | Maximum number of labels in automatic modes. |
labelIds | readonly string[] | — | Subset of ids to visibly label when labelStrategy is manual. |
ghost | ScatterPlotGhostConfig<T> | — | Background context markers for unlabeled or explicit ghost layers. |
guides | readonly ScatterPlotGuideInput[] | — | Vertical or horizontal guide lines using numbers, median, or mean. |
regions | readonly ScatterPlotRegionInput[] | — | Background quadrants or analysis zones behind the points. |
referenceLine | "y=x" | false | false | Diagonal identity line for finishing-style scatters. |
methodologyNotes | ChartMethodologyNotes | — | Shared chart-frame note seam for sample, eligibility, and methodological context. |
staticMode | boolean | false | Switches to the deterministic, no-hover SVG path used by the static export renderer. |
`staticMode` is the export-safe live path for the component. `methodologyNotes` stay intentionally outside the stable `ExportFrameSpec` contract even though they are supported in the interactive/SSR React surface.
Create a React component using Campos ScatterPlot. Import ScatterPlot and scatterPlotRecipes from @withqwerty/campos-react, keep point shaping outside the component, show the smallest good usage first, then one recipe-driven quadrant, finishing, or ghost-context variant.