puudot/code/graph.py
Lauri Koskenniemi be4efa0fd2 First test version and data cleanup
Implemented code for the first test version.
Added Docker funtionality.

Define data location in compose and run:
	docker compose up

Removed test data from the repository.
2025-05-24 16:54:19 +03:00

94 lines
2.7 KiB
Python

import os
import uuid
HEADER = """
graph {
graph [splines=ortho, nodesep=1]
node [color=white]
compound=true
"""
FOOTER = """
}
"""
class Graph:
def __init__(self):
self.blocks = {}
self.nodes = []
self.links = {}
self.dot_file = ""
def __str__(self):
return self.dot_file
def get_id(self):
return "id" + str(uuid.uuid4().hex)
def process_blocks(self, data):
blocks = data.get('blocks', [])
for block in blocks:
block_id = self.get_id()
new_block = {
"label": block.get("label", ""),
"layer": block.get("layer", 0),
"texts": []
}
for text in block.get("texts", []):
node_id = self.get_id()
self.nodes.append({"id": node_id, "text": text.get("text", "")})
new_block["texts"].append(node_id)
links = text.get("links", {})
if links != {}:
from_links = links.get("from", [])
to_links = links.get("to", [])
for from_link in from_links:
self.links[from_link] = {"from": node_id, "to": "", "head": ""}
for to_link in to_links:
if to_link in self.links:
self.links[to_link]["to"] = node_id
self.links[to_link]["head"] = block_id
self.blocks[block_id] = new_block
def build_dot(self):
self.dot_file = HEADER
for node in self.nodes:
self.dot_file += f"{node['id']} [label=\"{node['text']}\"]\n"
self.dot_file += "\n"
for block_id, block in self.blocks.items():
self.dot_file += f"subgraph cluster_{block_id} {{\n"
self.dot_file += f"label=\"{block['label']}\"\n"
self.dot_file += f"labeljust=l\n"
for node in block["texts"]:
self.dot_file += f"{node}\n"
self.dot_file += "}\n\n"
for link in self.links:
if self.links[link]["to"] != "":
self.dot_file += f"{self.links[link]['from']} -- {self.links[link]['to']}"
if self.links[link]["head"] != "":
self.dot_file += f" [lhead=cluster_{self.links[link]['head']}]"
self.dot_file += "\n"
self.dot_file += FOOTER
def make_dot(self, format="svg", dot_file="dot.gv", svg_file="graph.svg"):
if self.dot_file != "":
with open(dot_file, "w") as f:
f.write(self.dot_file)
if format == "svg":
os.system(f"dot -T{format} {dot_file} -o {svg_file}")