From 2cee039dbc5ba543f3ebdc735d52186f859f26ed Mon Sep 17 00:00:00 2001 From: David Gustavsson Date: Thu, 25 Feb 2021 15:08:33 +0100 Subject: [PATCH] Add polar legend position --- src/args.jl | 2 + src/backends/gr.jl | 96 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 91 insertions(+), 7 deletions(-) diff --git a/src/args.jl b/src/args.jl index 519fea3c..3a3c963c 100644 --- a/src/args.jl +++ b/src/args.jl @@ -1262,6 +1262,8 @@ end convertLegendValue(val::Bool) = val ? :best : :none convertLegendValue(val::Nothing) = :none convertLegendValue(v::Tuple{S,T}) where {S<:Real, T<:Real} = v +convertLegendValue(v::Tuple{<:Real,Symbol}) = v +convertLegendValue(v::Real) = v convertLegendValue(v::AbstractArray) = map(convertLegendValue, v) # ----------------------------------------------------------------------------- diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 6a0ab1ee..29ac071c 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -911,7 +911,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) gr_update_viewport_ratio!(viewport_plotarea, sp) leg = gr_get_legend_geometry(viewport_plotarea, sp) gr_update_viewport_legend!(viewport_plotarea, sp, leg) - + # fill in the plot area background gr_fill_plotarea(sp, viewport_plotarea) @@ -1047,7 +1047,24 @@ end function gr_legend_pos(sp::Subplot, leg, viewport_plotarea) s = sp[:legend] - typeof(s) <: Symbol || return gr_legend_pos(s, viewport_plotarea) + s isa Real && return gr_legend_pos(s, leg, viewport_plotarea) + if s isa Tuple{<:Real,Symbol} + if s[2] !== :outer + return gr_legend_pos(s[1], leg, viewport_plotarea) + end + + xaxis, yaxis = sp[:xaxis], sp[:yaxis] + xmirror = xaxis[:guide_position] == :top || (xaxis[:guide_position] == :auto && xaxis[:mirror] == true) + ymirror = yaxis[:guide_position] == :right || (yaxis[:guide_position] == :auto && yaxis[:mirror] == true) + axisclearance = [ + !ymirror*gr_axis_width(sp, sp[:yaxis]), + ymirror*gr_axis_width(sp,sp[:yaxis]), + !xmirror*gr_axis_height(sp,sp[:xaxis]), + xmirror*gr_axis_height(sp,sp[:xaxis]), + ] + return gr_legend_pos(s[1], leg, viewport_plotarea; axisclearance) + end + s isa Symbol || return gr_legend_pos(s, viewport_plotarea) str = string(s) if str == "best" str = "topright" @@ -1098,6 +1115,55 @@ function gr_legend_pos(v::Tuple{S,T}, viewport_plotarea) where {S<:Real, T<:Real (xpos,ypos) end +function gr_legend_pos(theta::Real, leg, viewport_plotarea; axisclearance=nothing) + xmean = +(viewport_plotarea[1:2]...)/2 + ymean = +(viewport_plotarea[3:4]...)/2 + (s,c) = sincosd(theta) + + if isnothing(axisclearance) + # Inner + # rectangle relative to midpoint where the anchor can legally be + rect = viewport_plotarea .+ [ + - xmean + leg.xoffset + leg.leftw, + - xmean - leg.xoffset - leg.rightw - leg.textw, + - ymean + leg.yoffset + leg.h, + - ymean - leg.yoffset - leg.dy, + ] + x = c < 0 ? rect[1]/c : rect[2]/c + y = s < 0 ? rect[3]/s : rect[4]/s + A = min(x,y) # Biggest A that places (Acos(theta),Asin(theta)) inside rectangle + else + # Outer + # rectangle relative to midpoint where the anchor is forbidden + rect = viewport_plotarea .+ [ + - xmean - leg.xoffset - leg.rightw - leg.textw - axisclearance[1], + - xmean + leg.xoffset + leg.leftw + axisclearance[2], + - ymean - leg.yoffset - leg.dy - axisclearance[3], + - ymean + leg.yoffset + leg.h + axisclearance[4], + ] + t = tand(theta) + if c < 0 + if t < rect[4]/rect[1] + A = rect[4]/s + elseif t < rect[3]/rect[1] + A = rect[1]/c + else + A = rect[3]/s + end + else + if t < rect[3]/rect[2] + A = rect[3]/s + elseif t viewport_plotarea[2] + viewport_plotarea[2] -= leg.leftw + leg.textw + leg.rightw + leg.xoffset + end + if y < viewport_plotarea[3] + viewport_plotarea[3] += leg.h + leg.dy + leg.yoffset + !xmirror * gr_axis_height(sp, sp[:xaxis]) + elseif y > viewport_plotarea[4] + viewport_plotarea[4] -= leg.h + leg.dy + leg.yoffset + end + end + end + leg_str = string(s) if occursin("outer", leg_str) if occursin("right", leg_str) viewport_plotarea[2] -= leg.leftw + leg.textw + leg.rightw + leg.xoffset @@ -1171,7 +1253,7 @@ function gr_update_viewport_legend!(viewport_plotarea, sp, leg) viewport_plotarea[3] += leg.h + leg.dy + leg.yoffset + !xmirror * gr_axis_height(sp, sp[:xaxis]) end end - if sp[:legend] == :inline + if s === :inline if sp[:yaxis][:mirror] viewport_plotarea[1] += leg.w else @@ -1464,10 +1546,10 @@ function gr_label_axis_3d(sp, letter) if ax[:guide] != "" near_letter = letter in (:x, :z) ? :y : :x far_letter = letter in (:x, :y) ? :z : :x - + nax = sp[Symbol(near_letter, :axis)] fax = sp[Symbol(far_letter, :axis)] - + amin, amax = axis_limits(sp, letter) namin, namax = axis_limits(sp, near_letter) famin, famax = axis_limits(sp, far_letter) @@ -1732,7 +1814,7 @@ function gr_draw_contour(series, x, y, z, clims) end function gr_draw_surface(series, x, y, z, clims) - + if series[:seriestype] === :surface fillalpha = get_fillalpha(series) fillcolor = get_fillcolor(series)