
    evB                         d dl Z d dlmZ d dlmZ d dlZd dlZddlm	Z	 ddl
mZ ddlmZ ddlmZmZ d	d
lmZmZmZ d	dlmZ dZde z  Z G d de          Z G d de          ZdS )    N)
cmp_to_key)cycle   )Dataset)	Dimension)	Operation)get_param_valuesunique_array   )	EdgePathsGraphNodes)quadratic_bezier   
   c                   2   e Zd ZdZ ej        d          Z ej        dd          Z ej	        ddd	
          Z
 ej	        dd          Z ej        dd          Zd%dZd Zed             Zed             Zed             Zed             Zd Zed             Zed             Zed             Zed             Zd Zed             Zed             Zed             Zed             Zd Zed             Z d  Z!d! Z"d" Z#ed#             Z$d$ Z%dS )&_layout_sankeyz
    Computes a Sankey diagram from a Graph element for internal use in
    the Sankey element constructor.

    Adapted from d3-sankey under BSD-3 license.

    Source: https://github.com/d3/d3-sankey/tree/v0.12.3
    )r   r   i  i  default   z
        Width of the nodes.)r   docNTz<
        Number of pixels of padding relative to the bounds.)r   
allow_Noner       z:
        Number of iterations to run the layout algorithm.z)
        Sort nodes in ascending breadth.c                 |     | j         |fi | j        \  }}}t          |          }t          |j        ||ffd|i|S Nsankey)layoutpr	   Sankeydata)selfelementkeynodesedgesgraphparamss          8lib/python3.11/site-packages/holoviews/element/sankey.py_processz_layout_sankey._process+   sU    )dk'<<TV<<ue!'**w|UE2KK5KFKKK    c           	         t          j        | |          | _        g g d}|                     ||           |                     |           |                     |           |                     |           |                     |           |                     |           | 	                    |          }g }|d         D ]v}|
                    t          j        |d         |d         g          t          j        |d         |d         g          |d         ft          |d                   z              w|j        j        d	k    r|j        j        }nB|j        j        r*|j        j        d d
         |j        j        dd          z   }n|j        j        }|                    |||j        j                  }|                    |          }	||	|fS )N)r$   linksr$   x0x1y0y1indexvalues   r   kdimsvdims)paramParamOverridesr   computeNodeLinkscomputeNodeValuescomputeNodeDepthscomputeNodeHeightscomputeNodeBreadthscomputeLinkBreadthscomputePathsappendnpmeantupler$   ndimsr6   	node_typer7   	edge_type)
r!   r"   r'   r&   paths	node_datanoder6   r$   r%   s
             r(   r   z_layout_sankey.layout0   s   %dF33r**gu---u%%%u%%%&&&  '''  '''!!%((	'N 	D 	DDbgtDz4:&>?? gtDz4:&>??"7m--24>-B-BC D D D D =!##M'EE]  	,%+BQB/'-2Ebcc2JJEE%+E!!)5@S!TT!!%((eU""r*   c                    j         j        d         }i }j         j        r t          fdj         j        D              }nt	          t                      g          }t          j                             |          |          D ],\  }}|g g |d}|d                             |           |||<   -fd                                dd         D             }	t          t          |	           D ]}\  }
\  }}}||         ||         }}t          |
|||          }|d	                             |           |d
                             |           |d                             |           ~dS )z
        Populate the sourceLinks and targetLinks for each node.
        Also, if the source and target are not objects, assume they are indices.
        r4   c              3   L   K   | ]}j                             |          V  d S N)r$   dimension_values.0dr"   s     r(   	<genexpr>z2_layout_sankey.computeNodeLinks.<locals>.<genexpr>S   sG       9 9  #=99!<< 9 9 9 9 9 9r*   )r1   sourceLinkstargetLinksr2   r$   c                 :    g | ]}                     |          S  )rN   rO   s     r(   
<listcomp>z3_layout_sankey.computeNodeLinks.<locals>.<listcomp>\   s'    OOO))!,,OOOr*   Nr3   )r1   sourcetargetvaluer,   rS   rT   )r$   r6   r7   zipr   rD   rN   rA   
dimensions	enumeratedict)clsr"   r&   r1   node_mapr2   idxvalsrJ   r,   isrctgtrZ   rX   rY   links    `               r(   r:   z_layout_sankey.computeNodeLinksJ   s    #B'= 	& 9 9 9 9$+M$79 9 9 :FF EGG9%%FW];;EBBFKK 	! 	!IC BRVWWD'N!!$''' HSMMOOOOg6H6H6J6J2A26NOOO$-c5k$:$: 	/ 	/ A S%%c]HSMFFavUKKKD'N!!$'''=!((...=!((....	/ 	/r*   c                     |d         D ]^}t          j        d |d         D                       }t          j        d |d         D                       }t          ||g          |d<   _dS )zX
        Compute the value (size) of each node by summing the associated links.
        r$   c                     g | ]
}|d          S rZ   rV   rP   ls     r(   rW   z4_layout_sankey.computeNodeValues.<locals>.<listcomp>j        I I I7 I I Ir*   rS   c                     g | ]
}|d          S ri   rV   rj   s     r(   rW   z4_layout_sankey.computeNodeValues.<locals>.<listcomp>k   rl   r*   rT   rZ   N)rB   summax)r_   r&   rJ   
source_val
target_vals        r(   r;   z _layout_sankey.computeNodeValuesd   s    
 'N 	: 	:D I IT-5H I I IJJJ I IT-5H I I IJJJZ 899DMM	: 	:r*   c                     |d         }d}|rcg }|D ]-}||d<   |d         D ]}|                     |d                    .|}|dz  }|t          |d                   k    rt          d          |c|S )Nr$   r   depthrS   rY   r   ,Sankey diagrams only support acyclic graphs.rA   lenRecursionError)r_   r&   r$   rs   
next_nodesrJ   rf   s          r(   r<   z _layout_sankey.computeNodeDepthsn   s    g 		UJ 6 6 %W / 6 6D%%d8n55556EQJEs5>****$%STTT  		U r*   c                     |d         }d}|rcg }|D ]-}||d<   |d         D ]}|                     |d                    .|}|dz  }|t          |d                   k    rt          d          |c|S )Nr$   r   heightrT   rX   r   rt   ru   )r_   r&   r$   rz   rx   rJ   rf   s          r(   r=   z!_layout_sankey.computeNodeHeights~   s    g 		UJ 6 6!'X / 6 6D%%d8n55556EaKFE'N++++$%STTT  		U r*   c                     t          d |d         D                       dz   }| j        j        d         | j        j        d         }}| j        j        }||z
  |z
  |dz
  z  }d t	          |          D             }|d         D ]}t          dt          |dz
  t          j        |d         r|d         n|dz
                                |d	<   ||d	         |z  z   |d
<   |d
         |z   |d<   ||d	                                      |           |S )Nc              3   &   K   | ]}|d          V  dS )rs   NrV   )rP   xs     r(   rR   z4_layout_sankey.computeNodeColumns.<locals>.<genexpr>   s&      CCq'
CCCCCCr*   r$   r   r   r   c                     g | ]}g S rV   rV   )rP   _s     r(   rW   z5_layout_sankey.computeNodeColumns.<locals>.<listcomp>   s    888!2888r*   rS   rs   columnr-   r.   )	ro   r   bounds
node_widthrangeminmathfloorrA   )	r!   r&   depth_upper_boundr-   r.   dxkxcolumnsrJ   s	            r(   computeNodeColumnsz!_layout_sankey.computeNodeColumns   s:   CCE'NCCCCCaGq!46=#3BV2gl014588u%677888'N 	1 	1D %)J.3W.2  
 
DN d8nr11DJdbDJDN#**40000r*   c                 >    t          |d         |d         z
            S )Nr/   )intr_   abs      r(   ascendingBreadthz_layout_sankey.ascendingBreadth   s    1T7QtW$%%%r*   c                     d|d         v r,d|d         v r"|                      |d         |d                   nd p|d         |d         z
  S )Nr/   rX   r1   r   r   s      r(   ascendingSourceBreadthz%_layout_sankey.ascendingSourceBreadth   `    
 1X;&&41X;+>+> $$Qx[!H+>>>'
 zAgJ&	
r*   c                     d|d         v r,d|d         v r"|                      |d         |d                   nd p|d         |d         z
  S )Nr/   rY   r1   r   r   s      r(   ascendingTargetBreadthz%_layout_sankey.ascendingTargetBreadth   r   r*   c                     |D ]^}|d                              t          | j                             |d                              t          | j                             _d S )NrS   r#   rT   sortr   r   r   )r_   r$   r}   s      r(   reorderLinksz_layout_sankey.reorderLinks   sp     	N 	NAm!!j1K&L&L!MMMm!!j1K&L&L!MMMM	N 	Nr*   c                   
 | j         j        \  }
}t          
fd|D                       }|D ]}
}|D ]<}||d<   ||d         |z  z   |d<   |d         z   }|d         D ]}|d         |z  |d<   =|z
  z   t          |          dz   z  }t	          |          D ]1\  }	}|dxx         ||	dz   z  z  cc<   |dxx         ||	dz   z  z  cc<   2|                     |           d S )Nc              3      K   | ]9}z
  t          |          d z
  z  z
  t          d |D                       z  V  :dS )r   c              3   &   K   | ]}|d          V  dS )rZ   NrV   )rP   rJ   s     r(   rR   zB_layout_sankey.initializeNodeBreadths.<locals>.<genexpr>.<genexpr>   s&      /L/L$W/L/L/L/L/L/Lr*   N)rv   rn   )rP   cpyr/   r0   s     r(   rR   z8_layout_sankey.initializeNodeBreadths.<locals>.<genexpr>   sk       
 
 "WA
b((C/L/L!/L/L/L,L,LL
 
 
 
 
 
r*   r/   rZ   r0   rS   widthr   )r   r   r   rv   r]   r   )r!   r   r   r   kyr$   yrJ   rf   rc   r/   r0   s     `       @@r(   initializeNodeBreadthsz%_layout_sankey.initializeNodeBreadths   sj   v}2q" 
 
 
 
 
 

 
 
 
 
  	% 	%EA 7 7T
g!33T
JO / 7 7D$(MB$6DMM7a"Ua0A$U++ * *4T


a1q5k)


T


a1q5k)



e$$$$	% 	%r*   c                     |d         t          |d                   dz
  |z  dz  z
  }|d         D ]}|d         |u r n||d         |z   z  }|d         D ]}|d         |u r n||d         z  }|S )	Nr/   rT   r   r   rX   r   rS   rY   rv   r_   rX   rY   r   r   rf   s         r(   	sourceTopz_layout_sankey.sourceTop       4LC} 566:b@1DD=) 	$ 	$DH~''g##AA=) 	 	DH~''gAAr*   c                     |d         t          |d                   dz
  |z  dz  z
  }|d         D ]}|d         |u r n||d         |z   z  }|d         D ]}|d         |u r n||d         z  }|S )	Nr/   rS   r   r   rY   r   rT   rX   r   r   s         r(   	targetTopz_layout_sankey.targetTop   r   r*   c                     ||d          D ]F}||d         z
  |z  }|t           k    r |dxx         |z  cc<   |dxx         |z  cc<   |d         |z   }Gd S )Nr/   r0   _Y_EPSr_   r$   r   rc   alphar   rJ   dys           r(   resolveCollisionsTopToBottomz+_layout_sankey.resolveCollisionsTopToBottom   sy    !""I 	  	 Dd4j.E)BF{{T


b 


T


b 


T
RAA	  	 r*   c                     |dk    rY||         }|d         |z
  |z  }|t           k    r |dxx         |z  cc<   |dxx         |z  cc<   |d         |z
  }|dz  }|dk    Wd S d S )Nr   r0   r/   r   r   r   s           r(   resolveCollisionsBottomToTopz+_layout_sankey.resolveCollisionsBottomToTop   s     1ff8Dt*q.E)BF{{T


b 


T


b 


T
RAFA 1ffffffr*   c                 t   | j         j        \  }}}}t          |          dz  }||         }|                     ||d         |z
  |dz
  ||           |                     ||d         |z   |dz   ||           |                     ||t          |          dz
  ||           |                     ||d||           d S )Nr   r/   r   r0   r   )r   r   rv   r   r   )	r!   r$   r   r   r   r/   r0   rc   subjects	            r(   resolveCollisionsz _layout_sankey.resolveCollisions  s    v}2q"JJ!O())%1CQUESUVVV))%1CQUESUVVV))%SZZ!^UBOOO))%QrBBBBBr*   c                    |d         D ]6}|d         d                              t          | j                             7|d         D ]6}|d         d                              t          | j                             7d S )NrT   rX   rS   r   rY   r   )r_   rJ   rf   s      r(   reorderNodeLinksz_layout_sankey.reorderNodeLinks  s    ' 	 	DN=)..s9:: /     ' 	 	DN=)..s9:: /    	 	r*   c           	          |dd          D ]}|D ]}d}d}|d         D ]F}	|	d         }
|	d         |d         |
d         z
  z  }||                      |
||          |z  z  }||z  }G|dk    r\||z  |d         z
  |z  }|dxx         |z  cc<   |dxx         |z  cc<   |                     |           | j        j        r(|                    t          | j                  	           |                     |||           d S )
Nr   r   rT   rX   rZ   r   r/   r0   r   )r   r   r   	node_sortr   r   r   r   )r!   r   r   betar   r   rY   r   wrf   rX   vr   s                r(   relaxLeftToRightz_layout_sankey.relaxLeftToRight  sN   abbk 	5 	5F  . ."=1  D!(^FW)9F8<L)LMA;;a??AFAA66!efTl*e3t"t"%%f----v C
4+@ A ABBB""644444%	5 	5r*   c           	         |ddd         D ]}|D ]}d}d}|d         D ]F}	|	d         }
|	d         |
d         |d         z
  z  }||                      ||
|          |z  z  }||z  }G|dk    r\||z  |d	         z
  |z  }|d	xx         |z  cc<   |d
xx         |z  cc<   |                     |           | j        j        r(|                    t          | j                             |                     |||           dS )z:Reposition each node based on its outgoing (source) links.Nr4   r   rS   rY   rZ   r   r/   r0   r   )r   r   r   r   r   r   r   r   )r!   r   r   r   r   r   rX   r   r   rf   rY   r   r   s                r(   relaxRightToLeftz_layout_sankey.relaxRightToLeft1  sP   bf"fo 	5 	5F  . ."=1  D!(^FW)9F8<L)LMA;;a??AFAA66!efTl*e3t"t"%%f----v C
4+@ A ABBB""644444#	5 	5r*   c                 r   |                      |          }| j        j        \  }}}}t          t	          t
          |                    }d}| j        j        | j        j        n |dk    rt          ||z
  |dz
  z  |          n|}|                     ||           t          | j        j
                  D ]Z}	d|	z  }
t          d|
z
  |	dz   | j        j
        z            }|                     ||
||           |                     ||
||           [|d         D ] }t          |d         t                    |d<   !d S )N   r   gGz?r$   r0   )r   r   r   ro   maprv   node_paddingr   r   r   
iterationsr   r   round_Y_N_DECIMAL_DIGITS)r!   r&   r   r   r/   r0   max_column_sizemax_default_paddingr   rc   r   r   rJ   s                r(   r>   z"_layout_sankey.computeNodeBreadthsF  sc   ))%00v}2q"c#w//00  v". F "" b2g/A"568KLLL$ 	 	##GR000tv()) 	< 	<AAIEq5y1q5DF,="=>>D!!'5$;;;!!'5$;;;;'N 	@ 	@DtDz+>??DJJ	@ 	@r*   c                    |d         D ]^}|d                              t          | j                             |d                              t          | j                             _|d         D ]Z}|d         }|}|d         D ]}||d         dz  z   |d<   ||d         z  }|d         D ]}||d         dz  z   |d<   ||d         z  }[d S )	Nr$   rS   r   rT   r/   r   r   r0   r   )r_   r&   rJ   r/   r0   rf   s         r(   r?   z"_layout_sankey.computeLinkBreadths\  s   'N 	Q 	QD$$C4N)O)O$PPP$$C4N)O)O$PPPP'N 	$ 	$DdBB]+ $ $$w-!"33T
d7m#]+ $ $$w-!"33T
d7m#$	$ 	$r*   c                 >   g }|d         D ]}|d         |d         }}|d         }|d         }||z   dz  }|d         |d         dz  z   }	|d         |d         dz  z
  }
|d	         |d         dz  z   }|d	         |d         dz  z
  }t          j        ||	g||
gg          }t          ||
f||f||
f||f          }t          j        ||g||gg          }t          ||f||	f||f||	f          }t          j        ||||g          }|                    |           |S )
Nr,   rX   rY   r.   r-   r   r/   r   r0   )rB   arrayr   concatenaterA   )r!   r&   rH   rf   rX   rY   r-   r.   xmidy0_uppery0_lowery1_uppery1_lowerstartbottommidtopsplines                     r(   r@   z_layout_sankey.computePathsl  s   'N 	! 	!D!(^T(^FFBBGq=DDzDMA$55HDzDMA$55HDzDMA$55HDzDMA$55HHXX  E &XXx x 	 F (XX  C #XXx x 	 C ^UFC$=>>FLL    r*   rM   )&__name__
__module____qualname____doc__r8   NumericTupler   Numberr   Integerr   r   Booleanr   r)   r   classmethodr:   r;   r<   r=   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r>   r?   r@   rV   r*   r(   r   r      s          U(9:::Fb /      J !5=$ E? @ @ @L r 0= > > >J d 1, - - -IL L L L
# # #4 / / [/2 : : [:   [   [  . & & [& 
 
 [
 
 
 [
 N N [N
% % %( 
 
 [
 
 
 [
     [  	 	 [	C C C   [5 5 5*5 5 5*@ @ @, $ $ [$" " " " "r*   r   c                        e Zd ZdZ ej        d d          Z ej         ed          g          Z	d	 fd	Z
d
 fd	Z xZS )r   zt
    Sankey is an acyclic, directed Graph type that represents the flow
    of some quantity between its nodes.
    T)r   constantValuer   Nc                    |g }t          |t                    r|ddt          |          z
  z  z   }|\  }}}n|d d }}}|                    dd           }|o)t          |t                    ot          |t
                     }	 t          t          |           j        |f||d| |	r|b| 	                    dd          }
| 	                    dd          }t          t          j        |
|g                    }t          |d	          }nFt          |t                    s1	 t          |          }n # t          $ r t          |d	          }Y nw xY w|j        st!          d
          || _        t$                                                              |           \  }}}|| _        || _        || _        n~t          || j                  s t1          dt3          |           d          || _        t          || j                  st1          dt3          |          z            || _        || _        |                                  d S )NrM   r3   r   r5   r   F)expandedr   r1   zCould not determine index in supplied node data. Ensure data has at least one key dimension, which matches the node ids on the edges.z%Expected Nodes object in data, found .z,Expected EdgePaths object in data, found %s.)
isinstancerD   rv   popr   r   superr   __init__rN   r
   rB   r   r   	Exceptionr6   
ValueError_nodesr   instancer   
_edgepaths_sankeyrF   	TypeErrortyperG   	_validate)r!   r    r6   r7   r'   r%   r$   	edgepathssankey_graphcomputerd   re   r2   r&   	__class__s                 r(   r   zSankey.__init__  sx   <DdE"" 	7'1SYY;//D&*#E5))&*D$)5Ezz(D11#e
5%(@(@eZPY[dEeEef#eT#ENeNNvNNN 	(}++A+>>++A+>>%bnc3Z&@&@AA00w// 44#ENNEE  4 4 4#E733EEE4; M  "L M M M  DK&4&=&=&?&?&F&Ft&L&L#E9eDK'DO DLLeT^44 X VU V V VWWWDKi88 3 N"&y//!2 3 3 3'DO'DLs   $D4 4EEc                 \    |
| j         |d<    t                      j        ||||g|R i |S r   )r   r   clone)r!   r    shared_datanew_typerf   args	overridesr   s          r(   r   zSankey.clone  sP    <"&,Ihuww}T;$ 1"1 1 1&/1 1 	1r*   )NN)NTNT)r   r   r   r   r8   StringgroupListr   r7   r   r   __classcell__)r   s   @r(   r   r     s         
 ELD999EEJ		' 2 23444E( ( ( ( ( (T1 1 1 1 1 1 1 1 1 1r*   r   )r   	functoolsr   	itertoolsr   numpyrB   r8   	core.datar   core.dimensionr   core.operationr   	core.utilr	   r
   graphsr   r   r   utilr   r   r   r   r   rV   r*   r(   <module>r     s@                                 & & & & & & & & & & & & 6 6 6 6 6 6 6 6 + + + + + + + + + + " " " " " " 	##	#{ { { { {Y { { {|91 91 91 91 91U 91 91 91 91 91r*   