Skip to main content

Getting started

sdvplot-js draws team logos, headshots, team colours, playing surfaces (courts, rinks, fields) and styled tables for Observable Plot, D3, React, Plotly, Vega-Lite, ECharts and Chart.js. It is made of three packages.

Install​

pnpm add @sportsdataverse/sdvplot @sportsdataverse/sporty @sportsdataverse/sdvtables @observablehq/plot

The charting libraries (@observablehq/plot, d3, react, chart.js) are optional peers: install the one you draw with. The Plotly, Vega-Lite and ECharts adapters import nothing from their libraries. Keep @sportsdataverse/sporty in the install even if you draw no surface: sdvplot/plot, /d3, /shots and /chartjs/surface import it when they load.

Entry points​

@sportsdataverse/sdvplot (logo, headshot and colour data per league)

  • @sportsdataverse/sdvplot: loadLeague, team lookup, colours, marks, tiers.
  • @sportsdataverse/sdvplot/plot: Observable Plot marks: logos, surface, teamColor, axisLogos, teamTiers.
  • @sportsdataverse/sdvplot/d3: D3 helpers.
  • @sportsdataverse/sdvplot/react: React components and hooks.
  • @sportsdataverse/sdvplot/bins: hexagon and square binning (hexbin, squarebin, binner) in the points' own units.
  • @sportsdataverse/sdvplot/shots: shot-chart numbers, bins and FG% against a league (binShots, cellsVsLeague, fgPctByDistance, signaturePoints) and the diffScale colours; it imports no Plot or d3.
  • @sportsdataverse/sdvplot/plotly, /vega, /echarts: spec adapters for Plotly, Vega-Lite and ECharts.
  • @sportsdataverse/sdvplot/chartjs and /chartjs/surface: Chart.js colours, image plugins and surfaces.
  • @sportsdataverse/sdvplot/interact: linked figures and tables over one selection store (brushFilter, linkSelection, linkCursor, nearestHover, tooltip, highlight); see Linked figures and tables.
  • @sportsdataverse/sdvplot/testing: the adapter contract suite.

@sportsdataverse/sporty (playing-surface geometry and data frames)

  • @sportsdataverse/sporty: surface, toSurfaceFrame, court/rink/field specs.
  • @sportsdataverse/sporty/svg: SVG output.
  • @sportsdataverse/sporty/specs: raw surface specifications.
  • @sportsdataverse/sporty/plot: Plot marks and scales for a surface.
  • @sportsdataverse/sporty/d3: D3 drawing helpers.
  • @sportsdataverse/sporty/canvas: drawing on a 2D canvas context.

@sportsdataverse/sdvtables (tables from a plain-data spec)

  • @sportsdataverse/sdvtables: defineTable, the column kinds, decorations and themes.
  • @sportsdataverse/sdvtables/html: renderHTML, renderHTMLAsync, prepare, toElement.

Node and SSR​

Everything also runs in Node. Plot needs a DOM document (from jsdom or linkedom); read the figure's SVG string:

310320330340350360370380390400410420430↑ pa300350400450500pf →
import * as Plot from "@observablehq/plot";
import { STANDINGS } from "@sportsdataverse/examples/data";
import { loadLeague } from "@sportsdataverse/sdvplot";
import { logos } from "@sportsdataverse/sdvplot/plot";
import { JSDOM } from "jsdom";

await loadLeague("nfl");
const { document } = new JSDOM("").window;
const svg: string = Plot.plot({
document,
marks: [logos(STANDINGS, { league: "nfl", x: "pf", y: "pa", team: "team", height: 0.1 })],
}).outerHTML;

svg;

Where next​