Skip to content

Commit 84233a6

Browse files
committed
Implement several options for the GraphTool in hardcopy that should have been implemented before.
If the `scaleX`, `scaleSymbolX`, `scaleY`, `scaleSymbolY`, or `coordinateHintsType` options are used then the axis ticks and labels are adjusted in the JSXGraph HTML output for the GraphTool, but not in hardcopy. This was an oversight that I didn't do this when these options were implemented. I also added minor ticks to the hardcopy. Those were also never implemented. The documentation for the `scaleX` and `scaleY` options was also corrected. I misstated the way that this is handled by JSXGraph.
1 parent f5bb0b5 commit 84233a6

File tree

1 file changed

+102
-18
lines changed

1 file changed

+102
-18
lines changed

macros/graph/parserGraphTool.pl

Lines changed: 102 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -331,8 +331,12 @@ =head1 OPTIONS
331331
332332
=item scaleX, scaleY (Default: C<< scaleX => 1, scaleY => 1 >>)
333333
334-
These are the scale of the ticks on the x and y axes. That is the distance between two
335-
successive ticks on the axis (including both major and minor ticks).
334+
These are the scale of the tick distances on the x and y axes. That is the distance between two
335+
successive major ticks on the axis will be the product of the ticks distance and the scale.
336+
This is usually used in conjunction with the C<scaleSymbolX> and C<scaleSymbolY> options. For
337+
example, if C<ticksDistanceX> is 2, C<scaleX> is 3, and C<scaleSymbolX> is 'a', then the first
338+
positive major x axis tick will occur 6 units to the right and be labeled '2a', and the next
339+
major x axis tick will occur 12 units to the right and be labeled '4a'.
336340
337341
=item scaleSymbolX, scaleSymbolY (Default: C<< scaleSymbolX => '', scaleSymbolY => '' >>)
338342
@@ -1195,6 +1199,47 @@ sub generateHTMLAnswerGraph {
11951199
END_SCRIPT
11961200
}
11971201

1202+
# This is essentially copied from contextFraction.pl.
1203+
sub continuedFraction {
1204+
my ($x) = @_;
1205+
1206+
my $step = $x;
1207+
my $n = int($step);
1208+
my ($h0, $h1, $k0, $k1) = (1, $n, 0, 1);
1209+
1210+
while ($step != $n) {
1211+
$step = 1 / ($step - $n);
1212+
$n = int($step);
1213+
my ($newh, $newk) = ($n * $h1 + $h0, $n * $k1 + $k0);
1214+
last if $newk > 10**8; # Bail if the denominator is skyrocketing out of control.
1215+
($h0, $h1, $k0, $k1) = ($h1, $newh, $k1, $newk);
1216+
}
1217+
1218+
return ($h1, $k1);
1219+
}
1220+
1221+
sub formatTickLabelText {
1222+
my ($self, $value, $axis) = @_;
1223+
my $coordinateHintsType = $self->{"coordinateHintsType$axis"} // $self->{coordinateHintsType};
1224+
if ($coordinateHintsType eq 'fraction' || $coordinateHintsType eq 'mixed') {
1225+
my ($num, $den) = continuedFraction(abs($value));
1226+
if ($num && $den != 1 && !($num == 1 && $den == 1)) {
1227+
if ($coordinateHintsType eq 'fraction' || $num < $den) {
1228+
$value = ($value < 0 ? '-' : '') . "\\frac{$num}{$den}";
1229+
} else {
1230+
my $int = int($num / $den);
1231+
my $properNum = $num % $den;
1232+
$value = ($value < 0 ? '-' : '') . "$int\\frac{$properNum}{$den}";
1233+
}
1234+
}
1235+
}
1236+
my $scaleSymbol = $self->{"scaleSymbol$axis"} // '';
1237+
return
1238+
$value eq '0' ? '0'
1239+
: $scaleSymbol ? ($value eq '1' ? $scaleSymbol : $value eq '-1' ? "-$scaleSymbol" : "$value$scaleSymbol")
1240+
: $value;
1241+
}
1242+
11981243
sub generateTeXGraph {
11991244
my ($self, %options) = @_;
12001245

@@ -1203,7 +1248,7 @@ sub generateTeXGraph {
12031248

12041249
return &{ $self->{printGraph} } if ref($self->{printGraph}) eq 'CODE';
12051250

1206-
my @size = $self->{numberLine} ? (500, 100) : (500, 500);
1251+
my @size = $self->{numberLine} ? (500, 110) : (500, 500);
12071252

12081253
my $graph = main::createTikZImage();
12091254
$graph->tikzLibraries('arrows.meta');
@@ -1264,32 +1309,71 @@ sub generateTeXGraph {
12641309
}
12651310

12661311
# Horizontal axis ticks and labels
1267-
my @xTicks = grep { $_ < $self->{bBox}[2] }
1268-
map { $_ * $self->{ticksDistanceX} } (1 .. $self->{bBox}[2] / $self->{ticksDistanceX});
1269-
push(@xTicks,
1312+
my @xTicks =
12701313
grep { $_ > $self->{bBox}[0] }
1271-
map { -$_ * $self->{ticksDistanceX} } (1 .. -$self->{bBox}[0] / $self->{ticksDistanceX}));
1314+
map { -$_ * $self->{ticksDistanceX} * $self->{scaleX} }
1315+
reverse(1 .. -$self->{bBox}[0] / ($self->{ticksDistanceX} * $self->{scaleX}));
1316+
my $numNegative = @xTicks;
12721317
# Add zero if this is a number line and 0 is in the given range.
1273-
push(@xTicks, 0) if ($self->{numberLine} && $self->{bBox}[2] > 0 && $self->{bBox}[0] < 0);
1318+
push(@xTicks, 0) if $self->{numberLine} && $self->{bBox}[2] > 0 && $self->{bBox}[0] < 0;
1319+
push(@xTicks,
1320+
grep { $_ < $self->{bBox}[2] }
1321+
map { $_ * $self->{ticksDistanceX} * $self->{scaleX} }
1322+
(1 .. $self->{bBox}[2] / ($self->{ticksDistanceX} * $self->{scaleX})));
12741323
my $tickSize = $self->{numberLine} ? '9' : '5';
12751324
$tikz .=
1276-
"\\foreach \\x in {"
1277-
. join(',', @xTicks)
1278-
. "}{\\draw[thin] (\\x,${tickSize}pt) -- (\\x,-${tickSize}pt) node[below]{\\(\\x\\)};}\n"
1325+
"\\foreach \\x/\\label in {"
1326+
. join(',', map { "$_/" . $self->formatTickLabelText($_ / $self->{scaleX}, 'X') } @xTicks)
1327+
. "}{\\draw[thin, opacity = 0.5] (\\x,${tickSize}pt) -- (\\x,-${tickSize}pt) "
1328+
. "node[baseline, yshift = -15pt, opacity = 1]{\\(\\label\\)};}\n"
12791329
if (@xTicks);
12801330

1331+
# Add horizontal axis minor ticks.
1332+
splice(@xTicks, $numNegative, 0, 0) if !$self->{numberLine} || ($self->{bBox}[0] <= 0 && $self->{bBox}[2] >= 0);
1333+
unshift(@xTicks, $xTicks[0] - $self->{ticksDistanceX} * $self->{scaleX}) if $self->{bBox}[0] < 0;
1334+
push(@xTicks, $xTicks[-1] + $self->{ticksDistanceX} * $self->{scaleX}) if $self->{bBox}[2] > 0;
1335+
my @xMinorTicks;
1336+
my $xMinorTickDelta = $self->{ticksDistanceX} * $self->{scaleX} / ($self->{minorTicksX} + 1);
1337+
for my $tickIndex (0 .. $#xTicks - 1) {
1338+
push(@xMinorTicks, map { $xTicks[$tickIndex] + $_ * $xMinorTickDelta } 1 .. $self->{minorTicksX});
1339+
}
1340+
$tikz .=
1341+
"\\foreach \\x in {"
1342+
. join(',', @xMinorTicks)
1343+
. "}{\\draw[thin, opacity = 0.5] (\\x,0) -- (\\x,-${tickSize}pt);}\n"
1344+
if (@xMinorTicks);
1345+
12811346
# Vertical axis ticks and labels
12821347
unless ($self->{numberLine}) {
1283-
my @yTicks = grep { $_ < $self->{bBox}[1] }
1284-
map { $_ * $self->{ticksDistanceY} } (1 .. $self->{bBox}[1] / $self->{ticksDistanceY});
1285-
push(@yTicks,
1348+
my @yTicks =
12861349
grep { $_ > $self->{bBox}[3] }
1287-
map { -$_ * $self->{ticksDistanceY} } (1 .. -$self->{bBox}[3] / $self->{ticksDistanceY}));
1350+
map { -$_ * $self->{ticksDistanceY} * $self->{scaleY} }
1351+
reverse(1 .. -$self->{bBox}[3] / ($self->{ticksDistanceY} * $self->{scaleY}));
1352+
my $numNegative = @yTicks;
1353+
push(@yTicks,
1354+
grep { $_ < $self->{bBox}[1] }
1355+
map { $_ * $self->{ticksDistanceY} * $self->{scaleY} }
1356+
(1 .. $self->{bBox}[1] / ($self->{ticksDistanceY} * $self->{scaleY})));
12881357
$tikz .=
1289-
"\\foreach \\y in {"
1290-
. join(',', @yTicks)
1291-
. "}{\\draw[thin] (5pt,\\y) -- (-5pt,\\y) node[left]{\$\\y\$};}\n"
1358+
"\\foreach \\y/\\label in {"
1359+
. join(',', map { "$_/" . $self->formatTickLabelText($_ / $self->{scaleY}, 'Y') } @yTicks)
1360+
. "}{\\draw[thin, opacity = 0.5] (5pt,\\y) -- (-5pt,\\y) node[left, opacity = 1]{\$\\label\$};}\n"
12921361
if (@yTicks);
1362+
1363+
# Add vertical axis minor ticks.
1364+
splice(@yTicks, $numNegative, 0, 0);
1365+
unshift(@yTicks, $yTicks[0] - $self->{ticksDistanceY} * $self->{scaleY}) if $self->{bBox}[3] < 0;
1366+
push(@yTicks, $yTicks[-1] + $self->{ticksDistanceY} * $self->{scaleY}) if $self->{bBox}[1] > 0;
1367+
my @yMinorTicks;
1368+
my $yMinorTickDelta = $self->{ticksDistanceY} * $self->{scaleY} / ($self->{minorTicksY} + 1);
1369+
for my $tickIndex (0 .. $#yTicks - 1) {
1370+
push(@yMinorTicks, map { $yTicks[$tickIndex] + $_ * $yMinorTickDelta } 1 .. $self->{minorTicksY});
1371+
}
1372+
$tikz .=
1373+
"\\foreach \\y in {"
1374+
. join(',', @yMinorTicks)
1375+
. "}{\\draw[thin, opacity = 0.5] (0, \\y) -- (-5pt, \\y);}\n"
1376+
if @yMinorTicks;
12931377
}
12941378

12951379
# Border box

0 commit comments

Comments
 (0)