From 0536be3bf720c5fb5bc34ac3f7b2c050f32024c4 Mon Sep 17 00:00:00 2001 From: Simon Christ Date: Sun, 20 Sep 2020 20:59:06 +0200 Subject: [PATCH] add arrow support (#2989) * add arrow support * correctly handle arrow.side = :both --- src/backends/pgfplotsx.jl | 57 ++++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/src/backends/pgfplotsx.jl b/src/backends/pgfplotsx.jl index 6a7c9df8..f3fc1605 100644 --- a/src/backends/pgfplotsx.jl +++ b/src/backends/pgfplotsx.jl @@ -396,10 +396,53 @@ function pgfx_add_series!(::Val{:path}, axis, series_opt, series, series_func, o pgfx_filllegend!(series_opt, opt) end end - coordinates = PGFPlotsX.Table(pgfx_series_arguments(series, opt, rng)...) - segment_plot = - series_func(merge(series_opt, segment_opt), coordinates) - push!(axis, segment_plot) + # handle arrows + arrow = opt[:arrow] + if arrow isa Arrow + arrow_opt = merge( + segment_opt, + PGFPlotsX.Options("quiver" => PGFPlotsX.Options( + "u" => "\\thisrow{u}", + "v" => "\\thisrow{v}", + pgfx_arrow(arrow, :head) => nothing, + ) + ) + ) + if arrow.side == :head + x_arrow = opt[:x][rng][end-1:end] + y_arrow = opt[:y][rng][end-1:end] + x_path = opt[:x][rng][1:end-1] + y_path = opt[:y][rng][1:end-1] + elseif arrow.side == :tail + x_arrow = opt[:x][rng][2:-1:1] + y_arrow = opt[:y][rng][2:-1:1] + x_path = opt[:x][rng][2:end] + y_path = opt[:y][rng][2:end] + elseif arrow.side == :both + x_arrow = opt[:x][rng][[2,1,end-1,end]] + y_arrow = opt[:y][rng][[2,1,end-1,end]] + x_path = opt[:x][rng][2:end-1] + y_path = opt[:y][rng][2:end-1] + end + coordinates = PGFPlotsX.Table([ + :x => x_arrow[1:2:end-1], + :y => y_arrow[1:2:end-1], + :u => [x_arrow[i] - x_arrow[i-1] for i in 2:2:lastindex(x_arrow)], + :v => [y_arrow[i] - y_arrow[i-1] for i in 2:2:lastindex(y_arrow)], + ]) + arrow_plot = + series_func(merge(series_opt, arrow_opt), coordinates) + push!(axis, arrow_plot) + coordinates = PGFPlotsX.Table(x_path, y_path) + segment_plot = + series_func(merge(series_opt, segment_opt), coordinates) + push!(axis, segment_plot) + else + coordinates = PGFPlotsX.Table(pgfx_series_arguments(series, opt, rng)...) + segment_plot = + series_func(merge(series_opt, segment_opt), coordinates) + push!(axis, segment_plot) + end # fill between functions if sf isa Tuple && series[:ribbon] === nothing sf1, sf2 = sf @@ -716,7 +759,7 @@ end ## -------------------------------------------------------------------------------------- # Generates a colormap for pgfplots based on a ColorGradient pgfx_arrow(::Nothing) = "every arrow/.append style={-}" -function pgfx_arrow(arr::Arrow) +function pgfx_arrow(arr::Arrow, side = arr.side) components = String[] head = String[] push!(head, "{stealth[length = $(arr.headlength)pt, width = $(arr.headwidth)pt") @@ -725,11 +768,11 @@ function pgfx_arrow(arr::Arrow) end push!(head, "]}") head = join(head, "") - if arr.side == :both || arr.side == :tail + if side == :both || side == :tail push!(components, head) end push!(components, "-") - if arr.side == :both || arr.side == :head + if side == :both || side == :head push!(components, head) end components = join(components, "")