@sportsdataverse/sdvplot 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/NOTICE.md +109 -0
- package/README.md +984 -2
- package/dist/_web-D7Aa5Rd8.d.ts +69 -0
- package/dist/aaf-GJ3SH34T.js +13 -0
- package/dist/aaf-HCYN5T6Y.js +37 -0
- package/dist/aaf-ZAE5KS2Y.js +13 -0
- package/dist/ahl-E66MDVCU.js +66 -0
- package/dist/ahl-NPQQWZEV.js +249 -0
- package/dist/ahl-QRDU73XX.js +309 -0
- package/dist/axis-CraWQRUJ.d.ts +49 -0
- package/dist/bins.d.ts +174 -0
- package/dist/bins.js +4 -0
- package/dist/bins.js.map +1 -0
- package/dist/cfb-F42SVS4X.js +5000 -0
- package/dist/cfb-P3SHEYRZ.js +692 -0
- package/dist/cfb-WXRZANLP.js +10226 -0
- package/dist/chartjs-surface.d.ts +42 -0
- package/dist/chartjs-surface.js +65 -0
- package/dist/chartjs-surface.js.map +1 -0
- package/dist/chartjs.d.ts +162 -0
- package/dist/chartjs.js +342 -0
- package/dist/chartjs.js.map +1 -0
- package/dist/chunk-4C3GX6QO.js +92 -0
- package/dist/chunk-4C3GX6QO.js.map +1 -0
- package/dist/chunk-57WFSI4Q.js +128 -0
- package/dist/chunk-57WFSI4Q.js.map +1 -0
- package/dist/chunk-7ULOCCFL.js +313 -0
- package/dist/chunk-7ULOCCFL.js.map +1 -0
- package/dist/chunk-AMXASQHT.js +120 -0
- package/dist/chunk-AMXASQHT.js.map +1 -0
- package/dist/chunk-B2MP37SR.js +175 -0
- package/dist/chunk-B2MP37SR.js.map +1 -0
- package/dist/chunk-C2CDY5OG.js +137 -0
- package/dist/chunk-C2CDY5OG.js.map +1 -0
- package/dist/chunk-DYMUVE6K.js +127 -0
- package/dist/chunk-DYMUVE6K.js.map +1 -0
- package/dist/chunk-E7G7VSLV.js +43 -0
- package/dist/chunk-E7G7VSLV.js.map +1 -0
- package/dist/chunk-H2C3FMMA.js +300 -0
- package/dist/chunk-H2C3FMMA.js.map +1 -0
- package/dist/chunk-J4P4HDBF.js +175 -0
- package/dist/chunk-J4P4HDBF.js.map +1 -0
- package/dist/chunk-J6R2LEJ7.js +58 -0
- package/dist/chunk-J6R2LEJ7.js.map +1 -0
- package/dist/chunk-M3XD2OSN.js +132 -0
- package/dist/chunk-M3XD2OSN.js.map +1 -0
- package/dist/chunk-OIILARXI.js +30 -0
- package/dist/chunk-OIILARXI.js.map +1 -0
- package/dist/chunk-RPVVJY74.js +170 -0
- package/dist/chunk-RPVVJY74.js.map +1 -0
- package/dist/chunk-UL5M6KDE.js +205 -0
- package/dist/chunk-UL5M6KDE.js.map +1 -0
- package/dist/chunk-WQT4IVLX.js +10 -0
- package/dist/chunk-WQT4IVLX.js.map +1 -0
- package/dist/chunk-ZAEQXFJM.js +556 -0
- package/dist/chunk-ZAEQXFJM.js.map +1 -0
- package/dist/cricket-KPCYG2HL.js +493 -0
- package/dist/cricket-NDXLE25B.js +116 -0
- package/dist/cricket-YUUF7P6M.js +160 -0
- package/dist/cytoscape.d.ts +188 -0
- package/dist/cytoscape.js +219 -0
- package/dist/cytoscape.js.map +1 -0
- package/dist/d3.d.ts +234 -0
- package/dist/d3.js +198 -0
- package/dist/d3.js.map +1 -0
- package/dist/deckgl.d.ts +232 -0
- package/dist/deckgl.js +197 -0
- package/dist/deckgl.js.map +1 -0
- package/dist/echarts.d.ts +121 -0
- package/dist/echarts.js +228 -0
- package/dist/echarts.js.map +1 -0
- package/dist/echl-3CR4RGFC.js +241 -0
- package/dist/echl-NPC32C23.js +107 -0
- package/dist/echl-PI33DGJC.js +64 -0
- package/dist/export.d.ts +130 -0
- package/dist/export.js +258 -0
- package/dist/export.js.map +1 -0
- package/dist/g2.d.ts +251 -0
- package/dist/g2.js +102 -0
- package/dist/g2.js.map +1 -0
- package/dist/headshots-B2J_LOO8.d.ts +40 -0
- package/dist/index.d.ts +183 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/interact.d.ts +567 -0
- package/dist/interact.js +809 -0
- package/dist/interact.js.map +1 -0
- package/dist/lightweight-charts.d.ts +217 -0
- package/dist/lightweight-charts.js +155 -0
- package/dist/lightweight-charts.js.map +1 -0
- package/dist/maplibre.d.ts +271 -0
- package/dist/maplibre.js +175 -0
- package/dist/maplibre.js.map +1 -0
- package/dist/marks-DH-tQIP-.d.ts +75 -0
- package/dist/mbb-3TRLVW3H.js +3619 -0
- package/dist/mbb-DQUHCHZP.js +5111 -0
- package/dist/mbb-PRAIO2P5.js +371 -0
- package/dist/milb-6IQ6NCEW.js +291 -0
- package/dist/milb-EYY5MD4T.js +1752 -0
- package/dist/milb-EYZ4SZLI.js +797 -0
- package/dist/mlb-4PBUJSVQ.js +35 -0
- package/dist/mlb-FHPY3GQJ.js +701 -0
- package/dist/mlb-REVGL3N2.js +665 -0
- package/dist/mui.d.ts +338 -0
- package/dist/mui.js +184 -0
- package/dist/mui.js.map +1 -0
- package/dist/nba-ATT775GS.js +485 -0
- package/dist/nba-LKM4UHVU.js +482 -0
- package/dist/nba-YX7PXM3R.js +35 -0
- package/dist/nbagl-3WGZCZ4S.js +37 -0
- package/dist/nbagl-LP4XJRAL.js +229 -0
- package/dist/nbagl-VTTOU7LN.js +499 -0
- package/dist/ncaa_baseball-UV75LNVR.js +2670 -0
- package/dist/ncaa_baseball-VD5J5C72.js +419 -0
- package/dist/ncaa_baseball-YRBS32D6.js +4592 -0
- package/dist/ncaa_mhockey-IMYHS7QS.js +1033 -0
- package/dist/ncaa_mhockey-TXTKWHE3.js +115 -0
- package/dist/ncaa_mhockey-U3MFW5VT.js +663 -0
- package/dist/ncaa_softball-6WR6KS64.js +420 -0
- package/dist/ncaa_softball-RZCTIE56.js +2654 -0
- package/dist/ncaa_softball-VOD4PVGY.js +4599 -0
- package/dist/ncaa_whockey-6XXGUTBK.js +607 -0
- package/dist/ncaa_whockey-AKKYKY67.js +53 -0
- package/dist/ncaa_whockey-KBEKXFBB.js +293 -0
- package/dist/nfl-BDB2HYAR.js +625 -0
- package/dist/nfl-EHYHDLJD.js +37 -0
- package/dist/nfl-VF4NJCHY.js +514 -0
- package/dist/nfl_gsis-UY64JO37.js +4 -0
- package/dist/nhl-6WPHME7H.js +511 -0
- package/dist/nhl-EMIJFZHY.js +884 -0
- package/dist/nhl-ISFUKRFU.js +37 -0
- package/dist/nivo.d.ts +193 -0
- package/dist/nivo.js +8 -0
- package/dist/nivo.js.map +1 -0
- package/dist/ohl-2FEM554G.js +113 -0
- package/dist/ohl-C5Q4W6JB.js +32 -0
- package/dist/ohl-TQ4J46VC.js +66 -0
- package/dist/perspective.d.ts +198 -0
- package/dist/perspective.js +171 -0
- package/dist/perspective.js.map +1 -0
- package/dist/phf-H7POU2KW.js +32 -0
- package/dist/phf-K5IFMZUM.js +13 -0
- package/dist/phf-TWJI3BOW.js +20 -0
- package/dist/placement-UWkqUzpa.d.ts +32 -0
- package/dist/plot.d.ts +451 -0
- package/dist/plot.js +712 -0
- package/dist/plot.js.map +1 -0
- package/dist/plotly.d.ts +129 -0
- package/dist/plotly.js +360 -0
- package/dist/plotly.js.map +1 -0
- package/dist/pwhl-OX3BO4JI.js +53 -0
- package/dist/pwhl-W44OC3C6.js +17 -0
- package/dist/pwhl-ZJGG3H7W.js +23 -0
- package/dist/qmjhl-5HISEHLL.js +35 -0
- package/dist/qmjhl-DA3UHKE5.js +125 -0
- package/dist/qmjhl-YG4BOQPF.js +614 -0
- package/dist/react.d.ts +377 -0
- package/dist/react.js +522 -0
- package/dist/react.js.map +1 -0
- package/dist/recharts.d.ts +162 -0
- package/dist/recharts.js +8 -0
- package/dist/recharts.js.map +1 -0
- package/dist/resolve-CQW-jzvr.d.ts +28 -0
- package/dist/selection-D4T3PkRt.d.ts +140 -0
- package/dist/shadcn.d.ts +83 -0
- package/dist/shadcn.js +88 -0
- package/dist/shadcn.js.map +1 -0
- package/dist/shots.d.ts +364 -0
- package/dist/shots.js +86 -0
- package/dist/shots.js.map +1 -0
- package/dist/soccer-7BH3ZLVL.js +7898 -0
- package/dist/soccer-MRU25OGE.js +2636 -0
- package/dist/soccer-PF4IPPVA.js +12342 -0
- package/dist/surface-TR7YFJW3.js +4 -0
- package/dist/surface-TR7YFJW3.js.map +1 -0
- package/dist/surfaces-MIG7HOFU.js +6 -0
- package/dist/surfaces-MIG7HOFU.js.map +1 -0
- package/dist/surfaces-W-odWLpT.d.ts +47 -0
- package/dist/svelte/HeadshotMark.svelte +25 -0
- package/dist/svelte/HeadshotMark.svelte.d.ts +10 -0
- package/dist/svelte/HeadshotMark.svelte.d.ts.map +1 -0
- package/dist/svelte/LogoMark.svelte +25 -0
- package/dist/svelte/LogoMark.svelte.d.ts +10 -0
- package/dist/svelte/LogoMark.svelte.d.ts.map +1 -0
- package/dist/svelte/Marks.svelte +25 -0
- package/dist/svelte/Marks.svelte.d.ts +10 -0
- package/dist/svelte/Marks.svelte.d.ts.map +1 -0
- package/dist/svelte/Surface.svelte +29 -0
- package/dist/svelte/Surface.svelte.d.ts +9 -0
- package/dist/svelte/Surface.svelte.d.ts.map +1 -0
- package/dist/svelte/SurfaceBackdrop.svelte +26 -0
- package/dist/svelte/SurfaceBackdrop.svelte.d.ts +11 -0
- package/dist/svelte/SurfaceBackdrop.svelte.d.ts.map +1 -0
- package/dist/svelte/index.d.ts +13 -0
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +11 -0
- package/dist/svelte-core.d.ts +139 -0
- package/dist/svelte-core.js +123 -0
- package/dist/svelte-core.js.map +1 -0
- package/dist/tanstack.d.ts +240 -0
- package/dist/tanstack.js +110 -0
- package/dist/tanstack.js.map +1 -0
- package/dist/testing.d.ts +75 -0
- package/dist/testing.js +239 -0
- package/dist/testing.js.map +1 -0
- package/dist/three.d.ts +223 -0
- package/dist/three.js +50 -0
- package/dist/three.js.map +1 -0
- package/dist/tiers-BN4md-GB.d.ts +65 -0
- package/dist/types-C7n6gJF3.d.ts +62 -0
- package/dist/ufl-7VLZTLTT.js +143 -0
- package/dist/ufl-CCMBLPSW.js +100 -0
- package/dist/ufl-F2BJRXME.js +16 -0
- package/dist/unovis.d.ts +127 -0
- package/dist/unovis.js +108 -0
- package/dist/unovis.js.map +1 -0
- package/dist/uplot.d.ts +120 -0
- package/dist/uplot.js +110 -0
- package/dist/uplot.js.map +1 -0
- package/dist/usfl-4CR5RMZJ.js +32 -0
- package/dist/usfl-LD7HP2YK.js +14 -0
- package/dist/usfl-VU4YSJQD.js +19 -0
- package/dist/ushl-CPG2LB4L.js +73 -0
- package/dist/ushl-PQL6HJAD.js +88 -0
- package/dist/ushl-ZT2ATPHK.js +22 -0
- package/dist/vega.d.ts +85 -0
- package/dist/vega.js +362 -0
- package/dist/vega.js.map +1 -0
- package/dist/victory.d.ts +107 -0
- package/dist/victory.js +38 -0
- package/dist/victory.js.map +1 -0
- package/dist/wbb-3KHCDYTK.js +5087 -0
- package/dist/wbb-BMX53Q3Q.js +369 -0
- package/dist/wbb-QNRN2CJJ.js +3620 -0
- package/dist/whl-4ATYZWUB.js +97 -0
- package/dist/whl-RVFPL6MH.js +79 -0
- package/dist/whl-Y7ASKYMM.js +28 -0
- package/dist/wnba-FWX5SFVI.js +232 -0
- package/dist/wnba-GX6HZR4B.js +220 -0
- package/dist/wnba-NTMWIPP6.js +20 -0
- package/dist/xfl-43R2JMJK.js +30 -0
- package/dist/xfl-H3BXQPZZ.js +16 -0
- package/dist/xfl-XON7A7FI.js +69 -0
- package/package.json +366 -3
package/dist/plot.d.ts
ADDED
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
import * as Plot from '@observablehq/plot';
|
|
2
|
+
import { E as EspnHeadshotLeague } from './headshots-B2J_LOO8.js';
|
|
3
|
+
import { P as Placement, K as Kind } from './placement-UWkqUzpa.js';
|
|
4
|
+
import { V as Value } from './resolve-CQW-jzvr.js';
|
|
5
|
+
import { H as HeadshotIdSystem, L as League, S as SeasonInput, V as Variant, I as IdSystem, W as Which } from './types-C7n6gJF3.js';
|
|
6
|
+
export { A as Axis, a as AxisLogosOptions, b as AxisPassThrough, c as axisLogos } from './axis-CraWQRUJ.js';
|
|
7
|
+
import { T as TiersOptions, a as TierRow } from './tiers-BN4md-GB.js';
|
|
8
|
+
import { Scene, FrameName, Frame, BasketballZone, BasketballZoneArea } from '@sportsdataverse/sporty';
|
|
9
|
+
import { surfaceScales } from '@sportsdataverse/sporty/plot';
|
|
10
|
+
import { S as SurfaceSceneOptions } from './surfaces-W-odWLpT.js';
|
|
11
|
+
export { a as SURFACES, b as SURFACE_BASE, c as colorUpdates } from './surfaces-W-odWLpT.js';
|
|
12
|
+
import { BinShape } from './bins.js';
|
|
13
|
+
import { DiffScale, SignaturePoint, Split, CellVsLeague } from './shots.js';
|
|
14
|
+
|
|
15
|
+
/** A column name, an accessor, or an array of values (one per row). */
|
|
16
|
+
type Channel<R> = keyof R | ((d: R, i: number) => Value) | readonly Value[];
|
|
17
|
+
/** Rows to draw: any iterable, or an Arrow-like table `Plot.valueof` accepts. */
|
|
18
|
+
type Data<R> = Iterable<R> | {
|
|
19
|
+
numRows: number;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Every `Plot.image` option sdvplot does not compute passes through untouched: `x`, `y`, `fx`, `fy`, `tip`, `href`,
|
|
23
|
+
* `target`, `title`, `ariaLabel`, `ariaDescription`, `sort`, `filter`, `reverse`, `dx`, `dy`, `clip`, `className`,
|
|
24
|
+
* `opacity`, `rotate`, `frameAnchor`, `channels`, and `transform` / `initializer` / `render` (so Plot's transforms and
|
|
25
|
+
* `Plot.pointer` wrap the mark). sdvplot owns `src`, `width` and `height` (the image and its size).
|
|
26
|
+
*/
|
|
27
|
+
type ImagePassThrough = Omit<Plot.ImageOptions, "src" | "width" | "height" | "r" | "preserveAspectRatio">;
|
|
28
|
+
/** sdvplot's own image-mark options (shared by `logos`, `wordmarks` and `headshots`); the rest are Plot's. */
|
|
29
|
+
interface ImageMarkOptions extends ImagePassThrough {
|
|
30
|
+
/** Fraction of the (facet) frame height in (0, 1]; default 0.1. */
|
|
31
|
+
height?: number;
|
|
32
|
+
/**
|
|
33
|
+
* Opacity in [0, 1]; default 1. `alpha` is the Python sdvplot name for a constant `opacity`, kept for parity; Plot's
|
|
34
|
+
* `opacity` also takes a per-row channel. Passing both throws `InputError`.
|
|
35
|
+
*/
|
|
36
|
+
alpha?: number;
|
|
37
|
+
/**
|
|
38
|
+
* Read by `Plot.dodgeX` / `Plot.dodgeY` as the collision radius in pixels (dodge's own option); the image is never
|
|
39
|
+
* clipped or sized by it. Half the drawn height (`height` × frame height / 2) makes neighbours just touch; a smaller
|
|
40
|
+
* `r` lets them overlap (by design: the images keep their size). Plot's own image mark uses `r` to clip the image to
|
|
41
|
+
* a circle, while sdvplot uses `r` only for dodge spacing and never clips.
|
|
42
|
+
*/
|
|
43
|
+
r?: Plot.ChannelValue;
|
|
44
|
+
}
|
|
45
|
+
interface MarkOptions<R> extends ImageMarkOptions {
|
|
46
|
+
league: League;
|
|
47
|
+
team: Channel<R>;
|
|
48
|
+
/** A literal season (number, null, or a 4-digit string like "2023"), or a channel: any other string is a column name; functions and arrays are per-row channels. */
|
|
49
|
+
season?: SeasonInput | Channel<R>;
|
|
50
|
+
variant?: Variant;
|
|
51
|
+
idSystem?: IdSystem;
|
|
52
|
+
/**
|
|
53
|
+
* The link id stamped as each image's `data-sdv-id`, which `sdvplot/interact` matches against a store or a linked
|
|
54
|
+
* table's `rowKey` (`id: "team"` for a table keyed by abbreviation). One value per row, like every channel: ids
|
|
55
|
+
* index the data row, never the draw position, so each follows its row through `sort`, `filter`, facets
|
|
56
|
+
* (`fx`/`fy`) and `Plot.dodgeY`. It changes only the stamp: each image keeps its team's accessible name and tip.
|
|
57
|
+
* Default: the resolved ESPN team id ("12" for KC), which never matches "KC".
|
|
58
|
+
*/
|
|
59
|
+
id?: Channel<R>;
|
|
60
|
+
}
|
|
61
|
+
interface HeadshotOptions<R> extends ImageMarkOptions {
|
|
62
|
+
league: EspnHeadshotLeague;
|
|
63
|
+
player: Channel<R>;
|
|
64
|
+
/** "espn" (default) or "gsis". "gsis" is sync and needs `loadGsis()` to have run first, else this throws InputError. */
|
|
65
|
+
idSystem?: HeadshotIdSystem;
|
|
66
|
+
/** The link id stamped as each image's `data-sdv-id`, as `logos`' `id`. Default: the player id. */
|
|
67
|
+
id?: Channel<R>;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Plot `render` transform: size each `<image>` to `height` x the (facet) frame height, keep the mark's
|
|
71
|
+
* aspect, re-centre on the point and stamp the `data-sdv-*` attributes `drawnMarks` reads.
|
|
72
|
+
* `placed` is looked up by original row index (`Placement.index`), which is what Plot hands `render`; so are `ids`,
|
|
73
|
+
* the link ids by row (the `id` option), stamped in place of each placement's resolved id.
|
|
74
|
+
*/
|
|
75
|
+
declare function sizeRender(height: number, placed: readonly Placement[], kind: Kind, ids?: readonly string[]): Plot.RenderFunction;
|
|
76
|
+
/**
|
|
77
|
+
* Team logos as an Observable Plot mark at (x, y), `height` a fraction of the (facet) frame height. Needs
|
|
78
|
+
* `loadLeague(league)` first; a team that does not resolve is left out, with one warning. Every other `Plot.image`
|
|
79
|
+
* option passes through (`tip`, `href`, `fx`/`fy`, `sort`, `filter`, `dx`/`dy`, `className`, `clip`, …), and Plot's
|
|
80
|
+
* row-preserving transforms wrap it (`Plot.dodgeY`, `Plot.stackY`, `Plot.windowY`, `Plot.selectLast`, `Plot.pointer`);
|
|
81
|
+
* an aggregating transform (`bin`, `group`, `hexbin`) throws `InputError`. Each image is named for its team ("KC logo").
|
|
82
|
+
* `ariaLabel` is Plot's per-image channel, so a string is a COLUMN name (`ariaLabel: "qb"` names each image by its
|
|
83
|
+
* row's `qb`); pass an accessor or an array for any other text.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```ts
|
|
87
|
+
* import * as Plot from "@observablehq/plot";
|
|
88
|
+
* import { loadLeague } from "@sportsdataverse/sdvplot";
|
|
89
|
+
* import { logos } from "@sportsdataverse/sdvplot/plot";
|
|
90
|
+
*
|
|
91
|
+
* await loadLeague("nfl");
|
|
92
|
+
* const afc = [
|
|
93
|
+
* { team: "KC", pf: 385, pa: 326 },
|
|
94
|
+
* { team: "BUF", pf: 525, pa: 368 },
|
|
95
|
+
* { team: "DEN", pf: 425, pa: 311 },
|
|
96
|
+
* ];
|
|
97
|
+
* Plot.plot({ marks: [logos(afc, { league: "nfl", x: "pf", y: "pa", team: "team", tip: true })] });
|
|
98
|
+
* ```
|
|
99
|
+
*
|
|
100
|
+
* @example A beeswarm: Plot.dodgeY reads r as the collision radius in pixels, about half the drawn height.
|
|
101
|
+
* ```ts
|
|
102
|
+
* import * as Plot from "@observablehq/plot";
|
|
103
|
+
* import { loadLeague } from "@sportsdataverse/sdvplot";
|
|
104
|
+
* import { logos } from "@sportsdataverse/sdvplot/plot";
|
|
105
|
+
*
|
|
106
|
+
* await loadLeague("nfl");
|
|
107
|
+
* const afc = [
|
|
108
|
+
* { team: "KC", net_epa: 0.063 },
|
|
109
|
+
* { team: "LAC", net_epa: 0.101 },
|
|
110
|
+
* { team: "DEN", net_epa: 0.108 },
|
|
111
|
+
* { team: "BUF", net_epa: 0.19 },
|
|
112
|
+
* ];
|
|
113
|
+
* Plot.plot({ height: 160, marks: [logos(afc, Plot.dodgeY({ league: "nfl", team: "team", x: "net_epa", r: 12, height: 0.18 }))] });
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
declare function logos<R>(data: Data<R>, o: MarkOptions<R>): Plot.Markish;
|
|
117
|
+
/** Team wordmarks, as `logos` (same options and pass-through); each image is named for its team ("KC wordmark"). */
|
|
118
|
+
declare function wordmarks<R>(data: Data<R>, o: MarkOptions<R>): Plot.Markish;
|
|
119
|
+
/** ESPN player headshots, as `logos` with a `player` channel; each image is named for its player id ("3139477 headshot"; pass `ariaLabel` for names). */
|
|
120
|
+
declare function headshots<R>(data: Data<R>, o: HeadshotOptions<R>): Plot.Markish;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Plot `render` transform that stamps `data-sdv-id` on every element a one-element-per-row mark draws (dot, cell,
|
|
124
|
+
* rect / bar, text, tick, image), so `sdvplot/interact` can highlight it by class toggle, never a redraw. `id`
|
|
125
|
+
* defaults to the row index, which is also a linked table's id when its spec has no `rowKey`. Plot hands `render`
|
|
126
|
+
* the source row indexes, so a row Plot drops (a null coordinate) leaves the others aligned. A mark that draws one
|
|
127
|
+
* element per series (line, area) is left unstamped, with one warning.
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```ts
|
|
131
|
+
* import * as Plot from "@observablehq/plot";
|
|
132
|
+
* import { linkIds } from "@sportsdataverse/sdvplot/plot";
|
|
133
|
+
*
|
|
134
|
+
* const rows = [
|
|
135
|
+
* { team: "KC", wins: 15, net_epa: 0.063 },
|
|
136
|
+
* { team: "BUF", wins: 13, net_epa: 0.19 },
|
|
137
|
+
* ];
|
|
138
|
+
* const svg = Plot.plot({ marks: [Plot.dot(rows, { x: "wins", y: "net_epa", render: linkIds(rows, "team") })] });
|
|
139
|
+
* Array.from(svg.querySelectorAll("circle")).map((c) => c.getAttribute("data-sdv-id"));
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
declare function linkIds<R>(data: Data<R>, id?: Channel<R>): Plot.RenderFunction;
|
|
143
|
+
|
|
144
|
+
interface TeamColorOptions {
|
|
145
|
+
/** "primary" (default) or "secondary". */
|
|
146
|
+
which?: Which;
|
|
147
|
+
/** Season for era-aware resolution; passing it avoids the ambiguity warning for reused abbreviations. */
|
|
148
|
+
season?: SeasonInput;
|
|
149
|
+
idSystem?: IdSystem;
|
|
150
|
+
strict?: boolean;
|
|
151
|
+
/** Colour for values that resolve to no team; default "grey". Never gets `alpha`. */
|
|
152
|
+
naValue?: string;
|
|
153
|
+
/** Opacity in [0, 1], appended as an 8-bit hex alpha to team colours only. */
|
|
154
|
+
alpha?: number;
|
|
155
|
+
/** Domain = these distinct values; default every team_id and abbr of the league. */
|
|
156
|
+
values?: readonly Value[];
|
|
157
|
+
legend?: boolean;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Plot colour-scale options that colour a team column by team colour. The same scale serves `fill` and
|
|
161
|
+
* `stroke` (Plot has one colour scale), so `teamFill` is this function. Without `values` the domain is every
|
|
162
|
+
* `team_id` and `abbr`; some abbreviations are reused across eras, so pass `season` to avoid the
|
|
163
|
+
* ambiguity warning. Needs `loadLeague(league)` first.
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* ```ts
|
|
167
|
+
* import * as Plot from "@observablehq/plot";
|
|
168
|
+
* import { loadLeague } from "@sportsdataverse/sdvplot";
|
|
169
|
+
* import { teamColor } from "@sportsdataverse/sdvplot/plot";
|
|
170
|
+
*
|
|
171
|
+
* await loadLeague("nfl");
|
|
172
|
+
* const wins = [
|
|
173
|
+
* { team: "KC", wins: 15 },
|
|
174
|
+
* { team: "BUF", wins: 13 },
|
|
175
|
+
* { team: "LAC", wins: 11 },
|
|
176
|
+
* ];
|
|
177
|
+
* Plot.plot({
|
|
178
|
+
* color: teamColor("nfl", { values: wins.map((w) => w.team) }),
|
|
179
|
+
* marks: [Plot.barY(wins, { x: "team", y: "wins", fill: "team" })],
|
|
180
|
+
* });
|
|
181
|
+
* ```
|
|
182
|
+
*/
|
|
183
|
+
declare function teamColor(league: League, o?: TeamColorOptions): Plot.ScaleOptions;
|
|
184
|
+
declare const teamFill: typeof teamColor;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Plot's rule options sdvplot does not own pass through to both rules: `fx`, `fy`, `tip`, `title`, `className`,
|
|
188
|
+
* `ariaLabel`, `ariaDescription`, `dx`, `dy`, `clip`, and the rest. sdvplot owns the rule positions (`x`, `y`, `x1`,
|
|
189
|
+
* `x2`, `y1`, `y2`): the reducer computes them per facet, top-level or mark-level.
|
|
190
|
+
*/
|
|
191
|
+
type RuleLinePassThrough = Omit<Plot.RuleXOptions, "x" | "y" | "x1" | "x2" | "y1" | "y2">;
|
|
192
|
+
interface RefLineOptions<R> extends RuleLinePassThrough {
|
|
193
|
+
x?: Channel<R>;
|
|
194
|
+
y?: Channel<R>;
|
|
195
|
+
/** Default "red". */
|
|
196
|
+
stroke?: string;
|
|
197
|
+
/** Default "4 4". */
|
|
198
|
+
strokeDasharray?: string;
|
|
199
|
+
/** Default 1. */
|
|
200
|
+
strokeWidth?: number;
|
|
201
|
+
strokeOpacity?: number;
|
|
202
|
+
}
|
|
203
|
+
/** A vertical rule at mean(x) and/or a horizontal rule at mean(y), per facet. Throws InputError if neither is given. */
|
|
204
|
+
declare function meanLines<R>(data: Data<R>, o: RefLineOptions<R>): Plot.Markish[];
|
|
205
|
+
/** Like `meanLines`, at the median. */
|
|
206
|
+
declare function medianLines<R>(data: Data<R>, o: RefLineOptions<R>): Plot.Markish[];
|
|
207
|
+
|
|
208
|
+
interface TitleImageOptions {
|
|
209
|
+
/** A team (resolved in `league`), or an https image URL when `league` is not given. */
|
|
210
|
+
image: Value;
|
|
211
|
+
league?: League;
|
|
212
|
+
season?: SeasonInput;
|
|
213
|
+
/** Required when `figure` is a bare `<svg>`: it becomes the new `<h2>`. */
|
|
214
|
+
title?: string;
|
|
215
|
+
side?: "left" | "right";
|
|
216
|
+
/** Pixels (unlike the marks' fraction of the plot height); at least 1, default 24. */
|
|
217
|
+
height?: number;
|
|
218
|
+
}
|
|
219
|
+
/** Puts a team logo (or an https image) in the `<h2>` of a Plot figure and returns the `<figure>` (a bare `<svg>` is wrapped in a new one). An unknown team draws the title alone (the resolver warned once). */
|
|
220
|
+
declare function titleImage(figure: HTMLElement | SVGSVGElement, o: TitleImageOptions): HTMLElement;
|
|
221
|
+
|
|
222
|
+
/** Options for a tier plot (see `prepareTiers`), plus `devel` (draw team abbreviations as text, not logos) and `width` (px, default 640). */
|
|
223
|
+
type TeamTiersOptions = TiersOptions & {
|
|
224
|
+
league: League;
|
|
225
|
+
devel?: boolean;
|
|
226
|
+
width?: number;
|
|
227
|
+
/** Plot's tip on the logos, naming the team on hover (opt-in; default false). Ignored with `devel`. */
|
|
228
|
+
tip?: boolean;
|
|
229
|
+
};
|
|
230
|
+
/**
|
|
231
|
+
* A tier plot as `Plot.plot` options (SSR-composable; the caller runs `Plot.plot`): tier 1 on top, logos ranked
|
|
232
|
+
* within each tier, separator rules, wrapped tier labels on the y axis.
|
|
233
|
+
*
|
|
234
|
+
* @example
|
|
235
|
+
* ```ts
|
|
236
|
+
* import * as Plot from "@observablehq/plot";
|
|
237
|
+
* import { loadLeague } from "@sportsdataverse/sdvplot";
|
|
238
|
+
* import { teamTiers } from "@sportsdataverse/sdvplot/plot";
|
|
239
|
+
*
|
|
240
|
+
* await loadLeague("nfl");
|
|
241
|
+
* const rows = [
|
|
242
|
+
* { team: "BUF", tier_no: 1 },
|
|
243
|
+
* { team: "KC", tier_no: 1 },
|
|
244
|
+
* { team: "MIA", tier_no: 2 },
|
|
245
|
+
* { team: "NE", tier_no: 3 },
|
|
246
|
+
* ];
|
|
247
|
+
* Plot.plot(teamTiers(rows, { league: "nfl" }));
|
|
248
|
+
* ```
|
|
249
|
+
*/
|
|
250
|
+
declare function teamTiers(rows: readonly TierRow[], o: TeamTiersOptions): Plot.PlotOptions;
|
|
251
|
+
|
|
252
|
+
/** Sporty's surface options plus `team` painting; `colorUpdates` overrides are keyed by sporty colour keys. */
|
|
253
|
+
interface SurfaceOpts extends SurfaceSceneOptions {
|
|
254
|
+
/**
|
|
255
|
+
* A team logo at the surface centre (0, 0): `true` is 0.25 of the frame height, a number is that fraction in (0, 1] (0 or
|
|
256
|
+
* out of range throws InputError). Ignored without a `team`. xTrans/yTrans or a half-court displayRange can move (0, 0) off-frame.
|
|
257
|
+
*/
|
|
258
|
+
centerLogo?: boolean | number;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Plot marks + scales for a team-painted sporty surface, for any key of `SURFACES`. An unsupported key, or a `team` on a key
|
|
262
|
+
* without team identities, throws `InputError`; sporty's own
|
|
263
|
+
* errors (`SportyError` subclasses: unknown displayRange/unit, bad arcResolution) propagate unwrapped.
|
|
264
|
+
*
|
|
265
|
+
* @example
|
|
266
|
+
* ```ts
|
|
267
|
+
* import * as Plot from "@observablehq/plot";
|
|
268
|
+
* import { loadLeague } from "@sportsdataverse/sdvplot";
|
|
269
|
+
* import { surface } from "@sportsdataverse/sdvplot/plot";
|
|
270
|
+
*
|
|
271
|
+
* await loadLeague("nhl");
|
|
272
|
+
* // arcResolution: points per arc (default 200); 24 is plenty at 480 px and keeps the SVG small
|
|
273
|
+
* const rink = surface("nhl", { team: "BOS", displayRange: "offense", arcResolution: 24 });
|
|
274
|
+
* Plot.plot({ ...rink.scales, width: 480, marks: rink.marks });
|
|
275
|
+
* ```
|
|
276
|
+
*/
|
|
277
|
+
declare function surface(league: League | (string & {}), o?: SurfaceOpts): {
|
|
278
|
+
marks: Plot.Markish[];
|
|
279
|
+
scales: ReturnType<typeof surfaceScales>;
|
|
280
|
+
scene: Scene;
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Plot's geo options sdvplot does not own pass through (tip, title, href, fx, fy, filter, className, clip, …). `x` and
|
|
285
|
+
* `y` are sdvplot's: a cell's tip anchors on the cell's centre and a zone's on samples inside the zone, so neither
|
|
286
|
+
* needs a mark-level anchor.
|
|
287
|
+
*/
|
|
288
|
+
type GeoPassThrough = Omit<Plot.GeoOptions, "geometry" | "fill" | "r" | "x" | "y">;
|
|
289
|
+
/** Options for `shotCells`. */
|
|
290
|
+
interface ShotCellsOptions extends GeoPassThrough {
|
|
291
|
+
/**
|
|
292
|
+
* Size per cell in legacy tenths (`sizeCells(cells, …).r`) or one size for all: a hexagon's circumradius, or a
|
|
293
|
+
* square's side. 0 hides a cell.
|
|
294
|
+
*/
|
|
295
|
+
r: readonly number[] | number;
|
|
296
|
+
/** The cells' shape, as binned (`binShots`, `leagueIndex`); default `"hex"`. */
|
|
297
|
+
shape?: BinShape;
|
|
298
|
+
/** Colour of each cell's shrunk FG% vs league; default `diffScale()`. */
|
|
299
|
+
scale?: DiffScale;
|
|
300
|
+
/** `shrunkDiff` prior in attempts; default 25 (`main`), 0 = the raw difference (`master`). */
|
|
301
|
+
prior?: number;
|
|
302
|
+
/** Legacy tenths to plot coordinates: a sporty frame name or `Frame`; default `"nba-legacy"`. */
|
|
303
|
+
frame?: FrameName | Frame;
|
|
304
|
+
/** Default `var(--sdv-muted, #525252)`, so near-average cells stay visible (`hexShotChart.ts:159-161`). */
|
|
305
|
+
stroke?: Plot.ChannelValueSpec;
|
|
306
|
+
/** Default 0.85 px. */
|
|
307
|
+
strokeWidth?: Plot.ChannelValueSpec;
|
|
308
|
+
/**
|
|
309
|
+
* Drop the cells centred outside the plot's frame, as blazing-the-nets `main` drops those past its viewport
|
|
310
|
+
* (`hexShotChart.ts:74`); a cell centred inside is drawn whole. Not Plot's `clip` (which cuts paths, and passes
|
|
311
|
+
* through). Default true. Was `clip` before Phase 11.
|
|
312
|
+
*/
|
|
313
|
+
dropOutside?: boolean;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Data-space hexagons or squares (the dual encoding: `r` from `sizeCells`, `fill` from `diffScale`) drawn as
|
|
317
|
+
* `Plot.geo` through the plot's x/y scales, so they sit on a sporty court at any orientation. Fewest attempts first,
|
|
318
|
+
* so busy cells stay on top (blazing-the-nets `main` `lib/charts/hexShotChart.ts:79`); `r = 0` is not drawn, nor
|
|
319
|
+
* (by default, `dropOutside`) a cell centred outside the plot's frame. Each path carries `data-sdv-id="x,y"`, the cell's
|
|
320
|
+
* legacy centre. Marks paint in array order: after `...court.marks` the cells cover the court lines under them, as
|
|
321
|
+
* in `main`.
|
|
322
|
+
* `tip: true` shows attempts, FG%, league FG% and the shrunk difference (formats `.1%`, `+.1%`; a `tip` object's
|
|
323
|
+
* `format` overrides them key by key); every other
|
|
324
|
+
* `Plot.geo` option passes through, and the cells are the mark's data, so `fx`/`fy`, `filter`, `sort` (replacing the
|
|
325
|
+
* default order) and `title` read the caller's fields. A `transform` or `initializer` that makes new rows
|
|
326
|
+
* (`Plot.group`, `Plot.hexbin`) throws `InputError`.
|
|
327
|
+
*
|
|
328
|
+
* @example
|
|
329
|
+
* ```ts
|
|
330
|
+
* import * as Plot from "@observablehq/plot";
|
|
331
|
+
* import { shotCells, surface } from "@sportsdataverse/sdvplot/plot";
|
|
332
|
+
* import { cellsVsLeague, leagueIndex } from "@sportsdataverse/sdvplot/shots";
|
|
333
|
+
*
|
|
334
|
+
* // Brooklyn shots from the sportsdataverse-data nba_stats_shots release, 2025-26
|
|
335
|
+
* const shots = [
|
|
336
|
+
* { x_legacy: -1, y_legacy: 7, shot_distance: 1, shot_value: 2, shot_result: "Made" },
|
|
337
|
+
* { x_legacy: 0, y_legacy: 0, shot_distance: 0, shot_value: 2, shot_result: "Missed" },
|
|
338
|
+
* { x_legacy: -44, y_legacy: 252, shot_distance: 26, shot_value: 3, shot_result: "Made" },
|
|
339
|
+
* ];
|
|
340
|
+
* // the three shots stand in for the league; the gallery's hex chart uses the 2025-26 league's index
|
|
341
|
+
* const cells = cellsVsLeague(shots, leagueIndex(shots, 15));
|
|
342
|
+
* const court = surface("nba", { displayRange: "defense" });
|
|
343
|
+
* Plot.plot({ ...court.scales, marks: [...court.marks, shotCells(cells, { r: 15 })] });
|
|
344
|
+
* ```
|
|
345
|
+
*/
|
|
346
|
+
declare function shotCells(cells: readonly CellVsLeague[], o: ShotCellsOptions): Plot.Markish;
|
|
347
|
+
/** Options for `shotZones`. */
|
|
348
|
+
interface ShotZonesOptions extends GeoPassThrough {
|
|
349
|
+
/** Fill per zone (e.g. `diffScale()` of the zone's shrunk diff). */
|
|
350
|
+
fill: (zone: BasketballZone) => string;
|
|
351
|
+
/**
|
|
352
|
+
* A label per zone at its anchor, haloed so it reads over any fill (`hexShotChart.ts:83-95`); omit for none. Labels
|
|
353
|
+
* take no pointer events, so a click or hover on one reaches the zone under it. They are hidden from assistive
|
|
354
|
+
* technology, so each zone's accessible name carries its label's text after the zone's name ("Paint (non-RA),
|
|
355
|
+
* 136/326").
|
|
356
|
+
*/
|
|
357
|
+
text?: (zone: BasketballZone) => string;
|
|
358
|
+
/** The SAME frame as the shots (zones built with `scale: 10` are in legacy tenths); default `"nba-legacy"`. */
|
|
359
|
+
frame?: FrameName | Frame;
|
|
360
|
+
/** Default 0.85 (`hexShotChart.ts:110`). */
|
|
361
|
+
fillOpacity?: Plot.ChannelValueSpec;
|
|
362
|
+
/** Per-zone makes and attempts (`statsByZone(shots)`): with `tip`, each zone shows them. */
|
|
363
|
+
stats?: Readonly<Record<BasketballZone, Split>>;
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* sporty's zone areas (built with `scale: 10`, legacy tenths) filled per zone, plus optional haloed labels, the
|
|
367
|
+
* corner strips' set vertically (blazing-the-nets `main` zones mode, `lib/charts/hexShotChart.ts:97-136`). Each
|
|
368
|
+
* area's path carries `data-sdv-id` = its zone.
|
|
369
|
+
*
|
|
370
|
+
* Returns the zone paths, then the labels (with `text`), then the tip (with `tip`). Marks paint in array order and
|
|
371
|
+
* the tip is last, so spread these marks LAST, or add other marks before them: a mark added after them paints over
|
|
372
|
+
* the tip. After `...court.marks` the zone fills dim the court lines under them; `main` draws its lines after the
|
|
373
|
+
* zones, but moving the court mark last would hide the zones under its floor (sporty draws lines as filled polygons).
|
|
374
|
+
* For lines on top, put a second `surface` right after the paths, its `colorUpdates` setting `plot_background`,
|
|
375
|
+
* `defensive_half_court`, `offensive_half_court`, `court_apron`, `two_point_range`, `painted_area`,
|
|
376
|
+
* `center_circle_fill` and `free_throw_circle_fill` to `"#00000000"` so only the lines remain:
|
|
377
|
+
* `const [paths, ...rest] = shotZones(areas, o)`, then `marks: [...court.marks, paths, ...lines.marks, ...rest]`.
|
|
378
|
+
* The areas are the mark's data and each path is named by its zone (with `text`, then its label's text). `tip: true`
|
|
379
|
+
* adds a `Plot.tip` mark that names the zone under the pointer and, with `stats` (`statsByZone(shots)`), its
|
|
380
|
+
* makes/attempts and FG%. It follows the nearest of a grid of anchors inside the zones (a fortieth of their extent
|
|
381
|
+
* apart, 1.25 ft on an NBA half court), so within about that of a zone edge it may name the neighbour. The tip's data
|
|
382
|
+
* is the areas, so `channels` (shown in the tip) read the caller's fields; a `tip` object's `format` overrides
|
|
383
|
+
* sdvplot's key by key. Every other `Plot.geo` option passes through to the zone paths.
|
|
384
|
+
*
|
|
385
|
+
* @example
|
|
386
|
+
* ```ts
|
|
387
|
+
* import * as Plot from "@observablehq/plot";
|
|
388
|
+
* import { basketballZones } from "@sportsdataverse/sporty";
|
|
389
|
+
* import { shotZones, surface } from "@sportsdataverse/sdvplot/plot";
|
|
390
|
+
*
|
|
391
|
+
* const court = surface("nba", { displayRange: "defense" });
|
|
392
|
+
* const zones = shotZones(basketballZones("nba", { scale: 10 }), { fill: () => "#f7f7f7", text: (z) => z });
|
|
393
|
+
* Plot.plot({ ...court.scales, marks: [...court.marks, ...zones] });
|
|
394
|
+
* ```
|
|
395
|
+
*/
|
|
396
|
+
declare function shotZones(areas: readonly BasketballZoneArea[], o: ShotZonesOptions): Plot.Markish[];
|
|
397
|
+
/** Options for `shootingSignature`. */
|
|
398
|
+
interface ShootingSignatureOptions {
|
|
399
|
+
/** Colour of `colourDiff`; default `diffScale()`. */
|
|
400
|
+
fill?: DiffScale;
|
|
401
|
+
/** `"monotone-x"` (default, `main`) or `"basis"` (`master` `ShootingSignature/index.js:96`). */
|
|
402
|
+
curve?: "monotone-x" | "basis";
|
|
403
|
+
/**
|
|
404
|
+
* Ribbon half-width in y units. Default `main`'s 20 px at the busiest distance on its 190 px [0, 1] axis, never
|
|
405
|
+
* under 0.75 px (`shootingSignature.ts:13-15`, `:131-132`): `max(share / maxShare * 20, 0.75) / 190`. `master`:
|
|
406
|
+
* `(p) => (1 + p.share * 199) / 200` (`ShootingSignature/index.js:73-75`, `:88-90`).
|
|
407
|
+
*/
|
|
408
|
+
halfWidth?: (p: SignaturePoint, maxShare: number) => number;
|
|
409
|
+
/** The dashed league line, faint everywhere and full strength under the ribbon (`:165-181`); default true. */
|
|
410
|
+
league?: boolean;
|
|
411
|
+
/**
|
|
412
|
+
* A tip that follows the pointer along x: distance, FG%, league FG% and shot share (`Plot.tip` + `Plot.pointerX`).
|
|
413
|
+
* An options object's `format` overrides sdvplot's key by key.
|
|
414
|
+
*/
|
|
415
|
+
tip?: boolean | Plot.TipOptions;
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* The shooting signature: a ribbon along FG% by distance, as wide as the shot share and coloured along x by the
|
|
419
|
+
* shrunk FG% vs league (blazing-the-nets `main` `lib/charts/shootingSignature.ts:117-213`; `master`
|
|
420
|
+
* `src/components/ShootingSignature/index.js`). Input: `signaturePoints(...)`; a null `fgPct` is a gap. The gradient
|
|
421
|
+
* id is a hash of its stops and its pixel x range, so two signatures on a page, or one drawn at two widths, never
|
|
422
|
+
* share one (`master`'s fixed id did, `Gradient.js:10`).
|
|
423
|
+
*
|
|
424
|
+
* y is not clamped: the ribbon's edges are `fgPct ± halfWidth` in y units, so near 0% or 100% they pass a [0, 1]
|
|
425
|
+
* domain (`main` clamps the ribbon's centre instead, which misstates FG%). To clamp them, pass
|
|
426
|
+
* `y: { domain: [0, 1], clamp: true }`.
|
|
427
|
+
* `tip` adds a `Plot.tip` that follows the pointer along x (`Plot.pointerX`): distance, FG%, league FG% and share.
|
|
428
|
+
* It is the last mark returned, and a mark added after it paints over it, so spread these marks LAST, or add other
|
|
429
|
+
* marks (a `Plot.ruleY`, say) before them.
|
|
430
|
+
*
|
|
431
|
+
* @example
|
|
432
|
+
* ```ts
|
|
433
|
+
* import * as Plot from "@observablehq/plot";
|
|
434
|
+
* import { shootingSignature } from "@sportsdataverse/sdvplot/plot";
|
|
435
|
+
* import { fgPctByDistance, signaturePoints, vsLeague } from "@sportsdataverse/sdvplot/shots";
|
|
436
|
+
*
|
|
437
|
+
* // Brooklyn shots from the sportsdataverse-data nba_stats_shots release, 2025-26
|
|
438
|
+
* const shots = [
|
|
439
|
+
* { x_legacy: -1, y_legacy: 7, shot_distance: 1, shot_value: 2, shot_result: "Made" },
|
|
440
|
+
* { x_legacy: 0, y_legacy: 0, shot_distance: 0, shot_value: 2, shot_result: "Missed" },
|
|
441
|
+
* { x_legacy: -44, y_legacy: 252, shot_distance: 26, shot_value: 3, shot_result: "Made" },
|
|
442
|
+
* ];
|
|
443
|
+
* // the makes against all three attempts, which stand in for the league (the gallery's uses the 2025-26 league)
|
|
444
|
+
* const made = fgPctByDistance(shots.filter((s) => s.shot_result === "Made"));
|
|
445
|
+
* const points = signaturePoints(vsLeague(made, fgPctByDistance(shots)), { minAttempts: 1 });
|
|
446
|
+
* Plot.plot({ y: { domain: [0, 1] }, marks: shootingSignature(points) });
|
|
447
|
+
* ```
|
|
448
|
+
*/
|
|
449
|
+
declare function shootingSignature(points: readonly SignaturePoint[], o?: ShootingSignatureOptions): Plot.Markish[];
|
|
450
|
+
|
|
451
|
+
export { type Channel, type Data, type GeoPassThrough, type HeadshotOptions, type ImageMarkOptions, type ImagePassThrough, type MarkOptions, type RefLineOptions, type RuleLinePassThrough, type ShootingSignatureOptions, type ShotCellsOptions, type ShotZonesOptions, type SurfaceOpts, type TeamColorOptions, type TeamTiersOptions, type TitleImageOptions, headshots, linkIds, logos, meanLines, medianLines, shootingSignature, shotCells, shotZones, sizeRender, surface, teamColor, teamFill, teamTiers, titleImage, wordmarks };
|