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 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_extended_agg_desc(ext_agg): desc = [] col, agg, window, comp = (ext_agg.get(p) for p in ["col", "agg", "window", "comp"]) desc += [html.Span("Col: "), html.B(col)] desc += [html.Span(", Agg: "), html.B(agg)] if window: desc += [html.Span(", Win: "), html.B(window)] if comp: desc += [html.Span(", Roll Comp: "), html.B(comp)] return desc
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_error(error): return html.Div( [ html.I(className="ico-error"), html.Span(error), ], className="dtale-alert alert alert-danger", )
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_saved_header(config): chart_type = config["chart_type"] final_data = [ ("Data ID", config["data_id"]), ("Query", config.get("query")), ("Chart Type", chart_type), ] if config.get("agg") not in [None, "raw"]: final_data.append(("Aggregation", config["agg"])) if chart_type == "maps": group_by = config["map_group"] map_type = config.get("map_type") if map_type == "scattergeo": map_props = ["map_type", "lat", "lon", "map_val", "scope", "proj"] elif map_type == "mapbox": map_props = ["map_type", "lat", "lon", "map_val", "mapbox_style"] else: map_props = ["map_type", "loc_mode", "loc", "map_val"] if config.get("loc_mode") == "geojson-id": map_props += ["geojson", "featureidkey"] for prop in map_props: final_data.append((prop, config.get(prop))) elif chart_type == "candlestick": group_by = config["cs_group"] for prop in ["cs_x", "cs_open", "cs_close", "cs_high", "cs_low"]: final_data.append((prop.split("_")[-1], config.get(prop))) elif chart_type == "treemap": group_by = config["treemap_group"] for prop in ["treemap_value", "treemap_label"]: final_data.append((prop.split("_")[-1], config.get(prop))) elif chart_type == "funnel": group_by = config["funnel_group"] for prop in ["funnel_value", "funnel_label"]: final_data.append((prop.split("_")[-1], config.get(prop))) elif chart_type == "clustergram": group_by = config["clustergram_group"] for prop in ["clustergram_value", "clustergram_label"]: final_data.append((prop.split("_")[-1], config.get(prop))) else: group_by = config.get("group") final_data.append(("X-Axis", config["x"])) y = make_list(config["y"]) final_data.append(("Y-Axes" if len(y) > 1 else "Y-Axis", ",".join(y))) if chart_type in ZAXIS_CHARTS: final_data.append(("z", config.get("z"))) if chart_type == "scatter" and config["trendline"]: final_data.append(("Trendline", "\u2714")) if group_by: final_data.append(("Group By", ", ".join(make_list(group_by)))) group_type = config["group_type"] final_data.append(("Group Type", group_type)) if group_type == "bins": final_data.append(("Bin Type", config["bin_type"])) final_data.append(("Bins", config["bin_val"])) else: final_data.append( ("Selected Groups", ", ".join(make_list(config["groups"])))) if config["cpg"]: final_data.append(("Chart Per Group", "\u2714")) if config["cpy"]: final_data.append(("Chart Per Y", "\u2714")) if chart_type in ANIMATION_CHARTS and config["animate"]: final_data.append(("Animate", "\u2714")) if chart_type in ANIMATE_BY_CHARTS and config["animate_by"]: final_data.append( ("Animate By", ", ".join(make_list(config["animate_by"])))) return build_hoverable( html.I(className="ico-help-outline"), [ html.B("Chart Configuration"), html.Ul( [ html.Li( [html.B(text(prop)), html.Span(": {}".format(value))], className="mb-0", ) for prop, value in final_data if value is not None ], className="mb-0", ), ], hover_class="saved-chart-config", top="unset", )
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", ), ]