@khanacademy/perseus 57.1.0 → 57.2.1
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/dist/es/index.js +109 -24
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +109 -24
- package/dist/index.js.map +1 -1
- package/dist/widgets/interactive-graphs/backgrounds/axis-labels.d.ts +9 -0
- package/dist/widgets/interactive-graphs/interactive-graph-question-builder.d.ts +3 -1
- package/dist/widgets/interactive-graphs/locked-figures/utils.d.ts +1 -0
- package/dist/widgets/interactive-graphs/mafs-graph.d.ts +1 -0
- package/dist/widgets/interactive-graphs/reducer/use-graph-config.d.ts +2 -1
- package/dist/widgets/interactive-graphs/stateful-mafs-graph.d.ts +1 -0
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -25414,7 +25414,7 @@ class GradedGroupAnswerBar extends React__namespace.Component {
|
|
|
25414
25414
|
}, nextQuestion));
|
|
25415
25415
|
}
|
|
25416
25416
|
}
|
|
25417
|
-
const fontSize = 17;
|
|
25417
|
+
const fontSize$1 = 17;
|
|
25418
25418
|
const styles$j = {
|
|
25419
25419
|
answerBar: {
|
|
25420
25420
|
display: "flex",
|
|
@@ -25439,7 +25439,7 @@ const styles$j = {
|
|
|
25439
25439
|
flexDirection: "row",
|
|
25440
25440
|
alignItems: "center",
|
|
25441
25441
|
fontWeight: "bold",
|
|
25442
|
-
fontSize: fontSize
|
|
25442
|
+
fontSize: fontSize$1
|
|
25443
25443
|
}
|
|
25444
25444
|
};
|
|
25445
25445
|
|
|
@@ -28126,6 +28126,7 @@ const defaultGraphConfig = {
|
|
|
28126
28126
|
width: 0,
|
|
28127
28127
|
height: 0,
|
|
28128
28128
|
labels: [],
|
|
28129
|
+
labelLocation: "onAxis",
|
|
28129
28130
|
disableKeyboardInteraction: false,
|
|
28130
28131
|
interactiveColor: "var(--mafs-blue)"
|
|
28131
28132
|
};
|
|
@@ -28349,6 +28350,8 @@ function escapeIfUnescaped(character) {
|
|
|
28349
28350
|
}
|
|
28350
28351
|
}
|
|
28351
28352
|
|
|
28353
|
+
// Exported for testing purposes
|
|
28354
|
+
const fontSize = 14;
|
|
28352
28355
|
function AxisLabels(_ref) {
|
|
28353
28356
|
let {
|
|
28354
28357
|
i18n
|
|
@@ -28357,24 +28360,27 @@ function AxisLabels(_ref) {
|
|
|
28357
28360
|
range,
|
|
28358
28361
|
labels,
|
|
28359
28362
|
width,
|
|
28360
|
-
height
|
|
28363
|
+
height,
|
|
28364
|
+
labelLocation
|
|
28361
28365
|
} = useGraphConfig();
|
|
28362
28366
|
const {
|
|
28363
28367
|
strings
|
|
28364
28368
|
} = i18n;
|
|
28365
|
-
const yAxisLabelLocation = [0, range[Y][MAX]];
|
|
28366
|
-
const xAxisLabelLocation = [range[X][MAX], 0];
|
|
28367
|
-
const [xAxisLabelText, yAxisLabelText] = labels;
|
|
28368
28369
|
const graphInfo = {
|
|
28369
28370
|
range,
|
|
28370
28371
|
width,
|
|
28371
28372
|
height
|
|
28372
28373
|
};
|
|
28373
|
-
|
|
28374
|
-
//
|
|
28375
|
-
|
|
28376
|
-
|
|
28377
|
-
|
|
28374
|
+
|
|
28375
|
+
// Get the position of the main axis labels
|
|
28376
|
+
const [xAxisLabelLocation, yAxisLabelLocation] = getLabelPosition(graphInfo, labelLocation);
|
|
28377
|
+
const [xAxisLabelText, yAxisLabelText] = labels;
|
|
28378
|
+
|
|
28379
|
+
// Get the transform for the labels
|
|
28380
|
+
const {
|
|
28381
|
+
xLabelTransform,
|
|
28382
|
+
yLabelTransform
|
|
28383
|
+
} = getLabelTransform(labelLocation);
|
|
28378
28384
|
const {
|
|
28379
28385
|
TeX
|
|
28380
28386
|
} = getDependencies();
|
|
@@ -28382,23 +28388,72 @@ function AxisLabels(_ref) {
|
|
|
28382
28388
|
"aria-label": strings.xAxis,
|
|
28383
28389
|
style: {
|
|
28384
28390
|
position: "absolute",
|
|
28385
|
-
left:
|
|
28386
|
-
top:
|
|
28387
|
-
fontSize: "
|
|
28388
|
-
transform:
|
|
28391
|
+
left: xAxisLabelLocation[X],
|
|
28392
|
+
top: xAxisLabelLocation[Y],
|
|
28393
|
+
fontSize: fontSize + "px",
|
|
28394
|
+
transform: xLabelTransform
|
|
28389
28395
|
}
|
|
28390
28396
|
}, /*#__PURE__*/React__default["default"].createElement(TeX, null, replaceOutsideTeX(xAxisLabelText))), /*#__PURE__*/React__default["default"].createElement("span", {
|
|
28391
28397
|
"aria-label": strings.yAxis,
|
|
28392
28398
|
style: {
|
|
28393
28399
|
position: "absolute",
|
|
28394
|
-
left:
|
|
28395
|
-
top:
|
|
28396
|
-
fontSize: "
|
|
28397
|
-
transform:
|
|
28400
|
+
left: yAxisLabelLocation[X],
|
|
28401
|
+
top: yAxisLabelLocation[Y],
|
|
28402
|
+
fontSize: fontSize + "px",
|
|
28403
|
+
transform: yLabelTransform
|
|
28398
28404
|
}
|
|
28399
28405
|
}, /*#__PURE__*/React__default["default"].createElement(TeX, null, replaceOutsideTeX(yAxisLabelText))));
|
|
28400
28406
|
}
|
|
28401
28407
|
|
|
28408
|
+
/* Get the transform for the labels based on the labelLocation
|
|
28409
|
+
* Exported for testing purposes.
|
|
28410
|
+
*/
|
|
28411
|
+
const getLabelTransform = labelLocation => {
|
|
28412
|
+
// onAxis is the default label location
|
|
28413
|
+
const isOnAxis = labelLocation === undefined || labelLocation === "onAxis";
|
|
28414
|
+
const xLabelTransform = isOnAxis ? "translate(7px, -50%)" : "translate(-50%, -50%)";
|
|
28415
|
+
const yLabelTransform = isOnAxis ? "translate(-50%, 0px)" : "translate(-50%, 0px) rotate(-90deg)";
|
|
28416
|
+
return {
|
|
28417
|
+
xLabelTransform,
|
|
28418
|
+
yLabelTransform
|
|
28419
|
+
};
|
|
28420
|
+
};
|
|
28421
|
+
|
|
28422
|
+
/* Calculate the position of the main axis labels based on the labelLocation
|
|
28423
|
+
* and the ranges of the graph. Exported for testing purposes.
|
|
28424
|
+
*/
|
|
28425
|
+
const getLabelPosition = (graphInfo, labelLocation) => {
|
|
28426
|
+
// If the labels are placed along the edge of the graph, we need to place them at the
|
|
28427
|
+
// center of the graph, which is the average of the min and max values of the axes.
|
|
28428
|
+
if (labelLocation === "alongEdge") {
|
|
28429
|
+
// Offset the labels by a certain amount based on the range of the graph, to ensure that
|
|
28430
|
+
// the labels do not overlap with the axis tick if they are out of the graph bounds.
|
|
28431
|
+
const xAxisLabelOffset = graphInfo.range[Y][MIN] >= 0 ? [0, fontSize * 3] // Move the label down by 3 font sizes if the y-axis min is positive
|
|
28432
|
+
: [0, fontSize]; // Move the label down by 1 font size if the y-axis min is negative
|
|
28433
|
+
const yAxisLabelOffset = graphInfo.range[X][MIN] >= 0 ? [-fontSize * 3, -fontSize] // Move the label left by 3 font sizes if the x-axis min is positive
|
|
28434
|
+
: [-fontSize, -fontSize]; // Move the label left by 1 font size if the x-axis min is negative
|
|
28435
|
+
|
|
28436
|
+
// Calculate the location of the labels to be halfway between the min and max values of the axes
|
|
28437
|
+
const xAxisLabelLocation = [(graphInfo.range[X][MIN] + graphInfo.range[X][MAX]) / 2, graphInfo.range[Y][MIN]];
|
|
28438
|
+
const yAxisLabelLocation = [graphInfo.range[X][MIN], (graphInfo.range[Y][MIN] + graphInfo.range[Y][MAX]) / 2];
|
|
28439
|
+
|
|
28440
|
+
// Convert the Vector2 coordinates to pixel coordinates and add the offsets
|
|
28441
|
+
const xLabel = mafs.vec.add(pointToPixel(xAxisLabelLocation, graphInfo), xAxisLabelOffset);
|
|
28442
|
+
const yLabel = mafs.vec.add(pointToPixel(yAxisLabelLocation, graphInfo), yAxisLabelOffset);
|
|
28443
|
+
return [xLabel, yLabel];
|
|
28444
|
+
}
|
|
28445
|
+
|
|
28446
|
+
// Otherwise, the labels are placed on the axes (default), and we need to
|
|
28447
|
+
// place them at the end of the axis, which is the maximum value of the axis.
|
|
28448
|
+
const xLabelInitial = [graphInfo.range[X][MAX], 0];
|
|
28449
|
+
const yLabelInitial = [0, graphInfo.range[Y][MAX]];
|
|
28450
|
+
const yLabelOffset = [0, -fontSize * 2]; // Move the y-axis label up by 2 font sizes
|
|
28451
|
+
|
|
28452
|
+
const xLabel = pointToPixel(xLabelInitial, graphInfo);
|
|
28453
|
+
const yLabel = mafs.vec.add(pointToPixel(yLabelInitial, graphInfo), yLabelOffset);
|
|
28454
|
+
return [xLabel, yLabel];
|
|
28455
|
+
};
|
|
28456
|
+
|
|
28402
28457
|
// The size of the ticks and labels in pixels
|
|
28403
28458
|
const tickSize = 10;
|
|
28404
28459
|
const tickLabelSize = 14;
|
|
@@ -29331,7 +29386,28 @@ const LockedEllipse = props => {
|
|
|
29331
29386
|
}));
|
|
29332
29387
|
};
|
|
29333
29388
|
|
|
29389
|
+
function clampDomain(domain, graphBounds) {
|
|
29390
|
+
// If the domain is invalid, return the graph bounds
|
|
29391
|
+
if (domain[0] > domain[1]) {
|
|
29392
|
+
return graphBounds;
|
|
29393
|
+
}
|
|
29394
|
+
|
|
29395
|
+
// If the domain is outside the graph bounds, return null
|
|
29396
|
+
if (domain[0] < graphBounds[0] && domain[1] < graphBounds[0] || domain[0] > graphBounds[1] && domain[1] > graphBounds[1]) {
|
|
29397
|
+
return null;
|
|
29398
|
+
}
|
|
29399
|
+
|
|
29400
|
+
// Clamp the function to the bounds of the graph to prevent memory
|
|
29401
|
+
// leaks when the domain is set to something like [-Infinity, Infinity].
|
|
29402
|
+
const min = Math.max(domain[0], graphBounds[0]);
|
|
29403
|
+
const max = Math.min(domain[1], graphBounds[1]);
|
|
29404
|
+
return [min, max];
|
|
29405
|
+
}
|
|
29406
|
+
|
|
29334
29407
|
const LockedFunction = props => {
|
|
29408
|
+
const {
|
|
29409
|
+
range
|
|
29410
|
+
} = useGraphConfig();
|
|
29335
29411
|
const [equation, setEquation] = React.useState();
|
|
29336
29412
|
const {
|
|
29337
29413
|
color,
|
|
@@ -29341,8 +29417,7 @@ const LockedFunction = props => {
|
|
|
29341
29417
|
} = props;
|
|
29342
29418
|
const plotProps = {
|
|
29343
29419
|
color: perseusCore.lockedFigureColors[color],
|
|
29344
|
-
style: strokeStyle
|
|
29345
|
-
domain
|
|
29420
|
+
style: strokeStyle
|
|
29346
29421
|
};
|
|
29347
29422
|
const hasAria = !!props.ariaLabel;
|
|
29348
29423
|
React.useEffect(() => {
|
|
@@ -29353,6 +29428,12 @@ const LockedFunction = props => {
|
|
|
29353
29428
|
if (typeof equation === "undefined") {
|
|
29354
29429
|
return null;
|
|
29355
29430
|
}
|
|
29431
|
+
const clampedDomain = directionalAxis === "x" ? clampDomain(domain, range[0]) : clampDomain(domain, range[1]);
|
|
29432
|
+
|
|
29433
|
+
// The domain entirely is outside the bounds of the graph. Don't render.
|
|
29434
|
+
if (clampedDomain === null) {
|
|
29435
|
+
return null;
|
|
29436
|
+
}
|
|
29356
29437
|
return /*#__PURE__*/React__namespace.createElement("g", {
|
|
29357
29438
|
className: "locked-function",
|
|
29358
29439
|
"aria-label": hasAria ? props.ariaLabel : undefined,
|
|
@@ -29361,11 +29442,13 @@ const LockedFunction = props => {
|
|
|
29361
29442
|
}, directionalAxis === "x" && /*#__PURE__*/React__namespace.createElement(mafs.Plot.OfX, _extends__default["default"]({
|
|
29362
29443
|
y: x => equation.eval({
|
|
29363
29444
|
x
|
|
29364
|
-
})
|
|
29445
|
+
}),
|
|
29446
|
+
domain: clampedDomain
|
|
29365
29447
|
}, plotProps)), directionalAxis === "y" && /*#__PURE__*/React__namespace.createElement(mafs.Plot.OfY, _extends__default["default"]({
|
|
29366
29448
|
x: y => equation.eval({
|
|
29367
29449
|
y
|
|
29368
|
-
})
|
|
29450
|
+
}),
|
|
29451
|
+
domain: clampedDomain
|
|
29369
29452
|
}, plotProps)));
|
|
29370
29453
|
};
|
|
29371
29454
|
|
|
@@ -34747,6 +34830,7 @@ const MafsGraph = props => {
|
|
|
34747
34830
|
state,
|
|
34748
34831
|
dispatch,
|
|
34749
34832
|
labels,
|
|
34833
|
+
labelLocation,
|
|
34750
34834
|
readOnly,
|
|
34751
34835
|
fullGraphAriaLabel,
|
|
34752
34836
|
fullGraphAriaDescription
|
|
@@ -34827,6 +34911,7 @@ const MafsGraph = props => {
|
|
|
34827
34911
|
width,
|
|
34828
34912
|
height,
|
|
34829
34913
|
labels,
|
|
34914
|
+
labelLocation,
|
|
34830
34915
|
disableKeyboardInteraction: disableInteraction,
|
|
34831
34916
|
// If the graph is read-only or static, we want to make it
|
|
34832
34917
|
// visually clear that the graph is no longer interactive.
|
|
@@ -41954,7 +42039,7 @@ const addLibraryVersionToPerseusDebug = (libraryName, libraryVersion) => {
|
|
|
41954
42039
|
|
|
41955
42040
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
41956
42041
|
const libName = "@khanacademy/perseus";
|
|
41957
|
-
const libVersion = "57.1
|
|
42042
|
+
const libVersion = "57.2.1";
|
|
41958
42043
|
addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
41959
42044
|
|
|
41960
42045
|
const apiVersion = {
|