Returns data and metadata dictionaries containing HTML and JS
        components to include render in app, notebook, or standalone
        document. Depending on the backend the fmt defines the format
        embedded in the HTML, e.g. png or svg. If comm is enabled the
        JS code will set up a Websocket comm channel using the
        currently defined CommManager.

def components(self, obj, fmt=None, comm=True, **kwargs):
        """
        Returns data and metadata dictionaries containing HTML and JS
        components to include render in app, notebook, or standalone
        document. Depending on the backend the fmt defines the format
        embedded in the HTML, e.g. png or svg. If comm is enabled the
        JS code will set up a Websocket comm channel using the
        currently defined CommManager.
        """
        if isinstance(obj, (Plot, NdWidget)):
            plot = obj
        else:
            plot, fmt = self._validate(obj, fmt)

        widget_id = None
        data, metadata = {}, {}
        if isinstance(plot, NdWidget):
            js, html = plot(as_script=True)
            plot_id = plot.plot_id
            widget_id = plot.id
        else:
            html, js = self._figure_data(plot, fmt, as_script=True, **kwargs)
            plot_id = plot.id
            if comm and plot.comm is not None and self.comm_msg_handler:
                msg_handler = self.comm_msg_handler.format(plot_id=plot_id)
                html = plot.comm.html_template.format(init_frame=html,
                                                      plot_id=plot_id)
                comm_js = plot.comm.js_template.format(msg_handler=msg_handler,
                                                       comm_id=plot.comm.id,
                                                       plot_id=plot_id)
                js = '\n'.join([js, comm_js])
            html = "<div id='%s' style='display: table; margin: 0 auto;'>%s</div>" % (plot_id, html)
        if not os.environ.get('HV_DOC_HTML', False) and js is not None:
            js = embed_js.format(widget_id=widget_id, plot_id=plot_id, html=html) + js

        data['text/html'] = html
        if js:
            data[MIME_TYPES['js']] = js
            data[MIME_TYPES['jlab-hv-exec']] = ''
            metadata['id'] = plot_id
            self._plots[plot_id] = plot
        return (data, {MIME_TYPES['jlab-hv-exec']: metadata})