1212from spdx.model.relationship import Relationship
1313
1414
15- def visualize_document(document: Document, visualize: str) -> None:
16- try:
17- from networkx.drawing import nx_agraph
18- except ImportError:
19- raise ImportError
15+ def export_graph_from_document(document: Document, file_name: str) -> None:
16+ from networkx.drawing import nx_agraph
2017
21- graph = generate_graph_from_spdx (document)
18+ graph = generate_relationship_graph_from_spdx (document)
2219 _color_nodes(graph)
23- attributes_graph = nx_agraph.to_agraph(graph) # convert to a graphviz graph
24- attributes_graph.draw(visualize , prog="dot")
20+ attributes_graph = nx_agraph.to_agraph(graph) # convert to a pygraphviz graph
21+ attributes_graph.draw(file_name , prog="dot")
2522
2623
27- def generate_graph_from_spdx(document: Document) -> DiGraph:
28- try:
29- from networkx import DiGraph
30- except ImportError:
31- raise ImportError
24+ def generate_relationship_graph_from_spdx(document: Document) -> DiGraph:
25+ from networkx import DiGraph
26+
3227 graph = DiGraph()
3328 graph.add_node(document.creation_info.spdx_id, element=document.creation_info)
3429
@@ -38,42 +33,40 @@ def generate_graph_from_spdx(document: Document) -> DiGraph:
3833 ]
3934 graph.add_nodes_from(contained_element_nodes)
4035
41- relationships_by_spdx_id: Dict[str, List[Relationship]] = _get_relationships_by_spdx_id(document.relationships)
36+ relationships_by_spdx_id: Dict[str, List[Relationship]] = dict()
37+ for relationship1 in document.relationships:
38+ relationships_by_spdx_id.setdefault(relationship1.spdx_element_id, []).append(relationship1)
4239
4340 for spdx_id, relationships in relationships_by_spdx_id.items():
4441 if spdx_id not in graph.nodes():
45- graph.add_node(spdx_id, element=get_element_from_spdx_id(document, spdx_id))
42+ # this will add any external spdx_id to the graph where we have no further information about the element
43+ # to indicate that this node represents an element we add the attribute "element"
44+ graph.add_node(spdx_id, element=None)
4645 for relationship in relationships:
4746 relationship_node_key = relationship.spdx_element_id + "_" + relationship.relationship_type.name
4847 graph.add_node(relationship_node_key, comment=relationship.comment)
4948 graph.add_edge(relationship.spdx_element_id, relationship_node_key)
50- # if the related spdx element is SpdxNone or SpdxNoAssertion we need a
51- # type conversion
49+ # if the related spdx element is SpdxNone or SpdxNoAssertion we need a type conversion
5250 related_spdx_element_id = str(relationship.related_spdx_element_id)
5351
5452 if related_spdx_element_id not in graph.nodes():
53+ # this will add any external spdx_id to the graph where we have no further information about the element
54+ # to indicate that this node represents an element we add the attribute "element"
5555 graph.add_node(
5656 related_spdx_element_id,
57- element=get_element_from_spdx_id(document, spdx_id) ,
57+ element=None ,
5858 )
5959 graph.add_edge(relationship_node_key, related_spdx_element_id)
6060
6161 return graph
6262
6363
64- def _get_relationships_by_spdx_id(
65- relationships: List[Relationship],
66- ) -> Dict[str, List[Relationship]]:
67- relationships_by_spdx_id: Dict[str, List[Relationship]] = dict()
68- for relationship in relationships:
69- relationships_by_spdx_id.setdefault(relationship.spdx_element_id, []).append(relationship)
70-
71- return relationships_by_spdx_id
72-
73-
7464def _color_nodes(graph: DiGraph) -> None:
7565 for node in graph.nodes():
7666 if "_" in node:
67+ # nodes representing a RelationshipType are concatenated with the spdx_element_id
68+ # to only see the RelationshipType when rendering the graph to a picture we add
69+ # a label to these nodes
7770 graph.add_node(node, color="lightgreen", label=node.split("_", 1)[-1])
7871 elif node == "SPDXRef-DOCUMENT":
7972 graph.add_node(node, color="indianred2")
0 commit comments