
Mousewheel Graph Window Zoom

Wed, 02/10/2021 - 09:02 am
In my web browser I can magnify the window contents by holding down the command/control key and scrolling with mousewheel or trackpad. Now I can do the same in a graph window :)
You can already use the mousewheel/trackpad to change the axis range if you hover over an axis. The code below lets you zoom both axes simultaneously. Holding down the shift key as well as command/ctrl accelerates the zoom factor. Expansion/contraction is centred at the mouse cursor position, so you can position your mouse and command-shift-scroll to zoom in rapidly on a point of interest.
When the 'global' symbol is defined, scroll-to-zoom is active for all newly created graph windows. Otherwise, it can be turned on or off for each graph window.
#pragma DefaultTab={3,20,4}
#pragma version=1.50
#pragma ModuleName=ScrollToZoom
#define global
// key codes
// 2: shift; 4: option/alt; 8: command/ctrl
// On Windows, alt key is reserved for graph drag.
static constant kZoomKey=8
static constant kFasterKey=2
static constant kZoomSpeed=70
static constant kReverse=0 // reverse the direction of expansion
#ifdef global
static function AfterWindowCreatedHook(string win, variable type)
if (type == 1)
SetWindow $win hook(hScrollToZoom)=ScrollToZoom#hookScrollToZoom
endif
return 0
end
#else
menu "Graph", dynamic
ScrollToZoom#zoomMenu(), /Q, ScrollToZoom#toggleZoom()
end
static function /S zoomMenu()
GetWindow kwTopWin hook(hScrollToZoom)
return SelectString(strlen(s_value)>0, "", "!" + num2char(18)) + "Scroll-Zoom"
end
#endif
static function toggleZoom()
GetWindow kwTopWin hook(hScrollToZoom)
SetWindow kwTopWin hook(hScrollToZoom) = $SelectString(strlen(s_value)>0, "ScrollToZoom#hookScrollToZoom", "")
end
static function hookScrollToZoom(STRUCT WMWinHookStruct &s)
if (s.eventCode == 22 && s.eventMod&kZoomKey) // mousewheel/touchpad + zoom key
string strAxes = AxisList(s.WinName), axis = "", type = ""
int i, numAxes, isHorizontal, isLog
Make /D/free/N=3 wAx // free wave to hold axis minimum, maximum, axis value for mouse location
numAxes = ItemsInList(strAxes)
int rev = 1 - 2*kReverse
variable expansion = 1 - rev*s.wheelDy * kZoomSpeed/5000
if (s.eventMod & kFasterKey)
if (kFasterKey==2 && s.wheelDy==0)
// this works when shift key also transforms wheel.dY to wheel.dX
s.wheelDy = s.wheelDx
endif
expansion = 1 - rev*s.wheelDy * kZoomSpeed/500
endif
for (i=0;i<numAxes;i++)
axis = StringFromList(i, strAxes)
type = StringByKey("AXTYPE", AxisInfo(s.WinName, axis))
isHorizontal = (cmpstr(type, "bottom")==0 || cmpstr(type,"top")==0 || cmpstr(type[0,2],"/B=")==0 || cmpstr(type[0,2],"/T=")==0)
isLog = (NumberByKey("log(x)", AxisInfo(s.WinName, axis),"="))
GetAxis /W=$s.WinName/Q $axis
wAx = {v_min, v_max, AxisValFromPixel(s.WinName, axis, isHorizontal ? s.mouseLoc.h : s.mouseLoc.v)}
if (WaveMax(wAx) == wAx[2] || WaveMin(wAx) == wAx[2])
continue
endif
if (isLog)
wAx = log(wAx)
wAx = wAx[2] - (wAx[2] - wAx[p]) * expansion
wAx = alog(wAx)
else
wAx = wAx[2] - (wAx[2] - wAx[p]) * expansion
endif
WaveStats /Q/M=1 wAx
if ( (V_numNaNs+V_numInfs) || wAx[1]==wAx[0] )
continue
endif
if (wAx[1] > wAx[0])
SetAxis /W=$s.WinName $axis, wAx[0], wAx[1]
else
SetAxis /R/W=$s.WinName $axis, wAx[0], wAx[1]
endif
endfor
endif
return 0
end

Forum

Support

Gallery
Igor Pro 9
Learn More
Igor XOP Toolkit
Learn More
Igor NIDAQ Tools MX
Learn More
Edited snippet works with log axes.
February 17, 2021 at 12:30 am - Permalink
Edited to add /R flag for reversed axes. A subsequent autoscale will not switch the axis direction.
February 19, 2021 at 04:27 am - Permalink
I just noticed that forum member Henry S released a project back in 2014 that functions more-or-less identically to this code snippet.
https://www.wavemetrics.com/project/ScrollWheelZoom
I suspect that the 2014 project is not maintained any more. Nevertheless, I wanted to point out that Henry S got there first, and note that it's easy to overlook the resources available in this forum!
August 29, 2021 at 02:25 am - Permalink
Say, Tony- I'm guessing that this adds to the functionality you get currently when the mouse is over an axis and you use the mouse wheel?
August 30, 2021 at 09:24 am - Permalink
Yes, it zooms so that the point under the mouse stays put. The older project used a modifier key to prevent zooming, mine uses a modifier to allow. It feels quite 'natural'.
My version also handles log axes.
What I didn't do is to get a list of all axes and figure out which ones are relevant for the mouse cursor position...
Edit: v1.5 fixes this
August 31, 2021 at 12:39 am - Permalink