class_docstr: Time plots of the current resource usage on the cluster
  
  This is two plots, one for CPU and Memory and another for Network I/O
class_docstr_tok: ["Time","plots","of","the","current","resource","usage","on","the","cluster","This","is","two","plots",",","one","for","CPU","and","Memory","and","another","for","Network","I\/O"]
code: def __init__(self, server, doc=None, **kwargs):
      if doc is not None:
          self.doc = weakref.ref(doc)
      self.server = server
      self.log = self.server.io_loop.profile
      self.start = None
      self.stop = None
      self.ts = {"count": [], "time": []}
      self.state = profile.get_profile(self.log)
      data = profile.plot_data(self.state, profile_interval)
      self.states = data.pop("states")
      self.profile_plot, self.source = profile.plot_figure(
          data, **kwargs
      )
  
      changing = [False]  # avoid repeated changes from within callback
  
      @without_property_validation
      @log_errors
      def cb(attr, old, new):
          if changing[0] or len(new) == 0:
              return
  
          data = profile.plot_data(
              self.states[new[0]], profile_interval
          )
          del self.states[:]
          self.states.extend(data.pop("states"))
          changing[0] = True  # don't recursively trigger callback
          update(self.source, data)
          self.source.selected.indices = old
          changing[0] = False
  
      self.source.selected.on_change("indices", cb)
  
      self.ts_source = ColumnDataSource({"time": [], "count": []})
      self.ts_plot = figure(
          title="Activity over time",
          height=150,
          x_axis_type="datetime",
          active_drag="xbox_select",
          tools="xpan,xwheel_zoom,xbox_select,reset",
          sizing_mode="stretch_width",
          toolbar_location="above",
      )
      self.ts_plot.line("time", "count", source=self.ts_source)
      self.ts_plot.circle(
          "time",
          "count",
          source=self.ts_source,
          color=None,
          selection_color="orange",
      )
      self.ts_plot.yaxis.visible = False
      self.ts_plot.grid.visible = False
  
      @log_errors
      def ts_change(attr, old, new):
          selected = self.ts_source.selected.indices
          if selected:
              start = self.ts_source.data["time"][min(selected)] / 1000
              stop = self.ts_source.data["time"][max(selected)] / 1000
              self.start, self.stop = min(start, stop), max(start, stop)
          else:
              self.start = self.stop = None
          self.trigger_update()
  
      self.ts_source.selected.on_change("indices", ts_change)
  
      self.reset_button = Button(label="Reset", button_type="success")
      self.reset_button.on_click(lambda: self.update(self.state))
  
      self.update_button = Button(label="Update", button_type="success")
      self.update_button.on_click(self.trigger_update)
  
      self.root = column(
          row(
              self.reset_button,
              self.update_button,
              sizing_mode="scale_width",
          ),
          self.profile_plot,
          self.ts_plot,
          **kwargs,
      )
  
      self.subtitle = Title(text=" ", text_font_style="italic")
      self.profile_plot.add_layout(self.subtitle, "above")
      if not dask.config.get("distributed.worker.profile.enabled"):
          self.subtitle.text = "Profiling is disabled."
          self.reset_button.disabled = True
          self.update_button.disabled = True
  
imports: from __future__ import annotations
  import asyncio
  import weakref
  import tlz
  from bokeh.core.properties import without_property_validation
  from bokeh.layouts import column, row
  from bokeh.models import Button, ColumnDataSource, DataRange1d, HoverTool, LabelSet, NumeralTickFormatter, Range1d, Select, Title
  from bokeh.palettes import Spectral9
  from bokeh.plotting import figure
  from tornado import gen
  import dask
  from distributed import profile
  from distributed.compatibility import WINDOWS
  from distributed.dashboard.components import DashboardComponent
  from distributed.dashboard.utils import update
  from distributed.utils import log_errors
label_desc: Use image node_id 1 to create a new ProfileServer object from inherited base classes: DashboardComponent with example: obj = ProfileServer(server, doc)