
    Ugs#                        d Z ddlmZ ddlZddlZddlZ G d dej                        Z	 G d de	      Z
 G d d	e	      Zdd
ZddZd Zd Z G d de	      Zy)z,Assign coordinates to the nodes of a graph.
    )annotationsNc                  8   e Zd ZdZdZ ej                  ddd      Z ej                  dd	      Z	 ej                  d
d	      Z
 ej                  dd	      Z ej                  dd	      Z ej                  ddd      Z ej                  ddd      Zd Zy)LayoutAlgorithmz4
    Baseclass for all graph layout algorithms.
    TN)r   l    zS
        Random seed used to initialize the pseudo-random number
        generator.defaultboundsdocxz2
        Column name for each node's x coordinate.r   r	   yz2
        Column name for each node's y coordinate.sourcez,
        Column name for each edge's source.targetz,
        Column name for each edge's target.zH
        Column name for each edge weight. If None, weights are ignored.)r   
allow_Noner	   zi
        Column name for a unique identifier for the node.  If None, the
        dataframe index is used.c                    t         S )ae  
        This method takes two dataframes representing a graph's nodes
        and edges respectively. For the nodes dataframe, the only
        column accessed is the specified `id` value (or the index if
        no 'id'). For the edges dataframe, the columns are `id`,
        `source`, `target`, and (optionally) `weight`.

        Each layout algorithm will use the two dataframes as appropriate to
        assign positions to the nodes. Upon generating positions, this
        method will return a copy of the original nodes dataframe with
        two additional columns for the x and y coordinates.
        )NotImplementedError)selfnodesedgesparamss       1lib/python3.12/site-packages/datashader/layout.py__call__zLayoutAlgorithm.__call__)   s
     #"    )__name__
__module____qualname____doc___LayoutAlgorithm__abstractparamIntegerseedStringr
   r   r   r   weightidr    r   r   r   r      s     J5==l A D 	S '5 	6A 	S '5 	6A U\\( 1/ 0F U\\( 1/ 0F U\\$4 >K LF 
dt :$ 
%B#r   r   c                      e Zd ZdZddZy)random_layoutz
    Assign coordinates to the nodes randomly.

    Accepts an edges argument for consistency with other layout algorithms,
    but ignores it.
    Nc                Z   t        j                  | |      }t        j                  j	                  |j
                        }|j                         }t        j                  |j                  t        |      df            }|d d df   ||j                  <   |d d df   ||j                  <   |S )N   r      )r   ParamOverridesnprandomdefault_rngr    copyasarraylenr
   r   )r   r   r   r   prngdfpointss           r   r   zrandom_layout.__call__A   s      v.ii##AFF+ZZ\CJJB|45A,133A,133	r   N)r   r   r   r   r   r$   r   r   r&   r&   9   s    r   r&   c                  @    e Zd ZdZ ej
                  dd      ZddZy)circular_layoutz
    Assign coordinates to the nodes along a circle.

    The points on the circle can be spaced either uniformly or randomly.

    Accepts an edges argument for consistency with other layout algorithms,
    but ignores it.
    Tz5
        Whether to distribute nodes evenly on circler	   Nc                :   t        j                  | |      }t        j                  j	                  |j
                        }d}d\  }}dt        j                  z  }	|j                         }
|j                  r$t        j                  |	|	t        |
      z        }n1t        j                  |j                  t        |
      f            |	z  }||t        j                  |      z  z   |
|j                  <   ||t        j                  |      z  z   |
|j                  <   |
S )N      ?)r:   r:   r(   )step)r   r*   r+   r,   r-   r    pir.   uniformaranger0   r/   cosr
   sinr   )r   r   r   r   r1   r2   rx0y0circumferencer3   thetass               r   r   zcircular_layout.__call__\   s      v.ii##AFF+BBEE	ZZ\99YY}=R3HIFZZ

CG: 67-GFq266&>))133q266&>))133	r   r5   )r   r   r   r   r   Booleanr=   r   r$   r   r   r7   r7   O   s%     emmD '8 9Gr   r7   c                |   |t         j                  j                         }|j                  | j                  v rH|j
                  | j                  v r0t        j                  | |j                  |j
                  g         }|S t        j                  |j                  t        |       |j                  f      |      }|S )Ndtype)	r+   r,   r-   r
   columnsr   r/   r0   dim)r   r   rI   r2   r4   s        r   _extract_points_from_nodesrL   r   s    
{ii##%xx5== VXX%>E688VXX"678 M CJJE
FJJ'?@NMr   c                   t        |       }|j                  D|j                  | v r6t        t        | |j                     j                  t        |                  n2t        t        | j                  j                  t        |                  |j                  rT|j                  |v rF||j                  |j                  |j                  g   j                  }t        fd|D         \  }}}	n:||j                  |j                  g   j                  }t        fd|D         \  }}}	|	|	z   }
||z   }||z   }|||j                     ||j                     k(     }t        |      r|j                  rS|j                  |v rE||j                  |j                  |j                  g   j                  }t        fd|D         \  }}n9||j                  |j                  g   j                  }t        fd|D         \  }}|
|z  }
||z  }||z  }t        j                  j                  |
||ff||f|      }|j                  |      S )Nc              3  L   K   | ]  \  }}}|v r|v r|   |   |f  y wr5   r$   .0srcdstr"   indexs       r   	<genexpr>z2_convert_graph_to_sparse_matrix.<locals>.<genexpr>   s=      !C9D%5S#v$'5LSE\ #(*eCj&!A9Ds   !$c              3  J   K   | ]  \  }}|v r|v r|   |   d f  ywr)   Nr$   rP   rQ   rR   rS   s      r   rT   z2_convert_graph_to_sparse_matrix.<locals>.<genexpr>   s:      !C1<XS#$'5LSE\ #(*eCj!!<1<s    #c              3  F   K   | ]  \  }}}|v r|v r
|   | f  y wr5   r$   rO   s       r   rT   z2_convert_graph_to_sparse_matrix.<locals>.<genexpr>   s9      *LBM.>c3-0E\cUl ,1:w*?BMs   !c              3  B   K   | ]  \  }}|v r|v r	|   d f  yw)Nr$   rW   s      r   rT   z2_convert_graph_to_sparse_matrix.<locals>.<genexpr>   s4      *J8CHC+.%<C5L ,1:r*:8Cs   )shaperI   )r0   r#   dictzipvaluesrangerS   r"   r   r   scipysparse
coo_matrixasformat)r   r   r   rI   formatnlenedge_valuesrowscolsdatadrA   cloopsloop_values
diag_index	diag_dataMrS   s                     @r   _convert_graph_to_sparse_matrixrq   }   s&   u:Dyye!3Svyy)00%+>?S++U4[9:}}%/V]]FMM6==IJQQ !C9D!C DdD V]]FMM:;BB !C1<!C DdD
 	tAtAtA %&%*>>?E
5z==V]]e3v}} MNUUK$' *LBM*L %M!J	   >?FFK$' *J8C*J %K!J	 	
Y	Z	ZQFD$<uMA::fr   c                ~    | j                         }|d d df   ||j                  <   |d d df   ||j                  <   |S )Nr   r)   )r.   r
   r   )r   r4   r   ns       r   _merge_points_with_nodesrt      s<    

AA,AfhhKA,AfhhKHr   c           	        |t        |j                  dz         z  }t        j                  |j                  t        |      f      }t        |j                        D ]  }|dz  }t        | j                  d         D ]  }||   |z
  j                  }t        j                  |dz  j                  d            }	t        j                  |	dk  d|	      }	| |   j                         }
|j                  |j                  z  |	dz  z  }|j                  r!|t        |
j                  d      dz         z  }|j                  rt        j                   |dz         }|d d |fxx   |||
|	z  |j                  z  z
  z  j                  d      z  cc<    t        j                  |dz  j                  d            }t        j                  |dk  d|      }|||z  |z  j                  z  }||z  } y )Nr)   r   r(   )axisg{Gz?)float
iterationsr+   zerosrK   r0   r_   r[   Tsqrtsumwheretoarrayknohubslinloglog)matrixr4   temperaturer   dtdisplacement	iterationideltadistanceaidistlengths                r   coolingr      s   	uV..23	3B88VZZV56L6,,-	v||A'AAY'**E ww
//Q/78H xx4x@H ""$B 88fhh&Q6D}}eBFFFNQ$677}}vvdQh'A5D2=6883K,K#L"Q"QWX"Q"YY) (. ,!+00a089&4-v6<+-6999 	r= .r   c                      e Zd ZdZ ej
                  ddd      Z ej                  dd      Z ej                  dd	      Z	 ej                  d
d      Z ej
                  ddd      Zd Zy
)forceatlas2_layouta  
    Assign coordinates to the nodes using force-directed algorithm.

    This is a force-directed graph layout algorithm called
    `ForceAtlas2`.

    Timothee Poisot's `nxfa2` is the original implementation of this
    algorithm.

    .. _ForceAtlas2:
       http://journals.plos.org/plosone/article/file?id=10.1371/journal.pone.0098679&type=printable
    .. _nxfa2:
       https://github.com/tpoisot/nxfa2
    
   rV   z2
        Number of passes for the layout algorithmr   Fz4
        Whether to use logarithmic attraction forcer8   z
        Whether to grant authorities (nodes with a high indegree) a
        more central position than hubs (nodes with a high outdegree)Nz
        Compensates for the repulsion for nodes that are far away
        from the center. Defaults to the inverse of the number of
        nodes.r   r(   z+
        Coordinate dimensions of each nodec                Z   t        j                  | |      }t        j                  j	                  |j
                        }t        ||d|      }t        |||d      }|j                  &t        j                  dt        |      z        |_        d}t        ||||       t        |||      S )Nf)rI   r2   rH   g      ?g?)r   r*   r+   r,   r-   r    rL   rq   r   r{   r0   r   rt   )	r   r   r   r   r1   r2   r4   r   r   s	            r   r   zforceatlas2_layout.__call__   s      v.ii##AFF+ ,E1CSI0qL33;''#F+,AC  	Q/ (vq99r   )r   r   r   r   r   r   rx   rF   r   r   Numberr   rK   r   r$   r   r   r   r      s     r) B5 6J U]]5 '7 8F U]]5 'I JF 	T ( 	A
 %--) :. /C:r   r   )NN)Ncsr)r   
__future__r   numpyr+   r   scipy.sparser`   ParameterizedFunctionr   r&   r7   rL   rq   rt   r   r   r$   r   r   <module>r      sf    #   +#e11 +#\O , o  F)X!H7: 7:r   