def build_input(label, input, className="col-auto", label_class="input-group-addon", **kwargs): """ Helper function to build a standard label/input component in dash. :param label: name of the input you are displaying :type label: str :param input: dash component for storing state :param className: style class to be applied to encapsulating div :type className: str :param kwargs: Optional keyword arguments to be applied to encapsulating div (style, title, id...) :type kwargs: dict :return: dash components for label/input :rtype: :dash:`dash_html_components.Div <dash-html-components/div>` """ return html.Div([ html.Div( [html.Span(label, className=label_class)] + make_list(input), className="input-group mr-3", ) ], className=className, **kwargs)
def build_modal(map_type, loc_mode): return html.Div( [ html.Div( html.Span( html.Span(text("GeoJSON Options"), style=dict(whiteSpace="pre-line")), className="input-group-addon d-block pt-1 pb-0 pointer", ), className="input-group mr-3", id="open-geojson-modal", ), dbc.Modal( [ dbc.ModalHeader(text("Custom GeoJSON Options")), dbc.ModalBody(build_geojson_upload(loc_mode)), dbc.ModalFooter( dbc.Button(text("Close"), id="close-geojson-modal", className="ml-auto")), ], id="geojson-modal", size="lg", centered=True, ), ], className="col-auto", style={} if map_type == "choropleth" and loc_mode == "geojson-id" else {"display": "none"}, id="custom-geojson-input", )
def add_dash(server): """ Adds dash support to main D-Tale Flask process. :param server: main D-Tale Flask process :type server: :class:`flask:flask.Flask` :return: server with dash added :rtype: :class:`flask:flask.Flask` """ dash_app = DtaleDash(server=server, routes_pathname_prefix="/dtale/charts/", eager_loading=True) # Since we're adding callbacks to elements that don't exist in the app.layout, # Dash will raise an exception to warn us that we might be # doing something wrong. # In this case, we're adding the elements through a callback, so we can ignore # the exception. dash_app.config.suppress_callback_exceptions = True dash_app.layout = html.Div( [dcc.Location(id="url", refresh=False), html.Div(id="popup-content")]) dash_app.scripts.config.serve_locally = True dash_app.css.config.serve_locally = True init_callbacks(dash_app) return dash_app.server
def build_modal(ext_aggs, chart_type, y): return [ build_hoverable( html.I( className="ico-settings pointer", id="open-extended-agg-modal", style=show_style(chart_type not in NON_EXT_AGGREGATION and len(y)), ), html.Div(html.Span(text("ext_agg_desc")), id="extended-aggregation-tooltip"), hover_class="saved-chart-config", top="100%", additional_classes="mb-auto mt-auto", ), dcc.Store(id="extended-aggregations", data=ext_aggs), dcc.Store(id="prev-open-extended-agg-modal", data=0), dcc.Store(id="prev-close-extended-agg-modal", data=0), dcc.Store(id="prev-clear-extended-agg-modal", data=0), dcc.Store(id="prev-apply-extended-agg-modal", data=0), dbc.Modal( [ dbc.ModalHeader( html.Div( [ html.Div( text("Extended Aggregations"), className="col mt-auto mb-auto", ), html.Button( html.Span("X"), className="close mr-5", id="close-extended-agg-modal", ), ], className="row", )), dbc.ModalBody(build_body(ext_aggs)), dbc.ModalFooter([ dbc.Button( text("Clear"), id="clear-extended-agg-modal", className="ml-auto", ), dbc.Button( text("Apply"), id="apply-extended-agg-modal", ), ]), ], id="extended-agg-modal", size="lg", centered=True, ), ]
def build_error(error): return html.Div( [ html.I(className="ico-error"), html.Span(error), ], className="dtale-alert alert alert-danger", )
def build_hoverable( content, hoverable_content, hover_class="map-types", top="50%", additional_classes="", ): return html.Div( [ content, html.Div( hoverable_content, className="hoverable__content {}".format(hover_class), style=dict(top=top), ), ], style=dict(borderBottom="none"), className="hoverable {}".format(additional_classes), )
def build_layout(): return flatten_lists([[ dcc.Store(id="saved-chart-config-{}".format(i)), dcc.Store(id="prev-saved-chart-config-{}".format(i)), dcc.Store(id="saved-deletes-{}".format(i), data=0), html.Div( [ html.Div( [ html.H3( "{} {}".format(text("Saved Chart"), i), className="col-auto pr-3", ), html.Div( id="saved-chart-header-{}".format(i), className="col pl-0", ), html.Div( dbc.Button( text("Delete"), id="delete-saved-btn-{}".format(i), color="primary", className="delete-chart", ), className="col-auto", ), ], className="row", ), html.Div(id="saved-chart-{}".format(i)), ], id="saved-chart-div-{}".format(i), className="saved-chart-div pt-5", style=dict(display="none"), ), ] for i in SAVED_CHART_IDS])
def display_page(pathname, search): """ dash callback which gets called on initial load of each dash page (main & popup) """ dash_app.config.suppress_callback_exceptions = False if pathname is None: raise PreventUpdate params = chart_url_params(search) params["data_id"] = params.get("data_id") or get_data_id(pathname) df = global_state.get_data(params["data_id"]) settings = global_state.get_settings(params["data_id"]) or {} return html.Div( charts_layout(df, settings, **params) + saved_charts.build_layout(), className="charts-body", )
def build_drilldown_modal(idx): return dbc.Modal( [ dbc.ModalHeader( html.Div( [ html.Div( text("Chart Drilldown"), className="col mt-auto mb-auto", id="drilldown-modal-header-{}".format(idx), ), html.Button( html.Span("X"), className="close mr-5", id="close-drilldown-modal-header-{}".format(idx), ), ], className="row", )), dbc.ModalBody( dcc.Loading( [ html.Div( [ html.Div( dcc.Tabs( id="drilldown-chart-type-{}".format( idx), value="histogram", children=[ build_tab(t.capitalize(), t) for t in ["histogram", "bar"] ], style=dict(height="36px"), ), className="col-md-4", ), build_input( "X", dcc.Dropdown( id="drilldown-x-dropdown-{}".format( idx), options=[], placeholder="Select a column", value=None, style=dict(width="inherit"), className="drilldown-x-dropdown", ), id="drilldown-x-input-{}".format(idx), style=dict(display="none"), ), ], className="row pt-3 pb-5", ), html.Div(id="drilldown-content-{}".format(idx)), ], type="circle", )), dbc.ModalFooter( dbc.Button( text("Close"), id="close-drilldown-modal-{}".format(idx), className="ml-auto", )), ], id="drilldown-modal-{}".format(idx), size="lg", centered=True, className="drilldown-modal", )
def on_data( _ts1, _ts2, _ts3, _ts4, _ts5, _ts6, _ts7, _ts8, _ts9, _ts10, load_clicks, inputs, chart_inputs, yaxis_data, map_data, cs_data, treemap_data, funnel_data, clustergram_data, pareto_data, last_chart_inputs, auto_load, prev_load_clicks, ext_aggs, ): """ dash callback controlling the building of dash charts """ all_inputs = dict_merge( inputs, chart_inputs, dict(yaxis=yaxis_data or {}), map_data, cs_data, treemap_data, funnel_data, clustergram_data, pareto_data, dict(extended_aggregation=ext_aggs or []) if inputs.get("chart_type") not in NON_EXT_AGGREGATION else {}, ) if not auto_load and load_clicks == prev_load_clicks: raise PreventUpdate if all_inputs == last_chart_inputs: raise PreventUpdate if is_app_root_defined(dash_app.server.config.get("APPLICATION_ROOT")): all_inputs["app_root"] = dash_app.server.config["APPLICATION_ROOT"] charts, range_data, code = build_chart(**all_inputs) agg_disabled = len(ext_aggs) > 0 ext_agg_tt = text("ext_agg_desc") ext_agg_warning = show_style(agg_disabled) if agg_disabled: ext_agg_tt = html.Div([ html.Span(text("ext_agg_desc")), html.Br(), html.Ul([ html.Li( extended_aggregations.build_extended_agg_desc(ext_agg), className="mb-0", ) for ext_agg in ext_aggs ]), ]) final_cols = build_final_cols( make_list(inputs.get("y")), inputs.get("z"), inputs.get("agg"), ext_aggs if inputs.get("chart_type") not in NON_EXT_AGGREGATION else [], ) return ( charts, all_inputs, range_data, build_final_chart_code(code), get_yaxis_type_tabs(final_cols), load_clicks, dict(display="block" if valid_chart(**all_inputs) else "none"), agg_disabled, ext_agg_tt, ext_agg_warning, )
def build_body(ext_aggs): col_inputs = [html.Div(id="extended-agg-errors")] for i in INPUT_IDS: ext_agg = ext_aggs[i - 1] if len(ext_aggs) >= i else {} col_inputs.append( html.Div( [ html.Span( "{}.".format(i), className="col-auto pr-0 mt-auto mb-auto ext-agg-id", ), build_input( text("Col"), dcc.Dropdown( id="col-dropdown-{}".format(i), placeholder=text("Select"), style=dict(width="inherit"), value=ext_agg.get("col"), ), className="col-md-3", ), build_input( text("Agg"), dcc.Dropdown( id="agg-dropdown-{}".format(i), options=[ build_option(v, text(AGGS[v])) for v in [ "count", "nunique", "sum", "mean", "rolling", "corr", "first", "last", # "drop_duplicates", "median", "min", "max", "std", "var", "mad", "prod", "pctsum", "pctct", ] ], placeholder=text("Select"), style=dict(width="inherit"), value=ext_agg.get("agg"), ), className="col-md-3", ), html.Div( [ build_input( text("Window"), dcc.Input( id="window-input-{}".format(i), type="number", placeholder=text("Enter Days"), className="form-control text-center", style={"lineHeight": "inherit"}, value=ext_agg.get("window"), ), className="col-md-6", ), build_input( text("Computation"), dcc.Dropdown( id="rolling-comp-dropdown-{}".format(i), options=[ build_option("corr", text("Correlation")), build_option("count", text("Count")), build_option("cov", text("Covariance")), build_option("kurt", text("Kurtosis")), build_option("max", text("Maximum")), build_option("mean", text("Mean")), build_option("median", text("Median")), build_option("min", text("Minimum")), build_option("skew", text("Skew")), build_option( "std", text("Standard Deviation"), ), build_option("sum", text("Sum")), build_option("var", text("Variance")), ], placeholder=text("Select"), style=dict(width="inherit"), value=ext_agg.get("rolling_comp"), ), className="col-md-6 pl-0", ), ], id="rolling-inputs-{}".format(i), style=show_style(ext_agg.get("agg") == "rolling", display_style="inherit"), className="col-md-6 row p-0", ), ], className="row pb-3", )) return html.Div(col_inputs, id="extended-agg-body")
def build_geojson_upload(loc_mode, geojson_key=None, featureidkey=None): curr_geojson = get_custom_geojson(geojson_key) featureidkey_options = [] featureidkey_value = featureidkey featureidkey_placeholder = text("Select Uploaded Data") disabled = False if curr_geojson and not isinstance(curr_geojson, list): if curr_geojson.get("type") == "FeatureCollection": featureidkey_options = [ build_option(fik) for fik in curr_geojson["properties"] ] else: featureidkey_value = None disabled = True featureidkey_placeholder = "id" return [ html.Div( [ html.Div( [ dcc.Upload( html.Div( html.Span( html.Span( text("Upload File"), style=dict(whiteSpace="pre-line"), ), className= "input-group-addon d-block pt-1 pb-0 pointer", ), className="input-group mr-3", id="upload-geojson-btn", ), id="upload-geojson", ), ], className="col-auto", ), html.Div(id="output-geojson-upload", className="col mt-auto mb-auto"), ], className="row pb-5", ), html.Div( [ build_input( text("geojson"), dcc.Dropdown( id="geojson-dropdown", options=[ build_option(ct["key"]) for ct in CUSTOM_GEOJSON ], placeholder=text("Select Uploaded Data"), style=dict(width="inherit"), value=geojson_key if loc_mode == "geojson-id" else None, ), className="col-md-6", id="geojson-input", ), build_input( text("featureidkey"), dcc.Dropdown( id="featureidkey-dropdown", options=featureidkey_options, placeholder=featureidkey_placeholder, style=dict(width="inherit"), disabled=disabled, value=featureidkey_value, ), className="col-md-6", id="featureidkey-input", ), ], className="row", ), ]