Skip to content
This repository has been archived by the owner on Jul 13, 2021. It is now read-only.

Commit

Permalink
expand limits after unioning links, reset_limits! on scale change (#700)
Browse files Browse the repository at this point in the history
  • Loading branch information
jkrumbiegel authored Apr 22, 2021
1 parent 154982d commit 73ebbd1
Showing 1 changed file with 51 additions and 24 deletions.
75 changes: 51 additions & 24 deletions src/makielayout/layoutables/axis.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,22 @@ function layoutable(::Type{<:Axis}, fig_or_scene::Union{Figure, Scene}; bbox = n
targetlimits = Node{FRect2D}(defaultlimits(limits[], attrs.xscale[], attrs.yscale[]))
finallimits = Node{FRect2D}(targetlimits[])

onany(targetlimits, attrs.xscale, attrs.yscale) do lims, xsc, ysc
# the first thing to do when setting a new scale is
# resetting the limits because simply through expanding they might be invalid for log
# but we don't have the axis here yet, so we make this nice and ugly ref for it
this_axis = Ref{Union{Nothing, Axis}}(nothing)
onany(attrs.xscale, attrs.yscale) do _, _
isnothing(this_axis[]) || reset_limits!(this_axis[])
end

on(targetlimits) do lims
# this should validate the targetlimits before anything else happens with them
# so there should be nothing before this lifting `targetlimits`
# we don't use finallimits because that's one step later and you
# already shouldn't set invalid targetlimits (even if they could
# theoretically be adjusted to fit somehow later?)
# and this way we can error pretty early
validate_limits_for_scales(lims, xsc, ysc)
validate_limits_for_scales(lims, attrs.xscale[], attrs.yscale[])
end

scenearea = sceneareanode!(layoutobservables.computedbbox, finallimits, aspect)
Expand Down Expand Up @@ -377,6 +385,7 @@ function layoutable(::Type{<:Axis}, fig_or_scene::Union{Figure, Scene}; bbox = n
ax = Axis(fig_or_scene, layoutobservables, attrs, decorations, scene,
xaxislinks, yaxislinks, targetlimits, finallimits, block_limit_linking,
mouseeventhandle, scrollevents, keysevents, interactions)
this_axis[] = ax

function process_event(event)
for (active, interaction) in values(ax.interactions)
Expand Down Expand Up @@ -554,8 +563,20 @@ function expandlimits(lims, margin_low, margin_high, scale)
lims = inverse.((lims_scaled[1] - d_low_scaled, lims_scaled[2] + d_high_scaled))

# guard against singular limits from something like a vline or hline
if lims[2] - lims[1] == 0
lims = lims .+ (-10, 10)
if lims[2] - lims[1] 0
# this works for log as well
# we look at the distance to zero in scaled space
# then try to center the value between that zero and the value
# that is the same scaled distance away on the other side
# which centers the singular value optically
zerodist = abs(scale(lims[1]))

# for 0 in linear space this doesn't work so here we just expand to -1, 1
if zerodist 0 && scale === identity
lims = (-one(lims[1]), one(lims[1]))
else
lims = inverse.(scale.(lims) .+ (-zerodist, zerodist))
end
end
lims
end
Expand Down Expand Up @@ -661,16 +682,7 @@ end
function xautolimits(ax::Axis)
# try getting x limits for the axis and then union them with linked axes
xlims = getxlimits(ax)
# but if we have limits, then expand them with the auto margins
if !isnothing(xlims)
if !validate_limits_for_scale(xlims, ax.xscale[])
error("Found invalid x-limits $xlims for scale $(ax.xscale[]) which is defined on the interval $(defined_interval(ax.xscale[]))")
end
xlims = expandlimits(xlims,
ax.attributes.xautolimitmargin[][1],
ax.attributes.xautolimitmargin[][2],
ax.xscale[])
end

for link in ax.xaxislinks
if isnothing(xlims)
xlims = getxlimits(link)
Expand All @@ -681,6 +693,18 @@ function xautolimits(ax::Axis)
end
end
end

if !isnothing(xlims)
if !validate_limits_for_scale(xlims, ax.xscale[])
error("Found invalid x-limits $xlims for scale $(ax.xscale[]) which is defined on the interval $(defined_interval(ax.xscale[]))")
end

xlims = expandlimits(xlims,
ax.attributes.xautolimitmargin[][1],
ax.attributes.xautolimitmargin[][2],
ax.xscale[])
end

# if no limits have been found, use the targetlimits directly
if isnothing(xlims)
xlims = (ax.targetlimits[].origin[1], ax.targetlimits[].origin[1] + ax.targetlimits[].widths[1])
Expand All @@ -691,16 +715,7 @@ end
function yautolimits(ax)
# try getting y limits for the axis and then union them with linked axes
ylims = getylimits(ax)
# but if we have limits, then expand them with the auto margins
if !isnothing(ylims)
if !validate_limits_for_scale(ylims, ax.yscale[])
error("Found invalid direct y-limits $ylims for scale $(ax.yscale[]) which is defined on the interval $(defined_interval(ax.yscale[]))")
end
ylims = expandlimits(ylims,
ax.attributes.yautolimitmargin[][1],
ax.attributes.yautolimitmargin[][2],
ax.yscale[])
end

for link in ax.yaxislinks
if isnothing(ylims)
ylims = getylimits(link)
Expand All @@ -711,6 +726,18 @@ function yautolimits(ax)
end
end
end

if !isnothing(ylims)
if !validate_limits_for_scale(ylims, ax.yscale[])
error("Found invalid direct y-limits $ylims for scale $(ax.yscale[]) which is defined on the interval $(defined_interval(ax.yscale[]))")
end

ylims = expandlimits(ylims,
ax.attributes.yautolimitmargin[][1],
ax.attributes.yautolimitmargin[][2],
ax.yscale[])
end

# if no limits have been found, use the targetlimits directly
if isnothing(ylims)
ylims = (ax.targetlimits[].origin[2], ax.targetlimits[].origin[2] + ax.targetlimits[].widths[2])
Expand Down

0 comments on commit 73ebbd1

Please sign in to comment.