Skip to content

Commit 01cb73b

Browse files
authored
[Interactive Graph] [Locked Figures] Add weight option to locked polygon and locked polygon settings (#2649)
## Summary: To make locked figures easier to see over axis lines, and to give content authors a bit more freedom in how the locked figures look, we're adding a `weight` option to locked figures. Adding this `weight` select to the locked polygon editor and hooking it up to the rendered locked polygon here. Note: The schema has already been updated in the backend in `widgets.go`, so we should be okay to release this whenever. Issue: https://khanacademy.atlassian.net/browse/LEMS-3201 ## Demo: https://github.com/user-attachments/assets/c2fa668d-1da5-4d17-8823-dbfdcea577e3 ## Test plan: `pnpm jest packages/perseus/src/widgets/interactive-graphs/interactive-graph.test.tsx` `pnpm jest packages/perseus-core/src/parse-perseus-json/perseus-parsers/interactive-graph-widget.test.ts` `pnpm jest packages/perseus-editor/src/widgets/interactive-graph-editor/locked-figures/locked-polygon-settings.test.tsx` Storybook - Go to http://localhost:6006/?path=/story/perseuseditor-widgets-interactive-graph--locked-figures - Open the locked polygon settings - Change the weight using the weight select - Confirm that it updates the polygon in the preview Author: nishasy Reviewers: benchristel, nishasy, SonicScrewdriver, mark-fitzgerald Required Reviewers: Approved By: benchristel Checks: ✅ 8 checks were successful Pull Request URL: #2649
1 parent d1299f6 commit 01cb73b

File tree

17 files changed

+756
-8
lines changed

17 files changed

+756
-8
lines changed

.changeset/shaggy-apricots-lay.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@khanacademy/perseus": patch
3+
"@khanacademy/perseus-core": patch
4+
"@khanacademy/perseus-editor": patch
5+
---
6+
7+
[Interactive Graph][locked figures] Add `weight` option to locked polygon and locked polygon settings

packages/perseus-core/src/data-schema.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,8 @@ export const lockedFigureColors: Record<LockedFigureColor, string> = {
805805
orange: "#946700",
806806
} as const;
807807

808+
export type StrokeWeight = "thin" | "medium" | "thick";
809+
808810
export type LockedFigure =
809811
| LockedPointType
810812
| LockedLineType
@@ -873,6 +875,7 @@ export type LockedPolygonType = {
873875
showVertices: boolean;
874876
fillStyle: LockedFigureFillType;
875877
strokeStyle: LockedLineStyle;
878+
weight: StrokeWeight;
876879
labels: LockedLabelType[];
877880
ariaLabel?: string;
878881
};

packages/perseus-core/src/parse-perseus-json/perseus-parsers/interactive-graph-widget.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,11 @@ const parseLockedFigureFillType = enumeration(
137137

138138
const parseLockedLineStyle = enumeration("solid", "dashed");
139139

140+
export const parseStrokeWeight = defaulted(
141+
enumeration("medium", "thin", "thick"),
142+
() => "medium" as const,
143+
);
144+
140145
const parseLockedLabelType = object({
141146
type: constant("label"),
142147
coord: pairOfNumbers,
@@ -193,6 +198,7 @@ const parseLockedPolygonType = object({
193198
showVertices: boolean,
194199
fillStyle: parseLockedFigureFillType,
195200
strokeStyle: parseLockedLineStyle,
201+
weight: parseStrokeWeight,
196202
labels: defaulted(array(parseLockedLabelType), () => []),
197203
ariaLabel: optional(string),
198204
});

packages/perseus-core/src/parse-perseus-json/regression-tests/__snapshots__/parse-perseus-json-regression.test.ts.snap

Lines changed: 327 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8289,6 +8289,333 @@ Locked figures:
82898289
}
82908290
`;
82918291

8292+
exports[`parseAndMigratePerseusItem given interactive-graph-locked-polygon-missing-weight.json returns the same result as before 1`] = `
8293+
{
8294+
"answerArea": {
8295+
"calculator": false,
8296+
"chi2Table": false,
8297+
"financialCalculatorMonthlyPayment": false,
8298+
"financialCalculatorTimeToPayOff": false,
8299+
"financialCalculatorTotalAmount": false,
8300+
"periodicTable": false,
8301+
"periodicTableWithKey": false,
8302+
"tTable": false,
8303+
"zTable": false,
8304+
},
8305+
"hints": [
8306+
{
8307+
"content": "You'll want to select "B".",
8308+
"images": {},
8309+
"replace": false,
8310+
"widgets": {},
8311+
},
8312+
],
8313+
"question": {
8314+
"content": "**A "none"-type graph. Choose the correct radio button to get a point.**
8315+
8316+
[[☃ interactive-graph 1]]
8317+
8318+
[[☃ radio 1]]
8319+
8320+
",
8321+
"images": {},
8322+
"widgets": {
8323+
"interactive-graph 1": {
8324+
"alignment": "default",
8325+
"graded": true,
8326+
"options": {
8327+
"backgroundImage": {
8328+
"url": null,
8329+
},
8330+
"correct": {
8331+
"hasBeenInteractedWith": false,
8332+
"range": [
8333+
[
8334+
-10,
8335+
10,
8336+
],
8337+
[
8338+
-10,
8339+
10,
8340+
],
8341+
],
8342+
"snapStep": [
8343+
0.5,
8344+
0.5,
8345+
],
8346+
"type": "none",
8347+
},
8348+
"fullGraphAriaDescription": "A graph on a coordinate plane with two non-interactive closed shapes. One shape is an ellipse and the other shape is a three-sided polygon.",
8349+
"fullGraphAriaLabel": "A graph on a coordinate plane with non-interactive figures",
8350+
"graph": {
8351+
"type": "none",
8352+
},
8353+
"labels": [
8354+
"x",
8355+
"y",
8356+
],
8357+
"lockedFigures": [
8358+
{
8359+
"angle": 0.6981317007977318,
8360+
"ariaLabel": "Ellipse with x radius 2 and y radius 3, centered at 1 comma 0, rotated by 40 degrees. Appearance dashed red border, with no fill.",
8361+
"center": [
8362+
1,
8363+
0,
8364+
],
8365+
"color": "red",
8366+
"fillStyle": "none",
8367+
"labels": [],
8368+
"radius": [
8369+
2,
8370+
3,
8371+
],
8372+
"strokeStyle": "dashed",
8373+
"type": "ellipse",
8374+
},
8375+
{
8376+
"ariaLabel": "Polygon with 3 sides, vertices at 0 comma 5, negative 2 comma 2, 2 comma 2. Appearance solid purple border, with a translucent purple fill.",
8377+
"color": "purple",
8378+
"fillStyle": "translucent",
8379+
"labels": [],
8380+
"points": [
8381+
[
8382+
0,
8383+
5,
8384+
],
8385+
[
8386+
-2,
8387+
2,
8388+
],
8389+
[
8390+
2,
8391+
2,
8392+
],
8393+
],
8394+
"showVertices": false,
8395+
"strokeStyle": "solid",
8396+
"type": "polygon",
8397+
"weight": "medium",
8398+
},
8399+
],
8400+
"markings": "graph",
8401+
"range": [
8402+
[
8403+
-10,
8404+
10,
8405+
],
8406+
[
8407+
-10,
8408+
10,
8409+
],
8410+
],
8411+
"showProtractor": false,
8412+
"showTooltips": false,
8413+
"step": [
8414+
1,
8415+
1,
8416+
],
8417+
},
8418+
"static": false,
8419+
"type": "interactive-graph",
8420+
"version": {
8421+
"major": 0,
8422+
"minor": 0,
8423+
},
8424+
},
8425+
"radio 1": {
8426+
"alignment": "default",
8427+
"graded": true,
8428+
"options": {
8429+
"choices": [
8430+
{
8431+
"content": "Not this one",
8432+
"correct": false,
8433+
},
8434+
{
8435+
"content": "This one is correct",
8436+
"correct": true,
8437+
},
8438+
{
8439+
"content": "Nope",
8440+
"correct": false,
8441+
},
8442+
{
8443+
"content": "Definitely not",
8444+
"correct": false,
8445+
},
8446+
],
8447+
"countChoices": false,
8448+
"deselectEnabled": false,
8449+
"hasNoneOfTheAbove": false,
8450+
"multipleSelect": false,
8451+
"numCorrect": 1,
8452+
"randomize": false,
8453+
},
8454+
"static": false,
8455+
"type": "radio",
8456+
"version": {
8457+
"major": 3,
8458+
"minor": 0,
8459+
},
8460+
},
8461+
},
8462+
},
8463+
}
8464+
`;
8465+
8466+
exports[`parseAndMigratePerseusItem given interactive-graph-locked-polygon-missing-weight.json returns the same result as before with answer information removed 1`] = `
8467+
{
8468+
"answerArea": {
8469+
"calculator": false,
8470+
"chi2Table": false,
8471+
"financialCalculatorMonthlyPayment": false,
8472+
"financialCalculatorTimeToPayOff": false,
8473+
"financialCalculatorTotalAmount": false,
8474+
"periodicTable": false,
8475+
"periodicTableWithKey": false,
8476+
"tTable": false,
8477+
"zTable": false,
8478+
},
8479+
"hints": [],
8480+
"question": {
8481+
"content": "**A "none"-type graph. Choose the correct radio button to get a point.**
8482+
8483+
[[☃ interactive-graph 1]]
8484+
8485+
[[☃ radio 1]]
8486+
8487+
",
8488+
"images": {},
8489+
"widgets": {
8490+
"interactive-graph 1": {
8491+
"alignment": "default",
8492+
"graded": true,
8493+
"options": {
8494+
"backgroundImage": {
8495+
"url": null,
8496+
},
8497+
"correct": {
8498+
"type": "linear",
8499+
},
8500+
"fullGraphAriaDescription": "A graph on a coordinate plane with two non-interactive closed shapes. One shape is an ellipse and the other shape is a three-sided polygon.",
8501+
"fullGraphAriaLabel": "A graph on a coordinate plane with non-interactive figures",
8502+
"graph": {
8503+
"type": "none",
8504+
},
8505+
"labelLocation": "onAxis",
8506+
"labels": [
8507+
"x",
8508+
"y",
8509+
],
8510+
"lockedFigures": [
8511+
{
8512+
"angle": 0.6981317007977318,
8513+
"ariaLabel": "Ellipse with x radius 2 and y radius 3, centered at 1 comma 0, rotated by 40 degrees. Appearance dashed red border, with no fill.",
8514+
"center": [
8515+
1,
8516+
0,
8517+
],
8518+
"color": "red",
8519+
"fillStyle": "none",
8520+
"labels": [],
8521+
"radius": [
8522+
2,
8523+
3,
8524+
],
8525+
"strokeStyle": "dashed",
8526+
"type": "ellipse",
8527+
},
8528+
{
8529+
"ariaLabel": "Polygon with 3 sides, vertices at 0 comma 5, negative 2 comma 2, 2 comma 2. Appearance solid purple border, with a translucent purple fill.",
8530+
"color": "purple",
8531+
"fillStyle": "translucent",
8532+
"labels": [],
8533+
"points": [
8534+
[
8535+
0,
8536+
5,
8537+
],
8538+
[
8539+
-2,
8540+
2,
8541+
],
8542+
[
8543+
2,
8544+
2,
8545+
],
8546+
],
8547+
"showVertices": false,
8548+
"strokeStyle": "solid",
8549+
"type": "polygon",
8550+
"weight": "medium",
8551+
},
8552+
],
8553+
"markings": "graph",
8554+
"range": [
8555+
[
8556+
-10,
8557+
10,
8558+
],
8559+
[
8560+
-10,
8561+
10,
8562+
],
8563+
],
8564+
"showProtractor": false,
8565+
"showTooltips": false,
8566+
"step": [
8567+
1,
8568+
1,
8569+
],
8570+
},
8571+
"static": false,
8572+
"type": "interactive-graph",
8573+
"version": {
8574+
"major": 0,
8575+
"minor": 0,
8576+
},
8577+
},
8578+
"radio 1": {
8579+
"alignment": "default",
8580+
"graded": true,
8581+
"options": {
8582+
"choices": [
8583+
{
8584+
"content": "Not this one",
8585+
"isNoneOfTheAbove": undefined,
8586+
},
8587+
{
8588+
"content": "This one is correct",
8589+
"isNoneOfTheAbove": undefined,
8590+
},
8591+
{
8592+
"content": "Nope",
8593+
"isNoneOfTheAbove": undefined,
8594+
},
8595+
{
8596+
"content": "Definitely not",
8597+
"isNoneOfTheAbove": undefined,
8598+
},
8599+
],
8600+
"countChoices": false,
8601+
"deselectEnabled": false,
8602+
"hasNoneOfTheAbove": false,
8603+
"multipleSelect": false,
8604+
"numCorrect": undefined,
8605+
"randomize": false,
8606+
},
8607+
"static": false,
8608+
"type": "radio",
8609+
"version": {
8610+
"major": 3,
8611+
"minor": 0,
8612+
},
8613+
},
8614+
},
8615+
},
8616+
}
8617+
`;
8618+
82928619
exports[`parseAndMigratePerseusItem given interactive-graph-missing-graph.json returns the same result as before 1`] = `
82938620
{
82948621
"answerArea": {

0 commit comments

Comments
 (0)