class_docstr: Dashboard class for creating interactive dashboard objects.
  
  Dashboards are dicts that contain boxes which hold plot information.
  These boxes can be arranged in various ways. The most basic form of
  a box is:
  
  ```
  {
      'type': 'box',
      'boxType': 'plot'
  }
  ```
  
  where 'fileId' can be set to the 'username:#' of your plot. The other
  parameters a box takes are `shareKey` (default is None) and `title`
  (default is '').
  
  `.get_preview()` should be called quite regularly to get an HTML
  representation of the dashboard in which the boxes in the HTML
  are labelled with on-the-fly-generated numbers or box ids which
  change after each modification to the dashboard.
  
  `.get_box()` returns the box located in the dashboard by calling
  its box id as displayed via `.get_preview()`.
  
  Example 1: Create a simple Dashboard object
  ```
  import plotly.dashboard_objs as dashboard
  
  box_a = {
      'type': 'box',
      'boxType': 'plot',
      'fileId': 'username:some#',
      'title': 'box a'
  }
  
  box_b = {
      'type': 'box',
      'boxType': 'plot',
      'fileId': 'username:some#',
      'title': 'box b'
  }
  
  box_c = {
      'type': 'box',
      'boxType': 'plot',
      'fileId': 'username:some#',
      'title': 'box c'
  }
  
  my_dboard = dashboard.Dashboard()
  my_dboard.insert(box_a)
  # my_dboard.get_preview()
  my_dboard.insert(box_b, 'above', 1)
  # my_dboard.get_preview()
  my_dboard.insert(box_c, 'left', 2)
  # my_dboard.get_preview()
  my_dboard.swap(1, 2)
  # my_dboard.get_preview()
  my_dboard.remove(1)
  # my_dboard.get_preview()
  ```
  
  Example 2: 4 vertical boxes of equal height
  ```
  import plotly.dashboard_objs as dashboard
  
  box_a = {
      'type': 'box',
      'boxType': 'plot',
      'fileId': 'username:some#',
      'title': 'box a'
  }
  
  my_dboard = dashboard.Dashboard()
  my_dboard.insert(box_a)
  my_dboard.insert(box_a, 'below', 1)
  my_dboard.insert(box_a, 'below', 1)
  my_dboard.insert(box_a, 'below', 3)
  # my_dboard.get_preview()
  ```
docstr: Returns JSON or HTML respresentation of the dashboard.
  
  If IPython is not imported, returns a pretty print of the dashboard
  dict. Otherwise, returns an IPython.core.display.HTML display of the
  dashboard.
  
  The algorithm used to build the HTML preview involves going through
  the paths of the node generator of the dashboard. The paths of the
  dashboard are sequenced through from shorter to longer and whether
  it's a box or container that lies at the end of the path determines
  the action.
  
  If it's a container, draw a line in the figure to divide the current
  box into two and store the specs of the resulting two boxes. If the
  path points to a terminal box (often containing a plot), then draw
  the box id in the center of the box.
  
  It's important to note that these box ids are generated on-the-fly and
  they do not necessarily stay assigned to the boxes they were once
  assigned to.
docstr_tok: ["Returns","JSON","or","HTML","respresentation","of","the","dashboard",".","If","IPython","is","not","imported",",","returns","a","pretty","print","of","the","dashboard","dict",".","Otherwise",",","returns","an","IPython.core.display.HTML","display","of","the","dashboard",".","The","algorithm","used","to","build","the","HTML","preview","involves","going","through","the","paths","of","the","node","generator","of","the","dashboard",".","The","paths","of","the","dashboard","are","sequenced","through","from","shorter","to","longer","and","whether","it","'s","a","box","or","container","that","lies","at","the","end","of","the","path","determines","the","action",".","If","it","'s","a","container",",","draw","a","line","in","the","figure","to","divide","the","current","box","into","two","and","store","the","specs","of","the","resulting","two","boxes",".","If","the","path","points","to","a","terminal","box","(","often","containing","a","plot",")",",","then","draw","the","box","id","in","the","center","of","the","box",".","It","'s","important","to","note","that","these","box","ids","are","generated","on-the-fly","and","they","do","not","necessarily","stay","assigned","to","the","boxes","they","were","once","assigned","to","."]
code: def get_preview(self):
      """
      Returns JSON or HTML respresentation of the dashboard.
  
      If IPython is not imported, returns a pretty print of the dashboard
      dict. Otherwise, returns an IPython.core.display.HTML display of the
      dashboard.
  
      The algorithm used to build the HTML preview involves going through
      the paths of the node generator of the dashboard. The paths of the
      dashboard are sequenced through from shorter to longer and whether
      it's a box or container that lies at the end of the path determines
      the action.
  
      If it's a container, draw a line in the figure to divide the current
      box into two and store the specs of the resulting two boxes. If the
      path points to a terminal box (often containing a plot), then draw
      the box id in the center of the box.
  
      It's important to note that these box ids are generated on-the-fly and
      they do not necessarily stay assigned to the boxes they were once
      assigned to.
      """
      if IPython is None:
          pprint.pprint(self)
          return
  
      elif self["layout"] is None:
          return IPython.display.HTML(dashboard_html)
  
      top_left_x = 0
      top_left_y = 0
      box_w = MASTER_WIDTH
      box_h = MASTER_HEIGHT
      html_figure = dashboard_html
      box_ids_to_path = self._compute_box_ids()
      # used to store info about box dimensions
      path_to_box_specs = {}
      first_box_specs = {
          "top_left_x": top_left_x,
          "top_left_y": top_left_y,
          "box_w": box_w,
          "box_h": box_h,
      }
      # uses tuples to store paths as for hashable keys
      path_to_box_specs[("first",)] = first_box_specs
  
      # generate all paths
      all_nodes, all_paths = self._make_all_nodes_and_paths()
  
      max_path_len = max(len(path) for path in all_paths)
      for path_len in range(1, max_path_len + 1):
          for path in [
              path for path in all_paths if len(path) == path_len
          ]:
              current_box_specs = path_to_box_specs[path]
  
              if self._path_to_box(path)["type"] == "split":
                  fill_percent = self._path_to_box(path)["size"]
                  direction = self._path_to_box(path)["direction"]
                  is_horizontal = direction == "horizontal"
  
                  top_left_x = current_box_specs["top_left_x"]
                  top_left_y = current_box_specs["top_left_y"]
                  box_w = current_box_specs["box_w"]
                  box_h = current_box_specs["box_h"]
  
                  html_figure = _draw_line_through_box(
                      html_figure,
                      top_left_x,
                      top_left_y,
                      box_w,
                      box_h,
                      is_horizontal=is_horizontal,
                      direction=direction,
                      fill_percent=fill_percent,
                  )
  
                  # determine the specs for resulting two box split
                  if is_horizontal:
                      new_top_left_x = top_left_x
                      new_top_left_y = top_left_y
                      new_box_w = box_w * (fill_percent / 100.0)
                      new_box_h = box_h
  
                      new_top_left_x_2 = top_left_x + new_box_w
                      new_top_left_y_2 = top_left_y
                      new_box_w_2 = box_w * (
                          (100 - fill_percent) / 100.0
                      )
                      new_box_h_2 = box_h
                  else:
                      new_top_left_x = top_left_x
                      new_top_left_y = top_left_y
                      new_box_w = box_w
                      new_box_h = box_h * (fill_percent / 100.0)
  
                      new_top_left_x_2 = top_left_x
                      new_top_left_y_2 = top_left_y + box_h * (
                          fill_percent / 100.0
                      )
                      new_box_w_2 = box_w
                      new_box_h_2 = box_h * (
                          (100 - fill_percent) / 100.0
                      )
  
                  first_box_specs = {
                      "top_left_x": top_left_x,
                      "top_left_y": top_left_y,
                      "box_w": new_box_w,
                      "box_h": new_box_h,
                  }
                  second_box_specs = {
                      "top_left_x": new_top_left_x_2,
                      "top_left_y": new_top_left_y_2,
                      "box_w": new_box_w_2,
                      "box_h": new_box_h_2,
                  }
  
                  path_to_box_specs[path + ("first",)] = first_box_specs
                  path_to_box_specs[
                      path + ("second",)
                  ] = second_box_specs
  
              elif self._path_to_box(path)["type"] == "box":
                  for box_id in box_ids_to_path:
                      if box_ids_to_path[box_id] == path:
                          number = box_id
                  html_figure = _add_html_text(
                      html_figure,
                      number,
                      path_to_box_specs[path]["top_left_x"],
                      path_to_box_specs[path]["top_left_y"],
                      path_to_box_specs[path]["box_w"],
                      path_to_box_specs[path]["box_h"],
                  )
  
      # display HTML representation
      return IPython.display.HTML(html_figure)
  
imports: import pprint
  import _plotly_utils.exceptions
  from _plotly_utils import optional_imports
  from chart_studio import exceptions
label_desc: Use image node_id 8 for calling the Dashboard obj's underlying member method code with example usage: obj.get_preview() and returns: IPython, IPython