Esempio n. 1
0
def tree_to_cytoscape(visualized_object):
    nodes, edges, root_ids = dict_to_tree(visualized_object)
    cyto_fig = html.Div(children=[
        cyto.Cytoscape(id='cytoscape-tree-result',
                       layout={
                           'name': 'breadthfirst',
                           'roots': root_ids
                       },
                       style={
                           'width': '100%',
                           'margin': '0 auto',
                           'height': '900px',
                           'backgroundColor': '#f8f7ed'
                       },
                       elements=nodes + edges,
                       stylesheet=[{
                           'selector': 'node',
                           'style': {
                               'content': 'data(label)',
                               'color': 'black'
                           }
                       }, {
                           'selector': 'edge',
                           'style': {
                               'color': 'black',
                               'curve-style': 'bezier',
                               'target-arrow-shape': 'triangle'
                           }
                       }]),
        html.Br(),
        html.Pre(id='output-tree-as-json', style={'display': 'none'}),
        html.Br(),
        html.Button(id="show-json", children="SHOW TREE AS JSON")
    ])
    return cyto_fig
Esempio n. 2
0
 def cytoscape_component():
     cytoscape = dash_cytoscape.Cytoscape(
         id='cytoscape',
         elements=[],
         layout={
             'name': 'cose',
             'idealEdgeLength': 100,
             'nodeOverlap': 20,
             'refresh': 20,
             'fit': True,
             'padding': 30,
             'randomize': False,
             'componentSpacing': 100,
             'nodeRepulsion': 400000,
             'edgeElasticity': 100,
             'nestingFactor': 5,
             'gravity': 80,
             'numIter': 1000,
             'initialTemp': 200,
             'coolingFactor': 0.95,
             'minTemp': 1.0
         },
         style={
             'height': '65vh',
             'width': 'calc(100% - 300px)'
         },
         stylesheet=BaseStylesheet().cy_stylesheet)
     return html.Div(style={'display': 'flex'}, children=[cytoscape])
Esempio n. 3
0
def update_layout(rows, derived_virtual_selected_rows):
    if derived_virtual_selected_rows is None:
        derived_virtual_selected_rows = []

    if rows is None:
        dff = df
    else:
        dff = pd.DataFrame(rows)

    colors = []
    for i in range(len(dff)):
        if i in derived_virtual_selected_rows:
            colors.append("#7FDBFF")
        else:
            colors.append("#0074D9")

    return html.Div([
        cyto.Cytoscape(
            id="cyto",
            layout={'name': 'circle'},
            zoomingEnabled=False,
            elements=elements,
            # stylesheet=[
            #     {
            #         'selector':'node',
            #         'style':colors
            #     }
            # ]
        )
    ])
Esempio n. 4
0
def model_category_nx_grah_to_cytoscape(join_result):
    model_category_join = join_result.get_model_category_join()
    G = model_category_join.get_commutative_triangle()
    nodes, edges = parse_cytoscape_nodes_edges(G)

    cyto_fig = html.Div(children=[
        cyto.Cytoscape(id='cytoscape-model-category',
                       layout={'name': 'circle'},
                       style={
                           'width': '90%',
                           'margin': '0 auto',
                           'height': '800px',
                           'backgroundColor': '#f8f7ed'
                       },
                       elements=nodes + edges,
                       stylesheet=[{
                           'selector': 'node',
                           'style': {
                               'content': 'data(label)',
                               'color': 'black'
                           }
                       }, {
                           'selector': 'edge',
                           'style': {
                               'content': 'data(label)',
                               'color': 'black',
                               'curve-style': 'bezier',
                               'target-arrow-shape': 'triangle'
                           }
                       }]),
    ])
    return cyto_fig
Esempio n. 5
0
def render_content(tab):
    if tab == 'tab-1':
        return html.Div([
            cyto.Cytoscape(id='cytoscape',
                           layout={'name': 'cose'},
                           style={'width': '1100px', 'height': '500px'},
                           stylesheet=[{
                               'selector': '.terminal',
                               'style': {
                                   'content': 'data(label)',
                                   'background-fit': 'cover',
                                   'background-image': 'data(url)'
                               },
                           }, {
                               'selector': '.people',
                               'style': {
                                   'content': 'data(label)',
                               },
                           }],
                           elements=elements,
                           )
        ])
    elif tab == 'tab-2':
        return html.Div([
            html.H3('Tab content 2')
        ])
Esempio n. 6
0
def ensemble_selector_view(parent: WebvizPluginABC) -> List[Component]:
    return [
        html.Div(
            [
                cyto.Cytoscape(
                    id=parent.uuid("ensemble-selector"),
                    layout={"name": "grid"},
                    className="ert-ensemble-selector-large",
                    stylesheet=assets.ERTSTYLE["ensemble-selector"]["stylesheet"],
                    responsive=False,
                ),
                html.Button(
                    id=parent.uuid("ensemble-selector-button"),
                    className="ert-ensemble-selector-view-toggle",
                    children=("Minimize"),
                ),
            ],
            id=parent.uuid("ensemble-selector-container"),
            className="ert-ensemble-selector-container-large",
        ),
        dcc.Store(id=parent.uuid("ensemble-selection-store"), storage_type="session"),
        dcc.Store(
            id=parent.uuid("ensemble-view-store"), storage_type="session", data=True
        ),
    ]
Esempio n. 7
0
 def initLayout(self):
     self.myapp.layout = html.Div([
         html.Div([
             html.Div(style={'width': '50%', 'display': 'inline'}, children=[
                 'Edge Color:',
                 dcc.Input(id='input-line-color', type='text')
             ]),
             html.Div(style={'width': '50%', 'display': 'inline'}, children=[
                 'Node Color:',
                 dcc.Input(id='input-bg-color', type='text')
             ]),
             dcc.Dropdown(
                 id="dp_tables",
                 options=[{"label": str(nom_table), "value": str(nom_table)}  for nom_table in self.listeTables],
                 multi=True,
                 value=list(self.listeTables),
                 className="dcc_control",
             ),
         ]),
         cyto.Cytoscape(
             id='lesTables',
             layout={'name': 'circle', 'radius': 20},
             stylesheet=self.default_stylesheet,
             style={'width': '100%', 'height': '450px'},
             elements=self.listeElements
         )
     ])
Esempio n. 8
0
def cytoscape_component():
    no_data = html.Div(children=[html.P()], id='no-data', className='non-show')

    cytoscape = dash_cytoscape.Cytoscape(
        id='cytoscape',
        className='show',
        elements=[],
        maxZoom=1.75,
        minZoom=0.35,
        layout={
            'name': 'cose',
            'idealEdgeLength': 100,
            'nodeOverlap': 20,
            'refresh': 20,
            'fit': True,
            'padding': 30,
            'randomize': False,
            'componentSpacing': 100,
            'nodeRepulsion': 400000,
            'edgeElasticity': 100,
            'nestingFactor': 5,
            'gravity': 80,
            'numIter': 1000,
            'initialTemp': 200,
            'coolingFactor': 0.95,
            'minTemp': 1.0
        },
        stylesheet=CytoscapeStylesheet.make_basic_stylesheet())
    return html.Div(children=[cytoscape, no_data], className='cyto-dim')
Esempio n. 9
0
    def toDash(self, t=0):
        elements = []
        stylesheet = []
        for n in self.nodes:
            e, s = n.toDash()
            elements.append(e)
            stylesheet.append(s)

        for i in range(self.n + 1):
            for j in range(self.n + 1):
                if (i != j):
                    elements.append(
                        {'data': {
                            'source': str(i),
                            'target': str(j)
                        }})

        return cyto.Cytoscape(id='cytoscape-two-nodes',
                              layout={'name': 'preset'},
                              style={
                                  'width': '100%',
                                  'height': '400px'
                              },
                              elements=elements,
                              stylesheet=stylesheet)
Esempio n. 10
0
    def render(self):
        dag = cyto.Cytoscape(
            id='indicator-graph',
            layout={
                'name': 'dagre',
                'ranker': 'longest-path',
                'nodeDimensionsIncludeLabels': True,
                'avoidOverlap': True,
                'fit': True,
                'nodeSep': 300,
            },
            # stylesheet=default_stylesheet,
            style={
                'width': '100%',
                'height': '1000px'
            },
            elements=self.make_elements(),
            stylesheet=STYLES,
            zoomingEnabled=True,
            maxZoom=2,
            minZoom=0.1,
        )
        self.make_elements()

        ret = html.Div([
            self._make_navbar(),
            dbc.Container(
                [dbc.Row([dag]),
                 dbc.Row(html.Div(id='indicator-output'))],
                className="app-content",
                fluid=True)
        ])
        return ret
Esempio n. 11
0
def cytolegendablock(title='legenda',
                     id='id-legenda:',
                     width='300px',
                     height='100px'):
    return html.Div(
        children=[
            #html.P(title),
            cyto.Cytoscape(
                id=id,
                layout={
                    'name': 'grid',
                    'animate': False,
                    'fit': True
                },
                style={
                    'width': width,
                    'height': height,
                    'border-style': 'solid',
                    'border-width': 'thin',
                    'background-color': 'Cornsilk'
                },
                boxSelectionEnabled=False,
                zoom=1,
                zoomingEnabled=True,
                elements=[],
                stylesheet=[],
            )
        ],
        style={
            'padding': '3px',
            'width': width,
            'display': 'inline-block'
        })  #
Esempio n. 12
0
def getMainMenuLayout():
    htmlEls = [
        html.H1(
            [
                'Select a Board',
                dcc.Link(
                    html.Button(
                        '+',
                        style={
                            'backgroundColor': 'blue',
                            'color': 'white',
                            'border': 'none',
                            'height': '30px',
                            'width': '30px',
                            'margin-left': '80px'
                        }
                    ),
                    href='/createBoard'
                )
 
            ],
            id='mainMenu',
            style={
                'textAlign': 'center',
                'display': 'block' if AppControl.page == 'HOME' else 'hidden'
            }
        ),
    ]

    # Add board as option on main menu
    for board in boardList:
        graph = board.getGraph()
        cytoscapeEdges = graph.getCytoscapeGraphEdges()
        htmlEls.append(
            dcc.Link(
                html.Div(
                    [
                        html.H2(
                            board.boardName,
                            id=board.boardName+'Name',
                            style={'textAlign': 'center'}
                        ),
                        cyto.Cytoscape(
                            id=board.boardName+'Preview',
                            layout={'name': 'preset'},
                            style={'width': '100%', 'height': '200px'},
                            stylesheet=board.getCytoscapeStylesheet(),
                            elements=board.getCytoscapeNodes() + cytoscapeEdges,
                            userZoomingEnabled=False,
                            userPanningEnabled=False
                        ),
                    ],
                    id=board.boardName,
                    style={'border': '2px solid gray', 'margin': '5px'}
                ),
                href="/game/"+board.boardName
            ),
        )

    return htmlEls
Esempio n. 13
0
def main():
    """First method called when ran as script"""
    rpc = GoBGPQueryWrapper("192.168.242.132", "50051")

    lsdb = rpc.get_lsdb()

    nx_graph = graphing.build_nx_from_lsdb(lsdb)

    elements = []

    for node in nx_graph.nodes():
        elements.append({
            "data": {
                "id": node,
                "label": node
            },
        }, )
    for source_edge, target_edge in nx_graph.edges():
        elements.append({
            "data": {
                "source": source_edge,
                "target": target_edge,
                "cost": nx_graph[source_edge][target_edge][0]["cost"],
            }
        })

    app = dash.Dash(__name__)
    app.layout = html.Div([
        html.P("Mad topology:"),
        cyto.Cytoscape(
            id="cytoscape",
            elements=elements,
            layout={"name": "cose"},
            style={
                "width": "100%",
                "height": "700px",
            },
            stylesheet=[
                {
                    "selector": "node",
                    "style": {
                        "label": "data(id)"
                    },
                },
                {
                    "selector": "edge",
                    "style": {
                        "source-label": "data(cost)",
                        "source-text-offset": 40,
                    },
                },
            ],
        ),
    ])

    app.run_server(debug=True)
Esempio n. 14
0
def model_category_building_tool(new_model_category):
    global nodes, edges, model_categories
    model_categories.append(new_model_category)
    added_graph = new_model_category.get_nx_graph()
    added_nodes, added_edges = parse_cytoscape_nodes_edges(added_graph)
    nodes, edges = nodes + added_nodes, edges + added_edges
    #print(nodes, edges)
    cyto_fig = html.Div(children=[ 
        html.Label([
            "Give a name for this converged data model", html.Br(),
            dcc.Input(
                id="object-name-input",
                type="text",
                value="",
                placeholder="name",
                style={'width': '90%',
                        "display": "inline-block"},
            )]), 
            html.Br(),
        cyto.Cytoscape(
            id='cytoscape-result',
            layout={'name': 'circle'},
            style={'width': '90%', 'margin': '0 auto',
                   'height': '800px', 'backgroundColor': '#f8f7ed'},
            elements=nodes + edges,
            stylesheet=[
                {
                    'selector': 'node',
                    'style': {
                        'content': 'data(label)',
                        'color': 'black'
                    }
                },
                {
                    'selector': 'edge',
                    'style': {
                        'content': 'data(label)',
                        'color': 'black',
                        'curve-style': 'bezier',
                        'target-arrow-shape': 'triangle'
                    }
                }
            ]
        ), html.Div(style={"border": "1px solid white", "padding": "10px", "margin": "10px"}, children=[
            html.Pre(id='cytoscape-tapNodeData-domain', style={
                'border': 'thin lightgrey solid', 'margin': '0 auto',
                'overflowX': 'scroll', 'width': '90%'}, children="Select domain node")]),
        html.Div(style={"border": "1px solid white", "padding": "10px", "margin": "10px"}, children=[
            html.Pre(id='cytoscape-tapNodeData-target', style={
                'border': 'thin lightgrey solid', 'margin': '0 auto',
                'overflowX': 'scroll', 'width': '90%'}, children="Select target node")]),
        html.Button(id="combine-domain-target", children="COMBINE SELECTED DOMAIN AND TARGET"),
        html.Br(),
        html.Button(id = "submit-final-model-category", children = "SUBMIT FINAL MODEL CATEGORY"),
        html.Div(id = "create-object-notification")])
    return cyto_fig
Esempio n. 15
0
    def __init__(self, graph, weight='weight', **attr):
        """
        :param graph: is the networkx graph object
        """
        super().__init__(**attr)
        # The networkx graph object

        self.G = graph
        # the weight attribute in the edge tuples data dictionary
        self.weight = weight
        # The dictionary of the nodes coordinates
        self.pos = nx.layout.spring_layout(self.G)
        # The edges and nodes graph data
        self.elements = []
        # Keeps track of the number of nodes in graph
        self.num_of_nodes = len(self.G.nodes)

        # Make elements
        self._make_elements()

        # The nodes graph data
        self.dash_layout = html.Div([
            cyto.Cytoscape(id='MST',
                           layout={'name': 'preset'},
                           style={
                               'width': '100%',
                               'height': '400px'
                           },
                           elements=self.elements,
                           stylesheet=[{
                               'selector': 'node',
                               'style': {
                                   'label': 'data(label)',
                                   'text-valign': 'center',
                                   'background-color': '#F1B40E',
                                   'color': '',
                                   'font-family': 'sans-serif',
                                   'font-size': '12',
                                   'font-weight': 'bold',
                                   'border-width': 1.5,
                                   'border-color': '#161615'
                               }
                           }, {
                               'selector': 'edge',
                               'style': {
                                   'line-color': '#6F5306',
                               }
                           }]),
            html.Pre(id='cytoscape-tapNodeData-json',
                     style={
                         'border': 'thin lightgrey solid',
                         'overflowX': 'scroll'
                     })
        ])
Esempio n. 16
0
    def __create_empty_network(self):
        size_stylesheet = [
            # Group selectors
            {
                'selector': 'node',
                'style': {
                    'content': 'data(label)',
                    'fontSize': '10px',
                    'width': "8px",
                    'height': "8px"
                }
            },
            {
                'selector': 'edge',
                'style': {
                    'width': 1
                }
            },
            {
                'selector': '.small',
                'style': {
                    'width': 10,
                    'height': 10,
                }
            },
            {
                'selector': '.bind',
                'style': {
                    'width': 1
                }
            },
            {
                'selector': '.internal',
                'style': {
                    'line-style': 'dashed'
                }
            }
        ]
        elements = []

        return cyto.Cytoscape(id='fig_network',
                              layout={
                                  'name': 'preset',
                                  'fit': True
                              },
                              style={
                                  'width': '100%',
                                  'height': '500px',
                                  'textValign': 'center',
                                  'textHalign': 'center'
                              },
                              stylesheet=size_stylesheet,
                              elements=elements)
Esempio n. 17
0
def get_solution_routing_cytoscape(solution: Solution) -> cyto.Cytoscape:
    """
    Returns a cytoscape object showing the network topology and stream routing
    """

    # elements
    elements = []
    nodes = []
    edges = []

    for n in solution.tc.N.values():
        el = {}
        el["data"] = {"id": n.id, "label": n.id}
        if isinstance(n, end_system):
            el["classes"] = "ES"
        else:
            el["classes"] = "SW"
        nodes.append(el)

    for l in solution.tc.L.values():
        el = {}
        el["data"] = {"source": l.src.id, "target": l.dest.id}
        el["classes"] = "link"
        edges.append(el)

    for f_id, mtree in solution.tc.R.items():
        for l in mtree.get_all_links(solution.tc):
            el = {}
            el["data"] = {"source": l.src.id, "target": l.dest.id}
            el["classes"] = f_id
            edges.append(el)

    elements = flatten([nodes, edges])

    # stylesheet

    stylesheet = flatten(
        [
            _cytoscape_base_stylesheet(),
            _cytoscape_base_stream_selectors(solution.tc.F_routed.keys()),
        ]
    )

    cyto.load_extra_layouts()
    graph = cyto.Cytoscape(
        id="cytoscape-routing-graph",
        layout={"name": "cose"},
        style={"width": "100%", "height": "800px"},
        elements=elements,
        stylesheet=stylesheet,
    )

    return graph
Esempio n. 18
0
def schemaGraph():
    return html.Div([
        cyto.Cytoscape(
            id='schema-graph',
            layout={'name': 'cose'},
            stylesheet=base_cyto_stylesheet,
            style={'width': '100%', 'height': '100%'},
            elements=[]
        )],
        style=schema_holder_style,
        id="schema-holder"
    )
Esempio n. 19
0
def render_content(tab):
    if tab == 'tab-1':
        return html.Div([
                cyto.Cytoscape(id='cytoscape',
                               elements=elements,
                               layout={'name': 'cose'},
                               style={'width': '1100px', 'height': '500px'},
                               stylesheet=stylesheet)
        ])
    elif tab == 'tab-2':
        return html.Div([
            html.H3('Tab content 2')
        ])
Esempio n. 20
0
 def _set_cyto_graph(self):
     """
     Sets the cytoscape graph elements.
     """
     self.cyto_graph = cyto.Cytoscape(
         id="cytoscape",
         layout={'name': self.layout_options[0]},
         style={
             'width': '100%',
             'height': '600px',
             'padding': '5px 3px 5px 3px'
         },
         elements=self.elements,
         stylesheet=self.stylesheet)
Esempio n. 21
0
 def _set_cyto_graph(self):
     """
     Updates and sets the two cytoscape graphs using the corresponding components.
     """
     layout = {'name': 'cose-bilkent'}
     style = {
         'width': '100%',
         'height': '600px',
         'padding': '5px 3px 5px 3px'
     }
     self.cyto_one = cyto.Cytoscape(
         id="cytoscape",
         layout=layout,
         style=style,
         elements=self.one_components[1],
         stylesheet=DualDashGraph._get_default_stylesheet(
             self.one_components[0]))
     self.cyto_two = cyto.Cytoscape(
         id="cytoscape_two",
         layout=layout,
         style=style,
         elements=self.two_components[1],
         stylesheet=DualDashGraph._get_default_stylesheet(
             self.two_components[0]))
Esempio n. 22
0
 def __create_cyto_graph(self):
     graph = html.Div(
         [
             # Div to upload the graph via callback
             cyto.Cytoscape(id='cytoscape-era-model',
                            stylesheet=styleERA.get_stylesheet_cyto(),
                            style={
                                'width': '1px%',
                                'height': '1px'
                            },
                            elements=[])
         ],
         id='graph-div',
         style={'border': '1px solid rgba(0, 0, 0, 0.08)'})
     return graph
Esempio n. 23
0
def create_traceroute_graph(elements, stylesheet):
    children = [
        cyto.Cytoscape(id='traceroute-cytoscape',
                       style={
                           'width': '1720px',
                           'height': '500px',
                       },
                       elements=elements,
                       stylesheet=stylesheet,
                       layout={
                           'name': 'preset',
                           'padding': 60,
                       }),
    ]
    return children
Esempio n. 24
0
def getpatientSubgraph(n_clicks, userID):
    if n_clicks != 0:
        try:
            elements = getPatientSubgraph(userID)
            graph = cyto.Cytoscape(
                id='patient-infection-subgraph',
                elements=elements,
                style={'width': '100%', 'height': '100%'},
                layout={
                    'name': 'cose'
                }
            )
            return graph
        except Exception as e:
            return [html.Br(), html.P("Error", style={'color': 'red'})]
Esempio n. 25
0
 def __get_cytoscape(self, elements):
     return cyto.Cytoscape(
         id='cytoscape-container',
         elements=elements,
         style={
             'width': self.screen_size[0] - 300,
             'height': self.screen_size[1]
         },
         layout={
             'name': self.__DEFAULT_LAYOUT,
         },
         stylesheet=self.stylesheetProvider.get_stylesheet(
             self.__DEFAULT_LAYOUT),
         maxZoom=10,
         minZoom=0.5)
Esempio n. 26
0
def get_course_path_graph(show_preq=False):
    course_path_graph = cyto.Cytoscape(
        id='course_path_graph',
        layout={'name':'cose'},
        style={
            'width': '100%',
            'height': '650px',
        },
        zoom= 1.2,
        minZoom= 0.3,
        maxZoom= 1.5,
        stylesheet=course_path_stylesheet,
        # If we're asking for the preq graph, use graph.preq_tree instead of graph.dfs_tree
        elements=graph.get_elements(graph.learning_path(
            'comp 302', (graph.preq_tree if show_preq else graph.dfs_tree)))
    )
    return course_path_graph
Esempio n. 27
0
def create_graph(gr):
    # Create the graph
    app.layout = html.Div([
        html.P("Neossins - TypeRefHash/GUID graph:"),
        cyto.Cytoscape(
            id='cytoscape-layout-2',
            elements=gr,
            #layout={'name': 'circle', 'radius': 500},
            layout={
                'name': 'cose',
                'animate': 'true'
            },
            style={
                'width': '100%',
                'height': '1000px'
            },
            stylesheet=[
                # Group selectors
                {
                    'selector': 'node',
                    'style': {
                        'content': 'data(label)'
                    }
                },
                {
                    'selector': '.red',
                    'style': {
                        'background-color': 'red',
                        'shape': 'rectangle'
                    }
                },
                {
                    'selector': '.pink',
                    'style': {
                        'background-color': '#dea4d4'
                    }
                },
                {
                    'selector': '.blue',
                    'style': {
                        'background-color': '#32CBDF'
                    }
                }
            ])
    ])
    app.run_server(host='%s' % (config["server"]["ip"]), debug=True)
Esempio n. 28
0
def TopLevelGraph(elements):
    return cyto.Cytoscape(
        id='cytoscape-toplevel',
        elements=elements,
        layout={'name': 'circle'},
        stylesheet=[
            normal_node_style['style'],
            parent_node_style['style'],
            normal_edge_style['style'],
            factor_edge_style['style'],
            temporal_edge_style['style'],
            cycle_node_style['style'],
            root_node_style['style'],
            leaf_node_style['style'],
            isolate_node_style['style'],
            standard_node_style['style'],
            hidden_node_style['style']
        ])
Esempio n. 29
0
def create_graph(G):
    cytoscape_data_format = nx.cytoscape_data(G)
    nodes = cytoscape_data_format["elements"]["nodes"]
    edges = cytoscape_data_format["elements"]["edges"]

    app = dash.Dash(__name__)

    app.layout = html.Div([
        cyto.Cytoscape(id='cytoscape-two-nodes',
                       layout={'name': 'circle'},
                       style={
                           'width': '100%',
                           'height': '1400px'
                       },
                       elements=nodes + edges)
    ])

    app.run_server(debug=True)
Esempio n. 30
0
def render():
    return html.Div([
        dcc.Store(id=STORE_ID, storage_type='local'),
        scenario_modal(),
        campaign_modal(),
        event_modal(),
        dbc.NavbarSimple(
            [
                daq.BooleanSwitch(
                    id=MAP_TOGGLE_ID,
                    children=html.I(className="fas fa-map-marked"),
                    className="m-1"),
                dbc.Button(id=OPEN_CAMPAIGN_MODAL_ID,
                           children=html.I(className="fas fa-book-open"),
                           className="m-1",
                           color="info"),
                html.A(id=DOWNLOAD_DATA_ID,
                       children=html.I(className="fas fa-cloud-download-alt"),
                       download="gloomhaven-campaign-manager-data.json",
                       href="",
                       target="_blank",
                       className="btn btn-success m-1"),
                dbc.Button(id=CLEAR_DATA_ID,
                           children=[html.I(className="fas fa-trash-alt")],
                           color="danger",
                           className="m-1"),
            ],
            expand=True,
            brand="GCM",
        ),
        banners(),
        cyto.Cytoscape(id=CYTO_GRAPH_ID,
                       layout={
                           'name': 'cose',
                           'roots': '[id = "1"]',
                           'animate': 'True'
                       },
                       style={},
                       elements=[],
                       minZoom=0.5,
                       maxZoom=2,
                       stylesheet=CYTO_STYLESHEET),
        html.Div(toasts())
    ])