コード例 #1
0
 def __init__(self, head=(0.0, 0.0), tail=(1.0, 1.0)):
     if isinstance(head, (list, tuple)):
         head = D2.Point(*head)
     if isinstance(tail, (list, tuple)):
         tail = D2.Point(*tail)
     self.head = head
     self.tail = tail
コード例 #2
0
ファイル: Rect.py プロジェクト: JPilarr/tapyr
 def __init__(self, pos=(0.0, 0.0), size=(1.0, 1.0)):
     if isinstance(pos, (list, tuple)):
         pos = D2.Point(*pos)
     if isinstance(size, (list, tuple)):
         size = D2.Point(*size)
     self.ref_point = pos
     self.size = size
コード例 #3
0
ファイル: Relation.py プロジェクト: xiaochang91/tapyr
 def set_guides (self) :
     try :
         src_c = self.source_connector.side
         trg_c = self.target_connector.side
     except AttributeError :
         print \
             ( "Connector missing for %s: source_connector = %s"
               ", target_connector = %s"
             % (self, self.source_connector, self.target_connector)
             )
         raise
     dim          = src_c.dim
     delta        = self.delta
     guides       = self.guides = []
     g_offset     = self.guide_offset
     add          = guides.append
     self._points = None
     if src_c.is_opposite (trg_c) :
         if getattr (delta, src_c.other_dim) != 0 :
             p2_a = D2.Point (** {dim : 1})
             p2_b = D2.Point (* reversed (p2_a))
             off  = src_c.guide_offset (g_offset)
             add ((D2.Point (1, 1), D2.Point (0, 0), off))
             add ((p2_a,            p2_b,            off))
     elif src_c.side == trg_c.side :
         if getattr (delta, dim) == 0 :
             off  = src_c.guide_offset (g_offset)
             add ((D2.Point (1, 1), D2.Point (0, 0), off))
             add ((D2.Point (0, 0), D2.Point (1, 1), off))
     else :
         p2_a = src_c.guide_point (0)
         p2_b = D2.Point (* reversed (p2_a))
         add ((p2_a, p2_b))
コード例 #4
0
    def render_node(self, node, canvas):
        box = node.box
        pos = box.top_left + D2.Point(2, 1)
        width = box.size.x - 2
        height = box.size.y - 2

        def _label_parts(parts, width, height):
            i = 0
            l = len(parts)
            x = ""
            while i < l and height > 0:
                p = x + parts[i]
                i += 1
                while i < l and len(p) < width:
                    if len(p) + len(parts[i]) < width:
                        p += parts[i]
                        i += 1
                    else:
                        break
                yield p
                height -= 1
                x = " "

        for lp in _label_parts(node.entity.label_parts, width, height):
            canvas.text(pos, lp)
            pos.shift((0, 1))
        canvas.rectangle(box)
コード例 #5
0
 def _render_node_labels (self, node, grp) :
     P      = self.Parameters
     box    = node.box
     tp     = box.ref_point + D2.Point (P.font_size // 2, 0)
     width  = int ((box.size.x - P.font_size) / P.font_char_width)
     height = box.size.y / P.line_height - 1
     def _label_parts (parts, width, height) :
         i = 0
         l = len (parts)
         x = ""
         while i < l and height > 0:
             p  = x + parts [i]
             i += 1
             while i < l and len (p) < width :
                 if len (p) + len (parts [i]) < width :
                     p += parts [i]
                     i += 1
                 else :
                     break
             yield p
             height -= 1
     txt = SVG.Text \
         ( x           = tp.x
         , y           = tp.y
         , fill        = P.color.text
         , font_family = P.font_family
         , font_size   = P.font_size
         )
     dx = 0
     for lp in _label_parts (node.entity.label_parts, width, height) :
         txt.add (SVG.Tspan (lp, x = tp.x, dx = dx, dy = P.line_height))
         dx = P.font_size // 2
     grp.add (txt)
コード例 #6
0
ファイル: Rect.py プロジェクト: JPilarr/tapyr
 def point_in_rect(self, point):
     if isinstance(point, (list, tuple)):
         point = D2.Point(*point)
     tl = self.top_left
     br = tl + self.size
     if ((point.x < tl.x) or (point.x > br.x) or (point.y < tl.y)
             or (point.y > br.y)):
         return None
     return 1
コード例 #7
0
ファイル: Relation.py プロジェクト: xiaochang91/tapyr
 def points_gen \
         (self, head=None, tail=None, off_scale=0.5, y_inverted=False) :
     if head is None :
         head = self.source.pos
     if tail is None :
         tail = self.target.pos
     guides   = self.guides
     zero     = D2.Point (0, 0)
     y_corr   = D2.Point (1, (1, -1) [bool (y_inverted)])
     yield head
     if guides :
         for g in guides :
             if len (g) == 3 :
                 wh, wt = g [:2]
                 offset = off_scale * g [-1] * y_corr
             else :
                 wh, wt = g
                 offset = zero
             yield head * wh + tail * wt + offset
     yield tail
コード例 #8
0
 def intersection(self, other):
     """Returns intersection between the two lines in normal forms
        (None, if parallel).
     """
     try:
         x = float(self.b * other.c - self.c * other.b)
         y = float(self.c * other.a - self.a * other.c)
         divisor = float(self.a * other.b - self.b * other.a)
         return D2.Point(x / divisor, y / divisor)
     except ArithmeticError:
         return None
コード例 #9
0
ファイル: Rect.py プロジェクト: JPilarr/tapyr
 def connection_point(self, point_1, point_2):
     """Returns the intersection point between the rectangle and the line
        between `point_1` and `point_2`. If no intersection exists
        (both points are either inside or outside) than
        None is returned.
     """
     line = D2.Line(point_1, point_2)
     for side in (self.bottom, self.left, self.right, self.top):
         cp = side.intersection(line)
         if cp is not None:
             return cp
     return None
コード例 #10
0
class Renderer(MOM.Graph._Renderer_):
    """ASCII renderer for MOM.Graph"""

    Canvas = Canvas
    default_grid_scale = D2.Point(2, 3)
    extension = "txt"
    node_size = D2.Point(16, 4)  ### in characters

    conn_chars         = dict \
        ( bottom       = "v"
        , left         = "<"
        , right        = ">"
        , top          = "^"
        )
    link_chars         = dict \
        ( Attr         = dict (x = "_", y = ":")
        , IS_A         = dict (x = ".", y = ".")
        , Role         = dict (x = "-", y = "|")
        )
    rect_chars         = dict \
        ( bottom       = "-"
        , left         = "|"
        , right        = "|"
        , top          = "-"
        )

    def render(self):
        self.__super.render()
        return self.canvas.rendered()

    # end def render

    def render_link(self, link, canvas):
        chars = self.link_chars[link.relation.kind]
        head = link.points[0]
        tail = link.points[-1]
        side = link.relation.source_connector[0].side
        for line in pairwise(link.points):
            canvas.line(line, chars=chars)
        for p in link.points[1:-1]:
            canvas.text(p, "+")
        canvas.text(head, self.conn_chars[side])
        canvas.text(tail, self.conn_chars[side])

    # end def render_link

    def render_node(self, node, canvas):
        box = node.box
        pos = box.top_left + D2.Point(2, 1)
        width = box.size.x - 2
        height = box.size.y - 2

        def _label_parts(parts, width, height):
            i = 0
            l = len(parts)
            x = ""
            while i < l and height > 0:
                p = x + parts[i]
                i += 1
                while i < l and len(p) < width:
                    if len(p) + len(parts[i]) < width:
                        p += parts[i]
                        i += 1
                    else:
                        break
                yield p
                height -= 1
                x = " "

        for lp in _label_parts(node.entity.label_parts, width, height):
            canvas.text(pos, lp)
            pos.shift((0, 1))
        canvas.rectangle(box)
コード例 #11
0
ファイル: Rect.py プロジェクト: JPilarr/tapyr
class Rect(TFL.Meta.Object, metaclass=M_Rect):
    """Model an axes-parallel rectangle in 2D space.

    >>> def rect_points (r) :
    ...     for p in sorted (r.corner_dict.keys ()) :
    ...         print ("%-20s : %s" % (p, getattr (r, p)))
    >>> def rect_sides (r) :
    ...     for s in sorted (r.side_dict.keys ()) :
    ...         print ("%-20s : %s" % (s, getattr (r, s)))
    >>> def connection_points (r) :
    ...     P = D2.Point
    ...     for p, off in sorted (
    ...               [ (r.top_left,     P ( 0.0, +0.5))
    ...               , (r.top_left,     P (-0.5,  0.0))
    ...               , (r.top_right,    P ( 0.0, +0.5))
    ...               , (r.top_right,    P ( 0.5,  0.0))
    ...               , (r.bottom_left,  P ( 0.0, -0.5))
    ...               , (r.bottom_left,  P (-0.5,  0.0))
    ...               , (r.bottom_right, P ( 0.0, -0.5))
    ...               , (r.bottom_right, P ( 0.5,  0.0))
    ...               ]
    ...             , key = lambda x : tuple (x [0] + x [1])
    ...             ) :
    ...         q = p + off
    ...         print ("%s : %s" % (q, r.connection_point (q, r.center)))
    >>> q = Rect (D2.Point (1.0, 1.0), D2.Point (2.0, 1.0))
    >>> rect_points (q)
    bottom_left          : (1.0, 1.0)
    bottom_right         : (3.0, 1.0)
    center               : (2.0, 1.5)
    center_bottom        : (2.0, 1.0)
    center_left          : (1.0, 1.5)
    center_right         : (3.0, 1.5)
    center_top           : (2.0, 2.0)
    top_left             : (1.0, 2.0)
    top_right            : (3.0, 2.0)

    >>> q.scale (2)
    Rect ((1.0, 1.0), (4.0, 2.0))
    >>> rect_points (q)
    bottom_left          : (1.0, 1.0)
    bottom_right         : (5.0, 1.0)
    center               : (3.0, 2.0)
    center_bottom        : (3.0, 1.0)
    center_left          : (1.0, 2.0)
    center_right         : (5.0, 2.0)
    center_top           : (3.0, 3.0)
    top_left             : (1.0, 3.0)
    top_right            : (5.0, 3.0)

    >>> q.shift (D2.Point (1, 1))
    Rect ((2.0, 2.0), (4.0, 2.0))
    >>> rect_points (q)
    bottom_left          : (2.0, 2.0)
    bottom_right         : (6.0, 2.0)
    center               : (4.0, 3.0)
    center_bottom        : (4.0, 2.0)
    center_left          : (2.0, 3.0)
    center_right         : (6.0, 3.0)
    center_top           : (4.0, 4.0)
    top_left             : (2.0, 4.0)
    top_right            : (6.0, 4.0)

    >>> rect_sides (q)
    bottom               : ((2.0, 2.0), (6.0, 2.0))
    left                 : ((2.0, 2.0), (2.0, 4.0))
    right                : ((6.0, 2.0), (6.0, 4.0))
    top                  : ((2.0, 4.0), (6.0, 4.0))

    >>> q = Rect (D2.Point (1.0, 1.0), D2.Point (1.0, 1.0))
    >>> connection_points (q)
    (0.5, 1.0) : (1.0, 1.25)
    (0.5, 2.0) : (1.0, 1.75)
    (1.0, 0.5) : (1.25, 1.0)
    (1.0, 2.5) : (1.25, 2.0)
    (2.0, 0.5) : (1.75, 1.0)
    (2.0, 2.5) : (1.75, 2.0)
    (2.5, 1.0) : (2.0, 1.25)
    (2.5, 2.0) : (2.0, 1.75)

    """

    Bottom_Left = D2.Point(0.0, 0.0)
    Bottom_Right = D2.Point(1.0, 0.0)
    Center = D2.Point(0.5, 0.5)
    Center_Bottom = D2.Point(0.5, 0.0)
    Center_Left = D2.Point(0.0, 0.5)
    Center_Right = D2.Point(1.0, 0.5)
    Center_Top = D2.Point(0.5, 1.0)
    Top_Left = D2.Point(0.0, 1.0)
    Top_Right = D2.Point(1.0, 1.0)

    side_dict = \
        { "bottom" : (lambda r : D2.Line (r.bottom_left,  r.bottom_right))
        , "left"   : (lambda r : D2.Line (r.bottom_left,  r.top_left))
        , "right"  : (lambda r : D2.Line (r.bottom_right, r.top_right))
        , "top"    : (lambda r : D2.Line (r.top_left,     r.top_right))
        }

    @property
    def corners(self):
        return \
            self.bottom_left, self. bottom_right, self.top_left, self.top_right

    # end def sides

    @property
    def ref_point(self):
        return self.bottom_left

    # end def ref_point

    @ref_point.setter
    def ref_point(self, value):
        self.bottom_left = value

    # end def ref_point

    def __init__(self, pos=(0.0, 0.0), size=(1.0, 1.0)):
        if isinstance(pos, (list, tuple)):
            pos = D2.Point(*pos)
        if isinstance(size, (list, tuple)):
            size = D2.Point(*size)
        self.ref_point = pos
        self.size = size

    # end def __init__

    @classmethod
    def Sides(cls, diagonal, ratio):
        """Return the sides `(a, b)` of a rectangle with `diagonal` and `ratio`
           between the sides.
        """
        b = math.sqrt(diagonal * diagonal / (1 + ratio * ratio))
        a = b * ratio
        return a, b

    # end def Sides

    def connection_point(self, point_1, point_2):
        """Returns the intersection point between the rectangle and the line
           between `point_1` and `point_2`. If no intersection exists
           (both points are either inside or outside) than
           None is returned.
        """
        line = D2.Line(point_1, point_2)
        for side in (self.bottom, self.left, self.right, self.top):
            cp = side.intersection(line)
            if cp is not None:
                return cp
        return None

    # end def connection_point

    def point(self, p=Center):
        """Return point at position `p` relative to the rectangle."""
        return self.ref_point + (self.size * p)

    # end def point

    def point_in_rect(self, point):
        if isinstance(point, (list, tuple)):
            point = D2.Point(*point)
        tl = self.top_left
        br = tl + self.size
        if ((point.x < tl.x) or (point.x > br.x) or (point.y < tl.y)
                or (point.y > br.y)):
            return None
        return 1

    # end def point_in_rect

    def scale(self, right):
        self.size.scale(right)
        return self

    # end def scale

    def shift(self, right):
        self.ref_point.shift(right)
        return self

    # end def shift

    def transformed(self, affine):
        """Return another rectangle whose coordinates are derived via `affine`
           transform from `self`.
        """
        return self.__class__ \
            (self.ref_point.transform (affine), self.size.transformed (affine))

    # end def transformed

    def __getattr__(self, name):
        """Return the point or side `name`. The possible names are defined by
           `corner_dict` and `side_dict`.
        """
        if name in self.corner_dict:
            return self.point(self.corner_dict[name])
        elif name in self.side_dict:
            return self.side_dict[name](self)
        else:
            raise AttributeError(name)

    # end def __getattr__

    def __repr__(self):
        return "%s %s" % (self.__class__.__name__, str(self))

    # end def __repr__

    def __str__(self):
        return "(%s, %s)" % (self.ref_point, self.size)
コード例 #12
0
ファイル: Rect.py プロジェクト: JPilarr/tapyr
def rectangle(x, y, w, h):
    """Return a `Rect` at position `(x, y)` with size `(w, h)`"""
    return Rect(D2.Point(x, y), D2.Point(w, h))
コード例 #13
0
class Renderer (MOM.Graph._Renderer_) :
    """SVG renderer for MOM.Graph"""

    default_grid_scale = D2.Point ( 2,  3)
    encoding           = "utf-8"
    extension          = "svg"
    link_markers       = dict \
        ( attr         = dict (start = "MOM:AM")
        , is_a         = dict (end   = "MOM:IM")
        , role         = dict (start = "MOM:RM")
        )
    node_size          = D2.Point (160, 100)
    want_document      = True

    _Parameters        = None

    def __init__ (self, graph, ** kw) :
        self.pop_to_self (kw, "encoding", "want_document")
        self.pop_to_self (kw, "Parameters", prefix = "_")
        self.__super.__init__ (graph, ** kw)
    # end def __init__

    @property
    def Parameters (self) :
        result = self._Parameters
        if result is None :
            from _MOM._Graph.SVG_Parameters import SVG_Parameters
            result = self._Parameters = SVG_Parameters ()
        return result
    # end def Parameters

    def Canvas (self, min_x, min_y, max_x, max_y) :
        P      = self.Parameters
        graph  = self.graph
        w, h   = (max_x - min_x, max_y - min_y)
        result = SVG.Root \
            ( klass                 = "MOM-Graph"
            , preserve_aspect_ratio = "xMinYMin"
            , view_box              = "%d %d %d %d" % (min_x, min_y, w, h)
            , width                 = "100%"
            )
        if self.want_document :
            result = SVG.Document \
                ( result
                , encoding    = self.encoding
                , standalone  = False
                )
            if graph.title :
                result.add (SVG.Title (graph.title))
        elif graph.desc :
            result.add (SVG.Title (graph.desc))
        defs = SVG.Defs \
            ( SVG.Marker.Arrow_Head_Bar
                ( elid           = "MOM:AM"
                , ref_x          = P.attr_marker_ref_x
                , marker_width   = P.attr_marker_size
                , marker_height  = P.attr_marker_size
                , stroke         = P.color.attr_link.no_alpha
                , stroke_opacity = P.color.attr_link.alpha
                , fill           = P.color.link_bg.no_alpha
                , fill_opacity   = P.color.link_bg.alpha
                )
            , SVG.Marker.Arrow_Head
                ( elid           = "MOM:IM"
                , ref_x          = P.is_a_marker_ref_x
                , marker_width   = P.is_a_marker_size
                , marker_height  = P.is_a_marker_size
                , stroke         = P.color.is_a_link.no_alpha
                , stroke_opacity = P.color.is_a_link.alpha
                )
            , SVG.Marker.Plug
                ( elid           = "MOM:RM"
                , stroke         = P.color.role_link.no_alpha
                , stroke_opacity = P.color.role_link.alpha
                )
            )
        result.add (defs)
        return result
    # end def Canvas

    def render (self) :
        self.__super.render ()
        return "\n".join (self.canvas.as_xml ())
    # end def render

    def render_link (self, link, canvas) :
        P    = self.Parameters
        rel  = link.relation
        grp  = SVG.Group \
            ( elid         = rel.rid
            , opacity      = P.link_opacity
            )
        lkind = link.relation.kind.lower ()
        kw   = dict \
            (   ("marker_%s" % (k, ), "url(#%s)" % (v, ))
            for k, v in pyk.iteritems (self.link_markers.get (lkind, {}))
            )
        colr = getattr (P.color, "%s_link" % lkind)
        paid = "%s::path" % (rel.rid, )
        p, q = link.points [:2]
        p_q  = p - q
        anchor, off = "start", 10
        if max (abs (p_q)) < 5 * P.font_char_width and len (link.points) > 2 :
            p, q = link.points [1:3]
            p_q  = p - q
            off  = 2
        if p_q.x > 0 :
            p, q = q, p
            anchor, off = "end", 90
        offset = "%d%%" % off
        path   = SVG.Path \
            ( d            = (p, q)
            , elid         = paid
            , fill         = "none"
            , stroke       = "none"
            )
        grp.add \
            ( SVG.Title ("%s: %s" % (rel.title, rel.desc))
            , SVG.Polyline
                ( fill           = "none"
                , points         = link.points
                , stroke         = colr.no_alpha
                , stroke_width   = P.link_stroke_width
                , stroke_opacity = colr.alpha
                , ** kw
                )
            , path
            , SVG.Text
                ( SVG.Text_Path
                    ( SVG.Tspan
                        (rel.label, dy = - P.font_char_width * 3 // 4)
                    , start_offset       = offset
                    , text_anchor        = anchor
                    , xlink_href         = "#%s" % paid
                    )
                , fill         = colr.no_alpha
                , fill_opacity = colr.alpha
                , font_family  = P.font_family
                , font_size    = P.font_size
                )
            # rel.info
            )
        if rel.info :
            grp.add  \
                ( SVG.Text
                    ( SVG.Text_Path
                        ( SVG.Tspan
                            (rel.info, dy = P.font_size)
                        , start_offset       = offset
                        , text_anchor        = anchor
                        , xlink_href         = "#%s" % paid
                        )
                    , fill         = colr.no_alpha
                    , fill_opacity = colr.alpha
                    , font_family  = P.font_family
                    , font_size    = P.font_size
                    )
                )
        canvas.add (grp)
    # end def render_link

    def render_node (self, node, canvas) :
        P   = self.Parameters
        box = node.box
        grp = SVG.Group \
            ( elid         = node.entity.type_name
            , fill         = P.color.node_bg
            , klass        = "E_Type"
            , opacity      = P.partial_node_opacity
                if node.entity.is_partial else P.node_opacity
            )
        grp.add \
            ( SVG.Title ("%s: %s" % (node.entity.title, node.entity.desc))
            , SVG.Rect
                ( x            = box.ref_point.x
                , y            = box.ref_point.y
                , width        = box.size.x
                , height       = box.size.y
                , stroke       = P.color.node_border
                , stroke_width = P.node_border_width
                )
            )
        self._render_node_labels (node, grp)
        canvas.add (grp)
    # end def render_node

    def _render_node_labels (self, node, grp) :
        P      = self.Parameters
        box    = node.box
        tp     = box.ref_point + D2.Point (P.font_size // 2, 0)
        width  = int ((box.size.x - P.font_size) / P.font_char_width)
        height = box.size.y / P.line_height - 1
        def _label_parts (parts, width, height) :
            i = 0
            l = len (parts)
            x = ""
            while i < l and height > 0:
                p  = x + parts [i]
                i += 1
                while i < l and len (p) < width :
                    if len (p) + len (parts [i]) < width :
                        p += parts [i]
                        i += 1
                    else :
                        break
                yield p
                height -= 1
        txt = SVG.Text \
            ( x           = tp.x
            , y           = tp.y
            , fill        = P.color.text
            , font_family = P.font_family
            , font_size   = P.font_size
            )
        dx = 0
        for lp in _label_parts (node.entity.label_parts, width, height) :
            txt.add (SVG.Tspan (lp, x = tp.x, dx = dx, dy = P.line_height))
            dx = P.font_size // 2
        grp.add (txt)
コード例 #14
0
ファイル: Rect.py プロジェクト: Tapyr/tapyr
    def __getattr__ (self, name) :
        """Return the point or side `name`. The possible names are defined by
           `corner_dict` and `side_dict`.
        """
        if   name in self.corner_dict :
            return self.point (self.corner_dict [name])
        elif name in self.side_dict :
            return self.side_dict [name] (self)
        else :
            raise  AttributeError (name)
    # end def __getattr__

    def __repr__ (self) :
        return "%s %s" % (self.__class__.__name__, str (self))
    # end def __repr__

    def __str__ (self) :
        return "(%s, %s)" % (self.ref_point, self.size)
    # end def __str__

# end class Rect

def rectangle (x, y, w, h) :
    """Return a `Rect` at position `(x, y)` with size `(w, h)`"""
    return Rect (D2.Point (x, y), D2.Point (w, h))
# end def rectangle

if __name__ != "__main__" :
    D2._Export ("*")
### __END__ Rect
コード例 #15
0
ファイル: Point.py プロジェクト: xiaochang91/tapyr
    def __init__ \
        ( self, ref_points, x_weights, y_weights
        , offset = None, scale = None
        ) :
        if not (len (ref_points) == len (x_weights) == len (y_weights)) :
            raise ValueError \
                ( "%s must have equal length"
                % ((ref_points, x_weights, y_weights), )
                )
        self._ref_points  = ref_points
        self._x_weights   = x_weights
        self._y_weights   = y_weights
        self.__super.__init__ (offset, scale)
    # end def __init__

    def _reference (self) :
        return (self._ref_points, self._x_weights, self._y_weights)
    # end def _reference

# end class R_Point_nP

P  = Point
Pp = R_Point_P
Pl = R_Point_L
Pr = R_Point_R
Pn = R_Point_nP

if __name__ != "__main__" :
    D2._Export ("*", "_Point_", "_R_Point_", "P", "Pp", "Pl", "Pr", "Pn")
### __END__ TFL.D2.Point
コード例 #16
0
ファイル: Screen.py プロジェクト: xiaochang91/tapyr
class _Screen_Rect_(D2.Rect):
    """Model an axes-parallel rectangle in 2D screen coordinates.

    >>> def rect_points (r) :
    ...     for p in sorted (r.corner_dict.keys ()) :
    ...         print ("%-20s : %s" % (p, getattr (r, p)))
    >>> def rect_sides (r) :
    ...     for s in sorted (r.side_dict.keys ()) :
    ...         print ("%-20s : %s" % (s, getattr (r, s)))
    >>> def connection_points (r) :
    ...     P = D2.Point
    ...     for p, off in sorted (
    ...               [ (r.top_left,     P ( 0.0, -0.5))
    ...               , (r.top_left,     P (-0.5,  0.0))
    ...               , (r.top_right,    P ( 0.0, -0.5))
    ...               , (r.top_right,    P ( 0.5,  0.0))
    ...               , (r.bottom_left,  P ( 0.0,  0.5))
    ...               , (r.bottom_left,  P (-0.5,  0.0))
    ...               , (r.bottom_right, P ( 0.0,  0.5))
    ...               , (r.bottom_right, P ( 0.5,  0.0))
    ...               ]
    ...             , key = lambda x : tuple (x [0] + x [1])
    ...             ) :
    ...         q = p + off
    ...         print ("%s : %s" % (q, r.connection_point (q, r.center)))
    >>> q = Rect (D2.Point (1.0, 1.0), D2.Point (2.0, 1.0))
    >>> rect_points (q)
    bottom_left          : (1.0, 2.0)
    bottom_right         : (3.0, 2.0)
    center               : (2.0, 1.5)
    center_bottom        : (2.0, 2.0)
    center_left          : (1.0, 1.5)
    center_right         : (3.0, 1.5)
    center_top           : (2.0, 1.0)
    top_left             : (1.0, 1.0)
    top_right            : (3.0, 1.0)
    >>> q.scale (2)
    Rect ((1.0, 1.0), (4.0, 2.0))
    >>> rect_points (q)
    bottom_left          : (1.0, 3.0)
    bottom_right         : (5.0, 3.0)
    center               : (3.0, 2.0)
    center_bottom        : (3.0, 3.0)
    center_left          : (1.0, 2.0)
    center_right         : (5.0, 2.0)
    center_top           : (3.0, 1.0)
    top_left             : (1.0, 1.0)
    top_right            : (5.0, 1.0)
    >>> q.shift (D2.Point (1, 1))
    Rect ((2.0, 2.0), (4.0, 2.0))
    >>> rect_points (q)
    bottom_left          : (2.0, 4.0)
    bottom_right         : (6.0, 4.0)
    center               : (4.0, 3.0)
    center_bottom        : (4.0, 4.0)
    center_left          : (2.0, 3.0)
    center_right         : (6.0, 3.0)
    center_top           : (4.0, 2.0)
    top_left             : (2.0, 2.0)
    top_right            : (6.0, 2.0)
    >>> rect_sides (q)
    bottom               : ((2.0, 4.0), (6.0, 4.0))
    left                 : ((2.0, 2.0), (2.0, 4.0))
    right                : ((6.0, 2.0), (6.0, 4.0))
    top                  : ((2.0, 2.0), (6.0, 2.0))
    >>> q = Rect (D2.Point (1.0, 1.0), D2.Point (1.0, 1.0))
    >>> connection_points (q)
    (0.5, 1.0) : (1.0, 1.25)
    (0.5, 2.0) : (1.0, 1.75)
    (1.0, 0.5) : (1.25, 1.0)
    (1.0, 2.5) : (1.25, 2.0)
    (2.0, 0.5) : (1.75, 1.0)
    (2.0, 2.5) : (1.75, 2.0)
    (2.5, 1.0) : (2.0, 1.25)
    (2.5, 2.0) : (2.0, 1.75)

    """

    _real_name = "Rect"

    Bottom_Left = D2.Point(0.0, 1.0)
    Bottom_Right = D2.Point(1.0, 1.0)
    Center = D2.Point(0.5, 0.5)
    Center_Bottom = D2.Point(0.5, 1.0)
    Center_Left = D2.Point(0.0, 0.5)
    Center_Right = D2.Point(1.0, 0.5)
    Center_Top = D2.Point(0.5, 0.0)
    Top_Left = D2.Point(0.0, 0.0)
    Top_Right = D2.Point(1.0, 0.0)

    side_dict = \
        { "bottom" : (lambda r : D2.Line (r.bottom_left,  r.bottom_right))
        , "left"   : (lambda r : D2.Line (r.top_left,     r.bottom_left))
        , "right"  : (lambda r : D2.Line (r.top_right,    r.bottom_right))
        , "top"    : (lambda r : D2.Line (r.top_left,     r.top_right))
        }

    @property
    def ref_point(self):
        return self.top_left

    # end def ref_point

    @ref_point.setter
    def ref_point(self, value):
        self.top_left = value
コード例 #17
0
ファイル: _Renderer_.py プロジェクト: JPilarr/tapyr
class _Renderer_(TFL.Meta.Object):
    """Base class for MOM.Graph renderers."""

    node_size = D2.Point(90, 20)
    default_grid_scale = D2.Point(2, 4)
    _grid_size = None

    Canvas = None  ### redefine in descendants
    Link = Link
    Node = Node

    def __init__(self, graph, **kw):
        self.pop_to_self(kw, "node_size", "default_grid_scale")
        self.pop_to_self(kw, "grid_size", prefix="_")
        self.graph = graph
        Node = self.Node
        g_nodes = self.graph.nodes()
        self.nodes = ns = list(Node(e, self) for e in g_nodes)
        self.node_map = dict((n.entity.type_name, n) for n in ns)
        graph.setup_links()
        for n in ns:
            n.setup_links()
        self.canvas = self.Canvas \
            (self.min_x, self.min_y, self.max_x, self.max_y)

    # end def __init__

    @property
    def grid_size(self):
        result = self._grid_size
        if result is None:
            result = self._grid_size = self.node_size * self.default_grid_scale
        return result

    # end def grid_size

    @grid_size.setter
    def grid_size(self, value):
        self._grid_size = value

    # end def grid_size

    @TFL.Meta.Once_Property
    def max_x(self):
        return int(max(n.max_x for n in self.nodes) + self.grid_size.x // 4)

    # end def max_x

    @TFL.Meta.Once_Property
    def max_x_spec(self):
        return max(v.pos.x for v in pyk.itervalues(self.graph.node_map))

    # end def max_x_spec

    @TFL.Meta.Once_Property
    def max_y(self):
        return int(max(n.max_y for n in self.nodes) + self.grid_size.y // 4)

    # end def max_y

    @TFL.Meta.Once_Property
    def max_y_spec(self):
        return max(v.pos.y for v in pyk.itervalues(self.graph.node_map))

    # end def max_y_spec

    @TFL.Meta.Once_Property
    def min_x(self):
        result = int(min(n.min_x for n in self.nodes) - self.grid_size.x // 4)
        return max(result, 0)

    # end def min_x

    @TFL.Meta.Once_Property
    def min_x_spec(self):
        return min(v.pos.x for v in pyk.itervalues(self.graph.node_map))

    # end def min_x_spec

    @TFL.Meta.Once_Property
    def min_y(self):
        result = int(min(n.min_y for n in self.nodes) - self.grid_size.y // 4)
        return max(result, 0)

    # end def min_y

    @TFL.Meta.Once_Property
    def min_y_spec(self):
        return min(v.pos.y for v in pyk.itervalues(self.graph.node_map))

    # end def min_y_spec

    @TFL.Meta.Once_Property
    def transform(self):
        dx = -self.min_x_spec  ### shift minimum to zero
        dy = -self.max_y_spec  ### shift maximum to zero: to be reflected
        gs = self.grid_size
        result = \
            ( D2.Affine.Trans      (gs.x // 4,  gs.y // 4)
            * D2.Affine.Scale      (gs.x,       gs.y)
            * D2.Affine.Reflection (1,          0)
            * D2.Affine.Trans      (dx,         dy)
            )
        return result

    # end def transform

    def render(self):
        canvas = self.canvas
        nodes = sorted(self.nodes, key=TFL.Getter.entity.type_name)
        for n in nodes:
            self.render_node(n, canvas)
        link_sort_key = TFL.Sorted_By("relation.rid")
        for n in nodes:
            for l in sorted(pyk.itervalues(n.link_map), key=link_sort_key):
                self.render_link(l, canvas)

    # end def render

    def render_link(self, link, canvas):
        raise NotImplementedError \
            ("%s needs to implement render_link" % (self.__class__.__name__, ))

    # end def render_link

    def render_node(self, node, canvas):
        raise NotImplementedError \
            ("%s needs to implement render_node" % (self.__class__.__name__, ))
コード例 #18
0
ファイル: Rect.py プロジェクト: JPilarr/tapyr
            return self.side_dict[name](self)
        else:
            raise AttributeError(name)

    # end def __getattr__

    def __repr__(self):
        return "%s %s" % (self.__class__.__name__, str(self))

    # end def __repr__

    def __str__(self):
        return "(%s, %s)" % (self.ref_point, self.size)

    # end def __str__


# end class Rect


def rectangle(x, y, w, h):
    """Return a `Rect` at position `(x, y)` with size `(w, h)`"""
    return Rect(D2.Point(x, y), D2.Point(w, h))


# end def rectangle

if __name__ != "__main__":
    D2._Export("*")
### __END__ Rect