Skip to content

Commit

Permalink
✨ Allow for use of graphviz as the "engine" for needflow (#1235)
Browse files Browse the repository at this point in the history
This commit allows for the use of [`graphviz`](https://graphviz.org) as the underlying engine for `needflow` diagrams, in addition to the default [`plantuml`](https://plantuml.com).
The intention being to simplify and improve performance of graph builds, since plantuml has issues with JVM initialisation times and reliance on a third-party sphinx extension.

It introduces a new configuration option; `needs_flow_engine`, which can be set to either `plantuml` or `graphviz`, and defaults to `plantuml`,
and a new directive option; `engine`, which can be set to either `plantuml` or `graphviz`, and defaults to `plantuml`.
Thus, the `graphivz` engine can be activated on a per-diagram basis, or globally.

The `graphviz` engine supports all the existing `needflow` options,
although one key complication is the translation of existing "style related" configurations, which are hard-coded to plantuml syntax:

- fields in `needs_extra_links`: `style`, `style_part`, `style_start`, `style_end`
- `needs_flow_configs`
- `needs_diagram_template`

The `needs_extra_links` fields are translated to graphviz syntax, where possible, and warnings emitted for those that could not be. Two issues that probably cannot be resolved (it is unclear exactly how plantuml achieves them):
1. Link styles with a direction, such as `-up->`
2. Applying correct shapes for needs that contain children/parts; in graphviz nodes cannot contain other nodes, and instead we must use "subgraph clusters" for such nodes, which do not allow a `shape` attribute

A separate `needs_graphviz_styles` configuration is introduced, which is similar to `needs_flow_configs`, except allowing graphviz attributes to be set (and used by the `needflow` directive's `config` option).

`needs_diagram_template` is not used; currently the graphviz engine hard-codes the format of node labels, but this could potentially be added in the future.

Additionally, an `alt` option is added to the `needflow` directive, and supported by both engines.

Note, currently the rendering with the `graphviz` engine is restricted to HTML output only, this could fairly easily be extended to latex/man/text/texinfo, which `sphinx.ext.graphviz` already supports, the main reason it is not already, is that we override the visitor node currently, to make some improvements.
  • Loading branch information
chrisjsewell authored Aug 26, 2024
1 parent c04dc4e commit 295c254
Show file tree
Hide file tree
Showing 20 changed files with 1,677 additions and 447 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ jobs:
sphinx-version: "5.0"
steps:
- uses: actions/checkout@v4
- name: Install graphviz (linux)
if: matrix.os == 'ubuntu-latest'
run: sudo apt-get install graphviz
- name: Install graphviz (windows)
if: matrix.os == 'windows-latest'
run: choco install --no-progress graphviz
- name: Set Up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
Expand Down
24 changes: 24 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@
}
}

graphviz_output_format = "svg"

# -- Options for html builder ----------------------------------------------

html_static_path = ["_static"]
Expand Down Expand Up @@ -497,6 +499,7 @@
}
""",
"tutorial": """
left to right direction
skinparam backgroundcolor transparent
skinparam Arrow {
Color #57ACDC
Expand All @@ -507,6 +510,27 @@
""",
}

needs_graphviz_styles = {
"tutorial": {
"graph": {
"rankdir": "LR",
"bgcolor": "transparent",
},
"node": {
"fontname": "sans-serif",
"fontsize": 12,
"penwidth": 2,
"margin": "0.11,0.11",
"style": "rounded",
},
"edge": {
"color": "#57ACDC",
"fontsize": 10,
"fontcolor": "#808080",
},
}
}

needs_show_link_type = False
needs_show_link_title = False
needs_title_optional = True
Expand Down
85 changes: 81 additions & 4 deletions docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ By default it is set to:
* **title**: Title, used as human readable name in lists
* **prefix**: A prefix for generated IDs, to easily identify that an ID belongs to a specific type. Can also be ""
* **color**: A color as hex value. Used in diagrams and some days maybe in other representations as well. Can also be ""
* **style**: A plantuml node type, like node, artifact, frame, storage or database. See `plantuml documentation <http://plantuml.com/deployment-diagram>`_ for more.
* **style**: A plantuml node type, like node, artifact, frame, storage or database. See `plantuml documentation <http://plantuml.com/deployment-diagram>`__ for more.

.. note::

Expand Down Expand Up @@ -532,6 +532,19 @@ If set to False, the filter results contains the original need fields and any ma
needs_allow_unsafe_filters = True
.. _needs_flow_engine:
needs_flow_engine
~~~~~~~~~~~~~~~~~
.. versionadded:: 2.2.0
Select between the rendering engines for :ref:`needflow` diagrams,
* ``plantuml``: Use `PlantUML <https://plantuml.com/>`__ to render the diagrams (default).
* ``graphviz``: Use `Graphviz <https://graphviz.org>`__ to render the diagrams.
.. _needs_flow_show_links:
needs_flow_show_links
Expand Down Expand Up @@ -601,11 +614,75 @@ This configurations can then be used like this:
.. needflow::
:tags: flow_example
:types: spec
:config: my_config
:config: lefttoright,my_config
Multiple configurations can be used by separating them with a comma,
these will be applied in the order they are defined.
See :ref:`needflow config option <needflow_config>` for more details and already available configurations.
.. _needs_graphviz_styles:
needs_graphviz_styles
~~~~~~~~~~~~~~~~~~~~~
.. versionadded:: 2.2.0
This must be a dictionary which can store multiple `Graphviz configurations <https://graphviz.org>`__.
These configs can then be selected when using :ref:`needflow` and the engine is set to ``graphviz``.
.. code-block:: python
needs_graphviz_styles = {
"my_config": {
"graph": {
"rankdir": "LR",
"bgcolor": "transparent",
},
"node": {
"fontname": "sans-serif",
"fontsize": 12,
},
"edge": {
"color": "#57ACDC",
"fontsize": 10,
},
}
}
This configurations can then be used like this:
.. code-block:: restructuredtext
.. needflow::
:engine: graphviz
:config: lefttoright,my_config
Multiple configurations can be used by separating them with a comma,
these will be merged in the order they are defined.
For example ``my_config1,my_config2`` would be the same as ``my_config3``:
.. code-block:: python
needs_graphviz_styles = {
"my_config1": {
"graph": {
"rankdir": "LR",
}
},
"my_config2": {
"graph": {
"bgcolor": "transparent",
}
}
"my_config3": {
"graph": {
"rankdir": "LR",
"bgcolor": "transparent",
}
}
}
.. _needs_report_template:
needs_report_template
Expand Down Expand Up @@ -719,9 +796,9 @@ needs_diagram_template
~~~~~~~~~~~~~~~~~~~~~~
This option allows to control the content of diagram elements which get automatically generated by using
`.. needflow::` / :ref:`needflow`.
`.. needflow::` / :ref:`needflow` (when using the ``plantuml`` engine).
This function is based on `plantuml <http://plantuml.com>`_, so that each
This function is based on `plantuml <http://plantuml.com>`__, so that each
`supported style <http://plantuml.com/creole>`_ can be used.
The rendered template is used inside the following plantuml syntax and must care about leaving the final string
Expand Down
Loading

0 comments on commit 295c254

Please sign in to comment.