pub fn stack_clear(
rect: Rect,
away_sign: f64,
claims: &[Rect],
bounds: &Rect,
) -> RectExpand description
Shifts rect along the y axis, away from its own anchor edge, just far
enough to clear every rect in claims it would otherwise overlap, plus
[CORNER_STACK_GAP] of real clearance — “stack them” (#273). away_sign
is the direction away from the anchor edge: -1.0 shifts up (decreases
y), the right direction for a bottom-anchored corner’s items (they
stack upward, away from the bottom edge); any other value shifts down
(increases y), for a top-anchored corner. A claim with no horizontal
overlap with rect is never a reason to move (rects_intersect
requires both axes).
Iterates a bounded number of passes (claims.len() + 1): clearing one
claim can push rect into a new overlap with another claim it
already cleared in an earlier pass (claims aren’t assumed sorted, or
non-overlapping with each other), so each pass re-checks every claim;
one extra pass beyond the claim count is enough to reach a fixed point
for any realistic claim count (a handful of corner items at once), and
a pass that clears nothing stops early — the common case is one pass.
bounds (normally the panel’s own plot_area) clamps the final
result: stacking never pushes rect so far that it leaves bounds
entirely (#273’s DataZooDE/anofox-visualization#549 repro — a
bivariate legend’s tall rotated caption, in a panel too short for
every corner item to stack fully clear of it — would otherwise walk
the next item up past the panel’s own top edge and off the map
entirely, strictly worse than the residual overlap it was avoiding).
When rect is taller than bounds itself, it’s pinned to bounds’s
own top rather than centred or otherwise guessed at.