@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react/recharts.tsx","../src/react/nivo.tsx","../src/react/victory.tsx","../src/react/three.tsx","../src/react/index.tsx"],"names":["lazy","useMemo","jsx","Suspense","createElement","useState","useEffect"],"mappings":"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","file":"react.js","sourcesContent":["import { type ComponentType, type ReactElement, Suspense, lazy, useId, useMemo } from \"react\";\nimport { OptionalDependencyError, warn } from \"../errors.js\";\nimport type { Value } from \"../resolve.js\";\nimport type { SurfaceSceneOptions } from \"../surfaces.js\";\nimport type { League, SeasonInput } from \"../types.js\";\n\n/**\n * `<SurfaceBackdrop>` props: the league whose surface to draw, how to paint it (the options of sdvplot's other\n * `surface` functions), and which axes place it. The sporty-specific options are typed loosely, so `sdvplot/react`'s\n * types never name `@sportsdataverse/sporty` (an optional peer); sporty checks them when the surface is built.\n */\nexport interface SurfaceBackdropProps {\n /** The league whose court, field or rink to draw, e.g. \"nba\". */\n league: League;\n /** The team whose colours paint the surface. */\n team?: Value;\n /** The season the team's colours are taken from. */\n season?: SeasonInput;\n /** Overrides on top of the team painting, keyed by sporty colour key (e.g. `{ painted_area: \"#0e2240\" }`). */\n colorUpdates?: Readonly<Record<string, string>>;\n /** Degrees to rotate the surface by. */\n rotation?: number;\n /** A sporty display range for the league's sport, e.g. \"defense\"; one the sport does not know throws. */\n displayRange?: string;\n xlim?: readonly [number, number];\n ylim?: readonly [number, number];\n units?: \"ft\" | \"m\" | \"yd\" | \"in\" | \"cm\" | \"mm\";\n /** Sporty parameter overrides for the league's surface. */\n updates?: Readonly<Record<string, unknown>>;\n arcResolution?: number;\n xTrans?: number;\n yTrans?: number;\n /** The `xAxisId` of the numeric x axis the surface's units are on. Default 0. */\n xAxisId?: string | number;\n /** The `yAxisId` of the numeric y axis the surface's units are on. Default 0. */\n yAxisId?: string | number;\n}\n\nconst missing = (peer: string, e: unknown): OptionalDependencyError =>\n new OptionalDependencyError(\n `SurfaceBackdrop needs the optional peer ${peer}, which could not be loaded: pnpm add ${peer}`,\n { cause: e },\n );\ntype Domain = readonly unknown[] | undefined;\nconst numeric = (d: Domain): d is readonly [number, number] =>\n d !== undefined &&\n d.length === 2 &&\n d.every((v) => typeof v === \"number\" && Number.isFinite(v)) &&\n d[1] !== d[0];\n\n/** A scale (when recharts has the hooks) that grows with the value in direction `dir` (+1 left to right, -1 bottom\n * to top in pixels) and is linear: its midpoint lands half way. */\nfunction linear(scale: ((v: number) => unknown) | undefined, d0: number, d1: number, dir: 1 | -1): boolean {\n if (scale === undefined) return true;\n const [a, m, b] = [d0, (d0 + d1) / 2, d1].map((v) => Number(scale(v)));\n if (![a, m, b].every((v) => Number.isFinite(v))) return true; // not laid out yet: the domain check covers the rest\n return (\n dir * ((b as number) - (a as number)) > 0 &&\n Math.abs((m as number) - ((a as number) + (b as number)) / 2) < 0.5\n );\n}\n\n// recharts and sporty load on first render, never with sdvplot/react: a page that draws no backdrop needs neither.\nconst Backdrop = lazy(async (): Promise<{ default: ComponentType<SurfaceBackdropProps> }> => {\n const [rc, surfaces, svg] = await Promise.all([\n import(\"recharts\").catch((e: unknown) => {\n throw missing(\"recharts\", e);\n }),\n import(\"../surfaces.js\").catch((e: unknown) => {\n throw missing(\"@sportsdataverse/sporty\", e);\n }),\n import(\"@sportsdataverse/sporty/svg\").catch((e: unknown) => {\n throw missing(\"@sportsdataverse/sporty\", e);\n }),\n ]);\n // recharts 3.8 added the scale hooks; before it a reversed or log axis cannot be told apart (documented)\n const noScale = (): undefined => undefined;\n const useXScale: (id?: string | number) => ((v: number) => unknown) | undefined =\n rc.useXAxisScale ?? noScale;\n const useYScale: (id?: string | number) => ((v: number) => unknown) | undefined =\n rc.useYAxisScale ?? noScale;\n function Drawn({ league, xAxisId, yAxisId, ...o }: SurfaceBackdropProps): ReactElement | null {\n const area = rc.usePlotArea();\n const xd: Domain = rc.useXAxisDomain(xAxisId);\n const yd: Domain = rc.useYAxisDomain(yAxisId);\n const sx = useXScale(xAxisId);\n const sy = useYScale(yAxisId);\n const clip = `sdv-surface-${useId().replace(/[^\\w-]/g, \"\")}`;\n // a bigint team id is a `Value`: JSON.stringify throws on bigint, so key it as text\n const key = JSON.stringify(o, (_k, v: unknown) => (typeof v === \"bigint\" ? `${v}n` : v));\n // biome-ignore lint/correctness/useExhaustiveDependencies: `key` is `o` by value (a fresh object every render)\n const scene = useMemo(() => surfaces.surfaceScene(league, o as SurfaceSceneOptions), [league, key]);\n // undefined: the chart has not laid out yet (the first render), which is not worth a warning\n if (area === undefined || xd === undefined || yd === undefined) return null;\n if (!numeric(xd) || !numeric(yd)) {\n warn(\n \"react:SurfaceBackdrop:domain\",\n `SurfaceBackdrop draws nothing: both axes must be type=\"number\" with a numeric domain in the surface's units (got x ${JSON.stringify(xd)}, y ${JSON.stringify(yd)})`,\n );\n return null;\n }\n // ponytail: a linear map from the axes' domains (recharts 3.2 hooks): a reversed or log axis is refused, where\n // recharts 3.8's scale hooks can tell (on 3.2 to 3.7 it would draw mirrored or stretched)\n const [dx0, dx1] = xd;\n const [dy0, dy1] = yd;\n if (!linear(sx, dx0, dx1, 1) || !linear(sy, dy0, dy1, -1)) {\n warn(\n \"react:SurfaceBackdrop:scale\",\n \"SurfaceBackdrop draws nothing on a reversed or log axis: use linear, unreversed number axes\",\n );\n return null;\n }\n const fx = (v: number): number => area.x + ((v - dx0) / (dx1 - dx0)) * area.width;\n const fy = (v: number): number => area.y + ((dy1 - v) / (dy1 - dy0)) * area.height;\n const [x0, y0, x1, y1] = scene.bbox;\n const width = fx(x1) - fx(x0);\n const height = fy(y0) - fy(y1);\n if (!(width > 0 && height > 0)) {\n warn(\n \"react:SurfaceBackdrop:empty\",\n `SurfaceBackdrop draws nothing: the surface spans ${width} x ${height} px`,\n );\n return null;\n }\n // toSVG maps the scene's bbox onto its own viewport; placed and stretched over the bbox's pixel rectangle, the\n // surface's units land on the axes' (strokes stay 1 px: non-scaling)\n const drawn = svg\n .toSVG(scene, { width, height })\n .replace(\"<svg \", `<svg x=\"${fx(x0)}\" y=\"${fy(y1)}\" preserveAspectRatio=\"none\" `);\n return (\n <g data-sdv-surface=\"\" className=\"sdv-surface\">\n <defs>\n <clipPath id={clip}>\n <rect x={area.x} y={area.y} width={area.width} height={area.height} />\n </clipPath>\n </defs>\n {/* biome-ignore lint/security/noDangerouslySetInnerHtml: sporty's own SVG, its text and colours escaped by toSVG */}\n <g clipPath={`url(#${clip})`} dangerouslySetInnerHTML={{ __html: drawn }} />\n </g>\n );\n }\n return { default: Drawn };\n});\n\n/**\n * A team-painted court, field or rink under a Recharts chart's series: place it as a child of the chart (before the\n * series), as Recharts 3 renders any element there (`<Customized>` is deprecated). The surface is drawn in the\n * numeric axes' units: set both axes' `domain` to the surface's bbox (sporty's `surface(...).bbox`) to fill the plot\n * area, or to any range in those units to show part of it. recharts (3.8 or later) and `@sportsdataverse/sporty`\n * load when it first renders, never with `sdvplot/react`; either missing throws `OptionalDependencyError` then. A\n * server render draws nothing (it loads on the client).\n *\n * @example\n * ```tsx\n * import { SurfaceBackdrop } from \"@sportsdataverse/sdvplot/react\";\n * import { surface } from \"@sportsdataverse/sporty\";\n * import { Scatter, ScatterChart, XAxis, YAxis } from \"recharts\";\n *\n * const [x0, y0, x1, y1] = surface(\"basketball\", \"nba\", { displayRange: \"defense\" }).bbox;\n * <ScatterChart width={500} height={470}>\n * <XAxis type=\"number\" dataKey=\"x\" domain={[x0, x1]} hide />\n * <YAxis type=\"number\" dataKey=\"y\" domain={[y0, y1]} hide />\n * <SurfaceBackdrop league=\"nba\" team=\"DEN\" displayRange=\"defense\" />\n * <Scatter data={[{ x: 0, y: 5.25 }]} />\n * </ScatterChart>;\n * ```\n */\nexport function SurfaceBackdrop(props: SurfaceBackdropProps): ReactElement {\n return (\n <Suspense fallback={null}>\n <Backdrop {...props} />\n </Suspense>\n );\n}\n","import { type ComponentType, type ReactElement, Suspense, createElement, lazy, useMemo } from \"react\";\nimport { OptionalDependencyError } from \"../errors.js\";\nimport { type NivoLayerOptions, logoLayer, teamColors } from \"../nivo.js\";\nimport type { IdSystem, League, MarkType, SeasonInput, Variant } from \"../types.js\";\n\n/**\n * `<LogoBump>` props: the series, the league their ids belong to, and how to draw the logos; every other prop goes to\n * nivo's `Bump` as is (typed loosely, so `sdvplot/react`'s types never name `@nivo/bump`, an optional peer).\n */\nexport interface LogoBumpProps {\n /** nivo Bump series, `{ id, data: [{ x, y }] }`: each `id` is a team (abbreviation, name or id). */\n data: readonly {\n readonly id: string;\n readonly data: readonly { x: number | string; y: number | null }[];\n }[];\n /** The league the series' teams belong to, e.g. \"nfl\". */\n league: League;\n /** The season the teams are resolved for. */\n season?: SeasonInput;\n /** How the series' ids are read. Default \"auto\". */\n idSystem?: IdSystem;\n /** The chart's background: the line colours keep 3:1 contrast against it and aim to stay distinct (`teamColors`). */\n background?: string;\n /** Logo height as a fraction of the plot height, in (0, 1]. Default 0.08. */\n logoHeight?: number;\n /** Which points get a logo: \"last\" (default), \"first\" or \"all\". */\n at?: NivoLayerOptions[\"at\"];\n /** Logo variant, e.g. \"dark\". Default \"default\". */\n variant?: Variant;\n /** \"logo\" (default) or \"wordmark\". */\n markType?: MarkType;\n /** Width and height in px. Both given: a fixed-size `Bump`; otherwise a `ResponsiveBump` that fills its parent. */\n width?: number;\n /** Chart height in px (see `width`). */\n height?: number;\n /**\n * nivo's layers. Default nivo's own: grid, axes, labels, lines, points, then the logos, then mesh. Given, the logos\n * are appended after them all, after any \"mesh\" too, which is harmless: the logo layer has `pointer-events: none`.\n */\n layers?: readonly unknown[];\n /** Any other nivo `Bump` prop (margin, axes, pointSize, animate, theme, ...). */\n [prop: string]: unknown;\n}\n\nconst LAYERS = [\"grid\", \"axes\", \"labels\", \"lines\", \"points\"]; // then the logos, then nivo's \"mesh\" (mouse) on top\n\n// @nivo/bump loads on first render, never with sdvplot/react: a page that draws no LogoBump needs no nivo.\nconst Chart = lazy(async (): Promise<{ default: ComponentType<Record<string, unknown>> }> => {\n const m = await import(\"@nivo/bump\").catch((e: unknown) => {\n throw new OptionalDependencyError(\n \"LogoBump needs the optional peer @nivo/bump, which could not be loaded: pnpm add @nivo/bump @nivo/core\",\n { cause: e },\n );\n });\n const Drawn = (p: Record<string, unknown>): ReactElement =>\n createElement(\n (p.width === undefined || p.height === undefined ? m.ResponsiveBump : m.Bump) as ComponentType<\n Record<string, unknown>\n >,\n p,\n );\n return { default: Drawn };\n});\n\n/**\n * A nivo bump chart of teams: each line in its team's colour (`teamColors`), a logo at the end of each line\n * (`logoLayer`). `@nivo/bump` (0.99 or later) loads when it first renders, never with `sdvplot/react`; missing, it\n * throws `OptionalDependencyError` then. A server render draws nothing (it loads on the client). For anything this\n * does not cover, use `teamColors` and `logoLayer` from `sdvplot/nivo` on nivo's own `Bump`. A `colors` prop replaces\n * the team colours (it is passed to nivo after them).\n */\nexport function LogoBump({\n league,\n season,\n idSystem,\n background,\n logoHeight,\n at,\n variant,\n markType,\n layers,\n ...rest\n}: LogoBumpProps): ReactElement {\n const teams = rest.data.map((s) => s.id);\n const key = JSON.stringify([\n league,\n season,\n idSystem,\n background,\n logoHeight,\n at,\n variant,\n markType,\n teams,\n ]);\n // biome-ignore lint/correctness/useExhaustiveDependencies: `key` is the options by value\n const drawn = useMemo(() => {\n const o = {\n league,\n ...(season === undefined ? {} : { season }),\n ...(idSystem === undefined ? {} : { idSystem }),\n };\n return {\n colors: teamColors({ ...o, ...(background === undefined ? {} : { teams, background }) }),\n logos: logoLayer({\n ...o,\n ...(logoHeight === undefined ? {} : { height: logoHeight }),\n ...(at === undefined ? {} : { at }),\n ...(variant === undefined ? {} : { variant }),\n ...(markType === undefined ? {} : { markType }),\n }),\n };\n }, [key]);\n return (\n <Suspense fallback={null}>\n <Chart\n colors={drawn.colors}\n {...rest}\n layers={layers === undefined ? [...LAYERS, drawn.logos, \"mesh\"] : [...layers, drawn.logos]}\n />\n </Suspense>\n );\n}\n","import { type ComponentType, type ReactElement, Suspense, createElement, lazy } from \"react\";\nimport { type Row, aspect, checkAlpha, imageSource, place, seasons } from \"../_web.js\";\nimport { InputError, OptionalDependencyError, UnsupportedTargetError, warn } from \"../errors.js\";\nimport { type Placement, placedName } from \"../placement.js\";\nimport type { Value } from \"../resolve.js\";\nimport type { IdSystem, League, MarkType, SeasonInput, Variant } from \"../types.js\";\n\ninterface Shared {\n /** The league the teams belong to, e.g. \"nfl\". */\n league: League;\n /** Logo variant, e.g. \"dark\". Default \"default\". */\n variant?: Variant;\n /** How the team values are read. Default \"auto\". */\n idSystem?: IdSystem;\n /** \"logo\" (default) or \"wordmark\". */\n markType?: MarkType;\n /** url → data URI map from `embedSources`, to inline the images. */\n embed?: ReadonlyMap<string, string>;\n}\n/**\n * `<LogoPoint>` props: yours (the league, the datum field holding the team, ...), plus the point Victory hands its\n * `dataComponent` (`x`, `y`, `size`, `datum`, `events`), which you leave out.\n */\nexport interface LogoPointProps extends Shared {\n /** The field of each datum (each data row) holding the team: abbreviation, name or id (see `idSystem`). */\n team: string;\n /** A season (number or string) for every point, or the name of the datum field holding each one's season. */\n season?: SeasonInput;\n /** Opacity in [0, 1]. Default 1. */\n alpha?: number;\n /** Set by Victory: the point's centre in px. */\n x?: number;\n /** Set by Victory: the point's centre in px. */\n y?: number;\n /** Set by Victory: the point's radius in px (the scatter's `size`). The logo is twice it tall. */\n size?: number;\n /** Set by Victory: the data row the point was drawn from. */\n datum?: object;\n /** Set by Victory: the point's event handlers (tooltips, voronoi, your `events`). */\n events?: object;\n}\n/**\n * `<LogoTick>` props: yours (the league, the logo size, ...), plus the tick label Victory hands its\n * `tickLabelComponent` (`x`, `y`, `text`, the anchors, and VictoryLabel's other props), which you leave out.\n */\nexport interface LogoTickProps extends Shared {\n /** The season the axis' teams are resolved for. */\n season?: SeasonInput;\n /** The logo's height in px, 1 or more (Victory hands a tick label no plot height). Default 24. */\n size?: number;\n /** Set by Victory: the label's anchor in px. */\n x?: number;\n /** Set by Victory: the label's anchor in px. */\n y?: number;\n /** Set by Victory: the tick's label, the team (abbreviation, name or id; see `idSystem`). */\n text?: unknown;\n /** Set by Victory: which side of the anchor the label would run. VictoryLabel's default \"start\". */\n textAnchor?: string;\n /** Set by Victory: which side of the anchor the label would hang. VictoryLabel's default \"middle\". */\n verticalAnchor?: string;\n}\n\nconst isNum = (v: unknown): v is number => typeof v === \"number\" && Number.isFinite(v);\n\nfunction checkSize(size: unknown): number {\n if (!(isNum(size) && size > 0))\n throw new InputError(`size is an image height in px > 0, got ${String(size)}`);\n if (size < 1)\n throw new InputError(\n `size is a height in px, not a fraction of the plot (echarts' \\`height\\`): got ${size}, which draws a sub-pixel image`,\n );\n return size;\n}\n\nfunction placed(\n x: number,\n y: number,\n raw: Value,\n rows: readonly Row[],\n o: Shared & { season?: SeasonInput },\n) {\n const season = seasons(rows, o.season);\n return place([x], [y], [raw], {\n league: o.league,\n kind: o.markType ?? \"logo\",\n ...(season === undefined ? {} : { season }),\n ...(o.variant === undefined ? {} : { variant: o.variant }),\n ...(o.idSystem === undefined ? {} : { idSystem: o.idSystem }),\n })[0];\n}\n\n/** The `<image>` of a placed mark, `h` px tall with its top-left at (left, top), stamped with what `sdvplot/testing`'s\n * `drawnMarks` reads back. ponytail: the frame is 1 px, so drawnMarks' `height` reads in px (no plot height here). */\nfunction image(\n p: Placement,\n o: Shared,\n raw: Value,\n box: { left: number; top: number; h: number },\n at: { x: number; y: number },\n extra: object,\n): ReactElement {\n const kind = o.markType ?? \"logo\";\n return createElement(\"image\", {\n ...extra,\n href: imageSource(p, o.embed),\n x: box.left,\n y: box.top,\n width: box.h * aspect(p),\n height: box.h,\n preserveAspectRatio: \"xMidYMid meet\",\n role: \"img\",\n \"aria-label\": `${placedName(p, o.league, raw)} ${kind}`,\n \"data-sdv-id\": p.id,\n \"data-sdv-kind\": kind,\n \"data-sdv-x\": String(at.x),\n \"data-sdv-y\": String(at.y),\n \"data-sdv-frame\": \"1\",\n });\n}\n\n/** A stray `height` or `width` (the spec adapters' fraction of the plot, or a box) is refused: these size in px. */\nfunction noBox(props: object, name: string, how: string): void {\n for (const k of [\"height\", \"width\"]) if (k in props) throw new InputError(`${name} takes no ${k}: ${how}`);\n}\n\n/**\n * Team logos as a Victory scatter's points: `<VictoryScatter dataComponent={<LogoPoint league team />}>`. Each point\n * draws the logo of its datum's `team` field, centred on the point and as tall as the point it replaces (twice the\n * scatter's `size`, in px: set `size` on the `VictoryScatter`). A team with no logo draws nothing and warns once, as\n * `sdvplot/echarts` does. Victory's event handlers (tooltips, voronoi) stay on the image. Synchronous: call it after\n * `loadLeague(league)`. Needs nothing from victory itself, so it also renders on the server.\n *\n * @example\n * ```tsx\n * import { loadLeague } from \"@sportsdataverse/sdvplot\";\n * import { LogoPoint } from \"@sportsdataverse/sdvplot/react\";\n * import { VictoryChart, VictoryScatter } from \"victory\";\n *\n * await loadLeague(\"nfl\");\n * const rows = [\n * { team: \"KC\", pf: 385, pa: 326 },\n * { team: \"LAC\", pf: 402, pa: 301 },\n * { team: \"DEN\", pf: 425, pa: 311 },\n * ];\n * <VictoryChart domainPadding={30}>\n * <VictoryScatter data={rows} x=\"pf\" y=\"pa\" size={14} dataComponent={<LogoPoint league=\"nfl\" team=\"team\" />} />\n * </VictoryChart>;\n * ```\n */\nexport function LogoPoint(props: LogoPointProps): ReactElement | null {\n noBox(\n props,\n \"LogoPoint\",\n \"each logo is as tall as Victory drew the point (twice the scatter's size, in px)\",\n );\n const alpha = checkAlpha(props.alpha ?? 1);\n const { x, y, size } = props;\n if (!(isNum(x) && isNum(y) && isNum(size)))\n throw new UnsupportedTargetError(\n \"LogoPoint is a VictoryScatter dataComponent: it needs the point's x, y and size, which the scatter hands it\",\n );\n const row = (props.datum ?? {}) as Row;\n const raw = row[props.team] as Value;\n if (raw === undefined || raw === null) {\n warn(\n `victory:LogoPoint:no-team:${props.team}`,\n `LogoPoint: a datum has no ${props.team} field: nothing drawn`,\n );\n return null;\n }\n if (!(size > 0)) {\n warn(\n `victory:LogoPoint:size:${size}`,\n `LogoPoint: Victory drew a point of size ${size} (px): nothing drawn`,\n );\n return null;\n }\n const p = placed(x, y, raw, [row], props);\n if (p === undefined) return null; // no mark: nothing drawn, one warning (placeSync), as sdvplot/echarts\n const h = 2 * size;\n const w = h * aspect(p);\n return image(\n p,\n props,\n raw,\n { left: x - w / 2, top: y - h / 2, h },\n { x, y },\n { ...props.events, ...(alpha === 1 ? {} : { opacity: alpha }) },\n );\n}\n\n// victory loads only to draw a tick label as text (a team with no logo), never with sdvplot/react.\nconst Label = lazy(async (): Promise<{ default: ComponentType<Record<string, unknown>> }> => {\n const m = await import(\"victory\").catch((e: unknown) => {\n throw new OptionalDependencyError(\n \"LogoTick needs the optional peer victory to draw a label as text, and it could not be loaded: pnpm add victory\",\n { cause: e },\n );\n });\n return { default: m.VictoryLabel as ComponentType<Record<string, unknown>> };\n});\n\n/**\n * Team logos as an axis' tick labels: `<VictoryAxis tickLabelComponent={<LogoTick league />} />` on an axis whose\n * labels are teams. The logo sits where the label would, on the side of Victory's anchor the label would run (under\n * a bottom axis, left of a left one), `size` px tall. A label that resolves to no logo keeps its text, drawn by\n * Victory's own `VictoryLabel` (loaded from victory when it first draws one; it then also warns once), as\n * `sdvplot/echarts`' `withAxisLogos` does. Logos do not\n * rotate with a tick's `angle`. Synchronous: call it after `loadLeague(league)`.\n *\n * @example\n * ```tsx\n * import { loadLeague } from \"@sportsdataverse/sdvplot\";\n * import { LogoTick } from \"@sportsdataverse/sdvplot/react\";\n * import { VictoryAxis, VictoryBar, VictoryChart } from \"victory\";\n *\n * await loadLeague(\"nfl\");\n * const rows = [\n * { team: \"KC\", wins: 15 },\n * { team: \"BUF\", wins: 13 },\n * { team: \"LAC\", wins: 11 },\n * ];\n * <VictoryChart domainPadding={40} padding={{ top: 20, bottom: 60, left: 50, right: 20 }}>\n * <VictoryAxis tickLabelComponent={<LogoTick league=\"nfl\" size={32} />} />\n * <VictoryAxis dependentAxis />\n * <VictoryBar data={rows} x=\"team\" y=\"wins\" />\n * </VictoryChart>;\n * ```\n */\nexport function LogoTick(props: LogoTickProps): ReactElement {\n noBox(props, \"LogoTick\", \"size is the logo's height in px (Victory hands a tick label no plot height)\");\n const h = checkSize(props.size ?? 24);\n const { league, season, variant, idSystem, markType, embed, size, ...label } = props;\n const x = isNum(props.x) ? props.x : 0;\n const y = isNum(props.y) ? props.y : 0;\n const raw = typeof props.text === \"string\" || typeof props.text === \"number\" ? props.text : undefined;\n const p = raw === undefined ? undefined : placed(x, y, raw, [], props);\n if (p === undefined)\n return (\n <Suspense fallback={null}>\n <Label {...label} />\n </Suspense>\n );\n const w = h * aspect(p);\n const anchor = props.textAnchor ?? \"start\";\n const vertical = props.verticalAnchor ?? \"middle\";\n const left = anchor === \"end\" ? x - w : anchor === \"middle\" ? x - w / 2 : x;\n const top = vertical === \"end\" ? y - h : vertical === \"middle\" ? y - h / 2 : y;\n return image(p, props, raw as Value, { left, top, h }, { x, y }, {});\n}\n","import {\n type ComponentType,\n type ReactElement,\n Suspense,\n createElement,\n lazy,\n useEffect,\n useMemo,\n useState,\n} from \"react\";\nimport { OptionalDependencyError, warn } from \"../errors.js\";\nimport { checkLeague, getLeagueSync, loadLeague } from \"../index-data.js\";\nimport { type TrajectoryTubeOptions, type TubeMesh, trajectoryTube } from \"../three/tube.js\";\nimport type { IdSystem, League, SeasonInput, Which } from \"../types.js\";\n\ntype Three = typeof import(\"three\");\ntype Fiber = typeof import(\"@react-three/fiber\");\n/** What a drawn mesh needs: its buffers (positions, then colours or normals), indices and material. */\ninterface Buffers {\n positions: Float32Array;\n indices: Uint32Array;\n colors?: Float32Array;\n normals?: Float32Array;\n}\ntype MeshProps = { buffers: Buffers; material: Record<string, unknown>; renderOrder: number };\n\n/**\n * `three` and `@react-three/fiber`, loaded on first render, never with `sdvplot/react`: a page that draws no 3D needs\n * neither. Missing, the component throws `OptionalDependencyError` when it renders.\n */\nasync function peers(who: string): Promise<[Three, Fiber]> {\n try {\n return await Promise.all([import(\"three\"), import(\"@react-three/fiber\")]);\n } catch (e) {\n throw new OptionalDependencyError(\n `${who} needs the optional peers three and @react-three/fiber, which could not be loaded: pnpm add three @react-three/fiber`,\n { cause: e },\n );\n }\n}\n\n/**\n * A mesh of `buffers` in react-three-fiber: the geometry is built once per buffers object and freed when it changes\n * or unmounts. `useThree` makes using it outside a `<Canvas>` an error that says so, and asks a canvas drawn on demand\n * (`frameloop=\"demand\"`) for a frame.\n */\nfunction meshOf(THREE: Three, fiber: Fiber): ComponentType<MeshProps> {\n return function Drawn({ buffers, material, renderOrder }): ReactElement {\n const invalidate = fiber.useThree((s) => s.invalidate);\n // biome-ignore lint/correctness/useExhaustiveDependencies: THREE is the module namespace, the same object always\n const geometry = useMemo(() => {\n const g = new THREE.BufferGeometry();\n g.setAttribute(\"position\", new THREE.BufferAttribute(buffers.positions, 3));\n if (buffers.colors !== undefined) g.setAttribute(\"color\", new THREE.BufferAttribute(buffers.colors, 4));\n if (buffers.normals !== undefined)\n g.setAttribute(\"normal\", new THREE.BufferAttribute(buffers.normals, 3));\n g.setIndex(new THREE.BufferAttribute(buffers.indices, 1));\n g.computeBoundingSphere();\n return g;\n }, [buffers]);\n useEffect(() => {\n invalidate();\n return () => geometry.dispose();\n }, [geometry, invalidate]);\n // react-three-fiber frees the material it made; the geometry, made here, is freed above\n return createElement(\"mesh\", { geometry, renderOrder }, createElement(\"meshBasicMaterial\", material));\n };\n}\n\n/** Whether `league` (a known league, else InputError) is loaded for the *Sync lookups. */\nfunction loaded(league: League): boolean {\n checkLeague(league);\n try {\n getLeagueSync(league);\n return true;\n } catch {\n return false;\n }\n}\n\n/** `<Surface3D>` props: sporty's sport and league, and sporty's `surface()` options. */\nexport interface Surface3DProps {\n /** sporty's sport, e.g. \"baseball\". */\n sport: string;\n /** sporty's league key for it, e.g. \"mlb\". */\n league: string;\n /** sporty's `surface()` options (`colorUpdates`, `units`, `rotation`, ...). */\n options?: Record<string, unknown>;\n /** The mesh's `renderOrder`. Default -1: drawn before the scene's other objects, as a ground should be. */\n renderOrder?: number;\n}\n\n// the peers and sporty (through ../three/surface.js) load on first render, never with sdvplot/react\nconst SurfaceBody = lazy(async (): Promise<{ default: ComponentType<Surface3DProps> }> => {\n const [[THREE, fiber], { surfaceMesh }] = await Promise.all([\n peers(\"Surface3D\"),\n import(\"../three/surface.js\").catch((e: unknown) => {\n throw new OptionalDependencyError(\n \"Surface3D needs the optional peer @sportsdataverse/sporty, which could not be loaded: pnpm add @sportsdataverse/sporty\",\n { cause: e },\n );\n }),\n ]);\n const Drawn = meshOf(THREE, fiber);\n const material = {\n vertexColors: true,\n transparent: true,\n depthWrite: false,\n toneMapped: false,\n side: THREE.DoubleSide,\n };\n function Body({ sport, league, options, renderOrder = -1 }: Surface3DProps): ReactElement {\n const key = JSON.stringify([sport, league, options]);\n // biome-ignore lint/correctness/useExhaustiveDependencies: `key` is the props by value\n const buffers = useMemo(() => surfaceMesh(sport as never, league as never, options as never), [key]);\n return createElement<MeshProps>(Drawn, { buffers, material, renderOrder });\n }\n return { default: Body };\n});\n\n/**\n * sporty's playing surface in a react-three-fiber scene: `surfaceMesh` as one mesh in the z = 0 plane, in the\n * surface's own units (feet for a baseball field or a rink, metres for a pitch), z up, so set the camera's\n * `up={[0, 0, 1]}`. Drawn unlit in sporty's colours, before the scene's other objects and without depth writes, so its\n * features paint over each other in order with no z-fighting. Put it inside your `<Canvas>`. `three` and\n * `@react-three/fiber` (0.186.1 and 9.8.1 or later) and `@sportsdataverse/sporty` load when it first renders, never\n * with `sdvplot/react`; a missing peer throws `OptionalDependencyError` then. The failed load is kept until the page\n * reloads, so installing the peer needs a reload. A server render draws nothing.\n *\n * See it drawn in the Three.js guide (`sdvplot/three/statcast-pitches` in the gallery).\n */\nexport function Surface3D(props: Surface3DProps): ReactElement {\n return (\n <Suspense fallback={null}>\n <SurfaceBody {...props} />\n </Suspense>\n );\n}\n\n/** `<Trajectory>` props: the path, the tube's radius in world units, and its colour or team. */\nexport interface TrajectoryProps {\n /** The path, `[x, y, z]` points in world units (`statcastPitchPath` gives a pitch's). */\n points: readonly (readonly [x: number, y: number, z: number])[];\n /** The tube's radius in the points' world units, not px (a baseball's is 0.121 ft). */\n radius: number;\n /** Vertices round each ring, 3 or more. Default 12. */\n radialSegments?: number;\n /** The tube's colour, `#rrggbb`. Give this or `team` and `league`. */\n color?: string;\n /** The team whose colour the tube takes (abbreviation, name or id), with `league`. */\n team?: unknown;\n league?: League;\n season?: SeasonInput;\n idSystem?: IdSystem;\n /** \"primary\" (default) or \"secondary\". */\n which?: Which;\n /** What the tube is seen against: the colour keeps 3:1 contrast against it (`teamColorPalette`). */\n background?: string;\n /** The colour of a team that does not resolve. Default \"#808080\". */\n fallback?: string;\n /** The mesh's `renderOrder`. Default 0. */\n renderOrder?: number;\n}\n\nconst TubeBody = lazy(\n async (): Promise<{ default: ComponentType<{ tube: TubeMesh; renderOrder: number }> }> => {\n const [THREE, fiber] = await peers(\"Trajectory\");\n const Drawn = meshOf(THREE, fiber);\n function Body({ tube, renderOrder }: { tube: TubeMesh; renderOrder: number }): ReactElement {\n const material = useMemo(() => ({ color: tube.color, toneMapped: false }), [tube.color]);\n return createElement<MeshProps>(Drawn, { buffers: tube, material, renderOrder });\n }\n return { default: Body };\n },\n);\n\n/**\n * A team-coloured tube along a 3D path (a pitch, a ball flight) in a react-three-fiber scene: `trajectoryTube` as one\n * mesh, `radius` round in the points' world units, drawn unlit and not tone-mapped so the team's colour shows as it\n * is. Put it inside your `<Canvas>`, over a `<Surface3D>` in the same units. `three` and `@react-three/fiber` load\n * when it first renders, never with `sdvplot/react`; a missing peer throws `OptionalDependencyError` then (kept until\n * the page reloads, so installing the peer needs a reload), and a bad radius or colour throws `InputError`. With\n * `team`, the team's league must be loaded for its colour: until it is, the tube draws nothing (one warning), and in\n * the browser it loads the league and then draws. A server render draws nothing.\n *\n * See it drawn in the Three.js guide (`sdvplot/three/statcast-pitches` in the gallery).\n */\nexport function Trajectory({ points, renderOrder = 0, ...o }: TrajectoryProps): ReactElement | null {\n // a team's colour needs its league loaded: until it is, draw nothing (a server render included), and load it here\n const league = o.color === undefined ? o.league : undefined;\n const ready = league === undefined || loaded(league);\n const [, loadedNow] = useState(0);\n useEffect(() => {\n if (ready || league === undefined) return;\n let live = true;\n loadLeague(league).then(\n () => live && loadedNow((n) => n + 1),\n () => {}, // a league that cannot load leaves the tube undrawn, as it is now\n );\n return () => {\n live = false;\n };\n }, [league, ready]);\n const key = JSON.stringify([points, o, ready]);\n // biome-ignore lint/correctness/useExhaustiveDependencies: `key` is the props by value\n const tube = useMemo(() => (ready ? trajectoryTube(points, o as TrajectoryTubeOptions) : null), [key]);\n if (tube === null) {\n warn(\n `three:Trajectory:unloaded:${league}`,\n `<Trajectory team> draws nothing until league ${league} is loaded: await loadLeague(\"${league}\") first (on a server, before rendering)`,\n );\n return null;\n }\n return (\n <Suspense fallback={null}>\n <TubeBody tube={tube} renderOrder={renderOrder} />\n </Suspense>\n );\n}\n","import {\n type ImgHTMLAttributes,\n type ReactElement,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport { type ColorOptions, palette } from \"../colors.js\";\nimport { type EspnHeadshotLeague, HEADSHOT_ASPECT, headshotUrl, loadGsis } from \"../headshots.js\";\nimport { getLeagueSync, loadLeague } from \"../index-data.js\";\nimport { type LogoUrlOptions, logoUrlSync } from \"../marks.js\";\nimport { type ResolveOptions, type Value, resolveSync } from \"../resolve.js\";\nimport type { SelectionState, SelectionStore } from \"../selection.js\";\nimport type { HeadshotIdSystem, League, MarkType, TeamId, Variant } from \"../types.js\";\nexport { SurfaceBackdrop, type SurfaceBackdropProps } from \"./recharts.js\";\nexport { LogoBump, type LogoBumpProps } from \"./nivo.js\";\nexport { LogoPoint, type LogoPointProps, LogoTick, type LogoTickProps } from \"./victory.js\";\n\nexport { Surface3D, type Surface3DProps, Trajectory, type TrajectoryProps } from \"./three.js\";\n\ntype ImgProps = Omit<ImgHTMLAttributes<HTMLImageElement>, \"src\" | \"alt\" | \"height\" | \"width\">;\n\nexport interface TeamLogoProps extends ImgProps {\n team: Value;\n league: League;\n season?: LogoUrlOptions[\"season\"];\n variant?: Variant;\n markType?: MarkType;\n /** Rendered `height` in px; width is left unset so the browser keeps the aspect. */\n size?: number;\n /** Defaults to the team's name. */\n alt?: string;\n}\n\n/**\n * Team logo `<img>`. Loads the league index on first use; renders nothing until resolved and for an unknown team.\n *\n * @example\n * ```tsx\n * import { TeamLogo } from \"@sportsdataverse/sdvplot/react\";\n *\n * <TeamLogo team=\"KC\" league=\"nfl\" size={64} />;\n * ```\n */\nexport function TeamLogo({\n team,\n league,\n season,\n variant,\n markType,\n size,\n alt,\n ...imgProps\n}: TeamLogoProps): ReactElement | null {\n const [mark, setMark] = useState<{ src: string; name: string } | undefined>();\n useEffect(() => {\n let live = true;\n // One async body: any throw (bad league, bad variant, lookup error) becomes a rejection the .catch swallows.\n (async () => {\n await loadLeague(league);\n if (!live) return;\n const o: LogoUrlOptions = {};\n if (season !== undefined) o.season = season;\n if (variant !== undefined) o.variant = variant;\n if (markType !== undefined) o.markType = markType;\n const src = logoUrlSync(team, league, o);\n const id = resolveSync(team, league, { season });\n const name = getLeagueSync(league).teams.find((t) => t.team_id === id)?.name ?? \"\";\n setMark(src === undefined ? undefined : { src, name });\n })().catch(() => {\n if (live) setMark(undefined);\n });\n return () => {\n live = false;\n };\n }, [team, league, season, variant, markType]);\n if (mark === undefined) return null;\n // biome-ignore lint/a11y/useAltText: alt is always set (prop or team name); imgProps cannot carry it\n return <img src={mark.src} alt={alt ?? mark.name} height={size} {...imgProps} />;\n}\n\n/** `TeamLogo` with `markType=\"wordmark\"`. */\nexport function Wordmark(props: Omit<TeamLogoProps, \"markType\">): ReactElement | null {\n return <TeamLogo {...props} markType=\"wordmark\" />;\n}\n\nexport interface HeadshotProps extends ImgProps {\n playerId: Value;\n league: EspnHeadshotLeague;\n idSystem?: HeadshotIdSystem;\n /** Height in px (default 60); width follows the 600:436 headshot aspect. */\n height?: number;\n /** Default `name`, then \"Player headshot\". `\"\"` marks it decorative (the initials box is then `aria-hidden`). */\n alt?: string;\n /**\n * `\"initials\"`: when there is no headshot URL or the image fails to load, show up to three initials of `name` in a\n * box of the headshot's size (blazing-the-nets `main` `components/Headshot.tsx:15-29`). Default `\"none\"`: a failed\n * load leaves the `<img>`, and an id with no URL renders nothing.\n */\n fallback?: \"none\" | \"initials\";\n /** The player's name, for the initials and the default alt text. */\n name?: string;\n}\n\n/**\n * The first character of every space-separated word, up to three, as blazing-the-nets `main` does\n * (`Headshot.tsx:16-20`): suffixes and particles are words (\"Brian Thomas Jr.\" is \"BTJ\"), \"De'Von\" is one word.\n * It differs from `main` only on an astral first character, which it keeps whole where `w[0]` leaves half of it.\n */\nconst initialsOf = (name: string): string =>\n name\n .split(\" \")\n .map((w) => Array.from(w)[0] ?? \"\")\n .join(\"\")\n .slice(0, 3);\n\n// useLayoutEffect warns during React 18 server rendering; on the server no effect runs anyway.\nconst useClientLayoutEffect = typeof document === \"undefined\" ? useEffect : useLayoutEffect;\n\n/**\n * Player headshot `<img>`: sync for ESPN ids; gsis ids render once the gsis map has loaded. Renders nothing for an\n * unknown/malformed id, or a league/idSystem `headshotUrl` rejects, unless `fallback=\"initials\"` and a `name` are\n * given, which show the player's initials instead.\n *\n * @example\n * ```tsx\n * import { Headshot } from \"@sportsdataverse/sdvplot/react\";\n *\n * <Headshot playerId=\"3918298\" league=\"nfl\" height={80} alt=\"Josh Allen\" />;\n * ```\n */\nexport function Headshot({\n playerId,\n league,\n idSystem,\n height = 60,\n alt,\n fallback = \"none\",\n name,\n ...imgProps\n}: HeadshotProps): ReactElement | null {\n const [, setGsisReady] = useState(false); // re-render once loadGsis resolves\n const [failed, setFailed] = useState<string | undefined>(); // the src that failed to load\n const img = useRef<HTMLImageElement>(null);\n useEffect(() => {\n if (idSystem !== \"gsis\") return;\n let live = true;\n loadGsis().then(\n () => {\n if (live) setGsisReady(true);\n },\n () => {},\n );\n return () => {\n live = false;\n };\n }, [idSystem]);\n let src: string | undefined;\n try {\n src = headshotUrl(playerId, league, idSystem === undefined ? {} : { idSystem });\n } catch {\n src = undefined;\n }\n const label = alt ?? (name || undefined) ?? \"Player headshot\";\n const width = Math.round(height * HEADSHOT_ASPECT);\n // React replays no error that fired before hydration (or before mount): read the settled image instead. A\n // loading image is not complete yet, and a loaded one has a natural width.\n useClientLayoutEffect(() => {\n if (img.current?.complete && img.current.naturalWidth === 0) setFailed(src);\n }, [src]);\n if (src === undefined || (fallback === \"initials\" && src === failed)) {\n if (fallback !== \"initials\" || name === undefined) return null;\n return (\n <span\n {...(label === \"\" ? { \"aria-hidden\": true } : { role: \"img\", \"aria-label\": label })}\n className={imgProps.className}\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width,\n height,\n background: \"var(--sdv-line, #e2e2e2)\",\n color: \"var(--sdv-muted, #525252)\",\n ...imgProps.style,\n }}\n >\n {initialsOf(name)}\n </span>\n );\n }\n const shown = src;\n return (\n // biome-ignore lint/a11y/useAltText: alt always defaults to a string; imgProps cannot carry it\n <img\n ref={img}\n src={shown}\n alt={label}\n height={height}\n width={width}\n {...imgProps}\n onError={(e) => {\n setFailed(shown);\n imgProps.onError?.(e);\n }}\n />\n );\n}\n\n/** `{team: \"#hex\"}` for a league once loaded (`undefined` before); reloads when `league`/`which` change. */\nexport function useTeamColors(\n league: League,\n { which }: { which?: ColorOptions[\"which\"] } = {},\n): Record<string, string> | undefined {\n const [colors, setColors] = useState<Record<string, string> | undefined>();\n useEffect(() => {\n let live = true;\n setColors(undefined);\n palette(league, undefined, which === undefined ? {} : { which })\n .then((c) => {\n if (live) setColors(c);\n })\n .catch(() => {\n if (live) setColors(undefined);\n });\n return () => {\n live = false;\n };\n }, [league, which]);\n return colors;\n}\n\n/** Sync resolver `(value, opts?) => TeamId | undefined` once the league is loaded (`undefined` before); reloads when `league` changes. */\nexport function useResolve(\n league: League,\n): ((value: Value, opts?: ResolveOptions) => TeamId | undefined) | undefined {\n const [ready, setReady] = useState<League | undefined>();\n useEffect(() => {\n let live = true;\n setReady(undefined);\n loadLeague(league)\n .then(() => {\n if (live) setReady(league);\n })\n .catch(() => {\n if (live) setReady(undefined);\n });\n return () => {\n live = false;\n };\n }, [league]);\n return ready === undefined ? undefined : (value, opts) => resolveSync(value, ready, opts);\n}\n\n/**\n * The state of a `createSelection` store (J31), re-rendering on every change and never on a no-op patch. On the\n * server, and in the first client render, it reads the store's current state, so server and client markup agree.\n * Redrawing from it is the component's choice: filter rows with `state.predicate`, emphasise `state.selected`.\n *\n * @example\n * ```tsx\n * import { createSelection } from \"@sportsdataverse/sdvplot\";\n * import { useSelection } from \"@sportsdataverse/sdvplot/react\";\n * import type { ReactElement } from \"react\";\n *\n * const store = createSelection();\n * store.set({ selected: [\"KC\", \"BUF\"] });\n * function Picked(): ReactElement {\n * const { selected } = useSelection(store); // re-renders on every change of the store\n * return (\n * <table>\n * <tbody>\n * {[...selected].map((id) => (\n * <tr key={id}>\n * <td>{id}</td>\n * </tr>\n * ))}\n * </tbody>\n * </table>\n * );\n * }\n * <Picked />;\n * ```\n */\nexport function useSelection<Row>(store: SelectionStore<Row>): SelectionState<Row> {\n // The store's methods are closures (no `this`), so they pass unbound; getState is referentially stable between\n // changes, which is all useSyncExternalStore needs.\n return useSyncExternalStore(store.subscribe, store.getState, store.getState);\n}\n"]}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
import { E as EspnHeadshotLeague } from './headshots-B2J_LOO8.js';
|
|
3
|
+
import { W as Which, S as SeasonInput, I as IdSystem, H as HeadshotIdSystem, L as League, V as Variant, M as MarkType } from './types-C7n6gJF3.js';
|
|
4
|
+
export { R as Row, e as embedSources } from './_web-D7Aa5Rd8.js';
|
|
5
|
+
import './resolve-CQW-jzvr.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The Recharts adapter: team logos and player headshots as Recharts render props (a series' `dot` or `shape`, an
|
|
9
|
+
* axis' `tick`), and team colours for the series' `stroke` / `fill`. Pure: recharts is never imported (the prop types
|
|
10
|
+
* here are structural, read from recharts 3.8 and later); React's `createElement` builds the SVG `<image>` each prop
|
|
11
|
+
* returns. Call after `loadLeague(league)` / `preloadAll()`. The court / field / rink backdrop is a component,
|
|
12
|
+
* `<SurfaceBackdrop>` in `sdvplot/react`.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/** What Recharts hands a series' `dot` (Line, Area, Radar) or `shape` (Scatter) render prop: the subset read here. */
|
|
16
|
+
interface RechartsDotProps {
|
|
17
|
+
/** The point's centre in px. */
|
|
18
|
+
cx?: number | string | undefined;
|
|
19
|
+
cy?: number | string | undefined;
|
|
20
|
+
/** The point's index in its series. */
|
|
21
|
+
index?: number | undefined;
|
|
22
|
+
/** The series' points (a Line's or Area's `dot`), so `last` can find the final one. */
|
|
23
|
+
points?: readonly unknown[] | undefined;
|
|
24
|
+
/** The data row the point was drawn from. */
|
|
25
|
+
payload?: any;
|
|
26
|
+
}
|
|
27
|
+
/** What Recharts hands an axis' `tick` render prop: the subset read here. */
|
|
28
|
+
interface RechartsTickProps {
|
|
29
|
+
/** The tick label's anchor in px. */
|
|
30
|
+
x?: number | string | undefined;
|
|
31
|
+
y?: number | string | undefined;
|
|
32
|
+
/** The tick: `value` is the category the axis shows (a team). */
|
|
33
|
+
payload?: {
|
|
34
|
+
value?: any;
|
|
35
|
+
} | undefined;
|
|
36
|
+
/** Which side of the plot the axis is on. Default "bottom". */
|
|
37
|
+
orientation?: string | undefined;
|
|
38
|
+
/** The axis' tick text colour, kept for a category drawn as text. */
|
|
39
|
+
fill?: string | undefined;
|
|
40
|
+
}
|
|
41
|
+
/** A render prop for a series' `dot` or `shape`: an `<image>`, or nothing where no image can be drawn. */
|
|
42
|
+
type DotRenderer = (props: RechartsDotProps) => ReactElement | null;
|
|
43
|
+
/** A render prop for an axis' `tick`: an `<image>`, or the category's own text where no image can be drawn. */
|
|
44
|
+
type TickRenderer = (props: RechartsTickProps) => ReactElement;
|
|
45
|
+
interface Shared {
|
|
46
|
+
/** Image height in px, 1 or more (Recharts hands a render prop no plot height to take a fraction of). Default 24. */
|
|
47
|
+
size?: number;
|
|
48
|
+
/** Opacity in [0, 1]. Default 1. */
|
|
49
|
+
alpha?: number;
|
|
50
|
+
/**
|
|
51
|
+
* Draw only at the series' last point: an end-dot on a trend line. Default false. It needs the series' `points`,
|
|
52
|
+
* which Recharts hands a Line's or Area's `dot` but not a Scatter's `shape`: there every point is drawn, with one
|
|
53
|
+
* warning.
|
|
54
|
+
*/
|
|
55
|
+
last?: boolean;
|
|
56
|
+
/** url → data URI map from `embedSources`, to inline the images. */
|
|
57
|
+
embed?: ReadonlyMap<string, string>;
|
|
58
|
+
}
|
|
59
|
+
/** `logoDot` options. */
|
|
60
|
+
interface RechartsMarkOptions extends Shared {
|
|
61
|
+
/** Name of the data row column holding the team (abbreviation, name or id; see `idSystem`). */
|
|
62
|
+
team: string;
|
|
63
|
+
/** The league the teams belong to, e.g. "nba". */
|
|
64
|
+
league: League;
|
|
65
|
+
/** A season (number or string) for every row, or the name of a row column holding each row's season. */
|
|
66
|
+
season?: SeasonInput;
|
|
67
|
+
/** Logo variant, e.g. "dark". Default "default". */
|
|
68
|
+
variant?: Variant;
|
|
69
|
+
/** How the `team` values are read. Default "auto". */
|
|
70
|
+
idSystem?: IdSystem;
|
|
71
|
+
}
|
|
72
|
+
/** `headshotDot` options. */
|
|
73
|
+
interface RechartsHeadshotOptions extends Shared {
|
|
74
|
+
/** Name of the data row column holding the player id. */
|
|
75
|
+
player: string;
|
|
76
|
+
/** The league the players belong to, e.g. "nfl". */
|
|
77
|
+
league: EspnHeadshotLeague;
|
|
78
|
+
/** ESPN athlete ids, or nflverse gsis ids (needs `loadGsis()` first). Default "espn". */
|
|
79
|
+
idSystem?: HeadshotIdSystem;
|
|
80
|
+
}
|
|
81
|
+
/** `logoTick` options: the axis' categories are the teams. */
|
|
82
|
+
interface RechartsTickOptions {
|
|
83
|
+
/** The league the teams belong to, e.g. "nba". */
|
|
84
|
+
league: League;
|
|
85
|
+
/** The season the axis' teams are resolved for. */
|
|
86
|
+
season?: SeasonInput;
|
|
87
|
+
/** Image height in px, 1 or more. Default 24. */
|
|
88
|
+
size?: number;
|
|
89
|
+
/** Logo variant, e.g. "dark". Default "default". */
|
|
90
|
+
variant?: Variant;
|
|
91
|
+
/** "logo" (default) or "wordmark". */
|
|
92
|
+
markType?: MarkType;
|
|
93
|
+
/** How the axis categories are read. Default "auto". */
|
|
94
|
+
idSystem?: IdSystem;
|
|
95
|
+
/** url → data URI map from `embedSources`, to inline the images. */
|
|
96
|
+
embed?: ReadonlyMap<string, string>;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Team logos as a series' points: the `dot` of a `<Line>` / `<Area>`, or the `shape` of a `<Scatter>`. Each point
|
|
100
|
+
* draws the logo of its data row's `team` column, `size` px tall and centred on the point; `last: true` draws only
|
|
101
|
+
* the series' final point (an end-dot). A team with no logo draws nothing and warns once, as `sdvplot/echarts` does.
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```tsx
|
|
105
|
+
* import { loadLeague } from "@sportsdataverse/sdvplot";
|
|
106
|
+
* import { logoDot } from "@sportsdataverse/sdvplot/recharts";
|
|
107
|
+
* import { Scatter, ScatterChart, XAxis, YAxis } from "recharts";
|
|
108
|
+
*
|
|
109
|
+
* await loadLeague("nfl");
|
|
110
|
+
* const rows = [
|
|
111
|
+
* { team: "KC", pf: 385, pa: 326 },
|
|
112
|
+
* { team: "LAC", pf: 402, pa: 301 },
|
|
113
|
+
* ];
|
|
114
|
+
* <ScatterChart width={400} height={300}>
|
|
115
|
+
* <XAxis dataKey="pf" type="number" domain={[350, 450]} />
|
|
116
|
+
* <YAxis dataKey="pa" type="number" domain={[280, 350]} />
|
|
117
|
+
* <Scatter data={rows} shape={logoDot({ team: "team", league: "nfl", size: 32 })} />
|
|
118
|
+
* </ScatterChart>;
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
declare function logoDot(o: RechartsMarkOptions): DotRenderer;
|
|
122
|
+
/** ESPN player headshots as a series' points (`dot` or `shape`), from the data row's `player` column; an id with no
|
|
123
|
+
* headshot draws nothing and warns once. `idSystem: "gsis"` needs `loadGsis()` first. */
|
|
124
|
+
declare function headshotDot(o: RechartsHeadshotOptions): DotRenderer;
|
|
125
|
+
/**
|
|
126
|
+
* Team logos as an axis' tick labels: the `tick` of a category `<XAxis>` / `<YAxis>` whose values are teams. The
|
|
127
|
+
* logo sits where the label would (under a bottom axis, left of a left one). A category that resolves to no logo keeps
|
|
128
|
+
* its text label, as `sdvplot/echarts`' `withAxisLogos` does.
|
|
129
|
+
*/
|
|
130
|
+
declare function logoTick(o: RechartsTickOptions): TickRenderer;
|
|
131
|
+
/** `teamColorPalette` options. */
|
|
132
|
+
interface RechartsColorOptions {
|
|
133
|
+
which?: Which;
|
|
134
|
+
season?: SeasonInput;
|
|
135
|
+
idSystem?: IdSystem;
|
|
136
|
+
/** The colour of an unresolved team. Default "#808080". */
|
|
137
|
+
fallback?: string;
|
|
138
|
+
/**
|
|
139
|
+
* The chart's background. Given, a team colour under 3:1 contrast against it is swapped for the team's other
|
|
140
|
+
* colour, else moved towards white (on a dark background) or black (a light one) until it reads: dark mode. A
|
|
141
|
+
* colour that would then sit too close to an earlier team's (CIE76 ΔE under 20) takes the team's other colour, or
|
|
142
|
+
* the nearest colour to its own (lightness, hue or chroma stepped) that is distinct and still reads; failing that it
|
|
143
|
+
* is kept, with one warning.
|
|
144
|
+
*/
|
|
145
|
+
background?: string;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* One colour per team, in order, for each series' `stroke` / `fill`. With `background`, every colour keeps 3:1
|
|
149
|
+
* contrast against it (dark mode) and stays distinct from the others.
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```tsx
|
|
153
|
+
* import { loadLeague } from "@sportsdataverse/sdvplot";
|
|
154
|
+
* import { teamColorPalette } from "@sportsdataverse/sdvplot/recharts";
|
|
155
|
+
*
|
|
156
|
+
* await loadLeague("nba");
|
|
157
|
+
* teamColorPalette("nba", ["Clippers", "Suns", "Lakers"], { background: "#181a1b" });
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
declare function teamColorPalette(league: League, teams: readonly unknown[], o?: RechartsColorOptions): string[];
|
|
161
|
+
|
|
162
|
+
export { type DotRenderer, type RechartsColorOptions, type RechartsDotProps, type RechartsHeadshotOptions, type RechartsMarkOptions, type RechartsTickOptions, type RechartsTickProps, type TickRenderer, headshotDot, logoDot, logoTick, teamColorPalette };
|
package/dist/recharts.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { headshotDot, logoDot, logoTick, teamColorPalette } from './chunk-M3XD2OSN.js';
|
|
2
|
+
export { embedSources } from './chunk-UL5M6KDE.js';
|
|
3
|
+
import './chunk-7ULOCCFL.js';
|
|
4
|
+
import './chunk-ZAEQXFJM.js';
|
|
5
|
+
import './chunk-J6R2LEJ7.js';
|
|
6
|
+
import './chunk-E7G7VSLV.js';
|
|
7
|
+
//# sourceMappingURL=recharts.js.map
|
|
8
|
+
//# sourceMappingURL=recharts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"recharts.js"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { S as SeasonInput, I as IdSystem, T as TeamId, L as League } from './types-C7n6gJF3.js';
|
|
2
|
+
|
|
3
|
+
type Value = string | number | bigint | null | undefined;
|
|
4
|
+
type Resolved<T> = T extends readonly Value[] ? (TeamId | undefined)[] : TeamId | undefined;
|
|
5
|
+
interface ResolveOptions {
|
|
6
|
+
season?: SeasonInput | readonly SeasonInput[];
|
|
7
|
+
idSystem?: IdSystem;
|
|
8
|
+
strict?: boolean;
|
|
9
|
+
}
|
|
10
|
+
declare function resolveSync<T extends Value | readonly Value[]>(values: T, league: League, opts?: ResolveOptions): Resolved<T>;
|
|
11
|
+
/**
|
|
12
|
+
* Resolve team values (abbreviations, ids, names) to ESPN team ids, loading the league first. Unknown values give
|
|
13
|
+
* `undefined` and one warning per call; `strict: true` throws `UnresolvedTeamError`.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* import { resolve } from "@sportsdataverse/sdvplot";
|
|
18
|
+
*
|
|
19
|
+
* await resolve(["KC", "Kansas City Chiefs", "OAK"], "nfl", { season: 2019 });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
declare function resolve<T extends Value | readonly Value[]>(values: T, league: League, opts?: ResolveOptions): Promise<Resolved<T>>;
|
|
23
|
+
/** Port of `suggest`: difflib.get_close_matches(cutoff 0.6): SequenceMatcher(a=candidate, b=query).ratio() ≥ 0.6, best first, ties by candidate key descending; never picks one. */
|
|
24
|
+
declare function suggest(value: Value, league: League, opts?: {
|
|
25
|
+
n?: number;
|
|
26
|
+
}): Promise<Array<[TeamId, string]>>;
|
|
27
|
+
|
|
28
|
+
export { type ResolveOptions as R, type Value as V, type Resolved as a, resolveSync as b, resolve as r, suggest as s };
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A row test, true to keep the row: the brush region (or any caller's) as a predicate. The one definition: sdvtables
|
|
3
|
+
* re-exports this type for `setExternalFilter`, so a linked table applies a store's predicate as is (not a
|
|
4
|
+
* `ValuePredicate`, which tests one column's cell). Both compare it by identity: the same function again is a no-op.
|
|
5
|
+
*/
|
|
6
|
+
type RowFilter<Row> = (row: Row) => boolean;
|
|
7
|
+
/**
|
|
8
|
+
* A shared hover VALUE (J34): a number along one data field, such as the shot distance under the pointer, that every
|
|
9
|
+
* linked chart draws through its own scale (a rule, a band, a ring). Not an id: it never dims marks or filters a table.
|
|
10
|
+
* Unrelated to sdvtables' `TableCursor` (a grid's keyboard row).
|
|
11
|
+
*/
|
|
12
|
+
interface Cursor {
|
|
13
|
+
/** The data field the value is in, e.g. `"shot_distance"`. Never `""`. */
|
|
14
|
+
readonly field: string;
|
|
15
|
+
/** The value along that field. Always finite. */
|
|
16
|
+
readonly value: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* What a {@link SelectionStore} holds. Immutable: every change replaces it, and a snapshot is read-only at runtime too
|
|
20
|
+
* (its sets' `add`, `delete` and `clear`, and a write to it or its cursor, throw a `TypeError`): pass changes to
|
|
21
|
+
* `store.set`, or copy a set with `new Set(ids)`.
|
|
22
|
+
*/
|
|
23
|
+
interface SelectionState<Row = unknown> {
|
|
24
|
+
/** Ids under the pointer right now (transient). */
|
|
25
|
+
readonly hover: ReadonlySet<string>;
|
|
26
|
+
/** Ids picked by a table-row click or a brush (sticky). */
|
|
27
|
+
readonly selected: ReadonlySet<string>;
|
|
28
|
+
/** The brush region as a row test; null when nothing is brushed. */
|
|
29
|
+
readonly predicate: RowFilter<Row> | null;
|
|
30
|
+
/** The shared hover value; null when the pointer is on no linked chart. */
|
|
31
|
+
readonly cursor: Cursor | null;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* A partial update for {@link SelectionStore.set}: an absent field keeps its value. Each id goes through
|
|
35
|
+
* {@link toId}: a number is stringified (`12` and `"12"` are the same id) and null, undefined, NaN and `""` are
|
|
36
|
+
* dropped. A bare string throws `InputError` rather than being split into letters: pass `["KC"]`, not `"KC"`.
|
|
37
|
+
*/
|
|
38
|
+
interface SelectionPatch<Row = unknown> {
|
|
39
|
+
/** The new hover ids (replaces the set; `[]` clears it). */
|
|
40
|
+
readonly hover?: Iterable<string>;
|
|
41
|
+
/** The new selected ids (replaces the set; `[]` clears it). */
|
|
42
|
+
readonly selected?: Iterable<string>;
|
|
43
|
+
/** The new brush region; `null` clears it. */
|
|
44
|
+
readonly predicate?: RowFilter<Row> | null;
|
|
45
|
+
/** The new hover value; `null` clears it. An equal cursor (same field, same value) is a no-op. */
|
|
46
|
+
readonly cursor?: Cursor | null;
|
|
47
|
+
}
|
|
48
|
+
/** The linked-interactivity hub that {@link createSelection} returns. */
|
|
49
|
+
interface SelectionStore<Row = unknown> {
|
|
50
|
+
/** Referentially stable until the next change: what `useSyncExternalStore` reads. */
|
|
51
|
+
getState(): SelectionState<Row>;
|
|
52
|
+
/** Apply a patch. ONE notification when anything changed, none when nothing did, so linked components cannot ping-pong. */
|
|
53
|
+
set(patch: SelectionPatch<Row>): void;
|
|
54
|
+
/** Clear hover, selected, predicate and cursor. */
|
|
55
|
+
clear(): void;
|
|
56
|
+
/**
|
|
57
|
+
* Call `fn` after every change; returns the unsubscribe function. A listener that throws stops neither the others
|
|
58
|
+
* nor `set`: its error is rethrown in a microtask, as an `EventTarget` listener's is, so it still reaches
|
|
59
|
+
* `window.onerror` (or Node's `uncaughtException`) but one broken view cannot freeze the rest. A listener removed
|
|
60
|
+
* during a notification is not called for it.
|
|
61
|
+
*/
|
|
62
|
+
subscribe(fn: (state: SelectionState<Row>) => void): () => void;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* The link id of a value: `String(v)`, or `""` (never matched) for null, undefined, NaN and `""`. A figure and a table
|
|
66
|
+
* link only when they hold the same ids, so an ESPN team id (`"12"`) never matches an abbreviation (`"KC"`).
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* import { toId } from "@sportsdataverse/sdvplot";
|
|
71
|
+
*
|
|
72
|
+
* [toId(12), toId("KC"), toId(null), toId(Number.NaN)];
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
declare function toId(v: unknown): string;
|
|
76
|
+
/**
|
|
77
|
+
* Whether two id sets hold the same ids, in any order.
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```ts
|
|
81
|
+
* import { sameIds } from "@sportsdataverse/sdvplot";
|
|
82
|
+
*
|
|
83
|
+
* sameIds(new Set(["KC", "BUF"]), new Set(["BUF", "KC"]));
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
declare function sameIds(a: ReadonlySet<string>, b: ReadonlySet<string>): boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Whether two cursors are the same: the same field and an `===`-equal value, so `0` and `-0` are one hover value
|
|
89
|
+
* (NaN never gets into the store). `null` equals only `null`.
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```ts
|
|
93
|
+
* import { sameCursor } from "@sportsdataverse/sdvplot";
|
|
94
|
+
*
|
|
95
|
+
* const rim = { field: "shot_distance", value: 0.5 }; // the centre of the 0-1 ft bin
|
|
96
|
+
* [
|
|
97
|
+
* sameCursor(rim, { field: "shot_distance", value: 0.5 }), // a new object, the same value: true
|
|
98
|
+
* sameCursor(rim, { field: "shot_distance", value: 1.5 }), // the next bin: false
|
|
99
|
+
* sameCursor(rim, null), // the pointer left: false
|
|
100
|
+
* sameCursor(null, null),
|
|
101
|
+
* ];
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
declare function sameCursor(a: Cursor | null, b: Cursor | null): boolean;
|
|
105
|
+
/**
|
|
106
|
+
* What a figure should emphasise. `null`: nothing is active, draw everything normally. A set, possibly EMPTY
|
|
107
|
+
* (a brush that encloses no point): emphasise those ids and dim the rest. Hover and selected are unioned. The
|
|
108
|
+
* cursor is ignored: a shared hover value never dims anything.
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```ts
|
|
112
|
+
* import { createSelection, focusIds } from "@sportsdataverse/sdvplot";
|
|
113
|
+
*
|
|
114
|
+
* const store = createSelection();
|
|
115
|
+
* const idle = focusIds(store.getState()); // null: draw everything normally
|
|
116
|
+
* store.set({ selected: ["KC"], hover: ["BUF"] });
|
|
117
|
+
* ({ idle, focus: [...(focusIds(store.getState()) ?? [])] });
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
declare function focusIds<Row>(s: SelectionState<Row>): ReadonlySet<string> | null;
|
|
121
|
+
/**
|
|
122
|
+
* The linked-interactivity hub (J31): hover and selected id sets plus a row predicate. Pure data, zero deps, no DOM:
|
|
123
|
+
* creating or updating one in Node changes nothing a server renders. Ids are strings, normalised by {@link toId}
|
|
124
|
+
* (see {@link SelectionPatch}).
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ```ts
|
|
128
|
+
* import { createSelection } from "@sportsdataverse/sdvplot";
|
|
129
|
+
*
|
|
130
|
+
* const store = createSelection();
|
|
131
|
+
* let updates = 0;
|
|
132
|
+
* store.subscribe(() => updates++);
|
|
133
|
+
* store.set({ selected: ["KC", "BUF"] });
|
|
134
|
+
* store.set({ selected: ["BUF", "KC"] }); // the same ids: silent, so linked views cannot ping-pong
|
|
135
|
+
* ({ updates, selected: [...store.getState().selected] });
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
declare function createSelection<Row = unknown>(): SelectionStore<Row>;
|
|
139
|
+
|
|
140
|
+
export { type Cursor as C, type RowFilter as R, type SelectionStore as S, type SelectionState as a, type SelectionPatch as b, createSelection as c, sameIds as d, focusIds as f, sameCursor as s, toId as t };
|
package/dist/shadcn.d.ts
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { ComponentType } from 'react';
|
|
2
|
+
import { W as Which, S as SeasonInput, I as IdSystem, L as League } from './types-C7n6gJF3.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The shadcn/ui charts adapter. shadcn's charts are Recharts charts inside its copy-paste `chart.tsx`
|
|
6
|
+
* (`<ChartContainer config>`, `<ChartLegendContent>`, `<ChartTooltipContent>`), configured by a `ChartConfig`:
|
|
7
|
+
* `teamChartConfig` builds that config from teams, with CSS-safe keys, team colours for its light and dark themes,
|
|
8
|
+
* team names as labels and team logos as the legend's and tooltip's icons. Draw the series with `sdvplot/recharts`
|
|
9
|
+
* (`logoTick`, `logoDot`) as for any Recharts chart. Pure: shadcn is not a package (you copy `chart.tsx` into your
|
|
10
|
+
* app) and recharts is never imported, so the config's types are structural (read from shadcn's new-york-v4
|
|
11
|
+
* `chart.tsx`); React's `createElement` builds the icons. Call after `loadLeague(league)` / `preloadAll()`.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* One team's entry in the config: shadcn's `ChartConfig` item with a `theme` (never a single `color`), so
|
|
16
|
+
* `<ChartStyle>` writes the light colour under the chart and the dark one under `.dark`.
|
|
17
|
+
*/
|
|
18
|
+
interface TeamChartConfigItem {
|
|
19
|
+
/** The team's name, e.g. "Kansas City Chiefs" (its own value when it does not resolve). */
|
|
20
|
+
label: string;
|
|
21
|
+
/** The team's colour on a light chart and on a dark one, each 3:1 or more against that theme's background. */
|
|
22
|
+
theme: {
|
|
23
|
+
light: string;
|
|
24
|
+
dark: string;
|
|
25
|
+
};
|
|
26
|
+
/** The team's logo, at legend and tooltip size; absent when the team has no logo (shadcn draws its swatch). */
|
|
27
|
+
icon?: ComponentType;
|
|
28
|
+
}
|
|
29
|
+
/** What `teamChartConfig` returns. */
|
|
30
|
+
interface TeamChartConfig {
|
|
31
|
+
/** shadcn's `ChartConfig`, keyed by `keys`: pass it to `<ChartContainer config>`. */
|
|
32
|
+
config: Record<string, TeamChartConfigItem>;
|
|
33
|
+
/**
|
|
34
|
+
* `keys[i]` is `teams[i]`'s key in `config`: name a series' `dataKey` with it, colour it `var(--color-<key>)`, and
|
|
35
|
+
* put it in a row column for `<ChartTooltipContent nameKey>`. A clash is numbered in the order of `teams` (`lal`,
|
|
36
|
+
* `lal-2`), so read the key here rather than recomputing it, and pass each team once.
|
|
37
|
+
*/
|
|
38
|
+
keys: string[];
|
|
39
|
+
}
|
|
40
|
+
/** `teamChartConfig` options. */
|
|
41
|
+
interface TeamChartConfigOptions {
|
|
42
|
+
/** The team colour taken first: "primary" (default) or "secondary". */
|
|
43
|
+
which?: Which;
|
|
44
|
+
/** The season the teams (their names, colours and logos) are resolved for. */
|
|
45
|
+
season?: SeasonInput;
|
|
46
|
+
/** How the `teams` values are read. Default "auto". */
|
|
47
|
+
idSystem?: IdSystem;
|
|
48
|
+
/**
|
|
49
|
+
* The chart backgrounds the colours must read on (3:1 contrast), as hex. Default shadcn's neutral theme: `light`
|
|
50
|
+
* #ffffff (its page and card), `dark` #171717 (its dark card, `oklch(0.205 0 0)`; a colour that reads on it reads
|
|
51
|
+
* on the darker dark page, #0a0a0a, too).
|
|
52
|
+
*/
|
|
53
|
+
background?: {
|
|
54
|
+
light?: string;
|
|
55
|
+
dark?: string;
|
|
56
|
+
};
|
|
57
|
+
/** `false`: no logos, so shadcn draws its colour swatch for every team. Default true. */
|
|
58
|
+
icon?: boolean;
|
|
59
|
+
/** The logo's height in px, 1 or more, rounded to a whole px. Default 16. */
|
|
60
|
+
iconSize?: number;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* shadcn's `ChartConfig` for teams: one entry per team, keyed for CSS (team names like "Trail Blazers" are not valid
|
|
64
|
+
* custom property names), with the team's name as `label`, its colour on shadcn's light and dark backgrounds as
|
|
65
|
+
* `theme` (3:1 contrast on each, and distinct from the other teams'), and its logo as `icon`, which
|
|
66
|
+
* `<ChartLegendContent>` and `<ChartTooltipContent>` draw in place of their colour swatch. A team with no logo has
|
|
67
|
+
* no `icon` (shadcn falls back to the swatch) and warns once. The icons are the same components for the same logo
|
|
68
|
+
* on every call, so building the config inside a component's render is safe.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```ts
|
|
72
|
+
* import { loadLeague } from "@sportsdataverse/sdvplot";
|
|
73
|
+
* import { teamChartConfig } from "@sportsdataverse/sdvplot/shadcn";
|
|
74
|
+
*
|
|
75
|
+
* await loadLeague("nba");
|
|
76
|
+
* // "Trail Blazers" is not a CSS name: its key is "trail-blazers", a series' dataKey and var(--color-trail-blazers)
|
|
77
|
+
* const { config, keys } = teamChartConfig("nba", ["Trail Blazers", "Lakers"]);
|
|
78
|
+
* [keys, config["trail-blazers"]?.label, config["trail-blazers"]?.theme];
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
declare function teamChartConfig(league: League, teams: readonly unknown[], o?: TeamChartConfigOptions): TeamChartConfig;
|
|
82
|
+
|
|
83
|
+
export { type TeamChartConfig, type TeamChartConfigItem, type TeamChartConfigOptions, teamChartConfig };
|