Skip to content

Commit 3d6d790

Browse files
authored
Merge pull request #16 from csgoh/dev-processpiper-0.4.1
Dev processpiper 0.4.1
2 parents f3e14b1 + 69d52ba commit 3d6d790

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1659
-651
lines changed

.pylintrc

42.7 KB
Binary file not shown.

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ Two frontend applications have been developed to showcase ProcessPiper capabilit
7171
Please refer to [Processpiper Wiki](https://github.com/csgoh/processpiper/wiki) for more information on how to use this library.
7272

7373
## Examples
74-
### (Method 1) Generate diagram using plain text
75-
This is a sample code to generate a business process diagram using plain text.
74+
### (Method 1) Generate diagram using English like PiperFlow syntax
75+
This is a sample code to generate a business process diagram using PiperFlow syntax.
7676
```python
7777
from processpiper.text2diagram import render
7878

images/test/test_auto_case1.png

-1.83 KB
Loading

images/test/test_case1.png

0 Bytes
Loading
-4.01 KB
Loading

images/test/test_case10-DEFAULT.png

-3.76 KB
Loading
-4.12 KB
Loading

images/test/test_case10-GREYWOOF.png

-3.87 KB
Loading
-4 KB
Loading

images/test/test_case11.png

-45 Bytes
Loading

images/test/test_case12.png

-1.24 KB
Loading

images/test/test_case13.png

204 Bytes
Loading

images/test/test_case14.png

199 Bytes
Loading

images/test/test_case15.png

207 Bytes
Loading

images/test/test_case16.png

1011 Bytes
Loading

images/test/test_case17.png

13.5 KB
Loading

images/test/test_case2.png

-6.72 KB
Loading

images/test/test_case3.png

-83 Bytes
Loading

images/test/test_case4.png

-168 Bytes
Loading

images/test/test_case5.png

-1.83 KB
Loading

images/test/test_case6.png

-33 Bytes
Loading

images/test/test_case7.png

-146 Bytes
Loading

images/test/test_case8.png

-1.34 KB
Loading

images/test/test_case9.png

3 Bytes
Loading

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ classifiers = [
1414
"License :: OSI Approved :: MIT License",
1515
"Operating System :: OS Independent",
1616
]
17-
dependencies = ['Pillow>=9.4.0']
17+
dependencies = ['Pillow>=9.5.0']
1818

1919
[project.urls]
2020
"Homepage" = "https://github.com/csgoh/processpiper"

requirements.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
Pillow==9.5.0
2-
pytest==7.2.2
2+
pytest==7.3.2

src/processpiper/activity.py

+4-6
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,14 @@
2626
class Activity(Box):
2727
"""Represents an activity types in a process flow diagram."""
2828

29-
...
30-
3129

3230
class Task(Activity):
3331
"""A task is a special type of activity that is represented by a box."""
3432

35-
...
36-
3733

3834
class Subprocess(Activity):
39-
"""A subprocess is a special type of activity that is represented by a box with a plus sign in it."""
35+
"""A subprocess is a special type of activity that
36+
is represented by a box with a plus sign in it."""
4037

4138
def draw(self, painter: Painter):
4239
super().draw(painter)
@@ -63,4 +60,5 @@ def draw(self, painter: Painter):
6360
raise NotImplementedError("ServiceTask is not implemented yet.")
6461

6562

66-
### To implement: User Task,Script Task,Business Rule Task, Manual Task, Received Task,Send Task, Receive Task
63+
### To implement: User Task,Script Task,Business Rule Task,
64+
# Manual Task, Received Task,Send Task, Receive Task

src/processpiper/colourtheme.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -297,14 +297,15 @@ class ColourTheme:
297297
"""Colour theme for the ProcessPiper."""
298298

299299
def __init__(self, colour_theme_name: str) -> None:
300+
# sourcery skip: simplify-boolean-comparison, use-any
300301
"""Initialise the colour theme."""
301302

302303
found = False
303304
for theme in ColourThemesSettings:
304305
if theme["theme"] == colour_theme_name:
305306
found = True
306307

307-
if found == False:
308+
if found is False:
308309
raise ValueError(f"Colour theme {colour_theme_name} not recognised.")
309310

310311
self._colour_theme_name = colour_theme_name
@@ -314,7 +315,7 @@ def get_colour_theme_settings(self, processmap_component: str) -> tuple:
314315

315316
colour_settings = None
316317

317-
for _, value in enumerate(ColourThemesSettings):
318+
for value in ColourThemesSettings:
318319
if value["theme"] == self._colour_theme_name:
319320
colour_settings = value["settings"]
320321
break

src/processpiper/constants.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,16 @@ class Configs:
3939
LANE_SHAPE_LEFT_MARGIN = 50
4040
LANE_SHAPE_RIGHT_MARGIN = 30
4141

42-
HSPACE_BETWEEN_SHAPES = 50
42+
HSPACE_BETWEEN_SHAPES = 80
4343
VSPACE_BETWEEN_SHAPES = 100
4444

4545
VSPACE_BETWEEN_POOLS = 10
4646
VSPACE_BETWEEN_LANES = 2
4747

4848
HSPACE_BETWEEN_POOL_AND_LANE = 2
49+
50+
BOX_WIDTH = 100
51+
BOX_HEIGHT = 60
52+
CIRCLE_RADIUS = 20
53+
DIAMOND_WIDTH = 40
54+
DIAMOND_HEIGHT = DIAMOND_WIDTH

src/processpiper/event.py

+4-8
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,10 @@ def draw_stop_circle(painter: Painter, x_pos: int, y_pos: int, radius: int):
5555
class Event(Circle):
5656
"""Event class for representing events in a process."""
5757

58-
...
59-
6058

6159
class Start(Event):
6260
"""Start event class for representing start event in a process."""
6361

64-
...
65-
6662

6763
class End(Event):
6864
"""End event class for representing end event in a process."""
@@ -168,10 +164,10 @@ def draw(self, painter: Painter):
168164
circle_center[0] - envelope_width // 2,
169165
circle_center[1] - envelope_height // 2,
170166
)
171-
envelope_bottom_right = (
172-
circle_center[0] + envelope_width // 2,
173-
circle_center[1] + envelope_height // 2,
174-
)
167+
# envelope_bottom_right = (
168+
# circle_center[0] + envelope_width // 2,
169+
# circle_center[1] + envelope_height // 2,
170+
# )
175171

176172
painter.draw_box_with_outline(
177173
envelope_top_left[0],

src/processpiper/helper.py

+32-3
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,43 @@
2323

2424

2525
class Helper:
26+
show_layout_grid = False
27+
show_pool_lane = False
28+
show_x_position = False
29+
show_y_position = False
30+
show_draw_position = False
31+
show_draw_connection = False
32+
show_draw = False
33+
show_general = False
34+
35+
@staticmethod
36+
def printc(
37+
message: str, color: str = "30", end: str = "\n", show_level: str = "general"
38+
):
39+
"""Print text in color"""
40+
41+
root_logger = logging.getLogger()
42+
43+
if root_logger.getEffectiveLevel() == logging.DEBUG and (
44+
(show_level == "layout_grid" and Helper.show_layout_grid)
45+
or (show_level == "pool_lane" and Helper.show_pool_lane)
46+
or (show_level == "x_position" and Helper.show_x_position)
47+
or (show_level == "y_position" and Helper.show_y_position)
48+
or (show_level == "draw_connection" and Helper.show_draw_connection)
49+
or (show_level == "draw_position" and Helper.show_draw_position)
50+
or (show_level == "draw" and Helper.show_draw)
51+
or (show_level == "general" and Helper.show_general)
52+
):
53+
print(f"\033[1;{color}m{message}\033[0m", end=end)
54+
2655
@staticmethod
27-
def printc(message: str, color: str = "30"):
56+
def print_info(message: str, color: str = "30", end: str = "\n"):
2857
"""Print text in color"""
2958

3059
root_logger = logging.getLogger()
3160

32-
if root_logger.getEffectiveLevel() == logging.DEBUG:
33-
print(f"\033[1;{color}m{message}\033[0m")
61+
if root_logger.getEffectiveLevel() == logging.INFO:
62+
print(f"\033[1;{color}m{message}\033[0m", end=end)
3463

3564
@staticmethod
3665
def debug_log(message: str):

src/processpiper/lane.py

+47-108
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
from .gateway import *
3030
from .constants import Configs
3131
from .helper import Helper
32+
from .layout import Grid
3233

3334
# from .helper import Helper
3435

@@ -165,31 +166,6 @@ def __enter__(self):
165166
def __exit__(self, exc_type, exc_value, traceback) -> None:
166167
pass
167168

168-
def get_current_y_position(self) -> int:
169-
"""Get the current y position of the lane"""
170-
if self.shape_row_count == 0:
171-
self.shape_row_count = 1
172-
if self.next_shape_y == 0:
173-
self.next_shape_y = self.y + Configs.LANE_SHAPE_TOP_MARGIN
174-
175-
return self.next_shape_y
176-
177-
def get_next_y_position(self) -> int:
178-
"""Get the next y position of the lane"""
179-
180-
if self.next_shape_y == 0:
181-
# self.next_shape_y = self.y + 60 + Configs.LANE_SHAPE_TOP_MARGIN
182-
self.next_shape_y = self.y + Configs.LANE_SHAPE_TOP_MARGIN
183-
else:
184-
self.next_shape_y += 60 + Configs.VSPACE_BETWEEN_SHAPES
185-
186-
### For every method call, increment the shape row count
187-
if self.shape_row_count == 0:
188-
self.shape_row_count = 1
189-
else:
190-
self.shape_row_count += 1
191-
return self.next_shape_y
192-
193169
def draw(self) -> None:
194170
"""Draw the lane"""
195171

@@ -233,100 +209,63 @@ def draw_shape(self) -> None:
233209
if self.shapes:
234210
for shape in self.shapes:
235211
Helper.printc(
236-
f"Drawing shape: {shape.name}, x={shape.x}, y={shape.y}, w={shape.width}, h={shape.height}"
212+
f" Drawing shape: {shape.name}, x={shape.x}, y={shape.y}, w={shape.width}, h={shape.height}",
213+
show_level="draw",
237214
)
238215
shape.draw(self.painter)
239216

240-
def draw_connection(self) -> None:
217+
def draw_connection(self, all_shapes: list) -> None:
241218
"""Draw the connections in the lane"""
242219
if self.shapes:
243220
for shape in self.shapes:
244-
shape.draw_connection(self.painter)
221+
shape.draw_connection(self.painter, all_shapes)
245222

246-
def set_draw_position(self, x: int, y: int, painter: Painter) -> None:
223+
def set_draw_position(self, x: int, y: int, layout_grid: Grid) -> None:
247224
"""Set the draw position of the lane"""
248225

249-
self.painter = painter
226+
# self.painter = painter
227+
228+
### Determine the number of rows for the lane
229+
lane_row_count = layout_grid.get_lane_row_count(self.id)
250230

251-
### Determine the x and y position of the lane
252-
### If x and y are not specified, add the default margin
253-
self.x = x if x > 0 else Configs.SURFACE_LEFT_MARGIN + Configs.POOL_TEXT_WIDTH
231+
### Determine lane x and y position
232+
self.x = (
233+
x
234+
if x > 0
235+
else Configs.SURFACE_LEFT_MARGIN
236+
+ Configs.POOL_TEXT_WIDTH
237+
+ Configs.HSPACE_BETWEEN_POOL_AND_LANE
238+
)
254239
self.y = y if y > 0 else Configs.SURFACE_TOP_MARGIN
255240

256-
if self.shapes:
257-
self.next_shape_x = (
258-
self.x
259-
+ Configs.POOL_TEXT_WIDTH
260-
+ Configs.LANE_TEXT_WIDTH
261-
+ Configs.LANE_SHAPE_LEFT_MARGIN
262-
)
263-
264-
shape_x, shape_y, shape_w, shape_h = self.set_shape_draw_position(
265-
self.next_shape_x, self.y, self.shapes[0], painter
266-
)
267-
268-
self.width = max(self.width, shape_x + shape_w)
269-
self.height = max(
270-
self.height,
271-
shape_y + shape_h - self.y + Configs.LANE_SHAPE_BOTTOM_MARGIN,
272-
)
273-
274-
self.next_shape_x = shape_x + shape_w + Configs.HSPACE_BETWEEN_SHAPES
275-
276-
return self.x, self.y, self.width, self.height
277-
278-
def set_shape_draw_position(
279-
self, x: int, y: int, shape: Shape, painter: Painter
280-
) -> None:
281-
"""Set the draw position of the shapes in the lane"""
282-
### Set own shape position
283-
if shape.lane_name == self.name:
284-
shape_x, shape_y, shape_w, shape_h = shape.set_draw_position(
285-
x,
286-
(y + Configs.LANE_SHAPE_TOP_MARGIN),
287-
painter,
288-
)
289-
290-
#### Mark for removal
291-
# shape.draw_position_set = True
292-
293-
shape.x_pos_traversed = True
294-
295-
### Set next elements' position
296-
for index, next_shape in enumerate(shape.connection_to.target):
297-
### Check whether the position has been set, if yes, skipped.
298-
### This is needed to avoid infinite recursion
299-
if next_shape.traversed == True:
300-
continue
301-
302-
if index == 0:
303-
next_shape_y = y
304-
else:
305-
next_shape_y = (
306-
y
307-
+ Configs.LANE_SHAPE_TOP_MARGIN
308-
+ Configs.HSPACE_BETWEEN_SHAPES
309-
+ shape_h
310-
)
311-
312-
### Perform recursive call to set the position of the next element
313-
(
314-
next_shape_x,
315-
next_shape_y,
316-
next_shape_w,
317-
next_shape_h,
318-
) = self.set_shape_draw_position(
319-
self.next_shape_x, next_shape_y, next_shape, painter
320-
)
241+
### Determine lane width
242+
max_column_count = layout_grid.get_max_column_count()
243+
Helper.printc(
244+
f"~~~ max column count: {max_column_count}", show_level="pool_lane"
245+
)
246+
self.width = (
247+
(Configs.HSPACE_BETWEEN_SHAPES * max_column_count - 1)
248+
+ (Configs.BOX_WIDTH * max_column_count)
249+
+ (Configs.LANE_SHAPE_LEFT_MARGIN)
250+
)
321251

322-
shape_x, shape_y, shape_w, shape_h = (
323-
max(shape_x, next_shape_x),
324-
max(shape_y, next_shape_y),
325-
max(shape_w, next_shape_w),
326-
max(shape_h, next_shape_h),
327-
)
328-
self.next_shape_x = next_shape_x
329-
else:
330-
shape_x, shape_y, shape_w, shape_h = 0, 0, 0, 0
252+
Helper.printc(
253+
f"~~~ Lane: [{self.name}] shape row count: {lane_row_count}",
254+
35,
255+
show_level="pool_lane",
256+
)
257+
258+
### Determine lane height
259+
self.height = (
260+
(lane_row_count * 60)
261+
+ ((lane_row_count - 1) * Configs.VSPACE_BETWEEN_SHAPES)
262+
+ Configs.LANE_SHAPE_TOP_MARGIN
263+
+ Configs.LANE_SHAPE_BOTTOM_MARGIN
264+
)
265+
Helper.printc(
266+
f"~~~ [{self.name}] {self.x=}, {self.y=}, {self.width=}, {self.height=}",
267+
show_level="pool_lane",
268+
)
269+
y_pos = self.y + self.height + Configs.VSPACE_BETWEEN_LANES
331270

332-
return shape_x, shape_y, shape_w, shape_h
271+
return self.x, y_pos, self.width, self.height

0 commit comments

Comments
 (0)