@@ -10,18 +10,23 @@ import {replaceOutsideTeX} from "../utils";
10
10
import type { I18nContextType } from "../../../components/i18n-context" ;
11
11
import type { GraphConfig } from "../reducer/use-graph-config" ;
12
12
import type { GraphDimensions } from "../types" ;
13
- import type { Interval } from "mafs" ;
14
13
15
- const fontSize = 14 ;
14
+ // Exported for testing purposes
15
+ export const fontSize = 14 ;
16
+
16
17
export default function AxisLabels ( { i18n} : { i18n : I18nContextType } ) {
17
18
const { range, labels, width, height, labelLocation} = useGraphConfig ( ) ;
18
19
const { strings} = i18n ;
19
20
20
- // Get the position of the main axis labels
21
- const [ xAxisLabelLocation , yAxisLabelLocation ] = getLabelPosition (
21
+ const graphInfo : GraphDimensions = {
22
22
range,
23
23
width,
24
24
height,
25
+ } ;
26
+
27
+ // Get the position of the main axis labels
28
+ const [ xAxisLabelLocation , yAxisLabelLocation ] = getLabelPosition (
29
+ graphInfo ,
25
30
labelLocation ,
26
31
) ;
27
32
@@ -72,24 +77,16 @@ export default function AxisLabels({i18n}: {i18n: I18nContextType}) {
72
77
}
73
78
74
79
export const getLabelPosition = (
75
- range : [ Interval , Interval ] ,
76
- width : number ,
77
- height : number ,
80
+ graphInfo : GraphDimensions ,
78
81
labelLocation : GraphConfig [ "labelLocation" ] ,
79
82
) : vec . Vector2 [ ] => {
80
- // If the labels are rotated, we need to calculate the position
81
- // of the labels based on the graph's dimensions and range.
82
- const graphInfo : GraphDimensions = {
83
- range,
84
- width,
85
- height,
86
- } ;
87
-
88
83
switch ( labelLocation ) {
84
+ // If the labels are placed on the axes (default), we need to place them at the
85
+ // end of the axis, which is the maximum value of the axis.
89
86
case "onAxis" : {
90
- const xLabelInitial : vec . Vector2 = [ range [ X ] [ MAX ] , 0 ] ;
91
- const yLabelInitial : vec . Vector2 = [ 0 , range [ Y ] [ MAX ] ] ;
92
- const yLabelOffset : vec . Vector2 = [ 0 , - fontSize * 2 ] ;
87
+ const xLabelInitial : vec . Vector2 = [ graphInfo . range [ X ] [ MAX ] , 0 ] ;
88
+ const yLabelInitial : vec . Vector2 = [ 0 , graphInfo . range [ Y ] [ MAX ] ] ;
89
+ const yLabelOffset : vec . Vector2 = [ 0 , - fontSize * 2 ] ; // Move the y-axis label up by 2 font sizes
93
90
94
91
const xLabel = pointToPixel ( xLabelInitial , graphInfo ) ;
95
92
const yLabel = vec . add (
@@ -98,25 +95,31 @@ export const getLabelPosition = (
98
95
) ;
99
96
return [ xLabel , yLabel ] ;
100
97
}
98
+ // If the labels are placed along the edges of the graph, we need to rotate them
99
+ // and place them at the center of the left and bottom edges of the graph.
101
100
case "alongEdge" : {
101
+ // Offset the labels by a certain amount based on the range of the graph, to ensure that
102
+ // the labels do not overlap with the axis tick if they are out of the graph bounds.
102
103
const xAxisLabelOffset : [ number , number ] =
103
- range [ Y ] [ MIN ] >= 0 // Move the label down by 3 font sizes if the y-axis is left of the graph
104
- ? [ 0 , fontSize * 3 ]
105
- : [ 0 , fontSize ] ;
104
+ graphInfo . range [ Y ] [ MIN ] >= 0
105
+ ? [ 0 , fontSize * 3 ] // Move the label down by 3 font sizes if the y-axis min is positive
106
+ : [ 0 , fontSize ] ; // Move the label down by 1 font size if the y-axis min is negative
106
107
const yAxisLabelOffset : [ number , number ] =
107
- range [ X ] [ MIN ] >= 0 // Move the label left by 3.5 font sizes if the x-axis is below the graph
108
- ? [ - fontSize * 3.5 , - fontSize ]
109
- : [ - fontSize , - fontSize ] ;
108
+ graphInfo . range [ X ] [ MIN ] >= 0
109
+ ? [ - fontSize * 3 , - fontSize ] // Move the label left by 3.5 font sizes if the x-axis min is positive
110
+ : [ - fontSize , - fontSize ] ; // Move the label left by 1 font size if the x-axis min is negative
110
111
112
+ // Calculate the location of the labels to be halfway between the min and max values of the axes
111
113
const xAxisLabelLocation : vec . Vector2 = [
112
- ( range [ X ] [ MIN ] + range [ X ] [ MAX ] ) / 2 ,
113
- range [ Y ] [ MIN ] ,
114
+ ( graphInfo . range [ X ] [ MIN ] + graphInfo . range [ X ] [ MAX ] ) / 2 ,
115
+ graphInfo . range [ Y ] [ MIN ] ,
114
116
] ;
115
117
const yAxisLabelLocation : vec . Vector2 = [
116
- range [ X ] [ MIN ] ,
117
- ( range [ Y ] [ MIN ] + range [ Y ] [ MAX ] ) / 2 ,
118
+ graphInfo . range [ X ] [ MIN ] ,
119
+ ( graphInfo . range [ Y ] [ MIN ] + graphInfo . range [ Y ] [ MAX ] ) / 2 ,
118
120
] ;
119
121
122
+ // Convert the Vector2 coordinates to pixel coordinates and add the offsets
120
123
const xLabel = vec . add (
121
124
pointToPixel ( xAxisLabelLocation , graphInfo ) ,
122
125
xAxisLabelOffset ,
@@ -125,6 +128,7 @@ export const getLabelPosition = (
125
128
pointToPixel ( yAxisLabelLocation , graphInfo ) ,
126
129
yAxisLabelOffset ,
127
130
) ;
131
+
128
132
return [ xLabel , yLabel ] ;
129
133
}
130
134
// Add more cases for other label locations as needed
0 commit comments