Skip to content

Commit 53d7269

Browse files
committed
REFACT: PLOT OPs HTML LABEL
1 parent cd130fc commit 53d7269

File tree

12 files changed

+708
-243
lines changed

12 files changed

+708
-243
lines changed

.vscode/cspell.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"autodoc",
2828
"autodocs",
2929
"baumgartner",
30+
"BGCOLOR",
3031
"blackline",
3132
"boltons",
3233
"bools",

CHANGES.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ Changelog
1616
%%%%%%%%%
1717

1818

19+
v5.8.0 (8 Apr 2020, @ankostis): Plot job, fix RTD deps
20+
======================================================
21+
+ FEAT(PLOT): plots are now fully configurable with *graph*, *node* & *edge*
22+
("non-private") attributes, conveyed with the `networkx` graph given to plot routine.
23+
24+
+ drop(plot): don't suppress the grafting of the title in netop images.
25+
26+
1927
v5.7.1 (7 Apr 2020, @ankostis): Plot job, fix RTD deps
2028
======================================================
2129
+ ENH(PLOT): Operation tooltips now show function sources.

docs/source/arch.rst

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -359,17 +359,26 @@ Architecture
359359
A :class:`.Plotter` is responsible for rendering `plottable`\s as images.
360360
It is the `installed plotter` that does that, unless overridden in a
361361
:meth:`.Plottable.plot()` call.
362-
Plotters can be customized by :ref:`various means <plot-customizations>`.
362+
Plotters can be customized by :ref:`various means <plot-customizations>`,
363+
such `plot styles`.
363364

364365
installed plotter
365-
The `plotter` currently installed in the respective `graphtik configuration`
366-
with one of :func:`.installed_plotter` or :func:`.set_installed_plotter`
367-
functions - this term implies also any :ref:`plot-customizations`
368-
done on the installed plotter's :class:`.plot.Style` attribute.
366+
default installed plotter
367+
The `plotter` currently installed "in-context" of the respective `graphtik
368+
configuration` - this term implies also any :ref:`plot-customizations`
369+
done on the installed plotter (such as `plot styles`).
370+
371+
Installation happens by calling one of :func:`.installed_plotter` or
372+
:func:`.set_installed_plotter` functions.
369373

370374
The **default** *installed plotter* is the plotter instance that this project
371375
comes pre-configured with, ie, when no *plot-customizations* have yet happened.
372376

377+
plot styles
378+
The attributes of :class:`.plot.Style` class.
379+
The actual styles in-use are those in the :attr:`.Plotter.style` attribute
380+
of the `installed plotter`.
381+
373382

374383
.. default-role:: obj
375384
.. |v410-flowchart| raw:: html

docs/source/conf.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
from sphinx.application import Sphinx
3131

3232
from graphtik.base import func_sourcelines
33-
from graphtik.plot import Plotter, Style, get_installed_plotter, set_installed_plotter
33+
from graphtik import plot
3434

3535

3636
log = logging.getLogger(__name__)
@@ -101,10 +101,14 @@
101101
"gg": ("https://github.com/pygraphkit/graphtik/issues/%s", "#"),
102102
}
103103

104-
# Plot graphs with links to docs.
105-
plotter = get_installed_plotter().copy()
106-
plotter.style.kw_op_url = {"url_format": "../reference.html#%s", "target": "_top"}
107-
set_installed_plotter(plotter)
104+
# Save dot files, for debug.
105+
graphtik_save_dot_files = True
106+
107+
# Plot graphtik SVGs with links to docs.
108+
#
109+
plotter = plot.get_installed_plotter().copy()
110+
plotter.style.py_item_url_format = "../reference.html#%(dot_path)s"
111+
plot.set_installed_plotter(plotter)
108112

109113
github_slug = "pygraphkit/graphtik"
110114
try:

docs/source/plotting.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ Plot customizations
324324
You may customize the styles and/or *plotter* behavior with various methods,
325325
ordered by breadth of the effects (most broadly effecting method at the top):
326326

327-
1. Get and modify in-place the styles of the *default* :term:`installed plotter`,
327+
1. Get and modify in-place the styles of the :term:`default installed plotter`,
328328
like that::
329329

330330
get_installed_plotter().style.kw_op["fillcolor"] = "purple"

graphtik/base.py

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,7 @@ def func_source(fn, default=..., human=None) -> Optional[Tuple[str, int]]:
208208
If given, better be a 2-tuple respecting types,
209209
or ``...``, to raise.
210210
:param human:
211-
when true, partials denote their args like ``$fn(a=1, ...)`` in the returned text,
212-
otherwise, just the (fqd-)name, appropriate for IDs.
211+
when true, denote builtins like python does
213212
"""
214213
import inspect
215214

@@ -450,13 +449,30 @@ def plot(
450449
No need to quote it, handled by the plotter, downstream.
451450
:param str graph:
452451
(optional) A :class:`nx.Digraph` with overrides to merge with the graph provided
453-
by underlying plottables (depending of course on the :term:`installed plotter`).
454-
It may contain "public" graph, node & edge attributes eventually reaching
455-
`Graphviz`_.
452+
by underlying plottables (translated by the :term:`installed plotter`).
453+
454+
It may contain "public" or "private *graph*, *node* & *edge* attributes:
455+
456+
- "private" attributes: those starting with underscore(``_``),
457+
handled by :term:`plotter`:
458+
459+
- ``_source`` *(graph)*: a non user-overridable attribute with values
460+
used to select plotter-styles::
461+
462+
netop | net | plan | solution | <'_source` missing>
463+
- ``_fn_link_target`` & ``_fn_link_target`` *(node)*: if truthy,
464+
override result 2-tuple of :meth:`_get_fn_link()`.
465+
- ``_op_tooltip`` & ``_fn_tooltip`` *(node)*: if truthy,
466+
override those derrived from :meth:`_make_op_tooltip()` &
467+
:meth:`_make_op_tooltip()`.
468+
469+
- "public" attributes: reaching `Graphviz`_ as-is.
470+
471+
.. Note::
472+
473+
Remember to escape those values as `Graphviz`_ HTML-Like strings
474+
(use :func:`.plot.graphviz_html_string()`).
456475
457-
.. Note::
458-
Remember to properly escape values for `Graphviz`_
459-
e.g. with :func:`html.escape()` or :func:`.plot.quote_dot_word()`.
460476
:param inputs:
461477
an optional name list, any nodes in there are plotted
462478
as a "house"
@@ -552,7 +568,7 @@ def plot(
552568
fontname=italic;
553569
label=<netop>;
554570
splines=ortho;
555-
<a> [fillcolor=wheat, shape=invhouse, style=filled, tooltip=<(int) 1>];
571+
<a> [fillcolor=wheat, shape=invhouse, style=filled, tooltip="(int) 1"];
556572
...
557573
558574
"""

graphtik/netop.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,14 +247,15 @@ def withset(
247247

248248
def prepare_plot_args(self, plot_args: PlotArgs) -> PlotArgs:
249249
"""Delegate to network if last-plan does not exist. """
250-
from .plot import quote_dot_word
250+
from .plot import graphviz_html_string
251251

252252
plottable = self.last_plan or self.net
253253
plot_args = plot_args.with_defaults(name=self.name)
254254
plot_args = plottable.prepare_plot_args(plot_args)
255255
assert plot_args.graph, plot_args
256256

257-
plot_args.graph.graph.setdefault("label", quote_dot_word(self.name))
257+
plot_args.graph.graph.setdefault("label", graphviz_html_string(self.name))
258+
plot_args.graph.graph["_source"] = "netop"
258259

259260
return plot_args
260261

graphtik/network.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,10 @@ def prepare_plot_args(self, plot_args: PlotArgs) -> PlotArgs:
341341
"""delegate to plan, with solution"""
342342
name = f"solution-x{len(self.plan.net.graph.nodes)}-nodes"
343343
plot_args = plot_args.with_defaults(name=name, solution=self)
344-
return self.plan.prepare_plot_args(plot_args)
344+
plot_args = self.plan.prepare_plot_args(plot_args)
345+
plot_args.graph.graph["_source"] = "solution"
346+
347+
return plot_args
345348

346349

347350
class _DataNode(str):
@@ -507,6 +510,7 @@ def prepare_plot_args(self, plot_args: PlotArgs) -> PlotArgs:
507510
if self.dag.nodes != graph.nodes:
508511
clusters = {n: "after pruning" for n in self.dag.nodes}
509512

513+
graph.graph["_source"] = "plan"
510514
return plot_args.with_defaults(
511515
name=f"plan-x{len(graph.nodes)}-nodes",
512516
steps=self.steps,
@@ -941,6 +945,7 @@ def prepare_plot_args(self, plot_args: PlotArgs) -> PlotArgs:
941945
inputs=self.needs,
942946
outputs=self.provides,
943947
)
948+
plot_args.graph.graph["_source"] = "net"
944949
return plot_args
945950

946951
def _append_operation(self, graph, operation: Operation):

0 commit comments

Comments
 (0)