示例#1
0
        fig.add_trace(go.Scatter(x=df.index, y=df[col]))
    return fig


def make_layout(tag):
    return [
        dcc.Graph(id=f"graph_{tag}"),
        html.Button(f"Update [{tag}]", id=f"btn_{tag}")
    ]


tags = ["default", "memoize", "prejson"]
memoize = dict(default=None, memoize=True, prejson=plotly_jsonify)
# Create dummy data.
df = pd.DataFrame(index=pd.date_range("2020-01", "2021-01", freq="H"),
                  columns=list("ABCDEFGHIJK"),
                  data=pd.np.nan)
df[:] = np.random.random(df.values.shape)
# Create example app.
app = Dash(prevent_initial_callbacks=True)
app.layout = html.Div(
    list(itertools.chain.from_iterable([make_layout(tag) for tag in tags])))
# Attach callbacks.
for t in tags:
    app.callback(Output(f"graph_{t}", "figure"),
                 Trigger(f"btn_{t}", "n_clicks"),
                 memoize=memoize[t])(make_figure)

if __name__ == '__main__':
    app.run_server(port=8877, debug=True)
示例#2
0
class Dashboard:
    """This is abstract dashboard method
    Every nested class should implement following abstract methods:
        - _set_layout: to set dash.app.layout property
    # TODO: expand the class with default layout
    # TODO: expand the class with default styling
    """
    def __init__(self, mode="default", **kwargs):
        external_stylesheets = [BOOTSTRAP]
        if mode == "jupyter":
            self.app = JupyterDash(external_stylesheets=external_stylesheets)
        else:
            self.app = Dash(
                external_stylesheets=external_stylesheets,
                prevent_initial_callbacks=True,
            )

        app = self.app  # For referencing with the decorator (see line below)
        app.title = "CEHS Uganda"

        @app.server.route("/static/<asset_type>/<path>")
        def static_file(asset_type, path):
            return send_from_directory(here / "static" / asset_type, path)

    ################
    #    LAYOUT    #
    ################

    def _set_layout(self):
        """Method is left deliberately empty. Every child class should implement this class"""
        raise NotImplementedError(
            "Every child class should implement __set_layout method!")

    ###################
    #    EXECUTION    #
    ###################

    def run(self, dev=False, **kwargs):
        self._set_layout()
        self._define_callbacks()
        self.app.run_server(debug=dev, use_reloader=dev, **kwargs)

    def switch_data_set(self, data):
        for x in self.data_cards:
            try:
                if isinstance(x, DataCard) or getattr(x, "data") is not None:
                    x.data = data
                    # x.figure = x._get_figure(x.data)
            except AttributeError as e:
                print(e)

    ###################
    #    CALLBACKS    #
    ###################

    def _define_callbacks(self):
        # TODO: self.data_cards is property of datastory... Move this to datastory or data_cards to dashboard?
        # Datacard level
        for x in self.data_cards:
            if x._requires_dropdown():
                for callback in x.callbacks:
                    self.register_callback(
                        function=callback.get("func"),
                        input_element_params=callback.get("input", []),
                        output_elements_params=callback.get("output", []),
                    )
        for x in self.ind_elements:  # FIXME
            if x._requires_dropdown():
                for callback in x.callbacks:
                    self.register_callback(
                        function=callback.get("func"),
                        input_element_params=callback.get("input", []),
                        output_elements_params=callback.get("output", []),
                    )

    def register_callback(
        self,
        function,
        input_element_params,
        output_elements_params=[],
        download_elements_params=[],
    ):
        callback_set = self.__define_callback_set(input_element_params,
                                                  output_elements_params)

        callback_function = self.__process_callback_function(function)

        self.app.callback(*callback_set)(callback_function)

    def __process_callback_function(self, function):
        def callback_wrapper(*input_values):
            value = function(*input_values)
            return value

        return callback_wrapper

    def __define_callback_set(self,
                              input_element_id_prop: list,
                              output_elements_id_prop: list = []):

        callback_set_outputs = [
            Output(component_id=component_id,
                   component_property=component_prop)
            for component_id, component_prop in output_elements_id_prop
        ]

        callback_set_input = [
            Input(component_id=component_id, component_property=component_prop)
            for component_id, component_prop in input_element_id_prop
        ]

        callback_set = [
            x for x in [callback_set_outputs, callback_set_input] if len(x) > 0
        ]

        return callback_set