File: base_zoom_tool.py

package info (click to toggle)
python-enable 4.3.0-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 7,280 kB
  • ctags: 13,899
  • sloc: cpp: 48,447; python: 28,502; ansic: 9,004; makefile: 315; sh: 44
file content (78 lines) | stat: -rw-r--r-- 2,821 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
""" Defines the base class for various types of zoom tools.
"""

from numpy import allclose, inf

# Enthought library imports
from traits.api import Enum, Float, HasTraits

class BaseZoomTool(HasTraits):
    """ Defines traits and methods to actually perform the logic of zooming
    onto a plot.
    """

    # If the tool only applies to a particular axis, this attribute is used to
    # determine which range to use.
    axis = Enum("x", "y")

    # The maximum ratio between the original data space bounds and the zoomed-in
    # data space bounds.  If None, then there is no limit (not advisable!).
    max_zoom_in_factor = Float(1e5, allow_none=True)

    # The maximum ratio between the zoomed-out data space bounds and the original
    # bounds.  If None, then there is no limit.
    max_zoom_out_factor = Float(1e5, allow_none=True)

    def _zoom_limit_reached(self, orig_position, orig_bounds, new_position, new_bounds):
        """ Returns True if the new low and high exceed the maximum zoom
        limits
        """
        if orig_bounds == inf:
            # There isn't really a good way to handle the case when the
            # original bounds were infinite, since any finite zoom
            # range will certainly exceed whatever zoom factor is set.
            # In this case, we just allow unbounded levels of zoom.
            return False

        if allclose(orig_bounds, 0.0):
            return True
        if allclose(new_bounds, 0.0):
            return True
        if (new_bounds / orig_bounds) > self.max_zoom_out_factor or \
           (orig_bounds / new_bounds) > self.max_zoom_in_factor:
            return True
        return False

    #------------------------------------------------------------------------
    # Utility methods for computing axes, coordinates, etc.
    #------------------------------------------------------------------------

    def _get_range_index(self):
        """ Returns the index into the view_position and view_bounds
            depending on value of self.axis.
        """
        if self.axis == 'x':
            return 0
        else:
            return 1

    def _get_axis_coord(self, event, axis="x"):
        """ Returns the coordinate of the event along the axis of interest
        to the tool (or along the orthogonal axis, if axis="value").
        """
        event_pos = (event.x, event.y)
        if axis == "x":
            return event_pos[ self._determine_axis() ]
        else:
            return event_pos[ 1 - self._determine_axis() ]

    def _determine_axis(self):
        """ Determines whether the index of the coordinate along the axis of
        interest is the first or second element of an (x,y) coordinate tuple.
        """
        if self.axis == "x":
            return 0
        else:
            return 1

# EOF