Exemplo n.º 1
0
    def update_click_data(
        click_data,
        pathname,
        inputs,
        chart_inputs,
        yaxis_data,
        map_data,
        current_click_data,
        drilldowns_on,
    ):
        if not drilldowns_on:
            raise PreventUpdate
        all_inputs = combine_inputs(dash_app, inputs, chart_inputs, yaxis_data,
                                    map_data)
        if (all_inputs.get("agg") or "raw") == "raw":
            raise PreventUpdate
        if not click_data:
            raise PreventUpdate
        data_id = get_data_id(pathname)
        chart_type = all_inputs.get("chart_type")
        click_data = click_data or current_click_data
        click_point = next((p for p in click_data.get("points", [])), None)
        if chart_type == "maps":
            props = [["location", "loc"], "lat", "lon"]
            val = ["z", "map_val"]
        else:
            props = ["x"]
            val = "y"
            if click_point.get("z"):
                props = ["x", "y"]
                val = "z"

        header = build_drilldown_title(data_id, all_inputs, click_point, props,
                                       val)
        return click_data, header
Exemplo n.º 2
0
    def query_input(query, pathname, curr_query):
        """
        dash callback for storing valid pandas dataframe queries.  This acts as an intermediary between values typed
        by the user and values that are applied to pandas dataframes.  Most of the time what the user has typed is not
        complete and thus not a valid pandas dataframe query.

        :param query: query input
        :type query: str
        :param pathname: URL path
        :param curr_query: current valid pandas dataframe query
        :return: tuple of (query (if valid), styling for query input (if invalid input), query input title (containing
        invalid query exception information)
        :rtype: tuple of (str, str, str)
        """
        try:
            data_id = get_data_id(pathname)
            data = global_state.get_data(data_id)
            ctxt_vars = global_state.get_context_variables(data_id)
            run_query(data, query, ctxt_vars)
            return query, {"line-height": "inherit"}, ""
        except BaseException as ex:
            return (
                curr_query,
                {
                    "line-height": "inherit",
                    "background-color": "pink"
                },
                str(ex),
            )
Exemplo n.º 3
0
 def group_values(
     chart_type,
     group_cols,
     map_group_cols,
     cs_group_cols,
     treemap_group_cols,
     pathname,
     inputs,
     prev_group_vals,
 ):
     data_id = get_data_id(pathname)
     group_cols = group_cols
     if chart_type == "maps":
         group_cols = map_group_cols
     elif chart_type == "candlestick":
         group_cols = cs_group_cols
     elif chart_type == "treemap":
         group_cols = treemap_group_cols
     group_cols = make_list(group_cols)
     group_types = get_group_types(inputs, data_id, group_cols)
     if "groups" not in group_types:
         return [], None
     group_vals = run_query(
         global_state.get_data(data_id),
         inputs.get("query"),
         global_state.get_context_variables(data_id),
     )
     group_vals = build_group_val_options(group_vals, group_cols)
     selections = []
     available_vals = [gv["value"] for gv in group_vals]
     if prev_group_vals is not None:
         selections = [pgv for pgv in prev_group_vals if pgv in available_vals]
     if not len(selections) and len(group_vals) <= MAX_GROUPS:
         selections = available_vals
     return group_vals, selections
Exemplo n.º 4
0
 def main_input_class(
     ts_, ts2_, _ts3, _ts4, pathname, inputs, map_inputs, cs_inputs, treemap_inputs
 ):
     return main_inputs_and_group_val_display(
         dict_merge(inputs, map_inputs, cs_inputs, treemap_inputs),
         get_data_id(pathname),
     )
Exemplo n.º 5
0
 def on_data(
     _ts1,
     _ts2,
     _ts3,
     _ts4,
     pathname,
     inputs,
     chart_inputs,
     yaxis_data,
     map_data,
     last_chart_inputs,
 ):
     """
     dash callback controlling the building of dash charts
     """
     all_inputs = dict_merge(inputs, chart_inputs,
                             dict(yaxis=yaxis_data or {}), map_data)
     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(get_data_id(pathname),
                                            **all_inputs)
     return (
         charts,
         all_inputs,
         range_data,
         "\n".join(make_list(code)),
         get_yaxis_type_tabs(make_list(inputs.get("y") or [])),
     )
Exemplo n.º 6
0
 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)
     data_id = get_data_id(pathname)
     df = global_state.get_data(data_id)
     settings = global_state.get_settings(data_id) or {}
     return charts_layout(df, settings, **params)
Exemplo n.º 7
0
    def input_toggles(_ts, inputs, pathname):
        """
        dash callback controlling showing/hiding of chart-specific inputs (for example z-axis) as well as chart
        formatting inputs (sorting for bars in bar chart, bar chart style (stacked) or y-axis ranges.
        """
        [chart_type, agg] = [inputs.get(p) for p in ["chart_type", "agg"]]
        show_input = show_input_handler(chart_type)

        y_multi_style = {
            "display": "block" if show_input("y", "multi") else "none"
        }
        y_single_style = {"display": "block" if show_input("y") else "none"}
        z_style = {"display": "block" if show_input("z") else "none"}
        group_style = {"display": "block" if show_input("group") else "none"}
        rolling_style = {"display": "inherit" if agg == "rolling" else "none"}
        cpg_style = {
            "display": "block" if show_chart_per_group(**inputs) else "none"
        }
        cpy_style = {
            "display": "block" if show_chart_per_y(**inputs) else "none"
        }
        bar_style, barsort_style = bar_input_style(**inputs)
        yaxis_style = {
            "display": "block" if show_yaxis_ranges(**inputs) else "none"
        }

        data_id = get_data_id(pathname)
        df = global_state.get_data(data_id)
        animate_style, animate_by_style, animate_opts = animate_styles(
            df, **inputs)
        trendline_style = dict(
            display="block" if chart_type == "scatter" else "none")
        return (
            y_multi_style,
            y_single_style,
            z_style,
            group_style,
            rolling_style,
            cpg_style,
            cpy_style,
            bar_style,
            barsort_style,
            barsort_style,
            yaxis_style,
            animate_style,
            animate_by_style,
            animate_opts,
            trendline_style,
        )
Exemplo n.º 8
0
 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",
     )
Exemplo n.º 9
0
    def cs_data_callback(
        cs_x,
        cs_open,
        cs_close,
        cs_high,
        cs_low,
        group,
        pathname,
    ):
        data_id = get_data_id(pathname)
        cs_data = dict(
            cs_x=cs_x,
            cs_open=cs_open,
            cs_close=cs_close,
            cs_high=cs_high,
            cs_low=cs_low,
        )
        if group is not None:
            cs_data["cs_group"] = group
        df = global_state.get_data(data_id)
        (
            x_options,
            close_options,
            open_options,
            low_options,
            high_options,
        ) = build_candlestick_options(
            df,
            cs_x=cs_x,
            cs_open=cs_open,
            cs_close=cs_close,
            cs_high=cs_high,
            cs_low=cs_low,
        )

        return (
            cs_data,
            x_options,
            open_options,
            close_options,
            high_options,
            low_options,
        )
Exemplo n.º 10
0
 def treemap_data_callback(
     treemap_value,
     treemap_label,
     group,
     pathname,
 ):
     data_id = get_data_id(pathname)
     treemap_data = dict(
         treemap_value=treemap_value,
         treemap_label=treemap_label,
     )
     if group is not None:
         treemap_data["treemap_group"] = group
     df = global_state.get_data(data_id)
     value_options, label_options = build_treemap_options(
         df,
         treemap_value=treemap_value,
         treemap_label=treemap_label,
     )
     return treemap_data, value_options, label_options
Exemplo n.º 11
0
 def build_x_dropdown(is_open, pathname, inputs, chart_inputs, yaxis_data, map_data):
     if not is_open:
         raise PreventUpdate
     df = global_state.get_data(get_data_id(pathname))
     all_inputs = combine_inputs(
         dash_app, inputs, chart_inputs, yaxis_data, map_data
     )
     chart_type, x, y, z, group, map_val, animate_by = (
         all_inputs.get(p)
         for p in ["chart_type", "x", "y", "z", "group", "map_val", "animate_by"]
     )
     if chart_type == "maps":
         if all_inputs.get("map_type") == "choropleth":
             x = all_inputs["loc"]
         else:
             x = "lat_lon"
         x_options = build_selections(map_val, animate_by)
     else:
         x_options = build_selections(z or y, animate_by)
     col_opts = list(build_cols(df.columns, get_dtypes(df)))
     x_options = [build_option(c, l) for c, l in col_opts if c not in x_options]
     return x_options, x
Exemplo n.º 12
0
    def group_values(chart_type, group_cols, map_group_cols, pathname, inputs,
                     prev_group_vals):
        group_cols = make_list(map_group_cols if chart_type ==
                               "maps" else group_cols)
        if not show_group_input(inputs, group_cols):
            return [], None
        data_id = get_data_id(pathname)
        group_vals = run_query(
            global_state.get_data(data_id),
            inputs.get("query"),
            global_state.get_context_variables(data_id),
        )
        group_vals = build_group_val_options(group_vals, group_cols)
        selections = []
        available_vals = [gv["value"] for gv in group_vals]
        if prev_group_vals is not None:
            selections = [
                pgv for pgv in prev_group_vals if pgv in available_vals
            ]
        if not len(selections) and len(group_vals) <= MAX_GROUPS:
            selections = available_vals

        return group_vals, selections
Exemplo n.º 13
0
    def map_data(
        map_type,
        loc_mode,
        loc,
        lat,
        lon,
        map_val,
        scope,
        style,
        proj,
        group,
        geojson,
        featureidkey,
        pathname,
    ):
        data_id = get_data_id(pathname)
        map_type = map_type or "choropleth"
        if map_type == "choropleth":
            map_data = dict(map_type=map_type,
                            loc_mode=loc_mode,
                            loc=loc,
                            map_val=map_val)
            if loc_mode == "geojson-id":
                map_data["geojson"] = geojson
                map_data["featureidkey"] = featureidkey
        elif map_type == "mapbox":
            map_data = dict(map_type=map_type,
                            lat=lat,
                            lon=lon,
                            map_val=map_val,
                            mapbox_style=style)
        else:
            map_data = dict(
                map_type=map_type,
                lat=lat,
                lon=lon,
                map_val=map_val,
                scope=scope,
                proj=proj,
            )

        if group is not None:
            map_data["map_group"] = group
        df = global_state.get_data(data_id)
        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)
        choro_style = {} if map_type == "choropleth" else {"display": "none"}
        coord_style = ({} if map_type in ["scattergeo", "mapbox"] else {
            "display": "none"
        })
        scatt_style = {} if map_type == "scattergeo" else {"display": "none"}
        mapbox_style = {} if map_type == "mapbox" else {"display": "none"}
        proj_hover_style = ({
            "display": "none"
        } if proj is None else dict(borderBottom="none"))
        proj_hopver_children = build_proj_hover_children(proj)
        loc_mode_hover_style = ({
            "display": "none"
        } if loc_mode is None else dict(borderBottom="none"))
        loc_mode_children = build_loc_mode_hover_children(loc_mode)
        custom_geojson_link = ({} if map_type == "choropleth"
                               and loc_mode == "geojson-id" else {
                                   "display": "none"
                               })
        return (
            map_data,
            loc_options,
            lat_options,
            lon_options,
            map_val_options,
            choro_style,
            choro_style,
            coord_style,
            coord_style,
            scatt_style,
            mapbox_style,
            scatt_style,
            proj_hover_style,
            proj_hopver_children,
            loc_mode_hover_style,
            loc_mode_children,
            custom_geojson_link,
        )
Exemplo n.º 14
0
 def input_data(
     _ts,
     chart_type,
     x,
     y_multi,
     y_single,
     z,
     group,
     group_val,
     agg,
     window,
     rolling_comp,
     pathname,
     query,
 ):
     """
     dash callback for maintaining chart input state and column-based dropdown options.  This will guard against
     users selecting the same column for multiple axes.
     """
     y_val = make_list(y_single if chart_type in ZAXIS_CHARTS else y_multi)
     if group_val is not None:
         group_val = [json.loads(gv) for gv in group_val]
     inputs = dict(
         query=query,
         chart_type=chart_type,
         x=x,
         y=y_val,
         z=z,
         group=group,
         group_val=group_val,
         agg=agg,
         window=window,
         rolling_comp=rolling_comp,
     )
     data_id = get_data_id(pathname)
     options = build_input_options(global_state.get_data(data_id), **inputs)
     (
         x_options,
         y_multi_options,
         y_single_options,
         z_options,
         group_options,
         barsort_options,
         yaxis_options,
     ) = options
     show_map = chart_type == "maps"
     map_style = {} if show_map else {"display": "none"}
     show_cs = chart_type == "candlestick"
     cs_style = {} if show_cs else {"display": "none"}
     show_treemap = chart_type == "treemap"
     treemap_style = {} if show_treemap else {"display": "none"}
     standard_style = ({
         "display": "none"
     } if show_map or show_cs or show_treemap else {})
     cscale_style = colorscale_input_style(chart_type=chart_type)
     drilldown_toggle_style = show_style((agg or "raw") != "raw")
     return (
         inputs,
         x_options,
         y_single_options,
         y_multi_options,
         z_options,
         group_options,
         barsort_options,
         yaxis_options,
         standard_style,
         map_style,
         cs_style,
         treemap_style,
         cscale_style,
         drilldown_toggle_style,
         lock_zoom_style(chart_type),
     )
Exemplo n.º 15
0
    def input_data(
        _ts,
        _ts2,
        chart_type,
        x,
        y_multi,
        y_single,
        z,
        group,
        group_type,
        group_val,
        bins_val,
        bin_type,
        agg,
        window,
        rolling_comp,
        load,
        load_type,
        cleaners,
        pathname,
        query,
        data_id,
        extended_aggregation,
    ):
        """
        dash callback for maintaining chart input state and column-based dropdown options.  This will guard against
        users selecting the same column for multiple axes.
        """
        y_val = make_list(y_single if chart_type in ZAXIS_CHARTS else y_multi)
        data_id = data_id or get_data_id(pathname)
        if group_val is not None:
            group_val = [json.loads(gv) for gv in group_val]

        inputs = dict(
            data_id=data_id,
            query=query,
            chart_type=chart_type,
            x=x,
            y=y_val,
            z=z,
            group=group,
            group_type=group_type or "groups",
            group_val=group_val if group else None,
            bins_val=bins_val if group else None,
            bin_type=bin_type or "width",
            agg=agg or "raw",
            window=window,
            rolling_comp=rolling_comp,
            load=load,
            load_type=load_type,
            cleaners=make_list(cleaners),
        )
        options = build_input_options(
            global_state.get_data(data_id),
            extended_aggregation=extended_aggregation,
            **inputs)
        (
            x_options,
            y_multi_options,
            y_single_options,
            z_options,
            group_options,
            barsort_options,
            yaxis_options,
        ) = options
        show_map = chart_type == "maps"
        map_style = {} if show_map else {"display": "none"}
        show_cs = chart_type == "candlestick"
        cs_style = {} if show_cs else {"display": "none"}
        show_treemap = chart_type == "treemap"
        treemap_style = {} if show_treemap else {"display": "none"}
        show_funnel = chart_type == "funnel"
        funnel_style = {} if show_funnel else {"display": "none"}
        standard_style = ({
            "display": "none"
        } if show_map or show_cs or show_treemap or show_funnel else {})
        cscale_style = colorscale_input_style(chart_type=chart_type)
        drilldown_toggle_style = show_style((agg or "raw") != "raw")
        return (
            inputs,
            x_options,
            y_single_options,
            y_multi_options,
            z_options,
            group_options,
            barsort_options,
            yaxis_options,
            standard_style,
            map_style,
            cs_style,
            treemap_style,
            funnel_style,
            cscale_style,
            drilldown_toggle_style,
            lock_zoom_style(chart_type),
            show_style(chart_type not in NON_EXT_AGGREGATION and len(y_val)),
            "({} Selected)".format(len(inputs["cleaners"]))
            if len(inputs["cleaners"]) else "",
        )
Exemplo n.º 16
0
    def load_drilldown_content(
        _click_data_ts,
        drilldown_type,
        drilldown_x,
        pathname,
        inputs,
        chart_inputs,
        yaxis_data,
        map_data,
        click_data,
        drilldowns_on,
    ):
        if not drilldowns_on:
            raise PreventUpdate
        all_inputs = combine_inputs(dash_app, inputs, chart_inputs, yaxis_data,
                                    map_data)
        agg = all_inputs.get("agg") or "raw"
        chart_type = all_inputs.get("chart_type")
        frame_col = all_inputs.get("animate_by")
        all_inputs.pop("animate_by", None)
        if agg == "raw":
            raise PreventUpdate
        if drilldown_x is None and chart_type != "maps":
            raise PreventUpdate
        if click_data:
            click_point = next((p for p in click_data.get("points", [])), None)
            if click_point:
                data_id = get_data_id(pathname)
                curr_settings = global_state.get_settings(data_id) or {}
                query = build_query(
                    data_id,
                    all_inputs.get("query") or curr_settings.get("query"))
                x_col = all_inputs.get("x")
                y_col = next((y2 for y2 in make_list(all_inputs.get("y"))),
                             None)
                if chart_type in ZAXIS_CHARTS:
                    x, y, z, frame = (click_point.get(p)
                                      for p in ["x", "y", "z", "customdata"])
                    if chart_type == "heatmap":
                        click_point_vals = {}
                        for dim in click_point["text"].split("<br>"):
                            prop, val = dim.split(": ")
                            click_point_vals[prop] = val
                        x, y, frame = (click_point_vals.get(p)
                                       for p in [x_col, y_col, frame_col])
                    point_filter = {x_col: x, y_col: y}
                    if frame_col:
                        point_filter[frame_col] = frame
                    if drilldown_type == "histogram":
                        z_col = next(
                            (z2 for z2 in make_list(all_inputs.get("z"))),
                            None)
                        hist_chart = build_histogram(data_id, z_col, query,
                                                     point_filter)
                        return hist_chart, dict(display="none")
                    else:
                        xy_query, _ = build_group_inputs_filter(
                            global_state.get_data(data_id),
                            [point_filter],
                        )
                        if not query:
                            query = xy_query
                        else:
                            query = "({}) and ({})".format(query, xy_query)
                        all_inputs["query"] = query
                        all_inputs["chart_type"] = drilldown_type
                        all_inputs["agg"] = "raw"
                        all_inputs["modal"] = True
                        all_inputs["x"] = drilldown_x
                        all_inputs["y"] = [all_inputs["z"]]
                        chart, _, _ = build_chart(get_data_id(pathname),
                                                  **all_inputs)
                        return chart, None

                elif chart_type == "maps":
                    map_type = all_inputs.get("map_type")
                    point_filter = {}
                    if frame_col:
                        point_filter[frame_col] = click_point["customdata"]
                    if map_type == "choropleth":
                        point_filter[
                            all_inputs["loc"]] = click_point["location"]
                    elif map_type == "scattergeo":
                        lat, lon = (click_point.get(p) for p in ["lat", "lon"])
                        point_filter[all_inputs["lat"]] = lat
                        point_filter[all_inputs["lon"]] = lon
                    map_val = all_inputs["map_val"]
                    if drilldown_type == "histogram":
                        hist_chart = build_histogram(data_id, map_val, query,
                                                     point_filter)
                        return hist_chart, dict(display="none")
                    else:
                        map_query, _ = build_group_inputs_filter(
                            global_state.get_data(data_id),
                            [point_filter],
                        )
                        if not query:
                            query = map_query
                        else:
                            query = "({}) and ({})".format(query, map_query)
                        all_inputs["query"] = query
                        all_inputs["chart_type"] = drilldown_type
                        all_inputs["agg"] = "raw"
                        all_inputs["modal"] = True

                        data_id = get_data_id(pathname)
                        data = global_state.get_data(data_id)
                        all_inputs["x"] = drilldown_x
                        x_style = None
                        if map_type != "choropleth":
                            all_inputs["x"] = "lat_lon"
                            lat, lon = (all_inputs.get(p)
                                        for p in ["lat", "lon"])
                            data.loc[:,
                                     "lat_lon"] = (data[lat].astype(str) +
                                                   "|" + data[lon].astype(str))
                            x_style = dict(display="none")
                        all_inputs["y"] = [map_val]
                        chart, _, _ = build_chart(data_id,
                                                  data=data,
                                                  **all_inputs)
                        return chart, x_style
                else:
                    x_filter = click_point.get("x")
                    point_filter = {x_col: x_filter}
                    if frame_col:
                        point_filter[frame_col] = click_point.get("customdata")
                    if drilldown_type == "histogram":
                        hist_chart = build_histogram(data_id, y_col, query,
                                                     point_filter)
                        return hist_chart, dict(display="none")
                    else:
                        x_query, _ = build_group_inputs_filter(
                            global_state.get_data(data_id),
                            [point_filter],
                        )
                        if not query:
                            query = x_query
                        else:
                            query = "({}) and ({})".format(query, x_query)
                        all_inputs["query"] = query
                        all_inputs["chart_type"] = drilldown_type
                        all_inputs["agg"] = "raw"
                        all_inputs["modal"] = True
                        all_inputs["x"] = drilldown_x
                        chart, _, _ = build_chart(get_data_id(pathname),
                                                  **all_inputs)
                        return chart, None
        return None, dict(display="none")