summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--networkx/readwrite/graphml.py13
-rw-r--r--networkx/readwrite/tests/test_graphml.py35
2 files changed, 45 insertions, 3 deletions
diff --git a/networkx/readwrite/graphml.py b/networkx/readwrite/graphml.py
index 1a463b54..1d3ec6df 100644
--- a/networkx/readwrite/graphml.py
+++ b/networkx/readwrite/graphml.py
@@ -247,8 +247,8 @@ def read_graphml(path, node_type=str, edge_key_type=int, force_multigraph=False)
there is no "key" attribute a default NetworkX multigraph edge key
will be provided.
- Files with the yEd "yfiles" extension will can be read but the graphics
- information is discarded.
+ Files with the yEd "yfiles" extension can be read. The type of the node's
+ shape is preserved in the `shape_type` node attribute.
yEd compressed files ("file.graphmlz" extension) can be read by renaming
the file to "file.graphml.gz".
@@ -912,7 +912,11 @@ class GraphMLReader(GraphML):
elif len(list(data_element)) > 0:
# Assume yfiles as subelements, try to extract node_label
node_label = None
- for node_type in ["ShapeNode", "SVGNode", "ImageNode"]:
+ # set GenericNode's configuration as shape type
+ gn = data_element.find(f"{{{self.NS_Y}}}GenericNode")
+ if gn:
+ data["shape_type"] = gn.get("configuration")
+ for node_type in ["GenericNode", "ShapeNode", "SVGNode", "ImageNode"]:
pref = f"{{{self.NS_Y}}}{node_type}/{{{self.NS_Y}}}"
geometry = data_element.find(f"{pref}Geometry")
if geometry is not None:
@@ -920,6 +924,9 @@ class GraphMLReader(GraphML):
data["y"] = geometry.get("y")
if node_label is None:
node_label = data_element.find(f"{pref}NodeLabel")
+ shape = data_element.find(f"{pref}Shape")
+ if shape is not None:
+ data["shape_type"] = shape.get("type")
if node_label is not None:
data["label"] = node_label.text
diff --git a/networkx/readwrite/tests/test_graphml.py b/networkx/readwrite/tests/test_graphml.py
index beb62265..da3d2974 100644
--- a/networkx/readwrite/tests/test_graphml.py
+++ b/networkx/readwrite/tests/test_graphml.py
@@ -604,6 +604,29 @@ class TestReadGraphML(BaseGraphML):
</y:ShapeNode>
</data>
</node>
+ <node id="n2">
+ <data key="d6" xml:space="preserve"><![CDATA[description
+line1
+line2]]></data>
+ <data key="d3">
+ <y:GenericNode configuration="com.yworks.flowchart.terminator">
+ <y:Geometry height="40.0" width="80.0" x="950.0" y="286.0"/>
+ <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
+ <y:BorderStyle color="#000000" type="line" width="1.0"/>
+ <y:NodeLabel alignment="center" autoSizePolicy="content"
+ fontFamily="Dialog" fontSize="12" fontStyle="plain"
+ hasBackgroundColor="false" hasLineColor="false" height="17.96875"
+ horizontalTextPosition="center" iconTextGap="4" modelName="custom"
+ textColor="#000000" verticalTextPosition="bottom" visible="true"
+ width="67.984375" x="6.0078125" xml:space="preserve"
+ y="11.015625">3<y:LabelModel>
+ <y:SmartNodeLabelModel distance="4.0"/></y:LabelModel>
+ <y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0"
+ labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0"
+ offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
+ </y:GenericNode>
+ </data>
+ </node>
<edge id="e0" source="n0" target="n1">
<data key="d7">
<y:PolyLineEdge>
@@ -626,24 +649,36 @@ class TestReadGraphML(BaseGraphML):
assert G.has_edge("n0", "n1", key="e0")
assert G.nodes["n0"]["label"] == "1"
assert G.nodes["n1"]["label"] == "2"
+ assert G.nodes["n2"]["label"] == "3"
+ assert G.nodes["n0"]["shape_type"] == "rectangle"
+ assert G.nodes["n1"]["shape_type"] == "rectangle"
+ assert G.nodes["n2"]["shape_type"] == "com.yworks.flowchart.terminator"
+ assert G.nodes["n2"]["description"] == "description\nline1\nline2"
fh.seek(0)
G = nx.read_graphml(fh)
assert list(G.edges()) == [("n0", "n1")]
assert G["n0"]["n1"]["id"] == "e0"
assert G.nodes["n0"]["label"] == "1"
assert G.nodes["n1"]["label"] == "2"
+ assert G.nodes["n2"]["label"] == "3"
+ assert G.nodes["n0"]["shape_type"] == "rectangle"
+ assert G.nodes["n1"]["shape_type"] == "rectangle"
+ assert G.nodes["n2"]["shape_type"] == "com.yworks.flowchart.terminator"
+ assert G.nodes["n2"]["description"] == "description\nline1\nline2"
H = nx.parse_graphml(data, force_multigraph=True)
assert list(H.edges()) == [("n0", "n1")]
assert H.has_edge("n0", "n1", key="e0")
assert H.nodes["n0"]["label"] == "1"
assert H.nodes["n1"]["label"] == "2"
+ assert H.nodes["n2"]["label"] == "3"
H = nx.parse_graphml(data)
assert list(H.edges()) == [("n0", "n1")]
assert H["n0"]["n1"]["id"] == "e0"
assert H.nodes["n0"]["label"] == "1"
assert H.nodes["n1"]["label"] == "2"
+ assert H.nodes["n2"]["label"] == "3"
def test_bool(self):
s = """<?xml version="1.0" encoding="UTF-8"?>