B
    @\H                 @   s   d Z ddlmZmZmZmZ ddlZee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mZmZmZ dd	lmZ d
Zdd Zdd Zdd Zdd Zd"ddZG dd de Z!dd Z"dd Z#d#ddZ$d d! Z%dS )$z0 Functions for arranging bokeh Layout objects.

    )absolute_importdivisionprint_functionunicode_literalsN   )Location
SizingMode)ProxyToolbar
ToolbarBox)Plot)	LayoutDOMRowColumnSpacer	WidgetBox)Widget)columngridplotGridSpeclayoutrow	widgetboxc              O   s   | dd}| dd}t| t| d|i}g }x<|D ]4}t|trX||_|| q8td|t|f q8W t	f ||d|S )a   Create a row of Bokeh Layout objects. Forces all objects to
    have the same sizing_mode, which is required for complex layouts to work.

    Args:
        children (list of :class:`~bokeh.models.layouts.LayoutDOM` ): A list of instances for
            the row. Can be any of the following - :class:`~bokeh.models.plots.Plot`,
            :class:`~bokeh.models.widgets.widget.Widget`, :class:`~bokeh.models.layouts.WidgetBox`,
            :class:`~bokeh.models.layouts.Row`,
            :class:`~bokeh.models.layouts.Column`,
            :class:`~bokeh.models.tools.ToolbarBox`,
            :class:`~bokeh.models.layouts.Spacer`.

        sizing_mode (``"fixed"``, ``"stretch_both"``, ``"scale_width"``, ``"scale_height"``, ``"scale_both"`` ): How
            will the items in the layout resize to fill the available space.
            Default is ``"fixed"``. For more information on the different
            modes see :attr:`~bokeh.models.layouts.LayoutDOM.sizing_mode`
            description on :class:`~bokeh.models.layouts.LayoutDOM`.

    Returns:
        Row: A row of LayoutDOM objects all with the same sizing_mode.

    Examples:

        >>> row([plot_1, plot_2])
        >>> row(children=[widget_box_1, plot_1], sizing_mode='stretch_both')
    sizing_modefixedchildrenNz_Only LayoutDOM items can be inserted into a row.
                Tried to insert: %s of type %s)r   r   )
pop_verify_sizing_mode_handle_children
isinstancer   r   append
ValueErrortyper   )argskwargsr   r   row_childrenitem r&   ,lib/python3.7/site-packages/bokeh/layouts.pyr   4   s    

r   c              O   s   | dd}| dd}t| t| d|i}g }x<|D ]4}t|trX||_|| q8td|t|f q8W t	f ||d|S )a   Create a column of Bokeh Layout objects. Forces all objects to
    have the same sizing_mode, which is required for complex layouts to work.

    Args:
        children (list of :class:`~bokeh.models.layouts.LayoutDOM` ): A list of instances for
            the column. Can be any of the following - :class:`~bokeh.models.plots.Plot`,
            :class:`~bokeh.models.widgets.widget.Widget`, :class:`~bokeh.models.layouts.WidgetBox`,
            :class:`~bokeh.models.layouts.Row`,
            :class:`~bokeh.models.layouts.Column`,
            :class:`~bokeh.models.tools.ToolbarBox`,
            :class:`~bokeh.models.layouts.Spacer`.

        sizing_mode (``"fixed"``, ``"stretch_both"``, ``"scale_width"``, ``"scale_height"``, ``"scale_both"`` ): How
            will the items in the layout resize to fill the available space.
            Default is ``"fixed"``. For more information on the different
            modes see :attr:`~bokeh.models.layouts.LayoutDOM.sizing_mode`
            description on :class:`~bokeh.models.layouts.LayoutDOM`.

    Returns:
        Column: A column of LayoutDOM objects all with the same sizing_mode.

    Examples:

        >>> column([plot_1, plot_2])
        >>> column(children=[widget_box_1, plot_1], sizing_mode='stretch_both')
    r   r   r   NzbOnly LayoutDOM items can be inserted into a column.
                Tried to insert: %s of type %s)r   r   )
r   r   r   r   r   r   r   r    r!   r   )r"   r#   r   r   Zcol_childrenr%   r&   r&   r'   r   c   s    

r   c              O   s   | dd}| dd}t| t| d|i}g }x<|D ]4}t|trX||_|| q8td|t|f q8W t	f ||d|S )a   Create a WidgetBox of Bokeh widgets. Forces all to
    have the same sizing_mode, which is required for complex layouts to work.

    Args:
        children (list of :class:`~bokeh.models.widgets.widget.Widget` ): A list
            of widgets for the WidgetBox.

        sizing_mode (``"fixed"``, ``"stretch_both"``, ``"scale_width"``, ``"scale_height"``, ``"scale_both"`` ): How
            will the items in the layout resize to fill the available space.
            Default is ``"fixed"``. For more information on the different
            modes see :attr:`~bokeh.models.layouts.LayoutDOM.sizing_mode`
            description on :class:`~bokeh.models.layouts.LayoutDOM`.

    Returns:
        WidgetBox: A WidgetBox of Widget instances all with the same sizing_mode.

    Examples:

        >>> widgetbox([button, select])
        >>> widgetbox(children=[slider], sizing_mode='scale_width')
    r   r   r   Nz]Only Widgets can be inserted into a WidgetBox.
                Tried to insert: %s of type %s)r   r   )
r   r   r   r   r   r   r   r    r!   r   )r"   r#   r   r   Zwidget_childrenr%   r&   r&   r'   r      s    

r   c              O   s8   | dd}| dd}t| t| d|i}t||S )a   Create a grid-based arrangement of Bokeh Layout objects. Forces all objects to
    have the same sizing mode, which is required for complex layouts to work. Returns a nested set
    of Rows and Columns.

    Args:
        children (list of lists of :class:`~bokeh.models.layouts.LayoutDOM` ): A list of lists of instances
            for a grid layout. Can be any of the following - :class:`~bokeh.models.plots.Plot`,
            :class:`~bokeh.models.widgets.widget.Widget`, :class:`~bokeh.models.layouts.WidgetBox`,
            :class:`~bokeh.models.layouts.Row`,
            :class:`~bokeh.models.layouts.Column`,
            :class:`~bokeh.models.tools.ToolbarBox`,
            :class:`~bokeh.models.layouts.Spacer`.

        sizing_mode (``"fixed"``, ``"stretch_both"``, ``"scale_width"``, ``"scale_height"``, ``"scale_both"`` ): How
            will the items in the layout resize to fill the available space.
            Default is ``"fixed"``. For more information on the different
            modes see :attr:`~bokeh.models.layouts.LayoutDOM.sizing_mode`
            description on :class:`~bokeh.models.layouts.LayoutDOM`.

    Returns:
        Column: A column of ``Row`` layouts of the children, all with the same sizing_mode.

    Examples:

        >>> layout([[plot_1, plot_2], [plot_3, plot_4]])
        >>> layout(
                children=[
                    [widget_box_1, plot_1],
                    [slider],
                    [widget_box_2, plot_2, plot_3]
                ],
                sizing_mode='fixed',
            )

    r   r   r   N)r   r   r   _create_grid)r"   r#   r   r   r&   r&   r'   r      s
    $r   r   aboveTc             C   s$  |dkri }t | |r.tt|s.td| t| d} |rdtdd | D rVtdtt| |} | slg } g }g }	x| D ]}
g }g }x|
D ]}|r|dk	rx*|t	t
dD ]}||jj }d|_qW |dkrd\}}x$|
D ]}t|t
r|j}|j}P qW t||d	}t|trP||_t|t
rD|r8||_|rD||_|| qtd
qW || }|	t||d q|W t|	|d}|s|S |rtf d|i|}t||d}|dkrt||g|dS |dkrt||g|dS |dkrt||g|dS |dkrt||g|dS |S dS )a
   Create a grid of plots rendered on separate canvases.

    The ``gridplot`` function builds a single toolbar for all the plots in the
    grid. ``gridplot`` is designed to layout a set of plots. For general
    grid layout, use the :func:`~bokeh.layouts.layout` function.

    Args:
        children (list of lists of :class:`~bokeh.models.plots.Plot` ): An
            array of plots to display in a grid, given as a list of lists of Plot
            objects. To leave a position in the grid empty, pass None for that
            position in the children list. OR list of :class:`~bokeh.models.plots.Plot` if called with
            ncols. OR an instance of GridSpec.

        sizing_mode (``"fixed"``, ``"stretch_both"``, ``"scale_width"``, ``"scale_height"``, ``"scale_both"`` ): How
            will the items in the layout resize to fill the available space.
            Default is ``"fixed"``. For more information on the different
            modes see :attr:`~bokeh.models.layouts.LayoutDOM.sizing_mode`
            description on :class:`~bokeh.models.layouts.LayoutDOM`.

        toolbar_location (``above``, ``below``, ``left``, ``right`` ): Where the
            toolbar will be located, with respect to the grid. Default is
            ``above``. If set to None, no toolbar will be attached to the grid.

        ncols (int, optional): Specify the number of columns you would like in your grid.
            You must only pass an un-nested list of plots (as opposed to a list of lists of plots)
            when using ncols.

        plot_width (int, optional): The width you would like all your plots to be

        plot_height (int, optional): The height you would like all your plots to be.

        toolbar_options (dict, optional) : A dictionary of options that will be
            used to construct the grid's toolbar (an instance of
            :class:`~bokeh.models.tools.ToolbarBox`). If none is supplied,
            ToolbarBox's defaults will be used.

        merge_tools (``True``, ``False``): Combine tools from all child plots into
            a single toolbar.

    Returns:
        Row or Column: A row or column containing the grid toolbar and the grid
            of plots (depending on whether the toolbar is left/right or
            above/below. The grid is always a Column of Rows of plots.

    Examples:

        >>> gridplot([[plot_1, plot_2], [plot_3, plot_4]])
        >>> gridplot([plot_1, plot_2, plot_3, plot_4], ncols=2, plot_width=200, plot_height=100)
        >>> gridplot(
                children=[[plot_1, plot_2], [None, plot_3]],
                toolbar_location='right'
                sizing_mode='fixed',
                toolbar_options=dict(logo='gray')
            )

    Nz%Invalid value of toolbar_location: %s)r   c             s   s   | ]}t |tV  qd S )N)r   list).0Zchildr&   r&   r'   	<genexpr>/  s    zgridplot.<locals>.<genexpr>z-Cannot provide a nested list when using ncols)r!   )r   r   )widthheightz.Only LayoutDOM items can be inserted into Grid)r   r   tools)toolbartoolbar_locationr)   Zbelowleftright)r   hasattrr   r    r   anyr*   _chunksZselectdictr   r0   r/   r1   r   
plot_widthplot_heightr   r   r   r   r   r   r	   r
   )r   r   r1   ncolsr8   r9   Ztoolbar_optionsZmerge_toolsr/   Zrowsr   Z	row_toolsr$   r%   Zplotr-   r.   ZneighborZgridproxyr0   r&   r&   r'   r      st    :










r   c               @   s(   e Zd ZdZdd Zdd Zdd ZdS )	r   z' Simplifies grid layout specification. c             C   s   || _ || _i | _d S )N)nrowsr:   _arrangement)selfr<   r:   r&   r&   r'   __init__t  s    zGridSpec.__init__c       	         s  |\}}t |tr&|| j\}}n6|dk r8|| j7 }|| jksJ|dk rRtd|d  }t |trz|| j\}}n6|dk r|| j7 }|| jks|dk rtd|d  }dd }|d kr|d kr؈| jf< n|d krxt|D ]$ | fddd | j f< qW n|d krZxt|D ]&|fddd | jf< q.W nJxHtt|t|D ].\ | fddd | j f< qrW d S )	Nr   zindex out of rangec             S   s    y|  S  t k
r   |S X d S )N)
IndexError)fndefaultr&   r&   r'   get_or_else  s    z)GridSpec.__setitem__.<locals>.get_or_elsec                  s      S )Nr&   r&   )colcol1objr&   r'   <lambda>  s    z&GridSpec.__setitem__.<locals>.<lambda>c                  s      S )Nr&   r&   )rF   r   row1r&   r'   rG     s    c                  s        S )Nr&   r&   )rD   rE   rF   r   rH   r&   r'   rG     s    )	r   sliceindicesr<   r@   r:   r=   rangezip)	r>   keyrF   Zk1Zk2Zrow2_Zcol2rC   r&   )rD   rE   rF   r   rH   r'   __setitem__y  s4    






&
( zGridSpec.__setitem__c                sJ    fddt d jD }x& j D ]\\}}}||| |< q&W t|S )Nc                s   g | ]}d g j  qS )N)r:   )r+   rN   )r>   r&   r'   
<listcomp>  s    z%GridSpec.__iter__.<locals>.<listcomp>r   )rK   r<   r=   itemsiter)r>   Zarrayr   rD   rF   r&   )r>   r'   __iter__  s    zGridSpec.__iter__N)__name__
__module____qualname____doc__r?   rO   rS   r&   r&   r&   r'   r   q  s   ,r   c              O   s~   | d}t| dkr&|d k	r&td|szt| dkrNt| d trN| d }n,t| dkrrt| d trr| d }nt| }|S )Nr   r   z;'children' keyword cannot be used with positional argumentsr   )getlenr    r   r*   r   )r"   r#   r   r&   r&   r'   r     s    


r   c             C   s   | t krtd|  d S )Nz Invalid value of sizing_mode: %s)r   r    )r   r&   r&   r'   r     s    r   c             C   s   g }x^| D ]V}t |tr0|t|||d  q
t |trL||_|| q
td|t|f q
W |d dkr|t||dS t	||dS )z)Recursively create grid from input lists.r   zbOnly LayoutDOM items can be inserted into a layout.
                Tried to insert: %s of type %s   r   )r   r   )
r   r*   r   r(   r   r   r    r!   r   r   )iterabler   ZlayerZreturn_listr%   r&   r&   r'   r(     s    


r(   c             c   sB   t |tstdx*tdt| |D ]}| |||  V  q$W dS )z-Yield successive n-sized chunks from list, l.zncols must be an integerr   N)r   intAssertionErrorrK   rY   )lr:   ir&   r&   r'   r6     s    r6   )r   r)   NNNNT)r   )&rW   Z
__future__r   r   r   r   ZloggingZ	getLoggerrT   logZ
core.enumsr   r   Zmodels.toolsr	   r
   Zmodels.plotsr   Zmodels.layoutsr   r   r   r   r   Zmodels.widgetsr   __all__r   r   r   r   r   objectr   r   r   r(   r6   r&   r&   r&   r'   <module>	   s*   
//*- 
 >
