U
    tdo5                     @   s   d Z ddlmZmZ ddlmZmZ ddlmZ ddl	m
Z
mZ G dd ded	ZG d
d deZG dd ded	ZG dd deZG dd deZdS )z1
Abstract base classes for the drawing routines.
    )ABCMetaabstractmethod)atan2pi   )TextAlignment))get_bezier_control_points_for_curved_edgeevaluate_cubic_bezierc                   @   s   e Zd ZdZedd ZdS )AbstractDrawerzXAbstract class that serves as a base class for anything that
    draws an igraph object.c                 O   s   t dS z8Abstract method, must be implemented in derived classes.NNotImplementedError)selfargskwds r   S/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/igraph/drawing/baseclasses.pydraw   s    zAbstractDrawer.drawN)__name__
__module____qualname____doc__r   r   r   r   r   r   r
      s   r
   )	metaclassc                   @   s&   e Zd ZdZdddZedd ZdS )AbstractXMLRPCDrawerzfAbstract drawer that uses a remote service via XML-RPC
    to draw something on a remote display.
    Nc                 C   sD   ddl }| |}|j|| _|dkr2| j| _nt| j|| _dS )a  Constructs an abstract drawer using the XML-RPC service
        at the given URL.

        @param url: the URL where the XML-RPC calls for the service should
          be addressed to.
        @param service: the name of the service at the XML-RPC address. If
          C{None}, requests will be directed to the server proxy object
          constructed by C{xmlrpclib.ServerProxy}; if not C{None}, the
          given attribute will be looked up in the server proxy object.
        r   N)xmlrpc.client_resolve_hostnameclientServerProxyserverservicegetattr)r   urlr   Zxmlrpcr   r   r   __init__    s    

zAbstractXMLRPCDrawer.__init__c                 C   s   ddl m}m} ddl}|| }|j}|d|r6| S ddlm} d|kr\|d|d }||}|j	dk	r|d||j	f }t
|}||d< ||S )	zParses the given URL, resolves the hostname to an IP address
        and returns a new URL with the resolved IP address. This speeds
        up things big time on Mac OS X where an IP lookup would be
        performed for every XML-RPC call otherwise.r   )urlparse
urlunparseNz	[0-9.:]+$)gethostbyname:z%s:%dr   )urllib.parser#   r$   renetlocmatchsocketr%   indexportlist)r!   r#   r$   r(   Z	url_partshostnamer%   r   r   r   r   4   s    
z&AbstractXMLRPCDrawer._resolve_hostname)N)r   r   r   r   r"   staticmethodr   r   r   r   r   r      s   
r   c                   @   sD   e Zd ZdZedd Zedd Zedd Zdd	 Z	d
d Z
dS )AbstractEdgeDrawerzeAbstract edge drawer object from which all concrete edge drawer
    implementations are derived.
    c                 C   s(   | dks| dkrdS | dkr dS t | S )zmConverts values given to the 'curved' edge style argument
        in plotting calls to floating point values.NFg        T      ?)float)valuer   r   r   _curvature_to_floatW   s
    z&AbstractEdgeDrawer._curvature_to_floatc                 C   s   t dS )a  Draws a directed edge.

        @param edge: the edge to be drawn. Visual properties of the edge
          are defined by the attributes of this object.
        @param src_vertex: the source vertex. Visual properties are defined
          by the attributes of this object.
        @param dest_vertex: the source vertex. Visual properties are defined
          by the attributes of this object.
        Nr   r   edge
src_vertexdest_vertexr   r   r   draw_directed_edgea   s    z%AbstractEdgeDrawer.draw_directed_edgec                 C   s   t dS )a  Draws an undirected edge.

        @param edge: the edge to be drawn. Visual properties of the edge
          are defined by the attributes of this object.
        @param src_vertex: the source vertex. Visual properties are defined
          by the attributes of this object.
        @param dest_vertex: the source vertex. Visual properties are defined
          by the attributes of this object.
        Nr   r6   r   r   r   draw_undirected_edgen   s    z'AbstractEdgeDrawer.draw_undirected_edgec                 C   s\  |j d |j d  }|j d |j d  }|dks8|dkrNt| |dt  }nd}|jr|j |j  \}}\}	}
t|||	|
|j\}}t||f|||	|
df }n0|j d |j d  d |j d |j d  d f}td }|dkrtjtj }}n`t|| d }tj	tj	tj	tj	tj
tj
tj
tj
g| }tjtjtjtjtjtjtjtjg| }|||ffS )	a  returns the position where the label of an edge should be drawn. the
        default implementation returns the midpoint of the edge and an alignment
        that tries to avoid overlapping the label with the edge.

        @param edge: the edge to be drawn. visual properties of the edge
          are defined by the attributes of this object.
        @param src_vertex: the source vertex. visual properties are given
          again as attributes.
        @param dest_vertex: the target vertex. visual properties are given
          again as attributes.
        @return: a tuple containing two more tuples: the desired position of the
          label and the desired alignment of the label, where the position is
          given as c{(x, y)} and the alignment is given as c{(horizontal, vertical)}.
          members of the alignment tuple are taken from constants in the
          l{textalignment} class.
        r   r      Nr2   g       @      )positionr   r   Zcurvedr   r	   r   ZCENTERintRIGHTLEFTZBOTTOMZTOP)r   r7   r8   r9   ZdxZdyZanglex1y1x2y2Zaux1Zaux2posZpi4ZhalignZvalignr,   r   r   r   get_label_position{   sZ        		z%AbstractEdgeDrawer.get_label_positionc           	      C   s`   |j |j  \}}\}}ddt t|| ||   d }d|  k rLdkr\n nd| d }|S )a  Get the rotation angle of the label to align with the edge.

        @param edge: the edge to be drawn. visual properties of the edge
          are defined by the attributes of this object.
        @param src_vertex: the source vertex. visual properties are given
          again as attributes.
        @param dest_vertex: the target vertex. visual properties are given
          again as attributes.
        @return: a float with the desired angle, in degrees (out of 360).
        ih  g     f@Z   i     )r?   r   r   )	r   r7   r8   r9   rC   rD   rE   rF   Zrotationr   r   r   get_label_rotation   s
    "z%AbstractEdgeDrawer.get_label_rotationN)r   r   r   r   r0   r5   r   r:   r;   rH   rK   r   r   r   r   r1   R   s   
	

Hr1   c                   @   s$   e Zd ZdZdd Zedd ZdS )AbstractVertexDrawerzdAbstract vertex drawer object from which all concrete vertex drawer
    implementations are derived.c                 C   s   || _ || _dS )a,  Constructs the vertex drawer and associates it to the given
        palette.

        @param palette: the palette that can be used to map integer
                        color indices to colors when drawing vertices
        @param layout:  the layout of the vertices in the graph being drawn
        N)layoutpalette)r   rN   rM   r   r   r   r"      s    zAbstractVertexDrawer.__init__c                 C   s   t dS )a  Draws the given vertex.

        @param visual_vertex: object specifying the visual properties of the
            vertex. Its structure is defined by the VisualVertexBuilder of the
            L{CairoGraphDrawer}; see its source code.
        @param vertex: the raw igraph vertex being drawn
        @param coords: the X and Y coordinates of the vertex as specified by the
            layout algorithm, scaled into the bounding box.
        Nr   )r   Zvisual_vertexZvertexcoordsr   r   r   r      s    zAbstractVertexDrawer.drawN)r   r   r   r   r"   r   r   r   r   r   r   rL      s   rL   c                   @   sB   e Zd ZdZedd ZedddZedd Zed	d
 Z	dS )AbstractGraphDrawerz\Abstract class that serves as a base class for anything that
    draws an igraph.Graph.
    c                 O   s   t dS r   r   )r   graphr   r   r   r   r   r      s    zAbstractGraphDrawer.drawNc                 C   sL   ddl m} t| |r"|| j} n&t| ts4| dkr@|| } n|| } | S )a  Helper method that ensures that I{layout} is an instance
        of L{Layout}. If it is not, the method will try to convert
        it to a L{Layout} according to the following rules:

          - If I{layout} is a string, it is assumed to be a name
            of an igraph layout, and it will be passed on to the
            C{layout} method of the given I{graph} if I{graph} is
            not C{None}.

          - If I{layout} is C{None}, the C{layout} method of
            I{graph} will be invoked with no parameters, which
            will call the default layout algorithm.

          - Otherwise, I{layout} will be passed on to the constructor
            of L{Layout}. This handles lists of lists, lists of tuples
            and such.

        If I{layout} is already a L{Layout} instance, it will still
        be copied and a copy will be returned. This is because graph
        drawers are allowed to transform the layout for their purposes,
        and we don't want the transformation to propagate back to the
        caller.
        r   )LayoutN)Zigraph.layoutrR   
isinstancerO   strrM   )rM   rQ   rR   r   r   r   ensure_layout  s    
z!AbstractGraphDrawer.ensure_layoutc                 C   s   d|kr|d S | ddkr"dS |d }d}t|trX|\}}t|trX| d}| j| }ttt	t
||jt|d}|S )a  Returns the order in which the edge of the given graph have to be
        drawn, assuming that the relevant keyword arguments (C{edge_order} and
        C{edge_order_by}) are given in C{kwds} as a dictionary. If neither
        C{edge_order} nor C{edge_order_by} is present in C{kwds}, this
        function returns C{None} to indicate that the graph drawer is free to
        choose the most convenient edge ordering.
edge_orderedge_order_byNFdesckeyreverse)getrS   tuplerT   lower
startswithessortedr.   rangelen__getitem__bool)rQ   r   rW   r[   attrsrV   r   r   r   _determine_edge_order&  s"    


  z)AbstractGraphDrawer._determine_edge_orderc                 C   s   d|kr|d S | ddkr"dS |d }d}t|trX|\}}t|trX| d}| j| }ttt	t
||jt|d}|S )a  Returns the order in which the vertices of the given graph have to be
        drawn, assuming that the relevant keyword arguments (C{vertex_order} and
        C{vertex_order_by}) are given in C{kwds} as a dictionary. If neither
        C{vertex_order} nor C{vertex_order_by} is present in C{kwds}, this
        function returns C{None} to indicate that the graph drawer is free to
        choose the most convenient vertex ordering.vertex_ordervertex_order_byNFrX   rY   )r\   rS   r]   rT   r^   r_   vsra   r.   rb   rc   rd   re   )rQ   r   ri   r[   rf   rh   r   r   r   _determine_vertex_orderD  s"    


  z+AbstractGraphDrawer._determine_vertex_order)N)
r   r   r   r   r   r   r0   rU   rg   rk   r   r   r   r   rP      s   
#
rP   N)r   abcr   r   mathr   r   textr   utilsr   r	   r
   r   r1   rL   rP   r   r   r   r   <module>   s   7  