Closed marimeireles closed 4 years ago
A design choice: should the directed be a graph property or an edge property? https://github.com/QuantStack/ipycytoscape/pull/62 assumes it as a graph property right now.
By being a graph property we can have 2 types of graphs, undirected and directed. By being an edge property, this will also work for mixed graph (undirected and directed edges in one single graph).
:+1: to mixed graphs! Edge properties seems like a great way to go towards that end.
I poked around a bit and it seems as though using the classes syntax in cytoscapejs would be a good way to do this. i.e. use Edge(classes='directed')
and add use the selector .directed
in the style. (Beware that to use selectors based on classes you need the changes in https://github.com/QuantStack/ipycytoscape/pull/63)
Nodes and edges in networkx can have data associated with them in a dictionary which is accessible by passing data=True
to the call to edges() or nodes(). If the styling is accomplished by a classes selector then the add_graph_from_*
functions could all look for the classes attribute of data and add it to the Edge
or Node
. This would give the user greater control of styling of the minutiae of styling if desired. This diff may be a start in that direction:
diff --git a/ipycytoscape/cytoscape.py b/ipycytoscape/cytoscape.py
index 8e1a2a6..67738f0 100644
--- a/ipycytoscape/cytoscape.py
+++ b/ipycytoscape/cytoscape.py
@@ -191,14 +191,18 @@ class Graph(Widget):
receives a generic NetworkX graph. more info in
https://networkx.github.io/documentation/
"""
- for node in g.nodes():
+ for node, data in g.nodes(data=True):
node_instance = Node()
- node_instance.data = {'id': int(node)}
+ node_instance.data = {'id': node}
+ if 'classes' in data:
+ node_instance.classes = data['classes']
self.nodes.append(node_instance)
- for edge in g.edges():
+ for source, target, edge in g.edges(data=True):
edge_instance = Edge()
- edge_instance.data = {'source': edge[0],'target': edge[1]}
+ edge_instance.data = {'source': source, 'target': target}
+ if 'classes' in data:
+ edge_instance.classes = data['classes']
self.edges.append(edge_instance)
def add_graph_from_json(self, json_file):
But it would still be good to add a directed
argument, to ensure the class is added.
@MridulS I think you are more knowledgeable about networkx than I am, is there an easy way to add to the data of nodes/edges after they've been created? I was moderately frustrated trying to use G = nx.complete_graph(5)
and then trying to modify the data of individual nodes and edges after that.
As suggested by @ianhi in https://github.com/QuantStack/ipycytoscape/issues/46 in his second point.
One idea is to add a flag that can be activated if the graph is directed in the
add_graphs
methods:https://github.com/QuantStack/ipycytoscape/blob/59e3440d8a77efb3ecae4867e1992d400be5b96c/ipycytoscape/cytoscape.py#L184
https://github.com/QuantStack/ipycytoscape/blob/59e3440d8a77efb3ecae4867e1992d400be5b96c/ipycytoscape/cytoscape.py#L204
https://github.com/QuantStack/ipycytoscape/blob/59e3440d8a77efb3ecae4867e1992d400be5b96c/ipycytoscape/cytoscape.py#L225
Once this flag is activated it calls a function that changes the style of the graph, you can either use the
set_style()
or copy the style in the dagre example and apply it to the graph.