Re: Interactive 2d zoom and some Dynamic questions
- To: mathgroup at smc.vnet.net
- Subject: [mg84626] Re: Interactive 2d zoom and some Dynamic questions
- From: Jerry <JLK2941 at yahoo.com>
- Date: Mon, 7 Jan 2008 02:42:20 -0500 (EST)
- References: <flfaf0$a9e$1@smc.vnet.net> <flqbr3$j2j$1@smc.vnet.net>
Hi, did you mean to replace the DynamicModule section of the above code with yours? I tried that and it seems to work like you say but the thing plotted isn't a 2D plot of 1/x vs x, it's a circular collections of connected dots, a "graph" I'd guess. Seems like I'm doing something wrong. m.r at inbox.ru wrote: > On Jan 2, 12:20 am, Szabolcs Horv=E1t <szhor... at gmail.com> wrote: >> Happy new year, MathGroup! >> >> And now, the question: >> >> First of all, those people who haven't seen it yet should definitely >> check out Daniel Huber's very nice Zoom2D palette:http://groups.google.com/group/comp.soft-sys.math.mathematica/browse_... >> >> But I would like to have something simpler, a "quick and dirty" zoom >> that has the simplest possible UI, and keeps the graphic in the >> notebook. So I came up with this: >> >> zoomGraphics[graph_Graphics] := >> With[ >> {gr = First[graph], >> opt = DeleteCases[Options[graph], PlotRange -> _], >> plr = PlotRange /. Options[graph, PlotRange], >> rectangle = {Dashing[Small], >> Line[{#1, {First[#2], Last[#1]}, #2, >> {First[#1], Last[#2]}, #1}]} & }, >> DynamicModule[{dragging = False, first, second, range = plr}, >> Panel@EventHandler[ >> Dynamic@Graphics[ >> If[dragging, {gr, rectangle[first, second]}, gr], >> PlotRange -> range, Sequence @@ opt >> ], >> {{"MouseDown", 1} :> (first = MousePosition["Graphics"]), >> {"MouseDragged", 1} :> >> (dragging = True; >> second = MousePosition["Graphics"]), >> {"MouseUp", 1} :> >> If[dragging, >> dragging = False; >> range = Transpose@{first, second}, range = plr] } >> ] >> ]] >> >> Usage example: >> >> Plot[1/x, {x, 0, 1}] // zoomGraphics >> >> Drag to zoom, click to reset. Remove Panel if you don't like it (or >> replace it with Framed). It's there to show the active ("draggable") area. >> >> I do not understand Dynamic things well, so comments, suggestions (e.g. >> for improving performance), problem cases where zoomGraphics fails are >> most welcome. >> >> One of the biggest problems with this is that EvantHandler prevents >> resizing the graphic from working. This is unacceptable because if we >> want to zoom, most likely we also want to keep the resize functionality. >> >> It also prevents dynamic things, like Locators from working properly. I >> could set PassEventsDown -> True in EventHandler, but zooming would >> still interfere with resizing or moving a Locator (and other strange >> behaviour appears too.) One solution that I can imagine is to zoom only >> while CTRL (or some other modifier key) is pressed. But I do not know >> how to implement this properly. This is what I have so far: >> >> zoomGraphics[graph_Graphics] := >> With[ >> {gr = First[graph], >> opt = DeleteCases[Options[graph], PlotRange -> _], >> plr = PlotRange /. Options[graph, PlotRange], >> rectangle = {Dashing[Small], >> Line[{#1, {First[#2], Last[#1]}, #2, {First[#1], >> Last[#2]}, #1}]} &, >> keyCheck = >> Function[{arg}, If[CurrentValue["ControlKey"], arg], HoldAll]}, >> DynamicModule[{dragging = False, first, second, range = plr}, >> Panel@EventHandler[ >> Dynamic[ >> Graphics[ >> If[dragging, {gr, rectangle[first, second]}, gr], >> PlotRange -> range, Sequence @@ opt >> ]], >> {{"MouseDown", 1} :> >> keyCheck[first = MousePosition["Graphics"]], >> {"MouseDragged", 1} :> >> keyCheck[dragging = True; second = MousePosition["Graphics"]], >> {"MouseUp", 1} :> >> keyCheck@ >> If[dragging, dragging = False; >> range = Transpose@{first, second}, range = plr]}] >> ]] >> >> OK, now zooming only works while CTRL is pressed. Now it is somewhat >> safer to set PassEventsDown -> True, and resizing works when CTRL is not >> pressed. But resizing and selecting graphics interferes with zooming >> when CTRL is pressed. The zoom level is also often reset unexpectedly >> if CTRL is not released (and pressed again), and the graphics are not >> deselected, between consecutive zoom attempts. I don't completely >> understand what is happening here. Is it possible to somehow set >> PassEventsDown -> True only when CTRL is not pressed? As a desperate >> attempt, I tried PassEventsDown -> >> Dynamic@Not@CurrentValue["ControlKey"], but, unsurprisingly, it does not >> work. >> >> As an alternative solution, I also tried using >> GraphicsGrid[{{zoomGraphics[someGraphic]}}] with the original version of >> zoomGraphics to enable resizing (not moving Locators), but now the >> events don't seem to reach the EventHandler. >> >> Another question: Could someone please explain, preferably with a >> working example, what PassEventsUp is for? >> >> Szabolcs > > You can dynamically change Deployed: > > DynamicModule[{mp, pos = {.5, .5}, sz = {1, 1}, mpos, f = True}, > mp[] := MousePosition["GraphicsScaled"]; > EventHandler[ > Style[Graphics[ > Inset[GraphData["HundredTwentyCellGraph"], > Center, Dynamic@Scaled@pos, Dynamic@Scaled@sz], > ImageSize -> 500], Deployed -> Dynamic[f]], > {"MouseDown" :> > (If[f && CurrentValue["MouseButtonTest"] && > CurrentValue["MouseClickCount"] == 2, > pos = {.5, .5}; sz = {1, 1}, > If[f && CurrentValue["ControlKey"], > f = False, > If[! f && CurrentValue["AltKey"], > f = True]]]; > mpos = mp[]), > "MouseDragged" :> > (If[f, > If[CurrentValue["MouseButtonTest"], > pos -= 2/sz[[1]] (mp[] - mpos), > sz += 4 sz[[1]] (mp[][[2]] - mpos[[2]])]; > mpos = mp[]])}, > PassEventsDown -> True]] > > Here dragging the mouse with the left button pressed pans the graphic, > dragging the mouse up/down with the right button pressed zooms in/out, > left double click resets to defaults, but if you do Control-click, you > switch to the standard interactive editing mode. Alt-click switches > back to zoom mode. > > Maxim Rytin > m.r at inbox.ru >