frameplot 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- frameplot/__init__.py +7 -0
- frameplot/api.py +61 -0
- frameplot/layout/__init__.py +268 -0
- frameplot/layout/order.py +169 -0
- frameplot/layout/place.py +193 -0
- frameplot/layout/rank.py +54 -0
- frameplot/layout/route.py +1031 -0
- frameplot/layout/scc.py +69 -0
- frameplot/layout/text.py +74 -0
- frameplot/layout/types.py +165 -0
- frameplot/layout/validate.py +108 -0
- frameplot/model.py +129 -0
- frameplot/render/__init__.py +4 -0
- frameplot/render/png.py +20 -0
- frameplot/render/svg.py +306 -0
- frameplot/theme.py +59 -0
- frameplot-0.1.0.dist-info/METADATA +132 -0
- frameplot-0.1.0.dist-info/RECORD +21 -0
- frameplot-0.1.0.dist-info/WHEEL +5 -0
- frameplot-0.1.0.dist-info/licenses/LICENSE +21 -0
- frameplot-0.1.0.dist-info/top_level.txt +1 -0
frameplot/layout/rank.py
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import heapq
|
|
4
|
+
|
|
5
|
+
from frameplot.layout.scc import SccResult
|
|
6
|
+
from frameplot.layout.types import ValidatedPipeline
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def assign_ranks(validated: ValidatedPipeline, scc_result: SccResult) -> dict[str, int]:
|
|
10
|
+
component_count = len(scc_result.components)
|
|
11
|
+
component_widths = [max(1, len(component)) for component in scc_result.components]
|
|
12
|
+
predecessors: dict[int, set[int]] = {component_id: set() for component_id in range(component_count)}
|
|
13
|
+
successors: dict[int, set[int]] = {component_id: set() for component_id in range(component_count)}
|
|
14
|
+
|
|
15
|
+
for edge in validated.edges:
|
|
16
|
+
source_component = scc_result.node_to_component[edge.source]
|
|
17
|
+
target_component = scc_result.node_to_component[edge.target]
|
|
18
|
+
if source_component == target_component:
|
|
19
|
+
continue
|
|
20
|
+
predecessors[target_component].add(source_component)
|
|
21
|
+
successors[source_component].add(target_component)
|
|
22
|
+
|
|
23
|
+
in_degree = {component_id: len(predecessors[component_id]) for component_id in predecessors}
|
|
24
|
+
heap: list[tuple[int, int]] = []
|
|
25
|
+
for component_id, degree in in_degree.items():
|
|
26
|
+
if degree == 0:
|
|
27
|
+
min_index = min(validated.node_index[node_id] for node_id in scc_result.components[component_id])
|
|
28
|
+
heapq.heappush(heap, (min_index, component_id))
|
|
29
|
+
|
|
30
|
+
topo_order: list[int] = []
|
|
31
|
+
while heap:
|
|
32
|
+
_, component_id = heapq.heappop(heap)
|
|
33
|
+
topo_order.append(component_id)
|
|
34
|
+
for successor in sorted(successors[component_id]):
|
|
35
|
+
in_degree[successor] -= 1
|
|
36
|
+
if in_degree[successor] == 0:
|
|
37
|
+
min_index = min(
|
|
38
|
+
validated.node_index[node_id] for node_id in scc_result.components[successor]
|
|
39
|
+
)
|
|
40
|
+
heapq.heappush(heap, (min_index, successor))
|
|
41
|
+
|
|
42
|
+
base_rank: dict[int, int] = {}
|
|
43
|
+
for component_id in topo_order:
|
|
44
|
+
base_rank[component_id] = max(
|
|
45
|
+
(base_rank[pred] + component_widths[pred] for pred in predecessors[component_id]),
|
|
46
|
+
default=0,
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
ranks: dict[str, int] = {}
|
|
50
|
+
for component_id, component in enumerate(scc_result.components):
|
|
51
|
+
for offset, node_id in enumerate(component):
|
|
52
|
+
ranks[node_id] = base_rank[component_id] + offset
|
|
53
|
+
|
|
54
|
+
return ranks
|