Skip to content

Commit aa45541

Browse files
committed
Add fill_min_y and fill_max_y options.
These options allow restricting the fill region in the y range when filling between curves. Furthermore, these options can be combined with the fill_min and fill_max options to restrict the fill region to a rectangle.
1 parent 2755fcf commit aa45541

File tree

3 files changed

+64
-5
lines changed

3 files changed

+64
-5
lines changed

lib/Plots/JSXGraph.pm

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,8 @@ sub add_curve {
326326
if ($curve_name) {
327327
my $fill_min = $data->str_to_real($data->style('fill_min'));
328328
my $fill_max = $data->str_to_real($data->style('fill_max'));
329+
my $fill_min_y = $data->str_to_real($data->style('fill_min_y'));
330+
my $fill_max_y = $data->str_to_real($data->style('fill_max_y'));
329331
my $fill_layer = $self->get_layer($data, 1) // $self->get_layer($data);
330332
my $fillOptions = Mojo::JSON::encode_json({
331333
strokeWidth => 0,
@@ -361,12 +363,24 @@ sub add_curve {
361363
".filter(p => {"
362364
. "return p.usrCoords[1] >= $fill_min && p.usrCoords[1] <= $fill_max ? true : false" . "})";
363365
}
366+
if ($fill_min_y ne '' && $fill_max_y ne '') {
367+
$self->{JS} .=
368+
".filter(p => {"
369+
. "return p.usrCoords[2] >= $fill_min_y && p.usrCoords[2] <= $fill_max_y ? true : false"
370+
. "})";
371+
}
364372
$self->{JS} .= ";const points2 = curve_${fill}.points";
365373
if ($fill_min ne '' && $fill_max ne '') {
366374
$self->{JS} .=
367375
".filter(p => {"
368376
. "return p.usrCoords[1] >= $fill_min && p.usrCoords[1] <= $fill_max ? true : false" . "})";
369377
}
378+
if ($fill_min_y ne '' && $fill_max_y ne '') {
379+
$self->{JS} .=
380+
".filter(p => {"
381+
. "return p.usrCoords[2] >= $fill_min_y && p.usrCoords[2] <= $fill_max_y ? true : false"
382+
. "})";
383+
}
370384
$self->{JS} .=
371385
";this.dataX = points1.map( p => p.usrCoords[1] ).concat("
372386
. "points2.map( p => p.usrCoords[1] ).reverse());"

lib/Plots/Tikz.pm

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -685,18 +685,26 @@ sub draw {
685685
# Make sure this is the name from the data style attribute, and not an internal name.
686686
my $name = $data->style('name');
687687
if ($name) {
688-
my $opacity = $data->style('fill_opacity') || 0.5;
689-
my $fill_min = $data->style('fill_min');
690-
my $fill_max = $data->style('fill_max');
688+
my $opacity = $data->style('fill_opacity') || 0.5;
689+
my $fill_min = $data->style('fill_min');
690+
my $fill_max = $data->style('fill_max');
691+
my $fill_min_y = $data->style('fill_min_y');
692+
my $fill_max_y = $data->style('fill_max_y');
691693
my $fill_range =
692-
$fill_min ne '' && $fill_max ne '' ? ", soft clip={domain=$fill_min:$fill_max}" : '';
694+
$fill_min ne '' && $fill_max ne '' && $fill_min_y ne '' && $fill_max_y ne ''
695+
? ", soft clip={($fill_min, $fill_min_y) rectangle ($fill_max, $fill_max_y)}"
696+
: $fill_min ne '' && $fill_max ne '' ? ", soft clip={domain=$fill_min:$fill_max}"
697+
: $fill_min_y ne '' && $fill_max_y ne '' ? ", soft clip={domain y=$fill_min_y:$fill_max_y}"
698+
: '';
693699
my $fill_layer = $data->style('fill_layer') || $layer;
700+
my $reverse = $data->style('fill_reverse') ? ', reverse' : '';
694701
$tikzCode .=
695702
"\\begin{scope}[/tikz/fill between/on layer=$fill_layer]\\begin{pgfonlayer}{$fill_layer}"
696703
. "\\clip\\axisclippath;\n"
697704
if $fill_layer;
698705
$tikzCode .=
699-
"\\addplot[$fill_color, fill opacity=$opacity] fill between[of=$name and $fill$fill_range];\n";
706+
"\\addplot[$fill_color, fill opacity=$opacity] "
707+
. "fill between[of=$name and $fill$fill_range$reverse];\n";
700708
$tikzCode .= "\\end{pgfonlayer}\\end{scope}\n" if $fill_layer;
701709
} else {
702710
warn q{Unable to create fill. Missing 'name' attribute.};

macros/graph/plots.pl

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,23 @@ =head2 DATASET OPTIONS
473473
fill_opacity => 0.2,
474474
);
475475
476+
The following fills the area between the two curves x = 4 - y^2 and x = y^2 - 4,
477+
and only fills in the area between y=-2 and y=2:
478+
479+
$plot->add_function(['4 - y^2', 'y'], 'y', -3, 3,
480+
color => 'blue',
481+
name => 'A'
482+
);
483+
$plot->add_function(['y^2 - 4', 'y'] 'y', -3, 3,
484+
color => 'blue',
485+
name => 'B',
486+
fill => 'A',
487+
fill_min_y => -2,
488+
fill_max_y => 2,
489+
fill_color => 'green',
490+
fill_opacity => 0.2,
491+
);
492+
476493
=item fill_color
477494
478495
The color used when filling the region. Default: C<color>
@@ -487,6 +504,26 @@ =head2 DATASET OPTIONS
487504
not defined, then the fill will use the full domain of the function.
488505
Default: undefined
489506
507+
=item fill_min_y, fill_max_y
508+
509+
The minimum and maximum y-values to fill between. If either of these are
510+
not defined, then the fill will use the full y range of the function.
511+
Default: undefined
512+
513+
Note that fill_min, fill_max, fill_min_y, and fill_max_y can be defined, and
514+
this will result in the region filled being restricted to the rectangle defined
515+
by those ranges.
516+
517+
=item fill_reverse
518+
519+
This reverses the fill for TikZ output if it is set to 1. This should only be
520+
used if the TikZ output is filling the wrong side of one of the curves. By
521+
default the pgfplots fillbetween library attempts to autodetect if one of the
522+
curves needs to be reversed in order to obtain the fill region between the
523+
curves. However, sometimes the autodetection is wrong. So set this option to 1.
524+
If the correct region is being filled as compared to the JSXGraph output, then
525+
leave this at 0.
526+
490527
=item layer
491528
492529
The layer to draw on. Available layers are "axis background", "axis grid",

0 commit comments

Comments
 (0)