accepted

XGTimeline cumulative lines are step-after, never smoothed

Cumulative xG paths are SVG `M/H/V` step-after segments — no cubic Béziers, no linear interpolation between shots. Smooth curves imply continuous chance generation, which is a lie. A step function says "this xG value held until the next shot", which is what actually happened.

XGTimeline visual-encodingfootball-semanticsalgorithm

Context

Two renderings of a cumulative time-series:

  • Smooth interpolation — looks pleasant, hides discreteness, suggests xG accrues continuously between shots.
  • Step function — is the statistical standard for cumulative distributions. Readable at a glance, clusters visible, clean alignment with halftime / stoppage bands.

Football matches are event streams. A shot in the 34th minute moves xG; the 35th minute doesn’t, unless another shot happens. Smooth curves editorialise the dead minutes.

Decision

Compute emits step-after SVG path strings directly: M x0 y0 H x1 V y1 H x2…. No curve primitive; no smoothing option. Halftime and full-time bands sit on integer minutes and align cleanly with the step transitions. Line segments are the only geometry; markers at shot points sit on top.

Consequences

  • Step-function rendering is the invariant; consumers wanting smoothed curves use a different chart (LineChart with interpolation).
  • Golden SVG fixtures lock the step grammar; tests comparing paths by shape catch accidental smoothing if it ever lands.
  • Annotation tier policy (which shots get labels) composes cleanly over step geometry — labels anchor at the vertical riser, not partway along a curve.
  • Dense matches render with many tight risers; readability is preserved by the annotation tier policy, not by geometry smoothing.
← All decisions