class_docstr: Data aggregation functionality for ``go.Figures``.
class_docstr_tok: ["Data","aggregation","functionality","for","``","go.Figures","``","."]
docstr: Registers the `update_graph` callback & show the figure in a dash app.
  
  Parameters
  ----------
  mode: str, optional
      Display mode. One of:
  
        * ``"external"``: The URL of the app will be displayed in the notebook
          output cell. Clicking this URL will open the app in the default
          web browser.
        * ``"inline"``: The app will be displayed inline in the notebook output
          cell in an iframe.
        * ``"inline_persistent"``: The app will be displayed inline in the
          notebook output cell in an iframe, if the app is not reachable a static
          image of the figure is shown. Hence this is a persistent version of the
          ``"inline"`` mode, allowing users to see a static figure in other
          environments, browsers, etc.
  
          !!! note
  
              This mode requires the ``kaleido`` and ``flask_cors`` package.
              Install them : ``pip install plotly_resampler[inline_persistent]``
              or ``pip install kaleido flask_cors``.
  
        * ``"jupyterlab"``: The app will be displayed in a dedicated tab in the
          JupyterLab interface. Requires JupyterLab and the ``jupyterlab-dash``
          extension.
      By default None, which will result in the same behavior as ``"external"``.
  config: dict, optional
      The configuration options for displaying this figure, by default None.
      This ``config`` parameter is the same as the dict that you would pass as
      ``config`` argument to the `show` method.
      See more [https://plotly.com/python/configuration-options/](https://plotly.com/python/configuration-options/)
  init_dash_kwargs: dict, optional
      Keyword arguments for the Dash app constructor.
      !!! note
          This variable is of special interest when working in a jupyterhub +
          kubernetes environment. In this case, user notebook servers are spawned
          as separate pods and user access to those servers are proxied via
          jupyterhub. Dash requires the `requests_pathname_prefix` to be set on
          __init__ - which can be done via this `init_dash_kwargs` argument.
          Note that you should also pass the `jupyter_server_url` to the
          `show_dash` method.
          More details: https://github.com/predict-idlab/plotly-resampler/issues/265
  graph_properties: dict, optional
      Dictionary of (keyword, value) for the properties that should be passed to
      the dcc.Graph, by default None.
      e.g.: `{"style": {"width": "50%"}}`
      Note: "config" is not allowed as key in this dict, as there is a distinct
      ``config`` parameter for this property in this method.
      See more [https://dash.plotly.com/dash-core-components/graph](https://dash.plotly.com/dash-core-components/graph)
  **kwargs: dict
      kwargs for the ``app.run_server()`` method, e.g., port=8037.
      !!! note
          These kwargs take precedence over the ones that are passed to the
          constructor via the ``show_dash_kwargs`` argument.
docstr_tok: ["Registers","the","`","update_graph","`","callback","&","show","the","figure","in","a","dash","app",".","Parameters","--","--","--","--","--","mode",":","str",",","optional","Display","mode",".","One","of",":","*","``","``","external","''","``",":","The","URL","of","the","app","will","be","displayed","in","the","notebook","output","cell",".","Clicking","this","URL","will","open","the","app","in","the","default","web","browser",".","*","``","``","inline","''","``",":","The","app","will","be","displayed","inline","in","the","notebook","output","cell","in","an","iframe",".","*","``","``","inline_persistent","''","``",":","The","app","will","be","displayed","inline","in","the","notebook","output","cell","in","an","iframe",",","if","the","app","is","not","reachable","a","static","image","of","the","figure","is","shown",".","Hence","this","is","a","persistent","version","of","the","``","``","inline","''","``","mode",",","allowing","users","to","see","a","static","figure","in","other","environments",",","browsers",",","etc",".","!","!","!","note","This","mode","requires","the","``","kaleido","``","and","``","flask_cors","``","package",".","Install","them",":","``","pip","install","plotly_resampler","[","inline_persistent","]","``","or","``","pip","install","kaleido","flask_cors","``",".","*","``","``","jupyterlab","''","``",":","The","app","will","be","displayed","in","a","dedicated","tab","in","the","JupyterLab","interface",".","Requires","JupyterLab","and","the","``","jupyterlab-dash","``","extension",".","By","default","None",",","which","will","result","in","the","same","behavior","as","``","``","external","''","``",".","config",":","dict",",","optional","The","configuration","options","for","displaying","this","figure",",","by","default","None",".","This","``","config","``","parameter","is","the","same","as","the","dict","that","you","would","pass","as","``","config","``","argument","to","the","`","show","`","method",".","See","more","[","https",":","\/\/plotly.com\/python\/configuration-options\/","]","(","https",":","\/\/plotly.com\/python\/configuration-options\/",")","init_dash_kwargs",":","dict",",","optional","Keyword","arguments","for","the","Dash","app","constructor",".","!","!","!","note","This","variable","is","of","special","interest","when","working","in","a","jupyterhub","+","kubernetes","environment",".","In","this","case",",","user","notebook","servers","are","spawned","as","separate","pods","and","user","access","to","those","servers","are","proxied","via","jupyterhub",".","Dash","requires","the","`","requests_pathname_prefix","`","to","be","set","on","__init__","-","which","can","be","done","via","this","`","init_dash_kwargs","`","argument",".","Note","that","you","should","also","pass","the","`","jupyter_server_url","`","to","the","`","show_dash","`","method",".","More","details",":","https",":","\/\/github.com\/predict-idlab\/plotly-resampler\/issues\/265","graph_properties",":","dict",",","optional","Dictionary","of","(","keyword",",","value",")","for","the","properties","that","should","be","passed","to","the","dcc.Graph",",","by","default","None",".","e.g",".",":","`","{","``","style","''",":","{","``","width","''",":","``","50","%","''","}","}","`","Note",":","``","config","''","is","not","allowed","as","key","in","this","dict",",","as","there","is","a","distinct","``","config","``","parameter","for","this","property","in","this","method",".","See","more","[","https",":","\/\/dash.plotly.com\/dash-core-components\/graph","]","(","https",":","\/\/dash.plotly.com\/dash-core-components\/graph",")","*","*","kwargs",":","dict","kwargs","for","the","``","app.run_server","(",")","``","method",",","e.g.",",","port=8037",".","!","!","!","note","These","kwargs","take","precedence","over","the","ones","that","are","passed","to","the","constructor","via","the","``","show_dash_kwargs","``","argument","."]
code: def show_dash(
      self,
      mode=None,
      config: dict | None = None,
      init_dash_kwargs: dict | None = None,
      graph_properties: dict | None = None,
      **kwargs,
  ):
      """Registers the `update_graph` callback & show the figure in a dash app.
  
      Parameters
      ----------
      mode: str, optional
          Display mode. One of:\n
            * ``"external"``: The URL of the app will be displayed in the notebook
              output cell. Clicking this URL will open the app in the default
              web browser.
            * ``"inline"``: The app will be displayed inline in the notebook output
              cell in an iframe.
            * ``"inline_persistent"``: The app will be displayed inline in the
              notebook output cell in an iframe, if the app is not reachable a static
              image of the figure is shown. Hence this is a persistent version of the
              ``"inline"`` mode, allowing users to see a static figure in other
              environments, browsers, etc.
  
              !!! note
  
                  This mode requires the ``kaleido`` and ``flask_cors`` package.
                  Install them : ``pip install plotly_resampler[inline_persistent]``
                  or ``pip install kaleido flask_cors``.
  
            * ``"jupyterlab"``: The app will be displayed in a dedicated tab in the
              JupyterLab interface. Requires JupyterLab and the ``jupyterlab-dash``
              extension.
          By default None, which will result in the same behavior as ``"external"``.
      config: dict, optional
          The configuration options for displaying this figure, by default None.
          This ``config`` parameter is the same as the dict that you would pass as
          ``config`` argument to the `show` method.
          See more [https://plotly.com/python/configuration-options/](https://plotly.com/python/configuration-options/)
      init_dash_kwargs: dict, optional
          Keyword arguments for the Dash app constructor.
          !!! note
              This variable is of special interest when working in a jupyterhub +
              kubernetes environment. In this case, user notebook servers are spawned
              as separate pods and user access to those servers are proxied via
              jupyterhub. Dash requires the `requests_pathname_prefix` to be set on
              __init__ - which can be done via this `init_dash_kwargs` argument.
              Note that you should also pass the `jupyter_server_url` to the
              `show_dash` method.
              More details: https://github.com/predict-idlab/plotly-resampler/issues/265
      graph_properties: dict, optional
          Dictionary of (keyword, value) for the properties that should be passed to
          the dcc.Graph, by default None.
          e.g.: `{"style": {"width": "50%"}}`
          Note: "config" is not allowed as key in this dict, as there is a distinct
          ``config`` parameter for this property in this method.
          See more [https://dash.plotly.com/dash-core-components/graph](https://dash.plotly.com/dash-core-components/graph)
      **kwargs: dict
          kwargs for the ``app.run_server()`` method, e.g., port=8037.
          !!! note
              These kwargs take precedence over the ones that are passed to the
              constructor via the ``show_dash_kwargs`` argument.
  
      """
      available_modes = [
          "external",
          "inline",
          "inline_persistent",
          "jupyterlab",
      ]
      assert (
          mode is None or mode in available_modes
      ), f"mode must be one of {available_modes}"
      graph_properties = (
          {} if graph_properties is None else graph_properties
      )
      assert (
          "config" not in graph_properties
      )  # There is a param for config
      if (
          self["layout"]["autosize"] is True
          and self["layout"]["height"] is None
      ):
          graph_properties.setdefault("style", {}).update(
              {"height": "100%"}
          )
  
      # 0. Check if the traces need to be updated when there is a xrange set
      # This will be the case when the users has set a xrange (via the `update_layout`
      # or `update_xaxes` methods`)
      relayout_dict = {}
      for xaxis_str in self._xaxis_list:
          x_range = self.layout[xaxis_str].range
          if x_range:  # when not None
              relayout_dict[f"{xaxis_str}.range[0]"] = x_range[0]
              relayout_dict[f"{xaxis_str}.range[1]"] = x_range[1]
      if relayout_dict:  # when not empty
          update_data = self._construct_update_data(relayout_dict)
  
          if not self._is_no_update(
              update_data
          ):  # when there is an update
              with self.batch_update():
                  # First update the layout (first item of update_data)
                  self.layout.update(
                      self._parse_relayout(update_data[0])
                  )
  
                  # Then update the data
                  for updated_trace in update_data[1:]:
                      trace_idx = updated_trace.pop("index")
                      self.data[trace_idx].update(updated_trace)
  
      # 1. Construct the Dash app layout
      init_dash_kwargs = (
          {} if init_dash_kwargs is None else init_dash_kwargs
      )
      if self._create_overview:
          # fmt: off
              # Add the assets folder to the init_dash_kwargs
              init_dash_kwargs["assets_folder"] = os.path.relpath(ASSETS_FOLDER, os.getcwd())
              # Also include the lodash script, as the client-side callbacks uses this
              init_dash_kwargs["external_scripts"] = ["https://cdn.jsdelivr.net/npm/lodash/lodash.min.js" ]
      # fmt: on
  
      if mode == "inline_persistent":
          mode = "inline"
          if _jupyter_dash_installed:
              # Inline persistent mode: we display a static image of the figure when the
              # app is not reachable
              # Note: this is the "inline" behavior of JupyterDashInlinePersistentOutput
              app = JupyterDashPersistentInlineOutput(
                  "local_app", **init_dash_kwargs
              )
              self._is_persistent_inline = True
          else:
              # If Jupyter Dash is not installed, inline persistent won't work and hence
              # we default to normal inline mode with a normal Dash app
              app = dash.Dash("local_app", **init_dash_kwargs)
              warnings.warn(
                  "'jupyter_dash' is not installed. The persistent inline mode will not work. Defaulting to standard inline mode."
              )
      else:
          # jupyter dash uses a normal Dash app as figure
          app = dash.Dash("local_app", **init_dash_kwargs)
  
          # fmt: off
          div = dash.html.Div(
              children=[
                  dash.dcc.Graph(
                      id="resample-figure", figure=self, config=config, **graph_properties
                  )
              ],
              style={
                  "display": "flex", "flex-flow": "column",
                  "height": "95vh", "width": "100%",
              },
          )
      # fmt: on
      if self._create_overview:
          overview_config = config.copy() if config is not None else {}
          overview_config["displayModeBar"] = False
          coarse_fig = self._create_overview_figure()
          div.children += [
              dash.dcc.Graph(
                  id="overview-figure",
                  figure=coarse_fig,
                  config=overview_config,
                  **graph_properties,
              ),
          ]
      app.layout = div
  
      self.register_update_graph_callback(
          app,
          "resample-figure",
          "overview-figure" if self._create_overview else None,
      )
  
      height_param = (
          "height" if self._is_persistent_inline else "jupyter_height"
      )
  
      # 2. Run the app
      if mode == "inline" and height_param not in kwargs:
          # If app height is not specified -> re-use figure height for inline dash app
          #  Note: default layout height is 450 (whereas default app height is 650)
          #  See: https://plotly.com/python/reference/layout/#layout-height
          fig_height = (
              self.layout.height
              if self.layout.height is not None
              else 450
          )
          kwargs[height_param] = fig_height + 18
  
      # kwargs take precedence over the show_dash_kwargs
      kwargs = {**self._show_dash_kwargs, **kwargs}
  
      # Store the app information, so it can be killed
      self._app = app
      self._host = kwargs.get("host", "127.0.0.1")
      self._port = kwargs.get("port", "8050")
  
      # function signature is slightly different for the Dash and JupyterDash implementations
      if self._is_persistent_inline:
          app.run(mode=mode, **kwargs)
      else:
          app.run(jupyter_mode=mode, **kwargs)
  
imports: from __future__ import annotations
  import os
  import warnings
  from pathlib import Path
  from typing import List, Optional, Tuple
  import dash
  import plotly.graph_objects
  from plotly.basedatatypes import BaseFigure
  from ..aggregation import AbstractAggregator, AbstractGapHandler, MedDiffGapHandler, MinMaxLTTB
  from .figure_resampler_interface import AbstractFigureAggregator
  from .utils import is_figure, is_fr
label_desc: Use image node_id 6 for calling the FigureResampler obj's underlying member method code with example usage: obj.show_dash(mode, config, init_dash_kwargs, graph_properties) without return types