
Modifying enabled axis ranges interactively

thomas_braun
I often plot multiple datasets against a common x-axis but each of them has its own y-axis.
Example:
Function dostuff() Make/O data1 = p Make/O data2 = -p Display AppendToGraph/L=ax1 data1 AppendToGraph/L=ax2 data2 ModifyGraph axisEnab(ax2)={0,0.475}, axisEnab(ax1)={0.525,1}, freePos(ax1)={0,bottom}, freePos(ax2)={0,bottom} End
This works without any problems and also looks nice. But now I have the request to allow the user to interactively change the enabled axis ranges with the mouse. Is that possible? IP9 only is okay.
How about a hook function where you react to a scroll event when the mouse is positioned in the left margin of the graph window. you could place some object (a button?) at the boundary that separates the two axes and have it enabled on mouseover, then shift the axis ranges and button position as the user scrolls.
January 7, 2022 at 08:31 am - Permalink
Maybe I don't get something here. Isn't that the default behavior of Igor? Hover with mouse cursor over the axis in question and scroll with the mouse to change the axis range. Just scroll to zoom or hold alt / option to shift ... or is click and drag desired?
January 7, 2022 at 08:43 am - Permalink
I think thomas wants to change the range over which the axis is drawn:
ModifyGraph axisEnab(ax2)={0,0.5}
January 7, 2022 at 09:01 am - Permalink
In IP9 you can make a transparent button that sits in the zone between the top and bottom plot areas.
On mouse enter, draw a horizontal line across the width of the graph as a visual cue and set a userdata flag to enable changing the ranges
A hook function checks the flag and changes the axis enabled ranges and the position of the horizontal line on scroll event
On mouse exit kill the dividing line, reposition the invisible button (taking a great deal of care with coordinates) and reset the userdata flag
edit: and the button has to be repositioned after window resize events.
January 7, 2022 at 09:11 am - Permalink
Wow so many replies so fast :)
Yes I want to change
axisEnab
and not the displayed axis range.
@tony:
Thanks for the idea, that seems doable. I'll report back.
January 7, 2022 at 09:25 am - Permalink
I have long thought there should be more mouse interaction with axis layout, but have many ideas and limited time.
January 7, 2022 at 09:42 am - Permalink
If that helps: The Global Fit Panel features a dragable divider line between the two listboxes using the mousedown, mousemoved and mouseup events. This works very nice and may serve as an inspiration for coding a similar dragable divider between the two axes, The code can be found in the panel's hook function starting from line 1732 inside Global Fit 2.ipf (this refers to the Igor 9 version; the particular code might be on a somewhat different line in the Igor 8 version but should be close).
January 7, 2022 at 09:57 am - Permalink
Here's a solution that the good folks at Wavemetrics helped out with several years ago which I use in our library of routines. It uses the marquee menu to zoom in on any axis of a graph.
January 7, 2022 at 10:55 am - Permalink
To test it, make thomas' plot, then execute
January 8, 2022 at 05:49 am - Permalink
Very nice. I had to add
pixDivider = pixDivider *96/72
after the pixDivider declaration to get the cursor to align with the split between the two plots on my Win10 machine (IP9).
January 8, 2022 at 09:33 am - Permalink
In reply to Very nice. I had to add … by jtigor
Rats- bitten yet again by windows coordinates!
I changed the line
to
That should fix it.
January 8, 2022 at 10:10 am - Permalink
Excellent snippet Tony. Works very nice :) I wonder if such code could be added to the Split Axes package in the future. I tried myself at optimizing the code a bit. Here is a CPU-friendly alternative without the do-while loop (the divider positions work fine here on windows; I hope there is no strange offset on Mac):
January 9, 2022 at 03:29 am - Permalink
@chozo,
Thanks, that is a more sensible structure. Unfortunately, the mouseup event is sometimes 'missed' using this version, leading to a 'sticky' behaviour.
Also, setting the cursor on all mousemoved events swallows up the UI cursor changes for a graph window, and the divider calculation is a bit off. You caught my missing return statement, but the hook should return 0 to avoid stealing these events. Try this:
I restricted the 'hot' zone to the left side of the graph window.
Edit: I added a check for missed mouseup event.
January 11, 2022 at 12:32 am - Permalink
Hi Tony, yes works great. I was also thinking of reducing the active area to the edge (maybe also the divider line should be drawn only in this region). Indeed as you write, return 1 was a bit excessive. I added this in because I had problems with accidentally dragging a marquee at the beginning and did not think much of it afterwards. I also don't know why the divider calculation now works fine without the 0.05 units offset. Must have been a glitch when I was testing things. I didn't get problems with a hanging mousedown state, but it is great to have this fallback in place.
Now if some code to detect multiple axes in both horizontal and vertical arrangements would be added, this could actually be a small complete project to dynamically change axis splits. Maybe I try this as a fun weekend project some time.
January 11, 2022 at 01:39 am - Permalink