Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/heavy-deers-whisper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@khanacademy/perseus": minor
"@khanacademy/perseus-core": minor
"@khanacademy/perseus-editor": minor
---

Creation of initial types and stubs for Vector graph
27 changes: 25 additions & 2 deletions packages/perseus-core/src/data-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1110,7 +1110,8 @@ export type PerseusGraphType =
| PerseusGraphTypeSinusoid
| PerseusGraphTypeExponential
| PerseusGraphTypeTangent
| PerseusGraphTypeLogarithm;
| PerseusGraphTypeLogarithm
| PerseusGraphTypeVector;

export type PerseusGraphTypeAngle = {
type: "angle";
Expand Down Expand Up @@ -1277,6 +1278,18 @@ export type PerseusGraphTypeRay = {
startCoords?: CollinearTuple;
};

export type PerseusGraphTypeVector = {
type: "vector";
/** The tail and tip coordinates of the vector: [tail, tip] */
coords?: CollinearTuple | null;
/** The initial coordinates the graph renders with. */
startCoords?: CollinearTuple;
/** How to match the answer.
* "exact" (default) — both tail and tip must match exactly.
* "congruent" — same direction and magnitude, any position. */
match?: "exact" | "congruent";
};

type AbsoluteValueGraphCorrect = {
type: "absolute-value";
coords: [Coord, Coord];
Expand Down Expand Up @@ -1357,6 +1370,15 @@ type RayGraphCorrect = {
coords: CollinearTuple;
};

type VectorGraphCorrect = {
type: "vector";
coords: CollinearTuple;
/** How to match the answer.
* "exact" (default) — both tail and tip must match exactly.
* "congruent" — same direction and magnitude, any position. */
match?: "exact" | "congruent";
};

export type PerseusGraphCorrectType =
| AbsoluteValueGraphCorrect
| AngleGraphCorrect
Expand All @@ -1372,7 +1394,8 @@ export type PerseusGraphCorrectType =
| SinusoidGraphCorrect
| ExponentialGraphCorrect
| TangentGraphCorrect
| LogarithmGraphCorrect;
| LogarithmGraphCorrect
| VectorGraphCorrect;

/** Options for the label-image widget. Asks learners to label image parts. */
export type PerseusLabelImageWidgetOptions = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,13 @@ const parsePerseusGraphTypeLogarithm = object({
),
});

const parsePerseusGraphTypeVector = object({
type: constant("vector"),
coords: optional(nullable(pair(pairOfNumbers, pairOfNumbers))),
startCoords: optional(pair(pairOfNumbers, pairOfNumbers)),
match: optional(enumeration("exact", "congruent")),
});

export const parsePerseusGraphType = discriminatedUnionOn("type")
.withBranch("absolute-value", parsePerseusGraphTypeAbsoluteValue)
.withBranch("angle", parsePerseusGraphTypeAngle)
Expand All @@ -164,7 +171,8 @@ export const parsePerseusGraphType = discriminatedUnionOn("type")
.withBranch("segment", parsePerseusGraphTypeSegment)
.withBranch("sinusoid", parsePerseusGraphTypeSinusoid)
.withBranch("tangent", parsePerseusGraphTypeTangent)
.withBranch("logarithm", parsePerseusGraphTypeLogarithm).parser;
.withBranch("logarithm", parsePerseusGraphTypeLogarithm)
.withBranch("vector", parsePerseusGraphTypeVector).parser;

const parseLockedFigureColor = enumeration(...lockedFigureColorNames);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,9 @@ function mergeGraphs(
case "logarithm":
invariant(b.type === "logarithm");
return {...a, ...b};
case "vector":
invariant(b.type === "vector");
return {...a, ...b};
default:
throw new UnreachableCaseError(a);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ export const shouldShowStartCoordsUI = (
case "sinusoid":
case "absolute-value":
case "logarithm":
case "vector":
return true;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a note: At this point of the PR this is ideally false, but since this is a stacked PRs and will be merging it soon, this will be okay.

default:
throw new UnreachableCaseError(graph);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ type LogarithmGraphOptions = {
startCoords?: {coords: readonly [Coord, Coord]; asymptote: number};
};

type VectorGraphOptions = {
type: "vector";
startCoords?: CollinearTuple;
};

type NoneGraphOptions = Record<string, never>;

type GraphOptions =
Expand All @@ -109,7 +114,8 @@ type GraphOptions =
| SegmentGraphOptions
| SinusoidGraphOptions
| TangentGraphOptions
| LogarithmGraphOptions;
| LogarithmGraphOptions
| VectorGraphOptions;

type AngleUserInput = {
coords?: readonly [Coord, Coord, Coord];
Expand Down Expand Up @@ -175,6 +181,10 @@ type TangentUserInput = {
coords?: readonly Coord[] | null;
};

type VectorUserInput = {
coords?: CollinearTuple | null;
};

type UserInput =
| AbsoluteValueUserInput
| AngleUserInput
Expand All @@ -189,7 +199,8 @@ type UserInput =
| SegmentUserInput
| SinusoidUserInput
| TangentUserInput
| LogarithmUserInput;
| LogarithmUserInput
| VectorUserInput;

/**
* JSON describing an interactive graph widget. Intended for consumption by AI tools.
Expand Down Expand Up @@ -328,6 +339,11 @@ const getGraphOptionsForProps = (
type: props.userInput.type,
startCoords: props.userInput.startCoords,
};
case "vector":
return {
type: props.userInput.type,
startCoords: props.userInput.startCoords,
};
default:
throw new UnreachableCaseError(type);
}
Expand Down Expand Up @@ -399,6 +415,10 @@ const getUserInput = (userInput: PerseusGraphType): UserInput => {
coords: userInput.coords,
asymptote: userInput.asymptote,
};
case "vector":
return {
coords: userInput.coords,
};
default:
throw new UnreachableCaseError(type);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,8 @@ class InteractiveGraph extends React.Component<Props, State> {
return InteractiveGraph.getTangentEquationString(props);
case "logarithm":
return InteractiveGraph.getLogarithmEquationString(props);
case "vector":
return "";
default:
throw new UnreachableCaseError(type);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,8 @@ const renderGraphElements = (props: {
return renderTangentGraph(state, dispatch, i18n);
case "logarithm":
return renderLogarithmGraph(state, dispatch, i18n);
case "vector":
throw new Error("Not implemented");
default:
throw new UnreachableCaseError(type);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ export function mafsStateToInteractiveGraph(
coords: state.coords,
asymptote: state.asymptote,
};
case "vector":
invariant(originalGraph.type === "vector");
return {
...originalGraph,
coords: state.coords,
};
default:
throw new UnreachableCaseError(state);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ export function initializeGraphState(
type: graph.type,
...getLogarithmCoords(graph, range, step),
};
case "vector":
throw new Error("Not implemented");
default:
throw new UnreachableCaseError(graph);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@ function doMovePointInFigure(
case "tangent":
case "exponential":
case "logarithm":
case "vector":
throw new Error(
`Don't use movePointInFigure for ${state.type} graphs. Use movePoint instead!`,
);
Expand Down
8 changes: 7 additions & 1 deletion packages/perseus/src/widgets/interactive-graphs/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ export type InteractiveGraphState =
| SinusoidGraphState
| ExponentialGraphState
| TangentGraphState
| LogarithmGraphState;
| LogarithmGraphState
| VectorGraphState;

export type UnlimitedGraphState = PointGraphState | PolygonGraphState;

Expand Down Expand Up @@ -91,6 +92,11 @@ export interface RayGraphState extends InteractiveGraphStateCommon {
coords: PairOfPoints;
}

interface VectorGraphState extends InteractiveGraphStateCommon {
type: "vector";
coords: PairOfPoints;
}

export interface PolygonGraphState extends InteractiveGraphStateCommon {
type: "polygon";
showAngles: boolean;
Expand Down