Skip to content

Commit

Permalink
Cleaning up Point state to save us potential pain in the future.
Browse files Browse the repository at this point in the history
  • Loading branch information
catandthemachines committed Dec 11, 2024
1 parent 16f28fe commit 0a986b1
Showing 1 changed file with 50 additions and 35 deletions.
85 changes: 50 additions & 35 deletions packages/perseus/src/widgets/interactive-graphs/graphs/point.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,10 @@ import useGraphConfig from "../reducer/use-graph-config";

import {MovablePoint} from "./components/movable-point";
import {srFormatNumber} from "./screenreader-text";
import {
useTransformDimensionsToPixels,
useTransformVectorsToPixels,
pixelsToVectors,
} from "./use-transform";
import {useTransformVectorsToPixels, pixelsToVectors} from "./use-transform";

import type {PerseusStrings} from "../../../strings";
import type {GraphConfig} from "../reducer/use-graph-config";
import type {
PointGraphState,
MafsGraphProps,
Expand All @@ -30,23 +27,54 @@ export function renderPointGraph(
};
}

type PointGraphProps = MafsGraphProps<PointGraphState>;
type Props = MafsGraphProps<PointGraphState>;
type StatefulProps = Props & {
graphConfig: GraphConfig;
pointsRef: React.MutableRefObject<(SVGElement | null)[]>;
top: number;
left: number;
};

function PointGraph(props: Props) {
const {numPoints} = props.graphState;
const graphConfig = useGraphConfig();
const pointsRef = React.useRef<Array<SVGElement | null>>([]);

// Dimensions to build the graph overlay for Unlimited Point.
const {
range: [x, y],
} = graphConfig;
const [[left, top]] = useTransformVectorsToPixels([x[0], y[1]]);

// This useEffect is to handle the focus snapping for Unlimited Point.
React.useEffect(() => {
const focusedIndex = props.graphState.focusedPointIndex;
if (focusedIndex != null) {
pointsRef.current[focusedIndex]?.focus();
}
}, [props.graphState.focusedPointIndex, pointsRef]);

const statefulProps = {
...props,
graphConfig,
pointsRef,
top,
left,
};

function PointGraph(props: PointGraphProps) {
const numPoints = props.graphState.numPoints;
if (numPoints === "unlimited") {
return UnlimitedPointGraph(props);
return UnlimitedPointGraph(statefulProps);
}

return LimitedPointGraph(props);
return LimitedPointGraph(statefulProps);
}

function LimitedPointGraph(props: PointGraphProps) {
const {dispatch} = props;
function LimitedPointGraph(statefulProps: StatefulProps) {
const {dispatch} = statefulProps;

return (
<>
{props.graphState.coords.map((point, i) => (
{statefulProps.graphState.coords.map((point, i) => (
<MovablePoint
key={i}
point={point}
Expand All @@ -60,27 +88,14 @@ function LimitedPointGraph(props: PointGraphProps) {
);
}

function UnlimitedPointGraph(props: PointGraphProps) {
const {dispatch} = props;
const graphConfig = useGraphConfig();
const {
range: [[minX, maxX], [minY, maxY]],
} = graphConfig;
const width = maxX - minX;
const height = maxY - minY;
const [[widthPx, heightPx]] = useTransformDimensionsToPixels([
width,
height,
]);
const [[left, top]] = useTransformVectorsToPixels([minX, maxY]);
const itemsRef = React.useRef<Array<SVGElement | null>>([]);
function UnlimitedPointGraph(statefulProps: StatefulProps) {
const {dispatch, graphConfig, pointsRef, top, left} = statefulProps;
const {coords} = statefulProps.graphState;

React.useEffect(() => {
const focusedIndex = props.graphState.focusedPointIndex;
if (focusedIndex != null) {
itemsRef.current[focusedIndex]?.focus();
}
}, [props.graphState.focusedPointIndex, itemsRef]);
const {graphDimensionsInPixels} = graphConfig;

const widthPx = graphDimensionsInPixels[0];
const heightPx = graphDimensionsInPixels[1];

return (
<>
Expand Down Expand Up @@ -110,7 +125,7 @@ function UnlimitedPointGraph(props: PointGraphProps) {
dispatch(actions.pointGraph.addPoint(graphCoordinates[0]));
}}
/>
{props.graphState.coords.map((point, i) => (
{coords.map((point, i) => (
<MovablePoint
key={i}
point={point}
Expand All @@ -119,7 +134,7 @@ function UnlimitedPointGraph(props: PointGraphProps) {
dispatch(actions.pointGraph.movePoint(i, destination))
}
ref={(ref) => {
itemsRef.current[i] = ref;
pointsRef.current[i] = ref;
}}
onFocus={() => {
dispatch(actions.pointGraph.focusPoint(i));
Expand Down

0 comments on commit 0a986b1

Please sign in to comment.