import panel as pn import param from panel.reactive import ReactiveHTML layouts = { "cose": {"name": "cose"}, "grid": {"name": "grid"}, "circle": {"name": "circle"}, "concentric": {"name": "concentric"}, "breadthfirst": {"name": "breadthfirst"}, "random": {"name": "random"}, "preset": {"name": "preset"}, } class Cytoscape(ReactiveHTML): layout_names = param.ObjectSelector( default="cose", doc="Layout Options to choose from.", objects=list(layouts.keys()) ) graph_layouts = param.Dict(default=layouts) style = param.List(doc="Use to set the styles of the nodes/edges") data = param.List(doc="Use to send node's data/attributes to Cytoscape") _template = """
""" __javascript__ = ["https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.25.0/cytoscape.umd.js"] _scripts = { "after_layout": """ self.create() """, "create": """ state.cy = cytoscape({ container: cy, layout: {name: 'cose'}, elements: [{data:{id:'A', label:'A'}},{data:{id:'B', label:'B'}}, {data:{source:'A', target:'B'}}], zoom: 1, pan: {x: 0, y: 0}, }); state.cy.on('click', function (evt) { console.log(evt.originalEvent, evt) state.cy.resize(); }); """, "remove": """ state.cy.destroy() delete state.cy """, "layout_names": """ console.log("layout_names") const layout = state.cy.layout(data.graph_layouts[data.layout_names]) layout.run() """, } _extension_name = "cytoscape" pn.extension("cytoscape", template="fast") my_graph = Cytoscape(width=800, height=400) widget_container = pn.Column(pn.pane.Markdown("## Title")) app = pn.Column(widget_container).servable(target="main") widget_container.append(pn.Row(my_graph.param.layout_names, my_graph)) app.servable()