Skip to content

Commit b441f02

Browse files
committed
add path handling so that clusters/groups will display correctly
1 parent eb55e9b commit b441f02

File tree

8 files changed

+404
-6
lines changed

8 files changed

+404
-6
lines changed

.idea/misc.xml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

graphviz2drawio/graphviz2drawio.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def convert(
1414
graph_to_convert: AGraph | str | TextIOBase | Path | TextIO,
1515
layout_prog: str = "dot",
1616
) -> str:
17-
graph = _load_pygraphviz_graph(graph_to_convert)
17+
graph = _load_pygraphviz_agraph(graph_to_convert)
1818

1919
graph_edges: dict[str, dict] = {
2020
f"{e[0]}->{e[1]}-"
@@ -49,12 +49,16 @@ def convert(
4949
return mx_graph.value()
5050

5151

52-
def _load_pygraphviz_graph(
52+
def _load_pygraphviz_agraph( # noqa: PLR0911
5353
graph_to_convert: AGraph | str | TextIOBase | Path | TextIO,
5454
) -> AGraph:
5555
if isinstance(graph_to_convert, AGraph):
5656
return graph_to_convert
5757
if isinstance(graph_to_convert, str):
58+
if graph_to_convert.endswith((".dot", ".gv", ".txt")):
59+
return AGraph(filename=graph_to_convert)
60+
if graph_to_convert.endswith(("}", "}\n")):
61+
return AGraph(string=graph_to_convert)
5862
# This fixes a pygraphviz bug where a string beginning with a comment
5963
# is mistakenly identified as a filename.
6064
# https://github.com/pygraphviz/pygraphviz/issues/536
@@ -63,6 +67,7 @@ def _load_pygraphviz_graph(
6367
flags=re.MULTILINE,
6468
)
6569
if pattern.search(graph_to_convert):
70+
# graph_to_convert was a graph / dot string
6671
return AGraph(string=graph_to_convert)
6772
return AGraph(filename=graph_to_convert)
6873
# pyrefly: ignore # missing-attribute

graphviz2drawio/mx/NodeFactory.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@
77
from . import MxConst, Shape
88
from .MxConst import DEFAULT_STROKE_WIDTH
99
from .Node import Gradient, Node
10-
from .RectFactory import rect_from_ellipse_svg, rect_from_image, rect_from_svg_points
10+
from .RectFactory import (
11+
rect_from_ellipse_svg,
12+
rect_from_image,
13+
rect_from_svg_path,
14+
rect_from_svg_points,
15+
)
1116
from .Text import Text
1217
from .utils import adjust_color_opacity
1318

@@ -64,6 +69,11 @@ def from_svg(
6469
stroke_width = ellipse.attrib.get("stroke-width", DEFAULT_STROKE_WIDTH)
6570
if "stroke-dasharray" in ellipse.attrib:
6671
dashed = True
72+
elif (path := SVG.get_first(g, "path")) is not None:
73+
rect = rect_from_svg_path(self.coords, path.attrib["d"])
74+
shape = Shape.RECT
75+
fill = self._extract_fill(path, gradients)
76+
stroke = self._extract_stroke(path)
6777
else:
6878
shape = Shape.ELLIPSE
6979

graphviz2drawio/mx/RectFactory.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,27 @@
1+
from svg import path as svg_path
2+
13
from ..models.CoordsTranslate import CoordsTranslate
24
from ..models.Rect import Rect
35

46

7+
def rect_from_svg_path(coords: CoordsTranslate, path_d: str) -> Rect:
8+
parsed_path: svg_path.Path = svg_path.parse_path(path_d)
9+
start: svg_path.Move = parsed_path.pop(0)
10+
min_x = start.start.real
11+
min_y = start.start.imag
12+
max_x = start.start.real
13+
max_y = start.start.imag
14+
for e in parsed_path:
15+
min_x = min(min_x, e.start.real, e.end.real)
16+
min_y = min(min_y, e.start.imag, e.end.imag)
17+
max_x = max(max_x, e.start.real, e.end.real)
18+
max_y = max(max_y, e.start.imag, e.end.imag)
19+
20+
(x, y) = coords.translate(min_x, min_y)
21+
22+
return Rect(x=x, y=y, width=max_x - min_x, height=max_y - min_y)
23+
24+
525
def rect_from_svg_points(coords: CoordsTranslate, svg: str) -> Rect:
626
"""Don't use this function.
727

graphviz2drawio/mx/Styles.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class Styles(Enum):
8181
)
8282
LARROW = "flipH=1;" + RARROW
8383
IMAGE = (
84-
"shape=image;verticalLabelPosition=bottom;labelBackgroundColor=default;verticalAlign=top;aspect=fixed;"
84+
"shape=image;verticalLabelPosition=top;labelBackgroundColor=default;verticalAlign=top;aspect=fixed;"
8585
"imageAspect=0;image={image};" + NODE
8686
)
8787

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@
4141
"Programming Language :: Python :: 3.14",
4242
],
4343
license="GPLv3",
44-
keywords="graphviz graph agraph dot convert conversion draw drawio mxgraph maxgraph",
44+
keywords="graphviz graph agraph dot convert conversion diagrams drawio mxgraph maxgraph Lucidchart",
4545
packages=find_packages(exclude=["doc", "test"]),
4646
python_requires=">=3.10",
4747
install_requires=["puremagic", "pygraphviz", "svg.path"],
48-
tests_require=["pytest"],
48+
tests_require=["diagrams", "pytest"],
4949
entry_points={"console_scripts": ["graphviz2drawio=graphviz2drawio.__main__:main"]},
5050
project_urls={
5151
"Bug Reports": "https://github.com/hbmartin/graphviz2drawio/issues",

test/directed/with_image.gv.txt

Whitespace-only changes.

test/test_diagrams_generate.py

Lines changed: 360 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)