
Adapt to user zooming into axis

thomas_braun
I have a graph with some data, attached to it a free axis and an axis hook function. The axis hook function should run some code whenever a user zooms in or out of an trace/image.
Fuction Setup() Make/O data = p Make/O largedata = p + 100 End Function AxisHook(s) STRUCT WMAxisHookStruct &s print "called with", s End Window Graph0() : Graph PauseUpdate; Silent 1 // building window... Display /W=(95.25,263,612,634.25) data NewFreeAxis/O/L test ModifyFreeAxis/Z test,master= bottom,hook= AxisHook ModifyGraph nticks(test)=0 ModifyGraph axThick(test)=0 ModifyGraph lblPos(left)=47 ModifyGraph freePos(test)=-50 SetAxis left -7.63192488262911,144.768075117371 EndMacro
Now this works for my use case.
But when I add more data to it via
AppendToGraph largeData
my hook function get's also called. But I would like to distinguish the case of users zooming into the axis and code changing the axis limits. Or to rephrase I actually want to run the code *only* when the user zooms in/out interactively and not when doing it programmatically.
Is that possible? Am I doing it right?
Hmm, that is surprisingly difficult. There seems to be no way to tell from the axis hook what event called the hook function. I came up with a somewhat kludgy workaround which saves the latest axis scaling in the graph's user data and only calls code if the axis range has changed (which happens when zooming):
November 5, 2020 at 04:51 pm - Permalink
Unfortunately, the axis range changes when you add a trace with different range, and also when the user changes the axis range.
November 5, 2020 at 04:56 pm - Permalink
Oh, that's right! So my example was not very useful. That's really an uphill battle, but one could use the same method to store a list of displayed traces on the graph and compare if something has changed between calls. I don't see how one can distinguish user's zooming in from any other event which changes the axis range.
November 5, 2020 at 05:03 pm - Permalink
You may need to have a button to turn the zoom feature (your hook function) on/off.
You may need to lock out any ability to manually add data to the graph and instead force the user to run a function instead (e.g. myappendtograph).
Doesn't Igor give an option to know what the last issued command was? Can that be tested in the hook function to distinguish a command-line input appendtograph and thereby ignore break from the hook?
Of these three, I might find the first the easiest to do even as it adds the overhead for the UI on the user.
November 5, 2020 at 05:15 pm - Permalink
Thanks all for your input. I've now found a solution. I've ditched the axis hook approach and went with a normal window hook. The code is basically
where PA_UpdateScaleBars reacts to the user zooming into an axis via the mouse wheel, and the menu reset the scale bars on Ctrl+a. I had to use the operation queue here so that it is executed after the axis has been rescaled by IP.
November 15, 2020 at 07:43 am - Permalink