예제 #1
0
def build_drilldown_title(data_id, all_inputs, click_point, props, val_prop):
    data = global_state.get_data(data_id)

    def _build_val(col, val):
        if classify_type(find_dtype(data[col])) == "D":
            return json_date(convert_date_val_to_date(val))
        return val

    if "text" in click_point:  # Heatmaps
        strs = []
        for dim in click_point["text"].split("<br>"):
            prop, val = dim.split(": ")
            strs.append("{} ({})".format(prop, val))
        return "{}: {}".format(text("Drilldown for"), ", ".join(strs))

    strs = []
    frame_col = all_inputs.get("animate_by")
    if frame_col:
        strs.append("{} ({})".format(frame_col, click_point.get("customdata")))
    for prop in props:
        prop = make_list(prop)
        val_key = prop[0]
        if click_point.get(val_key) is not None:
            col = make_list(all_inputs.get(prop[-1]))[0]
            strs.append("{} ({})".format(
                col, _build_val(col, click_point.get(val_key))))

    val_prop = make_list(val_prop)
    val_key = val_prop[0]
    val_col = make_list(all_inputs.get(val_prop[-1]))[0]
    agg = AGGS[all_inputs.get("agg") or "raw"]
    strs.append("{} {} ({})".format(
        agg, val_col, _build_val(val_col, click_point.get(val_key))))
    return "{}: {}".format(text("Drilldown for"), ", ".join(strs))
예제 #2
0
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",
    )
예제 #3
0
def build_histogram(data_id, col, query, point_filter):
    data = run_query(
        handle_predefined(data_id),
        query,
        global_state.get_context_variables(data_id),
    )
    query, _ = build_group_inputs_filter(data, [point_filter])
    data = run_query(data, query)
    s = data[~pd.isnull(data[col])][col]
    hist_data, hist_labels = np.histogram(s, bins=10)
    hist_labels = list(
        map(lambda x: json_float(x, precision=3), hist_labels[1:]))
    axes_builder = build_axes(
        dict(
            data=dict(all=dict(Frequency=hist_data, Bins=hist_labels)),
            min=dict(Frequency=0),
            max=dict(Frequency=max(hist_data)),
        ),
        "Bins",
        dict(type="single", data={}),
    )
    hist_data = dict(data={"all": dict(x=hist_labels, Frequency=hist_data)})
    bars = bar_builder(
        hist_data,
        "Bins",
        ["Frequency"],
        axes_builder,
        chart_builder_passthru,
        modal=True,
    )
    bars.figure["layout"]["xaxis"]["type"] = "category"
    bars.figure["layout"]["title"]["text"] = "{} {} ({} {})".format(
        text("Histogram of"), col, len(s), text("data points"))
    return bars
예제 #4
0
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,
        ),
    ]
예제 #5
0
 def update_geojson(contents, filename):
     if filename is None:
         raise PreventUpdate
     geojson_options = [
         build_option(ct["key"]) for ct in get_custom_geojson()
     ]
     try:
         geojson_key = load_geojson(contents, filename)
         geojson_options.append(build_option(geojson_key))
         return "{} {}!".format(geojson_key,
                                text("uploaded")), geojson_options
     except BaseException as ex:
         return str(ex), geojson_options
예제 #6
0
 def update_featureidkey_options(geojson):
     geojson_data = get_custom_geojson(geojson)
     placeholder = text("Select Uploaded Data")
     if geojson_data is None or isinstance(geojson_data, list):
         return [], False, placeholder
     disabled = geojson_data["type"] != "FeatureCollection"
     placeholder = "id" if disabled else placeholder
     if geojson_data and not disabled:
         return (
             [build_option(p) for p in geojson_data.get("properties", [])],
             disabled,
             placeholder,
         )
     return [], disabled, placeholder
예제 #7
0
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])
예제 #8
0
def load_geojson(contents, filename):
    if contents is None and filename is None:
        return None
    if not filename.endswith(".json"):
        raise Exception(text("geojson files must be JSON!"))
    _, content_string = contents.split(",")
    decoded = base64.b64decode(content_string)
    geojson = json.loads(decoded.decode("utf-8"))
    geojson_key = "".join(filename.split(".")[:-1])

    # get properties available to use for featureidkey
    data = dict(data=geojson,
                filename=filename,
                time=pd.Timestamp("now"),
                type=geojson["type"])
    if data["type"] == "FeatureCollection":
        data["properties"] = sorted(
            geojson["features"][0]["properties"].keys())

    geojson_key = add_custom_geojson(geojson_key, data)
    return geojson_key
예제 #9
0
파일: utils.py 프로젝트: unachka/dtale
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",
    )
예제 #10
0
 def on_data(
     _ts1,
     _ts2,
     _ts3,
     _ts4,
     _ts5,
     _ts6,
     _ts7,
     _ts8,
     load_clicks,
     inputs,
     chart_inputs,
     yaxis_data,
     map_data,
     cs_data,
     treemap_data,
     funnel_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,
         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,
         "\n".join(make_list(code) + [CHART_EXPORT_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,
     )
예제 #11
0
 def collapse_cleaners_input(n, is_open):
     final_is_open = is_open
     if n:
         final_is_open = not is_open
     return final_is_open, collapse_btn_text(final_is_open,
                                             text("Cleaners"))
예제 #12
0
 def collapse_data_input(n, is_open):
     final_is_open = is_open
     if n:
         final_is_open = not is_open
     return final_is_open, collapse_btn_text(final_is_open,
                                             text("Data Selection"))
예제 #13
0
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)))
    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",
    )
예제 #14
0
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",
        ),
    ]
예제 #15
0
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")