
    -e0                       d Z ddlmZ ddlZ ej        e          ZddlmZ ddl	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mZmZmZmZmZmZmZmZmZmZmZm Z m!Z! e
rddl"Z#d	d
l$m%Z% d	dl&m'Z' dZ(ddZ) G d d          Z*dS )a   Functions to draw the a clickable graph of the submodels of a bokeh model.

Clicking on the nodes representing the submodels reveals the attributes of that submodel.
Uses simple custom javascript callbacks so no server is necessary;
works in a jupyter notebook.

Suppose M is a bokeh model (i.e. a plot or figure).  Then
generate_structure_plot(M) is a bokeh model that displays the submodel graph.

Based on a private class, _BokehStructureGraph.

- K = _BokehStructureGraph(M) creates the object.
- K.model returns the model consisting of the structure graph and associated datatable.
- K.graph returns the directed graph in networkx format
- K.property_df returns the dataframe of models, submodels and their properties.

    )annotationsN)permutations)TYPE_CHECKING)UnsetValueError)column)BoxZoomToolCDSViewCircleColumnDataSourceCustomJS	DataTableGlyphRendererGroupFilter	HoverToolLabelLabelSet	MultiLinePanToolPlotRange1d	ResetToolTableColumnTapTool   )ID)Model)generate_structure_plotfr   returnc                *    t          |           j        S )z  Given a bokeh model f, return a model that displays the graph of its submodels.

    Clicking on the nodes of the graph reveals the attributes of that submodel.

    )_BokehStructureGraphmodel)r   s    ;lib/python3.11/site-packages/bokeh/models/util/structure.pyr   r   R   s      ""((    c                      e Zd ZdZddZedd            Zed             Zed	             ZddZ	ddZ
ddZddZddZddZdS )r!   a#   Class for exploring the graph of submodels of a Bokeh model.

    If M is such a model and X=_BokehStructureGraph(M), then:

    - X.model is the interactive model itself of
    the submodel graph; pass it to show or file_html.  Self contained so
    works in a jupyter notebook, no server needed.

    - X.graph is the networkx DiGraph of submodels.

    - X.property_df is a pandas dataframe including all of the properties of
    all of the submodels, with their docstrings.  Used for the datatable
    displayed when clicking on X.model

    r"   r   r   Nonec                   || _         |                     |          | _        ddi| j        j        d<   |                                 | _        |                                 | _        |                                 | _	        d| j         j
        j         d| j         j         | j        j        _        |                                 | _        d S )NrankdirLRgraphzStructure of model type z	 with id )_model_make_graph_graphr*   _make_prop_dict_prop_df_make_graph_plot_graph_plot_make_data_table_data_table	__class____name__idtitletext	_combined_structure_graph)selfr"   s     r#   __init__z_BokehStructureGraph.__init__q   s    &&u--&/%6'",,..00220022&zAVA_&z&zjnjujx&z&z# $ 0 0r$   c                    | j         S )z The bokeh model consisting of the structure graph and the datatable
        for the attributes.

        Can be passed to show or file_html. Self contained,
        so remains interactive in a notebook or html file; no server needed.

        )r:   r;   s    r#   r"   z_BokehStructureGraph.model|   s     $$r$   c                    | j         S )z@ The networkx digraph of submodels of the given model.

        )r-   r>   s    r#   r*   z_BokehStructureGraph.graph   s    
 {r$   c                    | j         S )z A pandas dataframe of all of the properties of the model with their
        values, types, and docstrings.  The base information for the datatable.

        )r/   r>   s    r#   property_dfz _BokehStructureGraph.property_df   s     }r$   Mc                   ddl }dd
}|                                }i                                 D ](}d |                                D             |j        <   )|                    fdD                        fdt          d          D             }|                    |           g }|j        D ]}                    d|i          }	|	                    |          D ]Z}
|	                    d|
i          }d}|	
                                D ]} ||||	          rd}|s|                    ||
f           [|                    |           |S )aq   Builds a networkx DiGraph() G from the model M.


        G.nodes are the submodels of M, with node attributes
            - "model" giving the class name of of the submodel
            - "id" giving the id of the submodel

        An edge runs from a to b if the submodel b belongs to an attribute of
            a

        Args:
            A bokeh model M

        r   Nsr   ystrHr   boolc                T   d}d}d}	 | t          ||          v }n# t          t          f$ r Y nw xY w	 | t          ||          k    }n# t          t          f$ r Y nw xY w	 | t          ||                                          v }n# t          t
          t          f$ r Y nw xY w||z  |z  S )NF)getattr	TypeErrorr   valuesAttributeError
ValueError)rD   rE   rG   answer1answer2answer3s         r#   test_conditionz8_BokehStructureGraph._make_graph.<locals>.test_condition   s    !G!G!Gwq!}},/   wq!}},/   wq!}}33555"J@   W$w..s/    //A AA $B BBc                    h | ]	}|j         
S  r6   ).0rE   s     r#   	<setcomp>z3_BokehStructureGraph._make_graph.<locals>.<setcomp>   s    444qt444r$   c                Z    g | ]'}|d                      d|i          j        j        if(S )r"   r6   )
select_oner4   r5   )rV   xrB   s     r#   
<listcomp>z4_BokehStructureGraph._make_graph.<locals>.<listcomp>   s9    SSSAa'1<<q	22<EFGSSSr$   c                B    g | ]\  }}|         |         k    ||fS rT   rT   )rV   rZ   rE   Ts      r#   r[   z4_BokehStructureGraph._make_graph.<locals>.<listcomp>   s.    CCC1adadllaVlllr$      r6   FT)rD   r   rE   rF   rG   r   r   rH   )networkxDiGraph
referencesr6   add_nodes_fromr   add_edges_fromnodesrY   	neighbors
propertiesappendremove_edges_from)r;   rB   nxrR   KmE
dead_edgesr6   rG   rZ   rD   	keep_edgerE   r]   s    `            @r#   r,   z _BokehStructureGraph._make_graph   s    		/ 	/ 	/ 	/$ JJLL! 	5 	5A44Q\\^^444AadGG	SSSSQRSSS	
 	
 	
 DCCCQ 2 2CCC	
' 		/ 		/BdBZ((A[[__ / /LL$++!	 ) )A%~aA.. )$(	  /%%r1g.../ 	
J'''r$   objc                :                                    }fd|                                D             }fd|                                D             }t          |                                          t          |                                          ||d}|S )z Returns a pandas dataframe of the properties of a bokeh model

        Each row contains  an attribute, its type (a bokeh property), and its docstring.

        c                :    g | ]}                     |          S rT   )lookuprV   rZ   ro   s     r#   r[   z:_BokehStructureGraph._obj_props_to_df2.<locals>.<listcomp>   s#    8881A888r$   c                T    g | ]$}t          t                    |          j        %S rT   )rJ   type__doc__rs   s     r#   r[   z:_BokehStructureGraph._obj_props_to_df2.<locals>.<listcomp>   s,    GGG!S		1%%-GGGr$   )propsrL   typesdoc)properties_with_valueskeyslistrL   )r;   ro   obj_dictrx   docsdfs    `    r#   _obj_props_to_df2z&_BokehStructureGraph._obj_props_to_df2   s     --//8888888GGGGx}}GGG(--//**8??,,--	
 
 	r$   r   c                    ddl }|j                             j        d          }t	          |                                 \  }} fd|D             }t          |                                          }t          ||||d          }g }g }	 j        j	        D ]e\  }
}|
                    ||
         d         ||         d         gg           |	
                    ||
         d         ||         d         gg           ft          ||	d          }t          d	
          }t          t          |          t          |          z
  d          }t          t          |          t          |          z
  d          }t          t          |          d|z  z
  t          |          d|z  z             |_        t          t          |          d|z  z
  t          |          d|z  z             |_        t#          |t%          dddd          t%          dddd          t%          dddd                    }t#          |t'          dd                    }t)          ddg          }|g|_        t-                      }|g|_        t/          ddd|ddd          }t1          d d d!d!dd"d#$          }|                    |           |                    |           |                    |           |j        
                    ||t7                      t9                      t;                      g           |j                            |           | _        | _         |S )%z7 Builds the graph portion of the final model.

        r   Ndot)progc                @    g | ]}j         j        |         d          S )r"   )r-   rd   )rV   rZ   r;   s     r#   r[   z9_BokehStructureGraph._make_graph_plot.<locals>.<listcomp>   s(    ???A$+#A&w/???r$   )rZ   rE   indexr"      )xsysg        )outline_line_alpha   g333333?)startendrZ   rE      	lightblue)rZ   rE   size
fill_colorgreen)data_sourceglyphnonselection_glyphselection_glyphr   r   )r   r   )r6   z@index)r"   z@model)tooltipsr"   8pti   )rZ   rE   r8   sourcetext_font_sizex_offsety_offset   screenitalicz&Click on a model to see its attributes)rZ   rE   x_unitsy_unitsr   text_font_styler8   )!r_   	nx_agraphgraphviz_layoutr-   ziprL   r|   r{   r   edgesextendr   maxminr   x_rangey_ranger   r
   r   r   	renderersr   r   r   
add_layouttoolsr   r   r   rg   _node_source_edge_source)r;   ri   rd   node_xnode_ymodelsnode_idnode_sourceedge_x_coordsedge_y_coords
start_nodeend_nodeedge_sourcep2	xinterval	yintervalnode_rendereredge_renderernode_hover_tooltap_toollabelshelps   `                     r#   r0   z%_BokehStructureGraph._make_graph_plot   s    	,,T[u,EEellnn-???????uzz||$$&v&II
 
 $(K$5 	O 	O J  5#4Q#7x9K"L!MNNN  5#4Q#7x9K"L!MNNNN&m='Q'QRRS)))Fc&kk1377	Fc&kk1377	f++y 00c&kkD9DT6T
 
 

 f++y 00c&kkD9DT6T
 
 

 &#3#B;GGG%sTTT"SCbWMMM	
 
 
 &#9+F+F+F
 
 
 $.>@S-TUUU%2O!99+_ 
 
 
  $9
 
 
 	d
m$$$
m$$$
hy{{GIIN	
 	
 	
 	F###''	r$   pd.DataFramec                   ddl } |j                    }| j                            d          D ]}| j                            t          |d                             } |j        |                     |                    }|d         |d<   t          |          |d<   |d         	                    d	           |d<   |d
         	                    d           |d
<    |j
        ||g          }|S )z Returns a dataframe containing all the properties of all the submodels of the model being
        analyzed. Used as datasource to show attributes.

        r   NT)datarU   r6   r"   rL   c                     t          |           S NrF   rZ   s    r#   <lambda>z6_BokehStructureGraph._make_prop_dict.<locals>.<lambda>;  s    CFF r$   rx   c                     t          |           S r   r   r   s    r#   r   z6_BokehStructureGraph._make_prop_dict.<locals>.<lambda><  s    #a&& r$   )pandas	DataFramer-   rd   r+   rY   dictr   rF   mapconcat)r;   pdr   rZ   rB   Zs         r#   r.   z$_BokehStructureGraph._make_prop_dict/  s    
 	R\^^"""-- 	$ 	$A&&tqt}}}55AT33A6677AdAdGQAgJH+//*:*:;;AhK7(8(899AgJB7##BB	r$   r   c           	     ,   t          dd          t          dd          g}t          | j                  }| j        j        d         d         }t          d|	          }t          |
          }t          |||dddd          }|| _        || _	        |S )z: Builds the datatable portion of the final plot.

        rw   Property)fieldr7   rL   Valuer   r   r6   )column_namegroup)filterFNT)r   viewcolumnsvisibleindex_positionfit_columnseditable)
r   r   r/   r   r   r   r	   r   _groupfilter_prop_source)r;   r   prop_sourcemodel_idgroupfilterdata_table2_viewdata_table2s          r#   r2   z%_BokehStructureGraph._make_data_table@  s    
 gZ888hg666
 't}55$)'215!d(CCC"+666!
 
 
 ('r$   c                    d}t          t          | j        | j        | j        | j                  |          }| j        j                            d|           t          | j	        | j                  }|S )z Connects the graph and the datatable with a simple CustomJS callback.

        Clicking on a node/submodel narrows the view in the datatable to the
        attributes associated with that submodel.

        z            const index = node_source.selected.indices[0];
            f['group'] = node_source.data['index'][index];
            table['visible'] = true;
            prop_source.change.emit();
        )r   r   r   table)argscodeindices)
r   r   r   r   r   r3   selectedjs_on_changer   r1   )r;   js_codejslayouts       r#   r9   z_BokehStructureGraph._combined[  s      - -#&	   
 
 
 	"//	2>>>($*:;;r$   N)r"   r   r   r&   )r   r   )rB   r   )ro   r   )r   r   )r   r   )r   r   )r5   
__module____qualname__rv   r<   propertyr"   r*   rA   r,   r   r0   r.   r2   r9   rT   r$   r#   r!   r!   `   s         	1 	1 	1 	1 % % % X%   X   X9 9 9 9v   "K K K KZ   "   6     r$   r!   )r   r   r   r   )+rv   
__future__r   logging	getLoggerr5   log	itertoolsr   typingr   bokeh.core.propertiesr   bokeh.layoutsr   bokeh.modelsr   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   
core.typesr   r"   r   __all__r   r!   rT   r$   r#   <module>r      s   * # " " " " " g!! # " " " " "             2 1 1 1 1 1                                                   *         ') ) ) )V V V V V V V V V Vr$   