예제 #1
0
파일: layout.py 프로젝트: verde2006/dtale
def charts_layout(df, settings, **inputs):
    """
    Builds main dash inputs with dropdown options populated with the columns of the dataframe associated with the
    page. Inputs included are: chart tabs, query, x, y, z, group, aggregation, rolling window/computation,
    chart per group toggle, bar sort, bar mode, y-axis range editors

    :param df: dataframe to drive the charts built on page
    :type df: :class:`pandas:pandas.DataFrame`
    :param settings: global settings associated with this dataframe (contains properties like "query")
    :type param: dict
    :return: dash markup
    """
    chart_type, x, y, z, group, agg = (
        inputs.get(p) for p in ['chart_type', 'x', 'y', 'z', 'group', 'agg'])
    y = y or []
    show_input = show_input_handler(chart_type)
    show_cpg = show_chart_per_group(**inputs)
    show_yaxis = show_yaxis_ranges(**inputs)
    bar_style = bar_input_style(**inputs)
    animate_style, animate_by_style, animate_opts = animate_styles(
        df, **inputs)

    options = build_input_options(df, **inputs)
    x_options, y_multi_options, y_single_options, z_options, group_options, barsort_options, yaxis_options = options
    query_placeholder = ("Enter pandas query (ex: col1 == 1)")
    query_value = inputs.get('query') or inner_build_query(
        settings, settings.get('query'))
    query_label = html.Div([
        html.Span('Query'),
        html.
        A(html.I(className='fa fa-info-circle ml-4'),
          href=
          'https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#indexing-query',
          target='_blank',
          style={'color': 'white'})
    ],
                           className='input-group-addon',
                           style={'minWidth': '7em'})
    yaxis_type = (inputs.get('yaxis') or {}).get('type') or 'default'
    yaxis_type_style = {
        'borderRadius': '0 0.25rem 0.25rem 0'
    } if yaxis_type == 'default' else None
    show_map = chart_type == 'maps'
    map_props = ['map_type', 'loc_mode', 'loc', 'lat', 'lon', 'map_val']
    map_type, loc_mode, loc, lat, lon, map_val = (inputs.get(p)
                                                  for p in map_props)
    map_scope, proj = (inputs.get(p) for p in ['scope', 'proj'])
    loc_options, lat_options, lon_options, map_val_options = build_map_options(
        df, type=map_type, loc=loc, lat=lat, lon=lon, map_val=map_val)
    cscale_style = colorscale_input_style(**inputs)
    default_cscale = 'Greens' if chart_type == 'heatmap' else 'Reds'

    group_val_style, main_input_class = main_inputs_and_group_val_display(
        inputs)
    group_val = [json.dumps(gv) for gv in inputs.get('group_val') or []]

    def show_style(show):
        return {'display': 'block' if show else 'none'}

    def show_map_style(show):
        return {} if show else {'display': 'none'}

    return html.Div([
        dcc.Store(id='query-data', data=inputs.get('query')),
        dcc.Store(id='input-data',
                  data={
                      k: v
                      for k, v in inputs.items()
                      if k not in ['cpg', 'barmode', 'barsort']
                  }),
        dcc.Store(id='chart-input-data',
                  data={
                      k: v
                      for k, v in inputs.items()
                      if k in ['cpg', 'barmode', 'barsort']
                  }),
        dcc.Store(id='map-input-data',
                  data={
                      k: v
                      for k, v in inputs.items() if k in [
                          'map_type', 'map_code', 'lat', 'lon', 'map_val',
                          'scope', 'proj'
                      ]
                  }),
        dcc.Store(id='range-data'),
        dcc.Store(id='yaxis-data', data=inputs.get('yaxis')),
        dcc.Store(id='last-chart-input-data', data=inputs),
        dcc.Input(id='chart-code', type='hidden'),
        html.Div(html.Div(dcc.Tabs(
            id='chart-tabs',
            value=chart_type or 'line',
            children=[
                build_tab(t.get('label', t['value'].capitalize()), t['value'])
                for t in CHARTS
            ],
            style=dict(height='36px')),
                          className='col-md-12'),
                 className='row pt-3 pb-3 charts-filters'),
        html.Div(html.Div([
            html.Div([
                query_label,
                dcc.Input(id='query-input',
                          type='text',
                          placeholder=query_placeholder,
                          className='form-control',
                          value=query_value,
                          style={'lineHeight': 'inherit'})
            ],
                     className='input-group mr-3')
        ],
                          className='col'),
                 className='row pt-3 pb-3 charts-filters'),
        html.Div([
            html.Div([
                html.Div([
                    build_input(
                        [html.Div('X'), html.Small('(Agg By)')],
                        dcc.Dropdown(
                            id='x-dropdown',
                            options=x_options,
                            placeholder='Select a column',
                            value=x,
                            style=dict(width='inherit'),
                        ),
                        label_class='input-group-addon d-block pt-1 pb-0'),
                    build_input('Y',
                                dcc.Dropdown(id='y-multi-dropdown',
                                             options=y_multi_options,
                                             multi=True,
                                             placeholder='Select a column(s)',
                                             style=dict(width='inherit'),
                                             value=y if show_input(
                                                 'y', 'multi') else None),
                                className='col',
                                id='y-multi-input',
                                style=show_style(show_input('y', 'multi'))),
                    build_input(
                        [html.Div('Y'), html.Small('(Agg By)')],
                        dcc.Dropdown(id='y-single-dropdown',
                                     options=y_single_options,
                                     placeholder='Select a column',
                                     style=dict(width='inherit'),
                                     value=y[0]
                                     if show_input('y') and len(y) else None),
                        className='col',
                        label_class='input-group-addon d-block pt-1 pb-0',
                        id='y-single-input',
                        style=show_style(show_input('y'))),
                    build_input('Z',
                                dcc.Dropdown(id='z-dropdown',
                                             options=z_options,
                                             placeholder='Select a column',
                                             style=dict(width='inherit'),
                                             value=z),
                                className='col',
                                id='z-input',
                                style=show_style(show_input('z'))),
                    build_input('Group',
                                dcc.Dropdown(
                                    id='group-dropdown',
                                    options=group_options,
                                    multi=True,
                                    placeholder='Select a group(s)',
                                    value=group,
                                    style=dict(width='inherit'),
                                ),
                                className='col',
                                id='group-input',
                                style=show_style(show_input('group')))
                ],
                         id='non-map-inputs',
                         style={} if not show_map else {'display': 'none'},
                         className='row pt-3 pb-3 charts-filters'),
                html.Div([
                    build_map_type_tabs(map_type),
                    html.Div([
                        html.Div(
                            [
                                build_loc_mode_hover(loc_mode),
                                dcc.Dropdown(id='map-loc-mode-dropdown',
                                             options=[
                                                 build_option(v) for v in [
                                                     "ISO-3", "USA-states",
                                                     "country names"
                                                 ]
                                             ],
                                             style=dict(width='inherit'),
                                             value=loc_mode)
                            ],
                            className='input-group mr-3',
                        )
                    ],
                             id='map-loc-mode-input',
                             style=show_map_style(map_type == 'choropleth'),
                             className='col-auto'),
                    build_input(
                        [html.Div('Locations'),
                         html.Small('(Agg By)')],
                        dcc.Dropdown(
                            id='map-loc-dropdown',
                            options=loc_options,
                            placeholder='Select a column',
                            value=loc,
                            style=dict(width='inherit'),
                        ),
                        id='map-loc-input',
                        label_class='input-group-addon d-block pt-1 pb-0',
                        style=show_map_style(map_type == 'choropleth')),
                    build_input(
                        [html.Div('Lat'),
                         html.Small('(Agg By)')],
                        dcc.Dropdown(
                            id='map-lat-dropdown',
                            options=lat_options,
                            placeholder='Select a column',
                            value=lat,
                            style=dict(width='inherit'),
                        ),
                        id='map-lat-input',
                        label_class='input-group-addon d-block pt-1 pb-0',
                        style=show_map_style(map_type == 'scattergeo')),
                    build_input(
                        [html.Div('Lon'),
                         html.Small('(Agg By)')],
                        dcc.Dropdown(id='map-lon-dropdown',
                                     options=lon_options,
                                     placeholder='Select a column',
                                     style=dict(width='inherit'),
                                     value=lon),
                        id='map-lon-input',
                        label_class='input-group-addon d-block pt-1 pb-0',
                        style=show_map_style(map_type == 'scattergeo')),
                    build_input(
                        'Scope',
                        dcc.Dropdown(id='map-scope-dropdown',
                                     options=[build_option(v) for v in SCOPES],
                                     style=dict(width='inherit'),
                                     value=map_scope or 'world'),
                        id='map-scope-input',
                        style=show_map_style(map_type == 'scattergeo')),
                    html.Div([
                        html.Div(
                            [
                                build_proj_hover(proj),
                                dcc.Dropdown(id='map-proj-dropdown',
                                             options=[
                                                 build_option(v)
                                                 for v in PROJECTIONS
                                             ],
                                             style=dict(width='inherit'),
                                             value=proj)
                            ],
                            className='input-group mr-3',
                        )
                    ],
                             id='map-proj-input',
                             style=show_map_style(map_type == 'scattergeo'),
                             className='col-auto'),
                    build_input(
                        'Value',
                        dcc.Dropdown(id='map-val-dropdown',
                                     options=map_val_options,
                                     placeholder='Select a column',
                                     style=dict(width='inherit'),
                                     value=map_val)),
                    build_input('Group',
                                dcc.Dropdown(
                                    id='map-group-dropdown',
                                    options=group_options,
                                    multi=True,
                                    placeholder='Select a group(s)',
                                    value=inputs.get('map_group'),
                                    style=dict(width='inherit'),
                                ),
                                className='col',
                                id='map-group-input')
                ],
                         id='map-inputs',
                         className='row pt-3 pb-3 charts-filters',
                         style={} if show_map else {'display': 'none'}),
                html.Div([
                    build_input(
                        'Aggregation',
                        dcc.Dropdown(
                            id='agg-dropdown',
                            options=[
                                build_option(v, AGGS[v]) for v in [
                                    'count', 'nunique', 'sum', 'mean',
                                    'rolling', 'corr', 'first', 'last',
                                    'median', 'min', 'max', 'std', 'var',
                                    'mad', 'prod', 'raw'
                                ]
                            ],
                            placeholder='Select an aggregation',
                            style=dict(width='inherit'),
                            value=agg or 'raw',
                        )),
                    html.Div([
                        build_input(
                            'Window',
                            dcc.Input(id='window-input',
                                      type='number',
                                      placeholder='Enter days',
                                      className='form-control text-center',
                                      style={'lineHeight': 'inherit'},
                                      value=inputs.get('window'))),
                        build_input(
                            'Computation',
                            dcc.Dropdown(id='rolling-comp-dropdown',
                                         options=[
                                             build_option(
                                                 'corr', 'Correlation'),
                                             build_option('count', 'Count'),
                                             build_option('cov', 'Covariance'),
                                             build_option('kurt', 'Kurtosis'),
                                             build_option('max', 'Maximum'),
                                             build_option('mean', 'Mean'),
                                             build_option('median', 'Median'),
                                             build_option('min', 'Minimum'),
                                             build_option('skew', 'Skew'),
                                             build_option(
                                                 'std', 'Standard Deviation'),
                                             build_option('sum', 'Sum'),
                                             build_option('var', 'Variance'),
                                         ],
                                         placeholder='Select an computation',
                                         style=dict(width='inherit'),
                                         value=inputs.get('rolling_comp')))
                    ],
                             id='rolling-inputs',
                             style=show_style(agg == 'rolling'))
                ],
                         className='row pt-3 pb-3 charts-filters'),
                html.Div([
                    build_input('Chart Per\nGroup',
                                html.Div(daq.BooleanSwitch(id='cpg-toggle',
                                                           on=inputs.get('cpg')
                                                           or False),
                                         className='toggle-wrapper'),
                                id='cpg-input',
                                style=show_style(show_cpg),
                                className='col-auto'),
                    build_input('Barmode',
                                dcc.Dropdown(
                                    id='barmode-dropdown',
                                    options=[
                                        build_option('group', 'Group'),
                                        build_option('stack', 'Stack'),
                                        build_option('relative', 'Relative'),
                                    ],
                                    value=inputs.get('barmode') or 'group',
                                    placeholder='Select a mode',
                                ),
                                className='col-auto addon-min-width',
                                style=bar_style,
                                id='barmode-input'),
                    build_input('Barsort',
                                dcc.Dropdown(id='barsort-dropdown',
                                             options=barsort_options,
                                             value=inputs.get('barsort')),
                                className='col-auto addon-min-width',
                                style=bar_style,
                                id='barsort-input'),
                    html.Div(html.Div(
                        [
                            html.Span('Y-Axis', className='input-group-addon'),
                            html.Div(dcc.Tabs(
                                id='yaxis-type',
                                value=yaxis_type,
                                children=get_yaxis_type_tabs(y),
                            ),
                                     id='yaxis-type-div',
                                     className='form-control col-auto pt-3',
                                     style=yaxis_type_style),
                            dcc.Dropdown(id='yaxis-dropdown',
                                         options=yaxis_options),
                            html.Span('Min:',
                                      className='input-group-addon col-auto',
                                      id='yaxis-min-label'),
                            dcc.Input(id='yaxis-min-input',
                                      type='number',
                                      className='form-control col-auto',
                                      style={'lineHeight': 'inherit'}),
                            html.Span('Max:',
                                      className='input-group-addon col-auto',
                                      id='yaxis-max-label'),
                            dcc.Input(id='yaxis-max-input',
                                      type='number',
                                      className='form-control col-auto',
                                      style={'lineHeight': 'inherit'})
                        ],
                        className='input-group',
                        id='yaxis-min-max-options',
                    ),
                             className='col-auto addon-min-width',
                             id='yaxis-input',
                             style=show_style(show_yaxis)),
                    build_input(
                        'Colorscale',
                        dcc.Dropdown(
                            id='colorscale-dropdown',
                            options=[build_option(o) for o in COLORSCALES],
                            value=inputs.get('colorscale') or default_cscale),
                        className='col-auto addon-min-width',
                        style=cscale_style,
                        id='colorscale-input'),
                    build_input('Animate',
                                html.Div(daq.BooleanSwitch(
                                    id='animate-toggle',
                                    on=inputs.get('animate') or False),
                                         className='toggle-wrapper'),
                                id='animate-input',
                                style=animate_style,
                                className='col-auto'),
                    build_input('Animate By',
                                dcc.Dropdown(id='animate-by-dropdown',
                                             options=animate_opts,
                                             value=inputs.get('animate_by')),
                                className='col-auto addon-min-width',
                                style=animate_style,
                                id='animate-by-input'),
                ],
                         className='row pt-3 pb-5 charts-filters')
            ],
                     id='main-inputs',
                     className=main_input_class),
            build_input('Group(s)',
                        dcc.Dropdown(
                            id='group-val-dropdown',
                            multi=True,
                            placeholder='Select a group value(s)',
                            value=group_val,
                            style=dict(width='inherit'),
                        ),
                        className='col-md-4 pt-3 pb-5',
                        id='group-val-input',
                        style=group_val_style)
        ],
                 className='row'),
        dcc.Loading(html.Div(id='chart-content', style={'height': '69vh'}),
                    type='circle'),
        dcc.Textarea(id="copy-text",
                     style=dict(position='absolute', left='-110%'))
    ],
                    className='charts-body')
예제 #2
0
파일: layout.py 프로젝트: hiwire03/dtale
def charts_layout(df, settings, **inputs):
    """
    Builds main dash inputs with dropdown options populated with the columns of the dataframe associated with the
    page. Inputs included are: chart tabs, query, x, y, z, group, aggregation, rolling window/computation,
    chart per group toggle, bar sort, bar mode, y-axis range editors

    :param df: dataframe to drive the charts built on page
    :type df: :class:`pandas:pandas.DataFrame`
    :param settings: global settings associated with this dataframe (contains properties like "query")
    :type param: dict
    :return: dash markup
    """
    [chart_type, x, y, z, group, agg] = [inputs.get(p) for p in ['chart_type', 'x', 'y', 'z', 'group', 'agg']]
    y = y or []
    show_input = show_input_handler(chart_type)
    show_cpg = show_chart_per_group(**inputs)
    show_yaxis = show_yaxis_ranges(**inputs)
    bar_style = bar_input_style(**inputs)

    options = build_input_options(df, **inputs)
    x_options, y_multi_options, y_single_options, z_options, group_options, barsort_options, yaxis_options = options
    query_placeholder = (
        "Enter pandas query (ex: col1 == 1)"
    )
    query_value = inputs.get('query') or inner_build_query(settings, settings.get('query'))
    query_label = html.Div([
        html.Span('Query'),
        html.A(html.I(className='fa fa-info-circle ml-4'),
               href='https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#indexing-query',
               target='_blank', style={'color': 'white'})
    ], className='input-group-addon', style={'minWidth': '7em'})
    yaxis_type = (inputs.get('yaxis') or {}).get('type') or 'default'
    yaxis_type_style = {'borderRadius': '0 0.25rem 0.25rem 0'} if yaxis_type == 'default' else None
    return html.Div([
        dcc.Store(id='query-data', data=inputs.get('query')),
        dcc.Store(id='input-data', data={k: v for k, v in inputs.items() if k not in ['cpg', 'barmode', 'barsort']}),
        dcc.Store(id='chart-input-data', data={k: v for k, v in inputs.items() if k in ['cpg', 'barmode', 'barsort']}),
        dcc.Store(id='range-data'),
        dcc.Store(id='yaxis-data', data=inputs.get('yaxis')),
        dcc.Store(id='last-chart-input-data', data=inputs),
        dcc.Input(id='chart-code', type='hidden'),
        html.Div(html.Div(dcc.Tabs(
            id='chart-tabs',
            value=chart_type or 'line',
            children=[build_tab(t.get('label', t['value'].capitalize()), t['value']) for t in CHARTS],
            style=dict(height='36px')
        ), className='col-md-12'), className='row pt-3 pb-3 charts-filters'),
        html.Div(html.Div([
            html.Div([
                query_label, dcc.Input(
                    id='query-input', type='text', placeholder=query_placeholder, className='form-control',
                    value=query_value, style={'lineHeight': 'inherit'})
            ], className='input-group mr-3')],
            className='col'
        ), className='row pt-3 pb-3 charts-filters'),
        html.Div([
            build_input('X', dcc.Dropdown(
                id='x-dropdown',
                options=x_options,
                placeholder='Select a column',
                value=x,
                style=dict(width='inherit'),
            )),
            build_input('Y', dcc.Dropdown(
                id='y-multi-dropdown',
                options=y_multi_options,
                multi=True,
                placeholder='Select a column(s)',
                style=dict(width='inherit'),
                value=y if show_input('y', 'multi') else None
            ), className='col', id='y-multi-input', style={'display': 'block' if show_input('y', 'multi') else 'none'}),
            build_input('Y', dcc.Dropdown(
                id='y-single-dropdown',
                options=y_single_options,
                placeholder='Select a column',
                style=dict(width='inherit'),
                value=y[0] if show_input('y') and len(y) else None
            ), className='col', id='y-single-input', style={'display': 'block' if show_input('y') else 'none'}),
            build_input('Z', dcc.Dropdown(
                id='z-dropdown',
                options=z_options,
                placeholder='Select a column',
                style=dict(width='inherit'),
                value=z
            ), className='col', id='z-input', style={'display': 'block' if show_input('z') else 'none'}),
            build_input('Group', dcc.Dropdown(
                id='group-dropdown',
                options=group_options,
                multi=True,
                placeholder='Select a group(s)',
                value=group,
                style=dict(width='inherit'),
            ), className='col', id='group-input', style={'display': 'block' if show_input('group') else 'none'}),
        ], className='row pt-3 pb-3 charts-filters'),
        html.Div([
            build_input('Aggregation', dcc.Dropdown(
                id='agg-dropdown',
                options=[build_option(v, AGGS[v]) for v in ['count', 'nunique', 'sum', 'mean', 'rolling', 'corr',
                                                            'first', 'last', 'median', 'min', 'max', 'std', 'var',
                                                            'mad', 'prod']],
                placeholder='Select an aggregation',
                style=dict(width='inherit'),
                value=agg,
            )),
            html.Div([
                build_input('Window', dcc.Input(
                    id='window-input', type='number', placeholder='Enter days', className='form-control text-center',
                    style={'lineHeight': 'inherit'}, value=inputs.get('window')
                )),
                build_input('Computation', dcc.Dropdown(
                    id='rolling-comp-dropdown',
                    options=[
                        build_option('corr', 'Correlation'),
                        build_option('count', 'Count'),
                        build_option('cov', 'Covariance'),
                        build_option('kurt', 'Kurtosis'),
                        build_option('max', 'Maximum'),
                        build_option('mean', 'Mean'),
                        build_option('median', 'Median'),
                        build_option('min', 'Minimum'),
                        build_option('skew', 'Skew'),
                        build_option('std', 'Standard Deviation'),
                        build_option('sum', 'Sum'),
                        build_option('var', 'Variance'),
                    ],
                    placeholder='Select an computation',
                    style=dict(width='inherit'), value=inputs.get('rolling_comp')
                ))
            ], id='rolling-inputs', style=dict(display='block' if agg == 'rolling' else 'none'))
        ], className='row pt-3 pb-3 charts-filters'),
        html.Div(
            [
                build_input('Chart Per\nGroup',
                            html.Div(daq.BooleanSwitch(id='cpg-toggle', on=inputs.get('cpg') or False),
                                     className='toggle-wrapper'),
                            id='cpg-input', style={'display': 'block' if show_cpg else 'none'}, className='col-auto'),
                build_input('Barmode', dcc.Dropdown(
                    id='barmode-dropdown',
                    options=[
                        build_option('group', 'Group'),
                        build_option('stack', 'Stack'),
                        build_option('relative', 'Relative'),
                    ],
                    value=inputs.get('barmode') or 'group',
                    placeholder='Select a mode',
                ), className='col-auto addon-min-width', style=bar_style, id='barmode-input'),
                build_input('Barsort', dcc.Dropdown(
                    id='barsort-dropdown', options=barsort_options, value=inputs.get('barsort')
                ), className='col-auto addon-min-width', style=bar_style, id='barsort-input'),
                html.Div(
                    html.Div(
                        [
                            html.Span('Y-Axis', className='input-group-addon'),
                            html.Div(dcc.Tabs(
                                id='yaxis-type',
                                value=yaxis_type,
                                children=get_yaxis_type_tabs(y),
                            ), id='yaxis-type-div', className='form-control col-auto pt-3', style=yaxis_type_style),
                            dcc.Dropdown(id='yaxis-dropdown', options=yaxis_options),
                            html.Span('Min:', className='input-group-addon col-auto', id='yaxis-min-label'),
                            dcc.Input(
                                id='yaxis-min-input', type='number', className='form-control col-auto',
                                style={'lineHeight': 'inherit'}
                            ),
                            html.Span('Max:', className='input-group-addon col-auto', id='yaxis-max-label'),
                            dcc.Input(
                                id='yaxis-max-input', type='number', className='form-control col-auto',
                                style={'lineHeight': 'inherit'}
                            )
                        ],
                        className='input-group', id='yaxis-min-max-options',
                    ),
                    className='col-auto addon-min-width', id='yaxis-input',
                    style=dict(display='block' if show_yaxis else 'none')
                ),
            ],
            className='row pt-3 pb-5 charts-filters'
        ),
        dcc.Loading(html.Div(id='chart-content', style={'height': '69vh'}), type='circle'),
        dcc.Textarea(id="copy-text", style=dict(position='absolute', left='-110%'))
    ], className='charts-body')