Skip to content

Commit

Permalink
Deprecate property 't' in <Parametric> in favor of 'domain'.
Browse files Browse the repository at this point in the history
Add 'domain' property to <Plot.OfX> and <Plot.OfY> so that users can apply their own limits to the plots.
  • Loading branch information
Mark Fitzgerald committed Jun 25, 2024
1 parent 4520319 commit 2022e7d
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 13 deletions.
14 changes: 9 additions & 5 deletions src/display/Plot/OfX.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,24 @@ import { usePaneContext } from "../../context/PaneContext"
import { Parametric, ParametricProps } from "./Parametric"
import { vec } from "../../vec"

export interface OfXProps extends Omit<ParametricProps, "xy" | "t"> {
export interface OfXProps extends Omit<ParametricProps, "xy" | "domain" | "t"> {
y: (x: number) => number
domain?: {min?: number, max?: number}
svgPathProps?: React.SVGProps<SVGPathElement>
}

export function OfX({ y, ...props }: OfXProps) {
export function OfX({ y, domain, ...props }: OfXProps) {
const {
xPaneRange: [xMin, xMax],
xPaneRange: [xpMin, xpMax],
} = usePaneContext()
// Determine the most restrictive range values (either user-provided or the pane context)
const xMin = Math.max(xpMin, domain?.min ?? -Infinity)
const xMax = Math.min(xpMax, domain?.max ?? Infinity)

const xy = React.useCallback<ParametricProps["xy"]>((x) => [x, y(x)], [y])
const t = React.useMemo<vec.Vector2>(() => [xMin, xMax], [xMin, xMax])
const parametricDomain = React.useMemo<vec.Vector2>(() => [xMin, xMax], [xMin, xMax])

return <Parametric xy={xy} t={t} {...props} />
return <Parametric xy={xy} domain={parametricDomain} {...props} />
}

OfX.displayName = "Plot.OfX"
14 changes: 9 additions & 5 deletions src/display/Plot/OfY.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,24 @@ import { usePaneContext } from "../../context/PaneContext"
import { Parametric, ParametricProps } from "./Parametric"
import { vec } from "../../vec"

export interface OfYProps extends Omit<ParametricProps, "xy" | "t"> {
export interface OfYProps extends Omit<ParametricProps, "xy" | "domain" | "t"> {
x: (y: number) => number
domain?: {min?: number, max?: number}
svgPathProps?: React.SVGProps<SVGPathElement>
}

export function OfY({ x, ...props }: OfYProps) {
export function OfY({ x, domain, ...props }: OfYProps) {
const {
yPaneRange: [yMin, yMax],
yPaneRange: [ypMin, ypMax],
} = usePaneContext()
// Determine the most restrictive range values (either user-provided or the pane context)
const yMin = Math.max(ypMin, domain?.min ?? -Infinity)
const yMax = Math.min(ypMax, domain?.max ?? Infinity)

const xy = React.useCallback<ParametricProps["xy"]>((y) => [x(y), y], [x])
const t = React.useMemo<vec.Vector2>(() => [yMin, yMax], [yMin, yMax])
const parametricDomain = React.useMemo<vec.Vector2>(() => [yMin, yMax], [yMin, yMax])

return <Parametric xy={xy} t={t} {...props} />
return <Parametric xy={xy} domain={parametricDomain} {...props} />
}

OfY.displayName = "Plot.OfY"
30 changes: 27 additions & 3 deletions src/display/Plot/Parametric.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@ import { Stroked } from "../Theme"
import { useTransformContext } from "../../context/TransformContext"
import { sampleParametric } from "./PlotUtils"

export interface ParametricProps extends Stroked {
interface ParametricPropsLegacy extends Stroked {
/** A function that takes a `t` value and returns a point. */
xy: (t: number) => vec.Vector2
/** The domain `t` between which to evaluate `xy`. */
/** The domain between which to evaluate `xy`. */
domain?: never
/**
* @deprecated - use the `domain` prop.
*/
t: vec.Vector2
/** The minimum recursive depth of the sampling algorithm. */
minSamplingDepth?: number
Expand All @@ -17,8 +21,28 @@ export interface ParametricProps extends Stroked {
svgPathProps?: React.SVGProps<SVGPathElement>
}

interface ParametricPropsNew extends Stroked {
/** A function that takes a `t` value and returns a point. */
xy: (t: number) => vec.Vector2
/** The domain between which to evaluate `xy`. */
domain: vec.Vector2
/**
* @deprecated - use the `domain` prop.
*/
t?: never
/** The minimum recursive depth of the sampling algorithm. */
minSamplingDepth?: number
/** The maximum recursive depth of the sampling algorithm. */
maxSamplingDepth?: number

svgPathProps?: React.SVGProps<SVGPathElement>
}

export type ParametricProps = ParametricPropsNew | ParametricPropsLegacy

export function Parametric({
xy,
domain,
t,
color,
style = "solid",
Expand All @@ -33,7 +57,7 @@ export function Parametric({
// Negative because the y-axis is flipped in the SVG coordinate system.
const pixelsPerSquare = -vec.det(viewTransform)

const [tMin, tMax] = t
const [tMin, tMax] = domain || t
const errorThreshold = 0.1 / pixelsPerSquare

const svgPath = React.useMemo(
Expand Down

0 comments on commit 2022e7d

Please sign in to comment.