Skip to content

Commit 941cf5d

Browse files
committed
Fix the rectangle zoom interaction (#310)
1 parent ee8000a commit 941cf5d

File tree

1 file changed

+31
-17
lines changed

1 file changed

+31
-17
lines changed

src/makie-axis.jl

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -297,9 +297,29 @@ getxlimits(la::GeoAxis) = getlimits(la, 1)
297297
getylimits(la::GeoAxis) = getlimits(la, 2)
298298

299299

300+
function _selection_vertices_notransform(ax_scene, outer, inner)
301+
_clamp(p, plow, phigh) = Point2(clamp(p[1], plow[1], phigh[1]), clamp(p[2], plow[2], phigh[2]))
302+
proj(point) = Makie.project(ax_scene, point) + Makie.origin(Makie.to_value(Makie.viewport(ax_scene)))
303+
outer = Makie.positivize(outer)
304+
inner = Makie.positivize(inner)
305+
306+
obl = Makie.bottomleft(outer)
307+
obr = Makie.bottomright(outer)
308+
otl = Makie.topleft(outer)
309+
otr = Makie.topright(outer)
310+
311+
ibl = _clamp(Makie.bottomleft(inner), obl, otr)
312+
ibr = _clamp(Makie.bottomright(inner), obl, otr)
313+
itl = _clamp(Makie.topleft(inner), obl, otr)
314+
itr = _clamp(Makie.topright(inner), obl, otr)
315+
# We plot the selection vertices in blockscene, which is pixelspace, so we need to manually
316+
# project the points to the space of `ax.scene`
317+
return [proj(obl), proj(obr), proj(otr), proj(otl), proj(ibl), proj(ibr), proj(itr), proj(itl)]
318+
end
319+
300320
function Makie.RectangleZoom(f::Function, ax::GeoAxis; kw...)
301321
r = Makie.RectangleZoom(f; kw...)
302-
selection_vertices = lift(Makie._selection_vertices, Observable(ax.scene), ax.finallimits, r.rectnode)
322+
selection_vertices = lift(_selection_vertices_notransform, Observable(ax.scene), ax.finallimits, r.rectnode)
303323
# manually specify correct faces for a rectangle with a rectangle hole inside
304324
faces = [1 2 5; 5 2 6; 2 3 6; 6 3 7; 3 4 7; 7 4 8; 4 1 8; 8 1 5]
305325
# plot to blockscene, so ax.scene stays exclusive for user plots
@@ -336,22 +356,14 @@ end
336356

337357
function Makie.process_interaction(r::Makie.RectangleZoom, event::MouseEvent, ax::GeoAxis)
338358

339-
# TODO: actually, the data from the mouse event should be transformed already
340-
# but the problem is that these mouse events are generated all the time
341-
# and outside of log axes, you would quickly run into domain errors
342-
transf = Makie.transform_func(ax)
343-
inv_transf = Makie.inverse_transform(transf)
344-
345-
if isnothing(inv_transf)
346-
@warn "Can't rectangle zoom without inverse transform" maxlog = 1
347-
# TODO, what can we do without inverse?
348-
return Consume(false)
349-
end
359+
# the data is already pre-transformed, let rectangle zoom work as it would on an axis without transformation
360+
# we handle the inverse transform needed in the handling of finallimits anyway, so it's no bother
361+
# and targetlimits is in transformed space, so we don't need to transform it
350362

351363
if event.type === MouseEventTypes.leftdragstart
352-
data = Makie.apply_transform(inv_transf, event.data)
353-
prev_data = Makie.apply_transform(inv_transf, event.prev_data)
354-
364+
data = event.data
365+
prev_data = event.prev_data
366+
355367
r.from = prev_data
356368
r.to = data
357369
r.rectnode[] = Makie._chosen_limits(r, ax)
@@ -360,8 +372,8 @@ function Makie.process_interaction(r::Makie.RectangleZoom, event::MouseEvent, ax
360372

361373
elseif event.type === MouseEventTypes.leftdrag
362374
# clamp mouse data to shown limits
363-
rect = Makie.apply_transform(transf, ax.finallimits[])
364-
data = Makie.apply_transform(inv_transf, Makie.rectclamp(event.data, rect))
375+
rect = ax.finallimits[]
376+
data = Makie.rectclamp(event.data, rect)
365377

366378
r.to = data
367379
r.rectnode[] = Makie._chosen_limits(r, ax)
@@ -406,6 +418,8 @@ function Makie.process_interaction(l::Makie.LimitReset, event::MouseEvent, ax::G
406418
end
407419

408420
function Makie.process_interaction(s::Makie.ScrollZoom, event::Makie.ScrollEvent, ax::GeoAxis)
421+
# TODO: zooming happens in transformed space here,
422+
# should it happen in data space instead?
409423
# use vertical zoom
410424
zoom = event.y
411425

0 commit comments

Comments
 (0)