a
    Df|                     @   s*  d dl mZ d dlmZ d dlZd dlZd dlZddl	m
Z
mZmZ ddlmZ ddlmZ ddlmZmZmZ d	d
lmZ d	dlmZ d	dlmZmZmZmZmZ G dd deZG dd deZ G dd deZ!G dd deZ"G dd de
eZ#G dd de#Z$G dd deZ%G dd de#Z&dS )    )defaultdict)FunctionTypeN   )Dataset	Dimension	Element2D)Redim)	Operation)is_dataframe	max_rangesearch_indices   )Points)Path)circular_layoutconnect_edges_pdconnect_tri_edges_pdquadratic_bezier
split_pathc                       s"   e Zd ZdZd fdd	Z  ZS )
RedimGraphz|
    Extension for the redim utility that allows re-dimensioning
    Graph objects including their nodes and edgepaths.
    Nc                    sn   t  j|fi |}|jf}| jjr@|| jjj|fi |f }| jjrd|| jjj|fi |f }||S N)	super__call__data_objnodesredim
_edgepaths	edgepathsclone)selfspecs
dimensionsZredimmedZnew_data	__class__ e/nfs/NAS7/SABIOD/METHODE/ermites/ermites_venv/lib/python3.9/site-packages/holoviews/element/graphs.pyr      s    zRedimGraph.__call__)N)__name__
__module____qualname____doc__r   __classcell__r%   r%   r#   r&   r      s   r   c                   @   sD   e Zd ZdZejdddZejdddZej	i ddZ
d
dd	ZdS )layout_nodesa  
    Accepts a Graph and lays out the corresponding nodes with the
    supplied networkx layout function. If no layout function is
    supplied uses a simple circular_layout function. Also supports
    LayoutAlgorithm function provided in datashader layouts.
    Fz*
        Whether to return Nodes or Graph.defaultdocNz#
        A NetworkX layout functionz9
        Keyword arguments passed to the layout function.c                 C   s  | j jrt| j jtrdd l}|ddg}||}d| j jv r|| j jd }t||| D ]\\}}}	|	|j	||f |< q\| j j|fi | j j}
dd t
|
 D }n||jddd}|jddd}tt||g}| j jr td|i}| j j|| fi | j j}|g d	 }nt|}||}|jrn|jjD ]*}|j|}|j|t|j|d
d}qB| j jr||S ||j|fS )Nr   r   weightc                 S   s   g | ]\}}t ||f qS r%   )tuple).0idxposr%   r%   r&   
<listcomp>B       z)layout_nodes._process.<locals>.<listcomp>Fexpandedindex)xyr9   T)Zvdim)playout
isinstancer   ZnetworkxarrayZfrom_edgelistkwargszipedgessorteditemsdimension_valuesnpuniqueconcatenatepdZ	DataFramedframer   	node_type_nodesr   vdimsadd_dimensionlen
only_nodesr   r   )r    elementkeyZnxrB   graphr0   stw	positionsr   sourcetargetdfdvalsr%   r%   r&   _process8   s4    



zlayout_nodes._process)N)r'   r(   r)   r*   paramBooleanrP   Callabler=   Dictr@   r]   r%   r%   r%   r&   r,   '   s
   r,   c                   @   s>   e Zd ZdZejedededgddZejd ddZ	d	S )
Nodesz
    Nodes is a simple Element representing Graph nodes as a set of
    Points.  Unlike regular Points, Nodes must define a third key
    dimension corresponding to the node index.
    r:   r;   r9      rd   r.   boundsTr.   constantN)
r'   r(   r)   r*   r^   Listr   kdimsStringgroupr%   r%   r%   r&   rb   W   s   rb   c                   @   s   e Zd ZdZejd ddZdS )	EdgePathszh
    EdgePaths is a simple Element representing the paths of edges
    connecting nodes in a graph.
    Trg   N)r'   r(   r)   r*   r^   rk   rl   r%   r%   r%   r&   rm   d   s   rm   c                       s   e Zd ZdZejd ddZejededgddZ	e
ZeZd$ fd	d
	Zedd Zdd Zdd Zd% fdd	Zd&ddZedd Zd' fdd	Zd( fdd	Zedd Zed d! Zed)d"d#Z  ZS )*Graphad  
    Graph is high-level Element representing both nodes and edges.
    A Graph may be defined in an abstract form representing just
    the abstract edges between nodes and optionally may be made
    concrete by supplying a Nodes Element defining the concrete
    positions of each node. If the node positions are supplied
    the EdgePaths (defining the concrete edges) can be inferred
    automatically or supplied explicitly.

    The constructor accepts regular columnar data defining the edges
    or a tuple of the abstract edges and nodes, or a tuple of the
    abstract edges, nodes, and edgepaths.
    Trg   startend)r   r   re   Nc           	         s  t |tr*|ddt|   }|\}}}n4t |t| rN||j|j  }}}n|d d   }}}|d urd }t || jrxqt |tr|jdkr| |}q|}d }nd }|d urt || j	s| 	|}|| _
|| _t j|f||d| |d ur| | |   d S )Nr   rd   rj   rM   )r>   r1   rO   typer   r   rK   r   ndims	edge_typerL   r   __init___add_node_info	_validate)	r    r   rj   rM   paramsrB   r   r   	node_infor#   r%   r&   ru      s.    


zGraph.__init__c                 C   s   t | ddS )NZdatasetmode)r   r    r%   r%   r&   r      s    zGraph.redimc              	      s(  | j jddgd}t|| jrD|jf i tt|jddd|j}|jsbt	|t	|krbt
d|jd j}| }| |jr|jd  ntd	 | }d	|jv rȈ jd	ksȈjd	d
idd
} fdd|jD }|| }tj|| jdd|j|jd d  g |jd}|| _d S )Npandas
dictionary)datatyperR   TlabelzThe supplied node data does not match the number of nodes defined by the edges. Ensure that the number of nodes matchor supply an index as the sole key dimension to allow the Graph to merge the data.r9   Z__index)columnsc                    s$   g | ]}|j vs| jkr|qS r%   )r   name)r2   cr3   Znode_dfr%   r&   r5      s   

z(Graph._add_node_info.<locals>.<listcomp>left)left_onZright_onhowr   rq   )r   r   r>   rK   r   dictrA   r"   rj   rO   
ValueErrorr   rJ   r   Zreset_indexr   renamerI   mergerM   rL   )r    ry   r   r   Znode_info_dfcolsr%   r   r&   rv      s4    

zGraph._add_node_infoc                 C   s   | j d u rd S g }t| jj| jjD ]$\}}||kr$|| d|  q$|r`tdd| t| j j	}t| }||krd}|dkr| j
 d }|d}ttt|d }t|d s|d7 }||k}|rtd||f d S )	Nz != zIEnsure that the first two key dimensions on Nodes and EdgePaths match: %sz, Tr   r   r   z_Ensure that the number of edges supplied to the Graph (%d) matches the number of edgepaths (%d))r   rA   r   rj   r   appendr   joinrO   r   splitrE   rF   whereisnan)r    ZmismatchZkd1Zkd2ZnpathsZnedgesrB   r\   r%   r%   r&   rw      s2    

zGraph._validatec                    s|   |d u r6| j | jf}| jd ur*|| jf }| j|d< n&t|ts\|| jf}| jr\|| jf }t j||||g|R i |S )NZplot_id)	r   r   r   r   Z_plot_idr>   r1   r   r   )r    r   Zshared_datanew_typelinkargsZ	overridesr#   r%   r&   r      s    


zGraph.clonerB   c                    s  ddl m} |dur&t||s&tdfdd| D }|rVtfdd|D r^|sb|sbS jjd jjj	  fd	d| D }|r|j
jd
dd}j| }njjf i t|fi |} fdd| D }d}	t|tjkr~ dd \}
}t|dd
}|dkrdj|
j|i}j|j|i}||B }	j}nj|
j||j|i}	d}|rj|}|	dur|dur||	M }n|	}|durj|}t|s6||f}|jdd
d}|jdd
d}tt||g}|jddddt|f }d}jrj}||j||}tjjdkr|| g}nj}j}|||fS )a  
        Allows selecting data by the slices, sets and scalar values
        along a particular dimension. The indices should be supplied as
        keywords mapping between the selected dimension and
        value. Additionally selection_specs (taking the form of a list
        of type.group.label strings, types or functions) may be
        supplied, which will ensure the selection is only applied if the
        specs match the selected object.

        Selecting by a node dimensions selects all edges and nodes that are
        connected to the selected nodes. To select only edges between the
        selected nodes set the selection_mode to 'nodes'.
        r   )dimNzThe first positional argument to the Dataset.select method is expected to be a
holoviews.util.transform.dim expression. Use the selection_specs keyword
argument to specify a selection specificationc                    s*   i | ]"\}}|  d dg v r||qS )rangesZselection_maskr"   )r2   r   selr|   r%   r&   
<dictcomp>  s   z Graph.select.<locals>.<dictcomp>c                 3   s   | ]}  |V  qd S r   )matches)r2   spr|   r%   r&   	<genexpr>
  r6   zGraph.select.<locals>.<genexpr>c                    s    i | ]\}}|j v r |qS r%   rj   r2   kv)	index_dimr    r%   r&   r     s   
FT)computeZ
keep_indexc                    s   i | ]\}}| v r||qS r%   r%   r   r   r%   r&   r     r6   rB   r   r7   r   )Zutil.transformr   r>   r   rD   anyr   rj   r   rM   applyselectr   rO   listrE   Z	interfaceZselect_maskrF   allr   rG   rH   r   _split_edgepathsZselect_pathsr   rJ   )r    Zselection_exprselection_specsselection_mode	selectionr   Znode_selectionmaskr   ZnodemaskxdimydimindicesZmask1Zmask2r   Z	new_graphrX   rY   Zunique_nodespathsr   r%   )r"   r   r    r&   r      sl    




zGraph.selectc                 C   s0   t | t | jjkr| jS | jt| jS d S r   )rO   r   r   r   r   r|   r%   r%   r&   r   G  s    zGraph._split_edgepathsc                    sZ   | j rJ|| j  v rJ| j |||}| jrF| j|||}t||gS |S t |||S r   )r   r"   ranger   r   r   )r    Z	dimensionZ
data_rangeZdimension_rangeZ
node_rangeZ
path_ranger#   r%   r&   r   N  s    zGraph.ranger   Fc                    sz   t  ||}|dkrv| jd ur0| j||}n>| jj| jj }|dv rXdd |D }n|dv rndd |D }|| S |S )Nr   )r   Tshortc                 S   s   g | ]
}|j qS r%   )r   r2   r[   r%   r%   r&   r5   _  r6   z$Graph.dimensions.<locals>.<listcomp>)longr   c                 S   s   g | ]
}|j qS r%   r   r   r%   r%   r&   r5   a  r6   )r   r"   rL   r   rK   rj   rM   )r    r   r   r"   Z	node_dimsr#   r%   r&   r"   W  s    
zGraph.dimensionsc                 C   s>   | j du r8ddlm} t| dd| _ d| j _| | j _| j S )z
        Computes the node positions the first time they are requested
        if no explicit node information was supplied.
        Nr   )chainT)rP   )rL   Zoperation.elementr   r,   Z_datasetinstanceZ	_pipeline)r    r   r%   r%   r&   r   e  s    
zGraph.nodesc                 C   s.   | j r| j S t| }| j|| jjdd dS )zl
        Returns the fixed EdgePaths or computes direct connections
        between supplied nodes.
        Nr   r   )r   r   rt   r   rj   )r    r   r%   r%   r&   r   s  s    zGraph.edgepathsc                    s  t |ts||fi |}tt| D ]\}}t|j| |  D ]&\}}t |ttfr`qH| | qHt |t	rt
|}t |t	rt
|}d | d | q*tfddD }	dd |	D }
t	fddddg|	 D } jjdd	 \}}|r`| |jd
 jtfdd D  \}}dd t t| D }ng }d}ttt| D ]\}}|j|}|du rq||\}}j | |j | | D ],\}}t |ttfrqΈ| | qt|D ] \}}| || |  qt |t	r:t
|}|j | q|t fddD }j|j|jg| t| }t	fdd|D }g }|D ]L}t |trt
|}n&|dur||jv r||}n|}|| q j||d} ||f|
dS )aw  
        Generate a HoloViews Graph from a networkx.Graph object and
        networkx layout function or dictionary of node positions.
        Any keyword arguments will be passed to the layout
        function. By default it will extract all node and edge
        attributes from the networkx.Graph but explicit node
        information may also be supplied. Any non-scalar attributes,
        such as lists or dictionaries will be ignored.

        Args:
            G (networkx.Graph): Graph to convert to Graph element
            positions (dict or callable): Node positions
                Node positions defined as a dictionary mapping from
                node id to (x, y) tuple or networkx layout function
                which computes a positions dictionary
            kwargs (dict): Keyword arguments for layout function

        Returns:
            Graph element
        ro   rp   c                    s0   g | ](}|d vrt  | t  d kr|qS ))ro   rp   ro   rO   r2   r   rB   r%   r&   r5     s   z'Graph.from_networkx.<locals>.<listcomp>c                 S   s"   g | ]}t |trt|n|qS r%   )r>   intstrr2   colr%   r%   r&   r5     r6   c                 3   s   | ]} | V  qd S r   r%   r   r   r%   r&   r     r6   z&Graph.from_networkx.<locals>.<genexpr>Nrd   r   c                 3   s"   | ]\}}| kr||fV  qd S r   r%   r   )idx_dimr%   r&   r     r6   c                 S   s   i | ]\}}||qS r%   r%   )r2   ir\   r%   r%   r&   r     r6   z'Graph.from_networkx.<locals>.<dictcomp>c                    s6   g | ].}| j jvrt| tj kr|qS r%   )rK   rj   rO   r   r   )clsnode_columnsr   r%   r&   r5     s   c                 3   s   | ]} | V  qd S r   r%   r   )r   r%   r&   r     r6   )rM   )r>   r   r   r   rB   rC   ZadjrD   r   r1   r   rK   rj   r   r   rA   r   get	enumerater   rM   Zget_dimension)r   GrW   r   r@   ro   rp   attrvalueZ	edge_colsZ
edge_vdimsZ	edge_datar   ZidimZ	info_colsvaluesry   r3   r4   noder:   r;   r   r   Z	node_colsr   	node_datarM   r   r%   )r   rB   r   r   r   r&   from_networkx~  sn    




zGraph.from_networkx)NN)NTNT)NNrB   )TT)r   F)N)r'   r(   r)   r*   r^   rk   rl   ri   r   rj   rb   rK   rm   rt   ru   propertyr   rv   rw   r   r   r   r   r"   r   r   classmethodr   r+   r%   r%   r#   r&   rn   m   s0   
$
T
	


rn   c                       sv   e Zd ZdZejg ddddZejd ddZe	Z
d fd	d
	Zedd Zdd Zedd Zd fdd	Z  ZS )TriMesha@  
    A TriMesh represents a mesh of triangles represented as the
    simplices and nodes. The simplices represent a indices into the
    nodes array. The mesh therefore follows a datastructure very
    similar to a graph, with the abstract connectivity between nodes
    stored on the TriMesh element itself, the node positions stored on
    a Nodes element and the concrete paths making up each triangle
    generated when required by accessing the edgepaths.

    Unlike a Graph each simplex is represented as the node indices of
    the three corners of each triangle.
    )node1node2Znode3rc   z@
        Dimensions declaring the node indices of each triangle.r.   rf   r/   Trg   Nc              
      s  t |tr*|ddt|   }|\}}}n4t |t| rN||j|j  }}}n|d d   }}}t j|f||d| |d u rt| dkrg }ntdt || j	rnt || j
r| 	t|ddtt|}nt |tr|jdv rt|r,t|jd d }|jjpd}	| 	|||	g }nfz4| 
|}
t|
ddtt|
}| 	|}W n0 ty } ztd	|W Y d }~n
d }~0 0 |d urt || js| |}|| _|| _d S )
Nr   rd   rq   r   z8TriMesh expects both simplices and nodes to be supplied.r9   r   )r   rd   zNodes argument could not be interpreted, expected data with two or three columns representing the x/y positions and optionally the node indices.)r>   r1   rO   rr   r   r   r   ru   r   rK   
point_typer   rN   rF   Zarangers   r
   r   r   r9   r   	Exceptionrt   rL   )r    r   rj   rM   rx   rB   r   r   coordsr9   pointsZdser#   r%   r&   ru     sD    
$


zTriMesh.__init__c                 C   st   zddl m} W n ty,   tddY n0 t|ts@t|}t|sT| g g fS ||ddg}| |j|fS )zc
        Uses Delauney triangulation to compute triangle simplices for
        each point.
        r   )Delaunayz@Generating triangles from points requires SciPy to be installed.Nr   )Zscipy.spatialr   ImportErrorr>   r   rO   r?   Z	simplices)r   r   r   Ztrisr%   r%   r&   from_vertices  s    
zTriMesh.from_verticesc                 C   s   | j r| j S t| s8| jg | jjdd d}|| _ |S t| }|jt|ddf}tj	|ddg dddf 
tddtjdd	ddd	 }| j|g| jjdd d
gd}|| _ |S )R
        Returns the EdgePaths by generating a triangle for each simplex.
        Nr   r   rd   )r   r   r   r   )r   r   )r   r   r   rh   )Z	pad_widthr{   Zconstant_valuesr   Zmultitabular)rj   r   )r   rO   rt   r   rj   r   r   ZreshaperF   padastypefloatnan)r    r   rZ   Zptsr   r%   r%   r&   _initialize_edgepaths0  s,    zTriMesh._initialize_edgepathsc                 C   s   |   S )r   )r   r|   r%   r%   r&   r   G  s    zTriMesh.edgepathsc                    s    |    t jf ddd|S )a  
        Allows selecting data by the slices, sets and scalar values
        along a particular dimension. The indices should be supplied as
        keywords mapping between the selected dimension and
        value. Additionally selection_specs (taking the form of a list
        of type.group.label strings, types or functions) may be
        supplied, which will ensure the selection is only applied if the
        specs match the selected object.
        Nr   )r   r   )r   r   r   )r    r   r   r#   r%   r&   r   N  s    

zTriMesh.select)NN)N)r'   r(   r)   r*   r^   ri   rj   rk   rl   r   r   ru   r   r   r   r   r   r   r+   r%   r%   r#   r&   r     s   
+

r   c                   @   s8   e Zd ZdZejddddZejdddZdd
dZd	S )layout_chordsa>  
    layout_chords computes the locations of each node on a circle and
    the chords connecting them. The amount of radial angle devoted to
    each node and the number of chords are scaled by the value
    dimension of the Chord element. If the values are integers then
    the number of chords is directly scaled by the value, if the
    values are floats then the number of chords are apportioned such
    that the lowest value edge is given one chord and all other nodes
    are given nodes proportional to their weight. The max_chords
    parameter scales the number of chords to be assigned to an edge.

    The chords are computed by interpolating a cubic spline from the
    source to the target node in the graph, the number of samples to
    interpolate the spline with is given by the chord_samples
    parameter.
    2   )r   NzB
        Number of samples per chord for the spline interpolation.r   i  z,
        Maximum number of chords to render.r-   Nc           0   	      sR   j r$jd }j|dd}n0 jddd} jddd}tt||g}| jj} fddtdD \}}	t	||}
t	|	|} j
r d}|jjd	vrtjt d
d}nT|jjdkrt|d|   }| |kr$t|t|  | }|d}ntjt d
d}tt|t|f}t|
||D ] \}}}|||f  |7  < qF|jdd|jdd }||  dtj  }t|jd d }||dd < | }tj|ddgdd}t|}t|}g }t|jd D ]Z}|| }|| ||d   }}t||t|}ttt|t|}|| qt tj!tj!gg}g }tt D ]}|
| ||  } }!||  ||!  }"}#|| |!f }$g }%tt|$D ]}&|"r|#sҐq|"" \}'}(|#sq|#" \})}*t#|'|(f|)|*f|'d |(d f|)d |*d f| jj$d}+|%|+ |%| qdd |%d d D }%|%rp|t|% n|t%d qxrt&t'rjnt'jd d |g fddj
D },t(fdd|,D }nt'jdg  }},t|r|||f| }-nt(dd |, D }-t'|-|,d}t)|}.t* j+||.fdd}/||/_,|/S )Nr   Fr7   r   r   c                 3   s   | ]}  |V  qd S r   rE   )r2   r   )rQ   r%   r&   r     r6   z)layout_chords._process.<locals>.<genexpr>r   Zuifr   )dtypefg      ?int64)Zaxisg      ?Zvalidrz   g       @)Zstepsc                 S   s   g | ]}t |r|qS r%   r   )r2   r<   r%   r%   r&   r5     r6   z*layout_chords._process.<locals>.<listcomp>)r   r   c                    s   g | ]}| vr|qS r%   r%   r2   Zvdr   r%   r&   r5     r6   c                 3   s   | ]}  |V  qd S r   r   r   )nodes_elr%   r&   r     r6   r%   c                 s   s   | ]
}g V  qd S r   r%   )r2   _r%   r%   r&   r     r6   rq   )r   )-rL   rj   rE   rF   rG   rH   r<   
max_chordsr   r   rM   r   kindZonesrO   ceilminsumr   r   zerosrA   pishapeZcumsumZconvolvecossinZlinspacer   r   r   r?   r   popr   chord_samplesemptyr>   rb   r1   rm   Chordr   _angles)0r    rQ   rR   r   r   rX   rY   r   srcZtgtZsrc_idxZtgt_idxr   ZmatrixrT   rU   r   Zweights_of_areasZareas_in_radiansr   Z	midpointsZmxsZmysZ	all_areasr   Zn_connZp0p1Zanglesr   r   r   ZsidxZtidxZsrc_areaZtgt_areaZn_connsZsubpathsr   Zx0Zy0x1y1brM   r   rB   chordr%   )rQ   rj   r   r&   r]   w  s    








zlayout_chords._process)N)	r'   r(   r)   r*   r^   ZIntegerr   r   r]   r%   r%   r%   r&   r   _  s   r   c                       sH   e Zd ZdZejd ddZd fdd	Zedd Z	ed	d
 Z
  ZS )r   a.  
    Chord is a special type of Graph which computes the locations of
    each node on a circle and the chords connecting them. The amount
    of radial angle devoted to each node and the number of chords are
    scaled by a weight supplied as a value dimension.

    If the values are integers then the number of chords is directly
    scaled by the value, if the values are floats then the number of
    chords are apportioned such that the lowest value edge is given
    one chord and all other nodes are given nodes proportional to
    their weight.
    Trg   Nc           
         sJ  |d u st |tr&|g kr&g g g ff}t |trP|ddt|   }|\}}}n|d d   }}}|d urt |ts|jdkrt|}n&t|}|j|jd |jdd  d}t	t
| j|f||d| |r|| _t| }	|	j| _|	j| _|	j| _nHt |tstdt| d|| _t |ts8tdt| || _|   d S )	Nr   rd   r   r   rq   z%Expected Nodes object in data, found .z,Expected EdgePaths object in data, found %s.)r>   r   r1   rO   r   rs   rb   r   rj   r   rn   ru   rL   r   r   r   r   r   	TypeErrorrr   rm   rw   )
r    r   rj   rM   r   rx   rB   r   r   r   r#   r%   r&   ru     s<    




zChord.__init__c                 C   s   | j S r   )r   r|   r%   r%   r&   r     s    zChord.edgepathsc                 C   s   | j S r   )rL   r|   r%   r%   r&   r     s    zChord.nodes)NNT)r'   r(   r)   r*   r^   rk   rl   ru   r   r   r   r+   r%   r%   r#   r&   r     s   #
r   )'collectionsr   typesr   numpyrF   r}   rI   r^   corer   r   r   Zcore.accessorsr   Zcore.operationr	   Z	core.utilr
   r   r   Zchartr   pathr   utilr   r   r   r   r   r   r,   rb   rm   rn   r   r   r   r%   r%   r%   r&   <module>   s.   	0	  r  