Skip to content
Snippets Groups Projects
Commit f6b610c7 authored by Tomáš Orviský's avatar Tomáš Orviský
Browse files

Reworked diagram drawing

parent 59d065e9
No related merge requests found
manim -pql main.py MainScene
\ No newline at end of file
from manim import *
from typing import Type
from pyPlantUML import *
import parser as p
class MainScene(Scene):
def construct(self):
self.camera.background_color = WHITE
with open('inputs/01_elements.puml', 'r') as file:
# fPath = 'inputs/01_elements.puml'
# fPath = 'inputs/02_relations.puml'
# fPath = 'inputs/03_relations_extra.puml'
# fPath = 'inputs/04_labels.puml'
fPath = 'inputs/_test.puml'
with open(fPath, 'r') as file:
input = file.read()
diagram = p.parser.parse(input)
diagram: Type[Diagram] = p.parser.parse(input)
diagram.setScene(self)
diagram.draw()
if __name__ == "__main__":
config.pixel_height = 720
config.pixel_width = 1280
config.save_as_gif = True
config.cairo_path = "media/images/"
config.ffmpeg_path = "media/videos/"
scene = MainScene()
scene.render()
......@@ -57,7 +57,7 @@ def p_left_relation(p):
leftClass = DiagramClass(leftClassName, 'class')
rightClass = DiagramClass(rightClassName, 'class')
line = DiagramLine(
line = DiagramEdge(
leftClassName + "-" + relation + "-" + rightClassName,
leftClass,
lineData[1],
......@@ -66,7 +66,7 @@ def p_left_relation(p):
relation
)
rightClass.addLine(line)
rightClass.addEdge(line)
p[0] = (leftClass, rightClass)
......@@ -83,7 +83,7 @@ def p_right_relation(p):
leftClass = DiagramClass(leftClassName, 'class')
rightClass = DiagramClass(rightClassName, 'class')
line = DiagramLine(
line = DiagramEdge(
leftClassName + "-" + relation + "-" + rightClassName,
rightClass,
lineData[1],
......@@ -92,7 +92,7 @@ def p_right_relation(p):
relation
)
leftClass.addLine(line)
leftClass.addEdge(line)
p[0] = (leftClass, rightClass)
......@@ -109,7 +109,7 @@ def p_simple_relation(p):
leftClass = DiagramClass(leftClassName, 'class')
rightClass = DiagramClass(rightClassName, 'class')
line = DiagramLine(
line = DiagramEdge(
leftClassName + "-" + rightClassName,
leftClass,
lineData[1],
......@@ -118,7 +118,7 @@ def p_simple_relation(p):
"none"
)
rightClass.addLine(leftClass)
rightClass.addEdge(leftClass)
p[0] = (leftClass, rightClass)
......@@ -136,7 +136,7 @@ def p_bi_relation(p):
leftClass = DiagramClass(leftClassName, 'class')
rightClass = DiagramClass(rightClassName, 'class')
line = DiagramLine(
line = DiagramEdge(
leftClassName + "-" + leftRelation + "-" + rightRelation + "-" + rightClassName,
leftClass,
lineData[1],
......@@ -145,7 +145,7 @@ def p_bi_relation(p):
rightRelation
)
rightClass.addLine(line)
rightClass.addEdge(line)
p[0] = (leftClass, rightClass)
......
import parser as p
from pprint import pprint
fPath = 'inputs/01_elements.puml'
fPath = 'inputs/02_relations.puml'
# fPath = 'inputs/03_relations_extra.puml'
# fPath = 'inputs/04_labels.puml'
# fPath = 'inputs/_test.puml'
with open(fPath, 'r') as file:
input = file.read()
diagram = p.parser.parse(input)
pprint(diagram.objects)
\ No newline at end of file
......@@ -10,35 +10,52 @@ class Diagram(DiagramObject):
self.objects: typing.Dict[str, DiagramObject] = {}
def draw(self):
for o in self.objects:
self.drawObject(o, 0, 0)
def drawObject(self, obj: DiagramObject, x: int, y: int):
for name, obj in self.objects.items():
self.drawObject(obj)
mobj = obj.draw()
for name, obj in self.objects.items():
for i, edge in enumerate(obj.edges):
self.scene.add(edge.draw(obj))
mobj.to_edge(UP)
mobj.shift(RIGHT * 2 * x)
mobj.shift(DOWN * 2 * y)
def drawObject(self, obj: DiagramObject):
self.scene.add(mobj)
if obj.mobject is None:
mobj = obj.draw()
x = len(obj.objects) * -0.5 + 0.5
y += 1
mobj.to_edge(UP)
for o in obj.objects:
self.drawObject(o, x, y)
x += 1
mobj.shift(RIGHT * obj.x * 2)
mobj.shift(DOWN * obj.y * 2)
for l in obj.lines:
self.scene.add(l.draw())
edgeCount = len(obj.edges)
xRange = self.rangeAroundZero(edgeCount)
for i, edge in enumerate(obj.edges):
edge.target.x = edge.target.x + xRange[i]
if edge.target.y == 0:
edge.target.y = obj.y + 1
self.scene.add(mobj)
def addObject(self, obj: DiagramObject):
if obj.name not in self.objects:
self.objects[obj.name] = obj
else:
self.objects[obj.name].lines += obj.lines
for edge in obj.edges:
if edge.target not in self.objects:
self.addObject(edge.target)
edge.target = self.objects[edge.target.name]
self.objects[obj.name].edges += obj.edges
def rangeAroundZero(self, n):
half_n = n // 2
return list(range(-half_n, half_n + 1))
def setScene(self, scene: Scene):
self.scene = scene
from .DiagramObject import DiagramObject
from .DiagramLine import DiagramLine
from . import *
from manim import *
class DiagramClass(DiagramObject):
def __init__(self, name: str, type:str):
def __init__(self, name: str, type: str):
super().__init__(name)
self.type = type
self.lines = []
def addLine(self, line: DiagramLine):
self.lines.append(line)
def draw(self):
......@@ -20,7 +15,7 @@ class DiagramClass(DiagramObject):
text = Text(self.name, color=BLACK, font_size=24)
header.surround(text)
propertyBody = Rectangle(color=GRAY, height=0.2, width=header.width)
propertyBody.next_to(header, DOWN, buff=0)
......@@ -29,4 +24,4 @@ class DiagramClass(DiagramObject):
self.mobject = VGroup(header, text, propertyBody, methodBody)
return self.mobject
\ No newline at end of file
return self.mobject
from . import *
from .DiagramObject import DiagramObject
from manim import *
class DiagramLine(DiagramObject):
class DiagramEdge(DiagramObject):
def __init__(self, name: str, target: DiagramObject, dotted: bool, size: int, sourceArrowType: str, targetArrowType: str):
DiagramObject.__init__(self, name)
......@@ -13,8 +14,27 @@ class DiagramLine(DiagramObject):
self.targetArrowType = targetArrowType
self.doCustomPosition = True
def draw(self):
line = Arrow(self.target.mobject.get_top(), self.source.mobject.get_bottom(), buff=0)
def draw(self, source: DiagramObject):
start = source.mobject.get_top()
target = self.target.mobject.get_bottom()
if source.mobject.get_top()[1] > self.target.mobject.get_bottom()[1]:
start = source.mobject.get_bottom()
target = self.target.mobject.get_top()
startCenter = source.mobject.get_center()
targetCenter = self.target.mobject.get_center()
if source.y == self.target.y:
if startCenter[0] < targetCenter[0]:
start = source.mobject.get_right()
target = self.target.mobject.get_left()
else:
start = source.mobject.get_left()
target = self.target.mobject.get_right()
line = Arrow(start, target, buff=0, stroke_width=1, tip_length=0.25)
line.color = BLACK
self.mobject = line
......@@ -23,9 +43,10 @@ class DiagramLine(DiagramObject):
def __str__(self):
result = super().__str__()
if self.dotted: result += ",dotted"
if self.dotted:
result += ",dotted"
result += ", size: " + str(self.size)
result += ", sourceArrow: " + self.sourceArrowType + "'"
result += ", targetArrow: '" + self.targetArrowType + "'"
return result
\ No newline at end of file
return result
......@@ -2,10 +2,13 @@ from __future__ import annotations
from abc import ABC, abstractmethod
from typing import List
from typing import List, TYPE_CHECKING
from manim import *
if TYPE_CHECKING:
from .DiagramEdge import DiagramEdge
class DiagramObject(ABC):
......@@ -13,11 +16,18 @@ class DiagramObject(ABC):
self.name = name
self.mobject: Mobject = None
self.doCustomPosition = False
self.edges: List[DiagramEdge] = []
self.x = 0
self.y = 0
@abstractmethod
def draw(self) -> Mobject:
pass
def addEdge(self, edge: DiagramEdge):
self.edges.append(edge)
def __str__(self):
result = "<" + self.__class__.__name__ + ">"
result += ", Name: '" + self.name + "'"
......@@ -28,4 +38,4 @@ class DiagramObject(ABC):
return self.__str__()
def __hash__(self):
return hash(str(self))
\ No newline at end of file
return hash(str(self))
from .Diagram import Diagram
from .DiagramObject import DiagramObject
from .DiagramClass import DiagramClass
from .DiagramLine import DiagramLine
\ No newline at end of file
from .DiagramEdge import DiagramEdge
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment