Centralize utility functions, add legend-angle to plotly, pgfplotsx
This commit is contained in:
parent
2cee039dbc
commit
6724a3a2fe
@ -211,6 +211,7 @@ include("output.jl")
|
||||
include("ijulia.jl")
|
||||
include("fileio.jl")
|
||||
include("init.jl")
|
||||
include("legend.jl")
|
||||
|
||||
include("backends/plotly.jl")
|
||||
include("backends/gr.jl")
|
||||
|
||||
@ -1116,52 +1116,24 @@ function gr_legend_pos(v::Tuple{S,T}, viewport_plotarea) where {S<:Real, T<:Real
|
||||
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)
|
||||
xcenter = +(viewport_plotarea[1:2]...)/2
|
||||
ycenter = +(viewport_plotarea[3:4]...)/2
|
||||
|
||||
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
|
||||
# rectangle where the anchor can legally be
|
||||
xmin = viewport_plotarea[1] + leg.xoffset + leg.leftw
|
||||
xmax = viewport_plotarea[2] - leg.xoffset - leg.rightw - leg.textw
|
||||
ymin = viewport_plotarea[3] + leg.yoffset + leg.h
|
||||
ymax = viewport_plotarea[4] - leg.yoffset - leg.dy
|
||||
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 <rect[4]/rect[2]
|
||||
A = rect[2]/c
|
||||
else
|
||||
A = rect[4]/s
|
||||
end
|
||||
end
|
||||
xmin = viewport_plotarea[1] - leg.xoffset - leg.rightw - leg.textw - axisclearance[1]
|
||||
xmax = viewport_plotarea[2] + leg.xoffset + leg.leftw + axisclearance[2]
|
||||
ymin = viewport_plotarea[3] - leg.yoffset - leg.dy - axisclearance[3]
|
||||
ymax = viewport_plotarea[4] + leg.yoffset + leg.h + axisclearance[4]
|
||||
end
|
||||
|
||||
return xmean + A*c, ymean + A*s
|
||||
return legend_pos_from_angle(theta,xmin,xcenter,xmax,ymin,ycenter,ymax)
|
||||
end
|
||||
|
||||
function gr_get_legend_geometry(viewport_plotarea, sp)
|
||||
|
||||
@ -769,8 +769,26 @@ pgfx_get_legend_pos(k) = get(
|
||||
Symbol(k),
|
||||
("at" => string((1.02, 1)), "anchor" => "north west"),
|
||||
)
|
||||
pgfx_get_legend_pos(t::Tuple) = ("at" => "{$(string(t))}", "anchor" => "north west")
|
||||
pgfx_get_legend_pos(t::Tuple{S,T}) where {S<:Real,T<:Real} = ("at" => "{$(string(t))}", "anchor" => "north west")
|
||||
pgfx_get_legend_pos(nt::NamedTuple) = ("at" => "{$(string(nt.at))}", "anchor" => string(nt.anchor))
|
||||
pgfx_get_legend_pos(theta::Real) = pgfx_get_legend_pos((theta,:inner))
|
||||
function pgfx_get_legend_pos(v::Tuple{S,Symbol}) where S <: Real
|
||||
(s,c) = sincosd(v[1])
|
||||
anchors = [
|
||||
"north west" "north" "north east";
|
||||
"west" "center" "east";
|
||||
"south west" "south" "south east";
|
||||
]
|
||||
|
||||
if v[2] === :inner
|
||||
rect = (0.07,0.5,1.0,0.07,0.52,1.0)
|
||||
anchor = anchors[legend_anchor_index(s),legend_anchor_index(c)]
|
||||
else
|
||||
rect = (-0.15,0.5,1.05,-0.15,0.52,1.1)
|
||||
anchor = anchors[4-legend_anchor_index(s),4-legend_anchor_index(c)]
|
||||
end
|
||||
return ("at"=>"$(string(legend_pos_from_angle(v[1],rect...)))", "anchor"=>anchor)
|
||||
end
|
||||
|
||||
pgfx_get_colorbar_pos(s) =
|
||||
get((left = " left", bottom = " horizontal", top = " horizontal"), s, "")
|
||||
|
||||
@ -384,6 +384,25 @@ end
|
||||
|
||||
plotly_legend_pos(v::Tuple{S,T}) where {S<:Real, T<:Real} = (coords=v, xanchor="left", yanchor="top")
|
||||
|
||||
plotly_legend_pos(theta::Real) = plotly_legend_pos((theta, :inner))
|
||||
|
||||
function plotly_legend_pos(v::Tuple{S,Symbol}) where S<:Real
|
||||
(s,c) = sincosd(v[1])
|
||||
xanchors = ["left", "center", "right"]
|
||||
yanchors = ["bottom", "middle", "top"]
|
||||
|
||||
if v[2] === :inner
|
||||
rect = (0.07,0.5,1.0,0.07,0.52,1.0)
|
||||
xanchor = xanchors[legend_anchor_index(c)]
|
||||
yanchor = yanchors[legend_anchor_index(s)]
|
||||
else
|
||||
rect = (-0.15,0.5,1.05,-0.15,0.52,1.1)
|
||||
xanchor = xanchors[4-legend_anchor_index(c)]
|
||||
yanchor = yanchors[4-legend_anchor_index(s)]
|
||||
end
|
||||
return (coords=legend_pos_from_angle(v[1],rect...), xanchor=xanchor, yanchor=yanchor)
|
||||
end
|
||||
|
||||
|
||||
function plotly_layout_json(plt::Plot)
|
||||
JSON.json(plotly_layout(plt), 4)
|
||||
@ -595,9 +614,9 @@ function plotly_series(plt::Plot, series::Series)
|
||||
elseif st == :mesh3d
|
||||
plotattributes_out[:type] = "mesh3d"
|
||||
plotattributes_out[:x], plotattributes_out[:y], plotattributes_out[:z] = x, y, z
|
||||
|
||||
|
||||
if series[:connections] !== nothing
|
||||
if typeof(series[:connections]) <: Tuple{Array,Array,Array}
|
||||
if typeof(series[:connections]) <: Tuple{Array,Array,Array}
|
||||
i,j,k = series[:connections]
|
||||
if !(length(i) == length(j) == length(k))
|
||||
throw(ArgumentError("Argument connections must consist of equally sized arrays."))
|
||||
|
||||
24
src/legend.jl
Normal file
24
src/legend.jl
Normal file
@ -0,0 +1,24 @@
|
||||
"""
|
||||
```julia
|
||||
legend_pos_from_angle(theta, xmin, xcenter, xmax, ymin, ycenter, ymax, inout)
|
||||
```
|
||||
|
||||
Return `(x,y)` at an angle `theta` degrees from
|
||||
`(xcenter,ycenter)` on a rectangle defined by (`xmin`,
|
||||
`xmax`, `ymin`, `ymax`).
|
||||
"""
|
||||
function legend_pos_from_angle(theta, xmin, xcenter, xmax, ymin, ycenter, ymax)
|
||||
(s,c) = sincosd(theta)
|
||||
x = c < 0 ? (xmin-xcenter)/c : (xmax-xcenter)/c
|
||||
y = s < 0 ? (ymin-ycenter)/s : (ymax-ycenter)/s
|
||||
A = min(x,y)
|
||||
return (xcenter + A*c, ycenter + A*s)
|
||||
end
|
||||
|
||||
|
||||
"""
|
||||
Split continuous range `[-1,1]` into an integer `[1,2,3]`
|
||||
"""
|
||||
function legend_anchor_index(x)
|
||||
return ceil(Integer,2//3*(x+1))
|
||||
end
|
||||
Loading…
x
Reference in New Issue
Block a user