MathGroup Archive 2008

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Interactive 2d zoom and some Dynamic questions

  • To: mathgroup at smc.vnet.net
  • Subject: [mg84588] Re: Interactive 2d zoom and some Dynamic questions
  • From: m.r at inbox.ru
  • Date: Sun, 6 Jan 2008 05:51:20 -0500 (EST)
  • References: <flfaf0$a9e$1@smc.vnet.net>

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


  • Prev by Date: Tooltips with 2 data points
  • Next by Date: Re: Histogram: Show all y-axis labels
  • Previous by thread: Re: Interactive 2d zoom and some Dynamic questions
  • Next by thread: Re: Interactive 2d zoom and some Dynamic questions