Skip to content

Commit 1a45100

Browse files
committed
feat(plot) +show_chaindocs (by default roor docs hidden)
1 parent 2983ee2 commit 1a45100

File tree

1 file changed

+27
-2
lines changed

1 file changed

+27
-2
lines changed

graphtik/plot.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from contextlib import contextmanager
2424
from contextvars import ContextVar
2525
from functools import partial
26+
from itertools import chain
2627
from typing import (
2728
Any,
2829
Callable,
@@ -162,7 +163,7 @@ def _monkey_patch_for_jupyter(pydot):
162163

163164
def parse_dot_data(s):
164165
"""Patched to fix pydot/pydot#171 by letting ex bubble-up."""
165-
global top_graphs # lint: disable=variable-not-defined-globally
166+
global top_graphs # pylint: disable=variable-not-defined-globally
166167

167168
top_graphs = list()
168169
graphparser = dot_parser.graph_definition()
@@ -176,6 +177,18 @@ def parse_dot_data(s):
176177
_monkey_patch_for_jupyter(pydot)
177178

178179

180+
def is_nx_node_dependent(graph, nx_node):
181+
"""Return true if node's edges are not :term:`subdoc` only. """
182+
return any(
183+
1
184+
for _src, _dst, subdoc in chain(
185+
graph.in_edges(nx_node, data="subdoc"),
186+
graph.out_edges(nx_node, data="subdoc"),
187+
)
188+
if not subdoc
189+
)
190+
191+
179192
# TODO: move to base.py, to reduce fan-in imports (and be frank with module diagram).
180193
def graphviz_html_string(
181194
s, *, repl_nl=None, repl_colon=None, xmltext=None,
@@ -691,6 +704,9 @@ class Theme:
691704
#: When true, plot also :term:`execution steps`, linking operations and evictions
692705
#: with green dotted lines labeled with numbers denoting the execution order.
693706
show_steps = False
707+
#: When true, plot also :term:`hierarchical data` nodes that
708+
#: are not directly linked to operations.
709+
show_chaindocs = False
694710
kw_step = {
695711
"style": "dotted", # Note: Step styles are not *remerged*.`
696712
"color": Ref("steps_color"),
@@ -1094,9 +1110,15 @@ def build_pydot(self, plot_args: PlotArgs) -> pydot.Dot:
10941110
if plot_args.name:
10951111
dot.set_name(as_identifier(plot_args.name))
10961112

1113+
hidden = set()
1114+
10971115
## NODES
10981116
#
10991117
for nx_node, data in graph.nodes.data(True):
1118+
if not theme.show_chaindocs and not is_nx_node_dependent(graph, nx_node):
1119+
hidden.add(nx_node)
1120+
continue
1121+
11001122
plot_args = base_plot_args._replace(nx_item=nx_node, nx_attrs=data)
11011123
dot_node = self._make_node(plot_args)
11021124
plot_args = plot_args._replace(dot_item=dot_node)
@@ -1106,6 +1128,9 @@ def build_pydot(self, plot_args: PlotArgs) -> pydot.Dot:
11061128
## EDGES
11071129
#
11081130
for src, dst, data in graph.edges.data(True):
1131+
if src in hidden or dst in hidden:
1132+
continue
1133+
11091134
plot_args = base_plot_args._replace(nx_item=(src, dst), nx_attrs=data)
11101135
dot.add_edge(self._make_edge(plot_args))
11111136

@@ -1156,7 +1181,7 @@ def _make_node(self, plot_args: PlotArgs) -> pydot.Node:
11561181
11571182
3. Set tooltips with the solution-values for data-nodes.
11581183
"""
1159-
theme = plot_args.theme
1184+
theme: Theme = plot_args.theme
11601185
graph = plot_args.graph
11611186
nx_node = plot_args.nx_item
11621187
node_attrs = plot_args.nx_attrs

0 commit comments

Comments
 (0)