Skip to content

Commit

Permalink
factor out RectFactory
Browse files Browse the repository at this point in the history
  • Loading branch information
hbmartin committed Jul 6, 2024
1 parent 0bb964c commit 3f6e49b
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 44 deletions.
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,9 @@ python -m graphviz2drawio test/directed/hello.gv.txt
- [x] Improved Bezier curve support [done](https://github.com/hbmartin/graphviz2drawio/pull/81)
- [ ] Subgraph conversion #33
- [ ] Invisible node handling for edges #67
- [ ] Image / tooltip support #49
- [ ] Image / tooltip support [#45](https://github.com/hbmartin/graphviz2drawio/issues/45)
- [ ] Text on edge alignment #59
- [ ] Support for node with `path` shape #47
- [x] Run ruff in CI

## Roadmap to 0.5
- [ ] Migrate to uv/hatch for packaging and dep mgmt
Expand Down
2 changes: 1 addition & 1 deletion graphviz2drawio/models/CoordsTranslate.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ def translate(self, x, y):
return float(x) + self.x, float(y) + self.y

@staticmethod
def from_svg_transform(transform):
def from_svg_transform(transform: str) -> "CoordsTranslate":
x, y = transform.split("translate(")[1].split(")")[0].split(" ")
return CoordsTranslate(x=float(x), y=float(y))
48 changes: 7 additions & 41 deletions graphviz2drawio/mx/NodeFactory.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from xml.etree.ElementTree import Element

from graphviz2drawio.models import SVG
from graphviz2drawio.models.Rect import Rect

from . import Shape
from .Node import Node
from .RectFactory import rect_from_ellipse_svg, rect_from_image, rect_from_svg_points
from .Text import Text


Expand All @@ -13,61 +13,27 @@ def __init__(self, coords) -> None:
super().__init__()
self.coords = coords

def rect_from_svg_points(self, svg: str) -> Rect:
points = svg.split(" ")
points = [self.coords.translate(*p.split(",")) for p in points]
min_x, min_y = points[0]
width = 0
height = 0
for p in points:
if p[0] < min_x:
min_x = p[0]
if p[1] < min_y:
min_y = p[1]
for p in points:
test_width = p[0] - min_x
test_height = p[1] - min_y
if test_width > width:
width = test_width
if test_height > height:
height = test_height
return Rect(x=min_x, y=min_y, width=width, height=height)

@staticmethod
def rect_from_image(attrib: dict[str, str]) -> Rect:
filtered = {
k: float(v.strip("px"))
for k, v in attrib.items()
if k in ["x", "y", "width", "height"]
}
return Rect(**filtered)

def rect_from_ellipse_svg(self, attrib: dict[str, str]) -> Rect:
cx = float(attrib["cx"])
cy = float(attrib["cy"])
rx = float(attrib["rx"])
ry = float(attrib["ry"])
x, y = self.coords.translate(cx, cy)
return Rect(x=x - rx, y=y - ry, width=rx * 2, height=ry * 2)

def from_svg(self, g: Element) -> Node:
texts = self._extract_texts(g)
rect = None
fill = g.attrib.get("fill", None)
stroke = g.attrib.get("stroke", None)

if (polygon := SVG.get_first(g, "polygon")) is not None:
rect = self.rect_from_svg_points(polygon.attrib["points"])
rect = rect_from_svg_points(self.coords, polygon.attrib["points"])
shape = Shape.RECT
if "stroke" in polygon.attrib:
stroke = polygon.attrib["stroke"]
if "fill" in polygon.attrib:
fill = polygon.attrib["fill"]
elif (image := SVG.get_first(g, "image")) is not None:
rect = self.rect_from_image(image.attrib)
rect = rect_from_image(image.attrib)
shape = Shape.RECT
elif (ellipse := SVG.get_first(g, "ellipse")) is not None:
rect = self.rect_from_ellipse_svg(ellipse.attrib)
rect = rect_from_ellipse_svg(
coords=self.coords,
attrib=ellipse.attrib, # pytype: disable=attribute-error
)
shape = Shape.ELLIPSE
if "fill" in ellipse.attrib:
fill = ellipse.attrib["fill"]
Expand Down
41 changes: 41 additions & 0 deletions graphviz2drawio/mx/RectFactory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from graphviz2drawio.models import Rect
from graphviz2drawio.models.CoordsTranslate import CoordsTranslate


def rect_from_svg_points(coords: CoordsTranslate, svg: str) -> Rect:
points = svg.split(" ")
points = [coords.translate(*p.split(",")) for p in points]
min_x, min_y = points[0]
width = 0
height = 0
for p in points:
if p[0] < min_x:
min_x = p[0]
if p[1] < min_y:
min_y = p[1]
for p in points:
test_width = p[0] - min_x
test_height = p[1] - min_y
if test_width > width:
width = test_width
if test_height > height:
height = test_height
return Rect(x=min_x, y=min_y, width=width, height=height)


def rect_from_image(attrib: dict[str, str]) -> Rect:
filtered = {
k: float(v.strip("px"))
for k, v in attrib.items()
if k in ["x", "y", "width", "height"]
}
return Rect(**filtered)


def rect_from_ellipse_svg(coords: CoordsTranslate, attrib: dict[str, str]) -> Rect:
cx = float(attrib["cx"])
cy = float(attrib["cy"])
rx = float(attrib["rx"])
ry = float(attrib["ry"])
x, y = coords.translate(cx, cy)
return Rect(x=x - rx, y=y - ry, width=rx * 2, height=ry * 2)

0 comments on commit 3f6e49b

Please sign in to comment.