How xlabel and label Are Handled Differently for Edges in graphviz2drawio
In graphviz2drawio, xlabel takes precedence over label when constructing lookup keys for edge attribute enrichment, while the visual text rendered on edges is extracted independently from SVG <text> elements.
The hbmartin/graphviz2drawio converter processes Graphviz DOT files by rendering them to SVG, then parsing that SVG to generate Draw.io diagrams. During this pipeline, edge attributes require special handling to map pygraphviz properties onto the visual elements, which creates a distinct separation between how xlabel and label influence the enrichment process versus the visual output.
Lookup Key Construction: xlabel Precedence
When building the internal attribute map, the converter prioritizes xlabel over label to create unique dictionary keys for each edge. In graphviz2drawio.py at lines 19‑24, the code constructs the lookup key using a fallback chain that checks xlabel first:
graph_edges = {
f"{e[0]}->{e[1]}-"
+ (e.attr.get("xlabel") or e.attr.get("label") or ""): e.attr.to_dict()
for e in graph.edges_iter()
}
This logic ensures that if an edge possesses both attributes, the xlabel value becomes the distinguishing component of the key. Consequently, two edges with identical source, destination, and label values—but different xlabel values—receive distinct entries in the graph_edges dictionary, enabling separate attribute enrichment for each.
Visual Label Extraction from SVG
The actual text displayed on the diagram originates from the SVG rendering rather than the pygraphviz attributes directly. The EdgeFactory.from_svg method in mx/EdgeFactory.py (lines 25‑30) parses the <g class="edge"> groups to collect all <text> elements:
labels: list[Text] = [
text_from_tag
for tag in g
if SVG.is_tag(tag, "text")
and (text_from_tag := Text.from_svg(tag)) is not None
]
These Text objects represent the rendered visual labels and are stored in the edge's labels property. This extraction process operates independently of whether the original Graphviz attribute was xlabel or label, meaning the visual content depends entirely on what Graphviz rendered into the SVG.
Edge Enrichment and Key Matching
After SVG parsing, the converter enriches edge objects with their original pygraphviz attributes by matching the visual labels back to the graph_edges lookup table. The Edge.key_for_enrichment property in mx/Edge.py (lines 111‑116) generates a key based on the SVG text content:
cleaned_label = "\n".join(
[label.text.replace("\xa0", " ") for label in self.labels],
)
return f"{self.gid}-{cleaned_label}"
This enrichment key combines the edge's graph ID (gid) with the cleaned label text extracted from the SVG. The convert function then uses this key to retrieve the corresponding attribute dictionary from graph_edges, effectively linking the visual representation back to the original xlabel or label metadata. Because the lookup table was constructed with xlabel precedence, edges with distinct xlabel values correctly map to their specific attribute sets during this enrichment phase.
Summary
xlabeltakes precedence overlabelwhen forming the lookup key ingraphviz2drawio.py, ensuring edges with differentxlabelvalues receive distinct attribute entries.- Visual labels originate from SVG
<text>elements parsed byEdgeFactory.from_svg, independent of the original Graphviz label attributes. - Enrichment relies on text-based keys generated by
Edge.key_for_enrichmentto map SVG-derived labels back to the pygraphviz attribute dictionary. - Parallel edge merging uses geometric keys (
key_for_label) rather than label values, while attribute distinction relies on thexlabel/labellookup logic.
Frequently Asked Questions
Does xlabel override label in graphviz2drawio?
Yes, during the construction of the edge attribute lookup table in graphviz2drawio.py, the code explicitly checks for xlabel first using the expression e.attr.get("xlabel") or e.attr.get("label"). This ensures that when both attributes are present, the xlabel value determines the dictionary key used for attribute enrichment.
Where does the visual edge text come from?
The visual text displayed on edges originates from SVG <text> elements extracted by the EdgeFactory.from_svg method in mx/EdgeFactory.py. This process parses the rendered SVG output to collect text objects, meaning the displayed content depends on what Graphviz rendered rather than the raw label or xlabel attribute values stored in the DOT file.
How are parallel edges with different labels handled?
Parallel edges are merged during SVG parsing based on geometric properties using Edge.key_for_label in mx/Edge.py, which considers the edge's curve shape and direction rather than label content. However, the subsequent enrichment step uses key_for_enrichment—which incorporates the SVG text content—to distinguish edges with different xlabel or label values and apply the correct attributes from the lookup table.
What is the purpose of the edge enrichment step?
The enrichment step in graphviz2drawio.convert maps pygraphviz edge attributes onto the SVG-derived edge objects by matching the key_for_enrichment (based on SVG text) against the lookup table built with xlabel/label keys. This restoration process ensures that styling, metadata, and other Graphviz properties survive the conversion to Draw.io format despite the intermediate SVG rendering step.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →