提交 a40d97c0 编写于 作者: HansBug's avatar HansBug 😆

dev(hansbug): optimize graphviz visualization

上级 d99d476c
import html
from functools import lru_cache
from typing import Type, Callable, Union, Optional, Tuple
from graphviz import Digraph, nohtml
from graphviz import Digraph
from hbutils.reflection import post_process, dynamic_call, freduce
from .tree import TreeValue
......@@ -134,6 +135,27 @@ _GENERIC_N = 36
_GENERIC_S = _GENERIC_N // 3
def _custom_repr(x):
if isinstance(x, (str,)):
return repr(x)
else:
return str(x)
_LEFT_ALIGN_LINESEP = r'\l'
def _custom_html_escape(x):
s = html.escape(x) \
.replace(' ', ' ') \
.replace('\r\n', _LEFT_ALIGN_LINESEP) \
.replace('\n', _LEFT_ALIGN_LINESEP) \
.replace('\r', _LEFT_ALIGN_LINESEP)
if len(x.splitlines()) > 1 and not s.endswith(_LEFT_ALIGN_LINESEP):
s += _LEFT_ALIGN_LINESEP
return s
def graphics(*trees, title: Optional[str] = None, cfg: Optional[dict] = None,
dup_value: Union[bool, Callable, type, Tuple[Type, ...]] = False,
repr_gen: Optional[Callable] = None,
......@@ -182,9 +204,9 @@ def graphics(*trees, title: Optional[str] = None, cfg: Optional[dict] = None,
return build_graph(
*trees,
node_id_gen=_node_tag,
graph_title=title or "<untitled>",
graph_title=title,
graph_cfg=cfg or {},
repr_gen=repr_gen or (lambda x: nohtml(repr(x))),
repr_gen=repr_gen or (lambda x: _custom_html_escape(_custom_repr(x))),
iter_gen=lambda n: iter(n.items()) if isinstance(n, TreeValue) else None,
node_cfg_gen=_dict_call_merge(lambda n, p, np, pp, is_node, is_root, root: {
'fillcolor': _shape_color(root[2]),
......@@ -193,7 +215,7 @@ def graphics(*trees, title: Optional[str] = None, cfg: Optional[dict] = None,
'style': 'filled',
'shape': 'diamond' if is_root else ('ellipse' if is_node else 'box'),
'penwidth': 3 if is_root else 1.5,
'fontname': "Times-Roman bold" if is_node else "Times-Roman",
'fontname': "monospace" if is_node else "monospace",
}, (node_cfg_gen or (lambda: {}))),
edge_cfg_gen=_dict_call_merge(lambda n, p, np, pp, is_node, root: {
'arrowhead': 'vee' if is_node else 'dot',
......
......@@ -6,8 +6,6 @@ from typing import Optional, Mapping, Any, Callable
from graphviz import Digraph
from hbutils.reflection import dynamic_call, post_process
from .random import random_hex_with_timestamp
def _title_flatten(title):
title = re.sub(r'[^a-zA-Z0-9_]+', '_', str(title))
......@@ -104,7 +102,7 @@ def build_graph(*roots, node_id_gen: Optional[Callable] = None,
roots = [item for item in roots if item is not None]
node_id_gen = dynamic_call(suffixed_node_id(node_id_gen or _default_node_id))
graph_title = graph_title or ('untitled_' + random_hex_with_timestamp())
graph_title = graph_title or ''
graph_name = graph_name or _title_flatten(graph_title)
graph_cfg = _no_none_value(graph_cfg or {})
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册